AVCaptureVideoPreviewLayer not filling screen

14,505

Solution 1

try:

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.session];
[captureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

Swift Update

let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

Swift 4.0 Update

let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

Solution 2

In case someone have this issue you need just to take the bounds of screen

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = UIScreen.main.bounds
    previewLayer.videoGravity = .resizeAspectFill
    camPreview.layer.addSublayer(previewLayer)

Solution 3

            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
            DispatchQueue.main.async {
                self.videoPreviewLayer?.frame = self.captureImageView.bounds
            }
            cropImageRect = captureImageView.frame
            videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
            videoPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
            captureImageView.layer.addSublayer(videoPreviewLayer!)
            session!.startRunning()

This is work for me. The problem I faced was, I put the following line out of main thread. Its create the problem I think.

self.videoPreviewLayer?.frame = self.captureImageView.bounds

Share:
14,505
user2135074
Author by

user2135074

Updated on June 24, 2022

Comments

  • user2135074
    user2135074 about 2 years

    I read about one million threads about how to make a VideoPreviewLayer filling the complete screen of an iPhone but nothing works ... maybe you can help me because I'm really stuck.

    This is my Preview layer init:

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        // Choosing bigger preset for bigger screen.
        _sessionPreset = AVCaptureSessionPreset1280x720;
    }
    else
    {
        _sessionPreset = AVCaptureSessionPresetHigh;
    }
    
    [self setupAVCapture];
    
    AVCaptureSession *captureSession = _session;
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
    UIView *aView = self.view;
    previewLayer.frame = aView.bounds;
    previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
    [aView.layer addSublayer:previewLayer];
    

    That's my setupAvCapture Method:

      //-- Setup Capture Session.
    _session = [[AVCaptureSession alloc] init];
    [_session beginConfiguration];
    
    //-- Set preset session size.
    [_session setSessionPreset:_sessionPreset];
    
    //-- Creata a video device and input from that Device.  Add the input to the capture session.
    AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if(videoDevice == nil)
        assert(0);
    
    //-- Add the device to the session.
    NSError *error;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if(error)
        assert(0);
    
    [_session addInput:input];
    
    //-- Create the output for the capture session.
    AVCaptureVideoDataOutput * dataOutput = [[AVCaptureVideoDataOutput alloc] init];
    [dataOutput setAlwaysDiscardsLateVideoFrames:YES]; // Probably want to set this to NO when recording
    
    //-- Set to YUV420.
    [dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]
                                                             forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; // Necessary for manual preview
    
    // Set dispatch to be on the main thread so OpenGL can do things with the data
    [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
    
    [_session addOutput:dataOutput];
    [_session commitConfiguration];
    
    [_session startRunning];
    

    I already tried to use different AVCaptureSessionPresets and ResizeFit options. But it always looks like this:

    http://imageshack.us/photo/my-images/707/img0013g.png/

    Or this if I use previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; If I log the size of the layer the correct full screen size is returned.

    http://imageshack.us/photo/my-images/194/img0014k.png/

  • mattdeboard
    mattdeboard almost 9 years
    This does work on first load. But on rotation re-applying this does not seem to do the needful.
  • Nikolay
    Nikolay almost 9 years
    maybe you should stop the rotation of the camera preview. Make a transparent view layered over the preview for the buttons you are going to place and leave it rotating. I think rotating the camera preview is kinda funny and the above is the right answer. :)