Get Camera Preview to AVCaptureVideoPreviewLayer

27,898

Solution 1

So after some trial and error and looking at apple's AVCam Sample Code

I wrapped the PreviewLayer code and session startRunning into a grand central dispatch block like so and it started working.

 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];
});

Solution 2

here is my code, it works perfect for me , you can refer to it

- (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];
}
Share:
27,898
William
Author by

William

Updated on July 09, 2022

Comments

  • William
    William almost 2 years

    I was trying to get the camera input to show on a preview layer view.

    self.cameraPreviewView is tied to a UIView in IB

    Here is my current code that I put together from the AV Foundation Programming Guide. But the preview never shows

    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];