2010-10-19 32 views
18

Tôi cần có thể có AVCaptureVideoDataOutputAVCaptureMovieFileOutput làm việc cùng một lúc. Mã dưới đây hoạt động, tuy nhiên, việc quay video thì không. Các đại biểu didFinishRecordingToOutputFileAtURL được gọi trực tiếp sau khi startRecordingToOutputFileURL được gọi. Bây giờ nếu tôi loại bỏ AVCaptureVideoDataOutput từ AVCaptureSession bằng cách đơn giản cho ý kiến ​​ra dòng:Đồng thời AVCaptureVideoDataOutput và AVCaptureMovieFileOutput

[captureSession addOutput:captureDataOutput];

Các công trình quay video nhưng sau đó SampleBufferDelegate không được gọi (mà tôi cần).

Tôi có thể làm cách nào để có AVCaptureVideoDataOutputAVCaptureMovieFileOutput hoạt động đồng thời.

- (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 
} 

tôi nên thêm tôi đang nhận được lỗi:

Error Domain=NSOSStatusErrorDomain Code=-12780 "The operation couldn’t be completed. (OSStatus error -12780.)" UserInfo=0x23fcd0 {AVErrorRecordingSuccessfullyFinishedKey=false} 

từ

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error 

Cheers

+1

Có một cách làm việc đã được chứng minh để làm điều này. Trong câu hỏi này: http://stackoverflow.com/questions/4944083/can-use-avcapturevideodataoutput-and-avcapturemoviefileoutput-at-the-same-time –

Trả lời

29

tôi đã liên lạc với một kỹ sư tại vùng hỗ trợ của Apple và ông nói với tôi rằng đồng thời AVCaptureVideoDataOutput + AVCaptureMovieFileOutput sử dụng không được hỗ trợ. Tôi không biết liệu họ có ủng hộ nó trong tương lai hay không, nhưng anh ấy đã dùng từ "không được hỗ trợ vào lúc này".

Tôi khuyến khích bạn điền vào một báo cáo lỗi/yêu cầu tính năng về điều này, như tôi đã làm (bugreport.apple.com), khi họ đo lường mức độ khó khăn của mọi người và chúng tôi có thể thấy điều này trong tương lai gần.

+2

Hãy chắc chắn để xem bình luận của Oded ở trên với một giải pháp làm việc: http: //stackoverflow.com/questions/4944083/can-use-avcapturevideodataoutput-and-avcapturemoviefileoutput-at-the-same-time –

+0

@StanJames là nó vẫn là trường hợp ngày hôm nay nơi workaround oded là cách tiếp cận tốt nhất để sử dụng AVCaptureVideoDataOutput + AVCaptureMovieFileOutput cùng một lúc? – Crashalot

+0

@StanJames nếu mục tiêu là tạo hai video cùng một lúc, bạn có thể sử dụng hai AVAssetWriters (chỉ với AVCaptureVideoDataOutput) thay vì cả AVCaptureVideoDataOutput và AVCaptureMovieFileOutput không? – Crashalot

2

Mặc dù bạn không thể sử dụng AVCaptureVideoDataOutput, bạn có thể sử dụng AVCaptureVideoPreviewLayer đồng thời với AVCaptureMovieFileOutput. Xem ví dụ "AVCam" trên Trang web của Apple.

Trong Xamarin.iOS, mã trông như thế này:

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); 
+0

và cách lấy bộ đệm khung thô từ AVCaptureVideoPreviewLayer? ... – user924

Các vấn đề liên quan