Cómo aplicar un filter a Video en time real usando Swift

¿Es posible aplicar un filter a AVLayer y agregarlo para ver como addSublayer ? Quiero cambiar los colors y agregar un poco de ruido al video desde la camera usando Swift y no sé cómo.

Pensé que es posible agregar filterLayer y previewLayer así:

self.view.layer.addSublayer(previewLayer) self.view.layer.addSublayer(filterLayer) 

y esto tal vez pueda crear videos con mi filter personalizado, pero creo que es posible hacerlo de manera más eficaz utilizando AVComposition

Entonces, lo que necesito saber:

  1. ¿Cuál es la forma más sencilla de aplicar el filter a la salida de video de la camera en time real?
  2. ¿Es posible fusionar AVCaptureVideoPreviewLayer y CALayer ?

Gracias por cada sugerencia …

Hay otra alternativa, use una AVCaptureSession para crear instancias de CIImage a las que puede aplicar CIFilters (de las cuales hay cargas, desde borrones hasta corrección de color a VFX).

Aquí hay un ejemplo con el efecto ComicBook. En pocas palabras, cree una AVCaptureSession:

 let captureSession = AVCaptureSession() captureSession.sessionPreset = AVCaptureSessionPresetPhoto 

Cree una AVCaptureDevice para representar la camera, aquí estoy configurando la camera trasera:

 let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

Luego crea una implementación concreta del dispositivo y adjúntalo a la session. En Swift 2, crear una instancia de AVCaptureDeviceInput puede generar un error, por lo que necesitamos capturar eso:

  do { let input = try AVCaptureDeviceInput(device: backCamera) captureSession.addInput(input) } catch { print("can't access camera") return } 

Ahora, aquí hay un poco de 'gotcha': aunque en realidad no usamos un AVCaptureVideoPreviewLayer, pero se requiere que el delegado de muestra funcione, entonces creamos uno de los siguientes:

 // although we don't use this, it's requinetworking to get captureOutput invoked let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) view.layer.addSublayer(previewLayer) 

A continuación, creamos una salida de video, AVCaptureVideoDataOutput que usaremos para acceder a la transmisión de video:

 let videoOutput = AVCaptureVideoDataOutput() 

Al asegurar que auto implementa AVCaptureVideoDataOutputSampleBufferDelegate, podemos establecer el delegado de buffer de muestra en la salida de video:

  videoOutput.setSampleBufferDelegate(self, queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL)) 

La salida de video se adjunta a la session de captura:

  captureSession.addOutput(videoOutput) 

… y, finalmente, comenzamos la session de captura:

 captureSession.startRunning() 

Debido a que hemos configurado el delegado, se invocará captureOutput con cada captura de marco. captureOutput se pasa un búfer de ejemplo de tipo CMSampleBuffer y solo toma dos líneas de código para convertir esos datos en un CIImage para que Core Image los maneje:

 let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!) 

… y los datos de la image se pasan a nuestro efecto de libro de historietas que, a su vez, se utiliza para completar una vista de la image:

 let comicEffect = CIFilter(name: "CIComicEffect") comicEffect!.setValue(cameraImage, forKey: kCIInputImageKey) let filtenetworkingImage = UIImage(CIImage: comicEffect!.valueForKey(kCIOutputImageKey) as! CIImage!) dispatch_async(dispatch_get_main_queue()) { self.imageView.image = filtenetworkingImage } 

Tengo el código fuente de este proyecto disponible en mi repository GitHub aquí .