同时AVCaptureVideoDataOutput和AVCaptureMovieFileOutput
我需要能够使AVCaptureVideoDataOutput
和AVCaptureMovieFileOutput
工作。 下面的代码工作,但是,video录制不。 在调用startRecordingToOutputFileURL
之后直接调用didFinishRecordingToOutputFileAtURL
委托。 现在,如果我通过简单的注释掉AVCaptureVideoDataOutput
从AVCaptureSession
删除:
[captureSession addOutput:captureDataOutput];
video录制的作品,但没有调用SampleBufferDelegate(我需要)。
我怎么能有AVCaptureVideoDataOutput
和AVCaptureMovieFileOutput
同时工作。
- (void)initCapture { AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:NULL]; captureDataOutput = [[AVCaptureVideoDataOutput alloc] init]; [captureDataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; m_captureFileOutput = [[AVCaptureMovieFileOutput alloc] init]; NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; [captureDataOutput setVideoSettings:videoSettings]; captureSession = [[AVCaptureSession alloc] init]; [captureSession addInput:captureInput]; [captureSession addOutput:m_captureFileOutput]; [captureSession addOutput:captureDataOutput]; [captureSession beginConfiguration]; [captureSession setSessionPreset:AVCaptureSessionPresetLow]; [captureSession commitConfiguration]; [self performSelector:@selector(startRecording) withObject:nil afterDelay:10.0]; [self performSelector:@selector(stopRecording) withObject:nil afterDelay:15.0]; [captureSession startRunning]; } - (void) startRecording { [m_captureFileOutput startRecordingToOutputFileURL:[self tempFileURL] recordingDelegate:self]; } - (void) stopRecording { if([m_captureFileOutput isRecording]) [m_captureFileOutput stopRecording]; } - (NSURL *) tempFileURL { NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"camera.mov"]; NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:outputPath]) { [[NSFileManager defaultManager] removeItemAtPath:outputPath error:nil]; [outputPath release]; return [outputURL autorelease]; } - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections { NSLog(@"start record video"); } - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { NSLog(@"end record"); } - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { // do stuff with sampleBuffer }
我应该补充我得到的错误:
Error Domain=NSOSStatusErrorDomain Code=-12780 "The operation couldn't be completed. (OSStatus error -12780.)" UserInfo=0x23fcd0 {AVErrorRecordingSuccessfullyFinishedKey=false}
从
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
干杯
我已经联系了苹果的支持工程师,他告诉我, AVCaptureVideoDataOutput
+ AVCaptureMovieFileOutput
同时使用不支持。 我不知道他们将来是否会支持,但是他用了“这个时候不支持”这个词。
我鼓励你填写一个bug报告/function请求,就像我一样(bugreport.apple.com),因为它们衡量人们想要的东西有多困难,而且我们也许可以在不久的将来看到这一点。
尽pipe无法使用AVCaptureVideoDataOutput
,但您可以使用AVCaptureVideoPreviewLayer
与AVCaptureMovieFileOutput
同时使用。 请参阅Apple网站上的“AVCam”示例。
在Xamarin.iOS中,代码如下所示:
var session = new AVCaptureSession(); var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video); var mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio); if(camera == null || mic == null){ throw new Exception("Can't find devices"); } if(session.CanAddInput(camera)){ session.AddInput(camera); } if(session.CanAddInput(mic)){ session.AddInput(mic); } var layer = new AVCaptureVideoPreviewLayer(session); layer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill; layer.VideoGravity = AVCaptureVideoPreviewLayer.GravityResizeAspectFill; cameraView = new UIView(); cameraView.Layer.AddSublayer(layer); var filePath = System.IO.Path.Combine( Path.GetTempPath(), "temporary.mov"); var fileUrl = NSUrl.FromFilename( filePath ); var movieFileOutput = new AVCaptureMovieFileOutput(); var recordingDelegate = new MyRecordingDelegate(); session.AddOutput(movieFileOutput); movieFileOutput.StartRecordingToOutputFile( fileUrl, recordingDelegate);