2015-05-17 73 views
3

我在一個視圖控制器中捕獲視頻,音頻和照片,理想情況下只需一個捕獲會話。(Swift)將視頻輸出保存到文件

我現在的問題是錄製視頻。它顯示輸出到我的預覽罰款。我啓用了AVCaptureFileOutputRecordingDelegate並實施了以下方法。

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

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

當我雖然運行上面的代碼,我得到這個錯誤:

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

我的配置:

func configureCaptureSession() { 
    capturedPhoto.contentMode = .ScaleAspectFill 
    capturedPhoto.clipsToBounds = true 
    capturedPhoto.hidden = true 

    captureSession = AVCaptureSession() 

    captureSession!.beginConfiguration() 

    captureSession!.sessionPreset = AVCaptureSessionPresetPhoto 


    var error: NSError? 

    AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryRecord, error: &error) 
    AVAudioSession.sharedInstance().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() 
} 

回答

3

我發現了兩個問題在您的碼。

重複的文件

爲每startRecordingToOutputFileURL:recordingDelegate:蘋果文檔:

開始錄製一個給定的URL。 該方法設置接收器當前正在寫入輸出媒體的文件URL。如果開始捕捉時給定URL處的文件已存在,則錄製到新文件將失敗。

在iOS中,不支持此幀準確的文件切換。在再次調用此方法之前,您必須調用stopRecording以避免任何錯誤。 當通過調用stopRecording,通過使用此方法更改文件或由於錯誤而停止錄製時,需要包含在文件中的其餘數據將寫入後臺。因此,您必須指定一個委託,在使用captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法將所有數據寫入文件時將會通知該委託。

在你的情況下,如果test.mp4已經存在,當你開始一個新的錄音時,它會失敗。所以最好每次給錄製文件一個唯一的名稱。例如,使用當前的時間戳。

會議預設

在代碼中,你設置sessionPresetAVCaptureSessionPresetPhoto

captureSession!.sessionPreset = AVCaptureSessionPresetPhoto 

但根據我個人的經驗,這是不適合的視頻輸出,並會導致您的錯誤。更改爲AVCaptureSessionPresetHigh並重試。建議撥打canSetSessionPreset:並僅在canSetSessionPreset:返回YES時應用預設。

示例代碼

蘋果的AVFoundation的使用提供了一個很好sample code,你可能要檢查它。

+0

問題出在預設。在我使用我忘記包含的錄音之前,我有刪除mp4的代碼,但對於實際產品,我們將使用時間戳。謝謝 – maxhud