2013-05-13 21 views
9

Stavo cercando di ottenere l'input della videocamera da mostrare su una vista del livello di anteprima.Ottieni anteprima fotocamera in AVCaptureVideoPreviewLayer

self.cameraPreviewView è legata ad un UIView in IB

Qui è il mio codice corrente che ho messo insieme dalla Guida AV Foundation programmazione. Ma l'anteprima non mostra mai

AVCaptureSession *session = [[AVCaptureSession alloc] init]; 
    session.sessionPreset = AVCaptureSessionPresetHigh; 

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    NSError *error = nil; 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 

    if (!input) { 
     NSLog(@"Couldn't create video capture device"); 
    } 
    [session addInput:input]; 


     // Create video preview layer and add it to the UI 
     AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
     UIView *view = self.cameraPreviewView; 
     CALayer *viewLayer = [view layer]; 

     newCaptureVideoPreviewLayer.frame = view.bounds; 

     [viewLayer addSublayer:newCaptureVideoPreviewLayer]; 

     self.cameraPreviewLayer = newCaptureVideoPreviewLayer; 



     [session startRunning]; 
+0

Puoi provare sottostante Codice ... newCaptureVideoPreviewLayer.frame = self.cameraPreviewView.bounds; [self.cameraPreviewView.layer addSublayer: newCaptureVideoPreviewLayer]; [session startRunning]; – BhushanVU

+0

@bhuXan - Solo provato e ancora vista nera. –

risposta

19

Così, dopo alcuni tentativi ed errori e guardando AVCam codice di esempio di Apple

ho avvolto il codice PreviewLayer e la sessione startRunning in un grande blocco di spedizione centrale in questo modo ed è iniziato a lavorare.

dispatch_async(dispatch_get_main_queue(), ^{ 
    AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
    UIView *view = self.cameraPreviewView; 
    CALayer *viewLayer = [view layer]; 

    newCaptureVideoPreviewLayer.frame = view.bounds; 

    [viewLayer addSublayer:newCaptureVideoPreviewLayer]; 

    self.cameraPreviewLayer = newCaptureVideoPreviewLayer; 

    [session startRunning]; 
}); 
+6

La riga più complicata qui è ** [session startRunning]; ** perché non è presentata nella maggior parte dei tutorial, sfortunatamente. –

+0

Mi spiace di non aver capito cosa sia esattamente 'self.cameraPreviewLayer'? Perchè confuso, ci dà chiaramente un errore se è a vista d'occhio –

17

Ecco il mio codice, funziona perfetto per me, è possibile fare riferimento ad esso

- (void)initCapture 
{ 
    AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil]; 
    if (!captureInput) { 
     return; 
    } 
    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    /* captureOutput:didOutputSampleBuffer:fromConnection delegate method !*/ 
    [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 
    NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
    NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
    NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
    [captureOutput setVideoSettings:videoSettings]; 
    self.captureSession = [[AVCaptureSession alloc] init]; 
    NSString* preset = 0; 
    if (!preset) { 
     preset = AVCaptureSessionPresetMedium; 
    } 
    self.captureSession.sessionPreset = preset; 
    if ([self.captureSession canAddInput:captureInput]) { 
     [self.captureSession addInput:captureInput]; 
    } 
    if ([self.captureSession canAddOutput:captureOutput]) { 
     [self.captureSession addOutput:captureOutput]; 
    } 

    //handle prevLayer 
    if (!self.captureVideoPreviewLayer) { 
     self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; 
    } 

    //if you want to adjust the previewlayer frame, here! 
    self.captureVideoPreviewLayer.frame = self.view.bounds; 
    self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    [self.view.layer addSublayer: self.captureVideoPreviewLayer]; 
    [self.captureSession startRunning]; 
} 
+1

ovviamente, puoi anche aggiungerlo con il blocco dispatch_async. – jianpx

+0

Grazie ha funzionato come un fascino :-) –

+0

Questo registrerà effettivamente? – user717452

Problemi correlati