(Swift) Guardar salida de video en file

Estoy capturando video, audio y fotos en un controller de vista, idealmente con una session de captura.

El problema que tengo actualmente es grabar video. Muestra la salida a mi vista previa bien. Tengo habilitado el AVCaptureFileOutputRecordingDelegate y se implementó el siguiente método.

 func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) 

 var outputUrl = NSURL(fileURLWithPath: NSTemporaryDirectory() + "test.mp4") movieOutput?.startRecordingToOutputFileURL(outputUrl, recordingDelegate: self) 

Recibo este error cuando ejecuto el código anterior sin embargo:

 'NSInvalidArgumentException', reason: '*** -[AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] - no active/enabled connections.' 

Mi configuracion:

 func configureCaptureSession() { captunetworkingPhoto.contentMode = .ScaleAspectFill captunetworkingPhoto.clipsToBounds = true captunetworkingPhoto.hidden = true captureSession = AVCaptureSession() captureSession!.beginConfiguration() captureSession!.sessionPreset = AVCaptureSessionPresetPhoto var error: NSError? AVAudioSession.shanetworkingInstance().setCategory(AVAudioSessionCategoryRecord, error: &error) AVAudioSession.shanetworkingInstance().setActive(true, error: &error) var audioDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio) var audioInput = AVCaptureDeviceInput(device: audioDevice, error: &error) if error == nil && captureSession!.canAddInput(audioInput) { captureSession!.addInput(audioInput) } photoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) photoDeviceInput = AVCaptureDeviceInput(device: photoCaptureDevice, error: &error) if error == nil && captureSession!.canAddInput(photoDeviceInput) { captureSession!.addInput(photoDeviceInput) stillImageOutput = AVCaptureStillImageOutput() stillImageOutput!.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] if captureSession!.canAddOutput(stillImageOutput) { captureSession!.addOutput(stillImageOutput) } movieOutput = AVCaptureMovieFileOutput() if captureSession!.canAddOutput(movieOutput) { captureSession!.addOutput(movieOutput) } photoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) photoPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill photoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait cameraView.layer.addSublayer(photoPreviewLayer) contentView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "focusPhoto:")) } captureSession!.commitConfiguration() captureSession!.startRunning() } 

Encontré dos problemas en tu código.

Archivo duplicado

Según la documentation de Apple de startRecordingToOutputFileURL:recordingDelegate: ::

Inicia la grabación en una URL determinada. El método establece la URL del file en el que el receptor está actualmente escribiendo los medios de salida. Si un file en la URL dada ya existe cuando comienza la captura, la grabación en el nuevo file fallará.

En iOS, este cambio de file preciso de marco no es compatible. Debe llamar a stopRecording antes de volver a llamar a este método para evitar cualquier error. Cuando la grabación se detiene llamando a stopRecording, cambiando files con este método o debido a un error, los datos restantes que deben includese en el file se escribirán en segundo plano. Por lo tanto, debe especificar un delegado que se notificará cuando todos los datos se hayan escrito en el file mediante el captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error: method.

En su caso, si test.mp4 ya existe cuando inicia una nueva grabación, fallará. Por lo tanto, es mejor dar al file grabado un nombre único cada vez. Por ejemplo, use la timestamp actual.

Preselección de session

En su código, establece sessionPreset en AVCaptureSessionPresetPhoto :

 captureSession!.sessionPreset = AVCaptureSessionPresetPhoto 

Pero según mi experiencia personal, no es adecuado para una salida de video y generará un error. Cambie a AVCaptureSessionPresetHigh e intente nuevamente. También se recomienda llamar a canSetSessionPreset: y aplicar el preset solo si canSetSessionPreset: devuelve YES .

Código de muestra

Apple ofrece un buen código de muestra sobre el uso de AVFoundation , es posible que desee comprobarlo.