Avcapturevideopreviewlayer Orientation - Need Landscape

AVCaptureVideoPreviewLayer landscape orientation

First, the answer

- (void)viewWillLayoutSubviews {
_captureVideoPreviewLayer.frame = self.view.bounds;
if (_captureVideoPreviewLayer.connection.supportsVideoOrientation) {
_captureVideoPreviewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
}

- (AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation:(UIInterfaceOrientation)orientation {
switch (orientation) {
case UIInterfaceOrientationPortrait:
return AVCaptureVideoOrientationPortrait;
case UIInterfaceOrientationPortraitUpsideDown:
return AVCaptureVideoOrientationPortraitUpsideDown;
case UIInterfaceOrientationLandscapeLeft:
return AVCaptureVideoOrientationLandscapeLeft;
case UIInterfaceOrientationLandscapeRight:
return AVCaptureVideoOrientationLandscapeRight;
default:
break;
}
NSLog(@"Warning - Didn't recognise interface orientation (%d)",orientation);
return AVCaptureVideoOrientationPortrait;
}

I've come across several SO posts on this matter, and couldn't find any simple explanation so I thought I'd share my own.

If you follow Apple's sample on the matter, you'll run into two potential problems when you rotate your iOS device to landscape

  1. Capture will appear rotated (as if you're holding the camera 90 degrees off)
  2. It won't span its set bounds entirely

The problem here is that 'CALayer' doesn't support autorotation hence, unlike a 'UIView' you'd add as a subview, it won't rotate when its parent 'UIView' rotates. Therefore, you have to manually update its frame every time the parent view's bounds changes (not parent view's frame since frame stays the same after rotation). This is achieved by overriding 'viewWillLayoutSubviews' in the container view controller.

Secondly, you should use 'videoOrientation' property to inform AVFoundation about the orientation so it does the preview properly.

Hope this helps.

AVCaptureVideoPreviewLayer orientation - need landscape

The default camera orientation is Landscape Left (home button one the left). You need to do two things here:

1- Change the previewLayer frame to:

self.previewLayer.frame=self.view.bounds;

You need to set the preview layer frame to the bounds of the screen so that the frame of the preview layer changes when the screen rotates (you cannot use frame of the root view because that does not change with rotation but the bounds of the root view do). In your example, you are setting the previewlayer frame to a previewView property which I do not see.

2- You need to rotate the preview layer connection with the rotation of the device. Add this code in viewDidAppear:

-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];

//Get Preview Layer connection
AVCaptureConnection *previewLayerConnection=self.previewLayer.connection;

if ([previewLayerConnection isVideoOrientationSupported])
[previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

Hope this solves it.

Full Disclosure: This is a simplified version since you do not care if Landscape right or Landscape left.

Allow AVCaptureVideoPreviewLayer preview rotate with device

I fixed it - I just had to add this-

    if UIDevice.current.orientation == .portrait {
previewLayer.connection?.videoOrientation = .portrait
} else if UIDevice.current.orientation == .portraitUpsideDown {
previewLayer.connection?.videoOrientation = .portraitUpsideDown
} else if UIDevice.current.orientation == .landscapeLeft {
previewLayer.connection?.videoOrientation = .landscapeRight
} else if UIDevice.current.orientation == .landscapeRight {
previewLayer.connection?.videoOrientation = .landscapeLeft
}

-which gets called when the device is rotated. I also call it on startup after I have initialized the AVCaptureVideoPreviewLayer.



Related Topics



Leave a reply



Submit