'AVCaptureVideoPreviewLayer not filling screen
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.
Solution 1:[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 = .resizeAspectFill
Solution 2:[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:[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
Solution 4:[4]
Swift 5 and Xcode13
This worked for me
Creates the AVCapturePreviewLayer
class ViewController: UIViewController {
let previewLayer = AVCapturePreviewLayer()
}
Adds PreviewLayer into View
override func viewDidLoad() {
super.viewDidLoad()
// Adds Element to the View Layer
view.layer.addSublayer(previewLayer)
Makes PreviewLayer the full bounds of View
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
previewLayer.frame = view.bounds
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ethan Allen |
Solution 2 | Ahmed Safadi |
Solution 3 | Y Junction |
Solution 4 | LawlessLLC |