我在一个视图控制器中捕获视频,音频和照片,理想情况下是一次捕获会话。
我目前遇到的问题是录制视频。它显示输出到我的预览正常。我已启用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()
}
答案 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,您可能需要查看它。