(Swift)将视频输出保存到文件

时间:2015-05-17 23:15:39

标签: ios 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()
}

1 个答案:

答案 0 :(得分:3)

我在你的代码中发现了两个问题。

重复文件

根据startRecordingToOutputFileURL:recordingDelegate:的Apple文档:

  

开始录制到指定的网址。   该方法设置接收器当前正在写入输出媒体的文件URL。如果捕获开始时已存在给定URL的文件,则记录到新文件将失败。

     

在iOS中,不支持此帧精确文件切换。在再次调用此方法之前,必须调用stopRecording以避免任何错误。   通过调用stopRecording,通过使用此方法更改文件或由于错误停止记录时,需要包含在文件中的剩余数据将在后台写入。因此,您必须指定一个代理,当使用captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法将所有数据写入文件时将通知该代理。

在您的情况下,如果您开始新录制时已存在test.mp4,则会失败。因此,每次为录制的文件指定唯一名称会更好。例如,使用当前时间戳。

会话预设

在您的代码中,您将sessionPreset设置为AVCaptureSessionPresetPhoto

captureSession!.sessionPreset = AVCaptureSessionPresetPhoto

但根据我的个人经验,它不适合视频输出,并会导致您的错误。更改为AVCaptureSessionPresetHigh,然后重试。另外,建议您致电canSetSessionPreset:并仅在canSetSessionPreset:返回YES时应用预设。

示例代码

Apple对AVFoundation的使用提供了很好的sample code,您可能需要查看它。