2010-10-19 11 views
18

Muszę mieć możliwość pracy w trybie AVCaptureVideoDataOutput i AVCaptureMovieFileOutput w tym samym czasie. Poniższy kod działa, jednak nagrywanie wideo nie. Delegat didFinishRecordingToOutputFileAtURL jest wywoływany bezpośrednio po wywołaniu startRecordingToOutputFileURL. Teraz jeśli usunąć AVCaptureVideoDataOutput z AVCaptureSession po prostu zakomentowanie linię:Jednoczesne AVCaptureVideoDataOutput i AVCaptureMovieFileOutput

[captureSession addOutput:captureDataOutput];

pracach nagrywania wideo, ale potem SampleBufferDelegate nie nazywa (które trzeba).

Jak mogę pracować mając jednocześnie AVCaptureVideoDataOutput i 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 
} 

Dodam otrzymuję błąd:

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

z

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

Cheers

+1

Jest to sprawdzony sposób pracy, aby to zrobić. Więcej na to pytanie: http://stackoverflow.com/questions/4944083/can-use-avcapturevideodataoutput-and-avcapturemoviefileoutput-at-tame-time-time –

Odpowiedz

29

I skontaktowaliśmy inżyniera przy wsparciu firmy Apple i powiedział mi, że jednoczesna AVCaptureVideoDataOutput + AVCaptureMovieFileOutput użycie nie jest obsługiwane. Nie wiem, czy będą go wspierać w przyszłości, ale użył słowa "nieobsługiwany w tym czasie".

Zachęcam do wypełnienia zgłoszenia błędu/prośby o funkcję w tej sprawie, tak jak ja (bugreport.apple.com), ponieważ mierzą, jak ciężko ludzie czegoś chcą, a być może zobaczymy to w niedalekiej przyszłości.

+2

Pamiętaj, aby zobaczyć komentarz Odeda powyżej z działającym rozwiązaniem: http: //stackoverflow.com/questions/4944083/can-use-avcapturevideodataoutput-and-avcapturemoviefileoutput-at-tame-time-time –

+0

@StanJames jest nadal w tym przypadku, gdzie obejście odeda jest najlepszym sposobem jednoczesnego korzystania z AVCaptureVideoDataOutput + AVCaptureMovieFileOutput? – Crashalot

+0

@StanJames, jeśli celem jest utworzenie dwóch filmów jednocześnie, czy można użyć dwóch zestawów AVA (tylko z AVCaptureVideoDataOutput) zamiast dwóch AVCaptureVideoDataOutput i AVCaptureMovieFileOutput? – Crashalot

2

Chociaż nie można używać AVCaptureVideoDataOutput, ty może używać AVCaptureVideoPreviewLayer równocześnie z AVCaptureMovieFileOutput. Zobacz przykład "AVCam" na stronie Apple.

W Xamarin.iOS, kod wygląda następująco:

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

i jak uzyskać surowy bufor ramki z AVCaptureVideoPreviewLayer? ... – user924

Powiązane problemy