Incorrect orientation of AVCaptureVideoPreviewLayer when UI rotation is disabled

I have an instance of AVCaptureVideoPreviewLayer added to the view controller view hierarchy.

 - (void) loadView { ... self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:nil]; self.previewLayer.frame = self.view.bounds; self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.view.layer addSublayer: _previewLayer]; // adding other UI elements ... } ... - (void) _setupPreviewLayerWithSession: (AVCaptureSession*) captureSession { self.previewLayer.session = self.captureManager.captureSession; self.previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight; } 

The layer frame is updated in the -viewDidLayoutSubviews method. View controller orientation locked on UIInterfaceOrientationMaskLandscapeRight .

The problem is as follows:

  • the device is held in landscape orientation
  • The view controller is presented as modal - the video layer is displayed. Correct orientation
  • the device is then locked, and when it is locked, the device rotates in portrait orientation.
  • the device then unlocks while it remains in portrait orientation, and a video slot rotated 90 degrees is displayed for several seconds. However, the frame for the video layer is correct. All other interface elements are displayed correctly. After a few seconds, the layer will snap to the correct orientation. Please find the borders for the layer and interface elements below. Incorrect orientation

I tried updating the orientation of the video layer as follows (with no results):

  • AVCaptureSessionDidStartRunningNotification and UIApplicationDidBecomeActiveNotification
  • calling the update when calling the -viewWillTransitionToSize:withTransitionCoordinator:
  • on -viewWillAppear:

The problem does not seem to be related to the orientation of the video layer, but more to view the hierarchy layout.

UPDATE:

As suggested, I also tried to update the orientation of the video layer when changing the orientation of the device, which did not help.

I also noticed that the problem mainly occurs after the application starts, and the screen is displayed for the first time. In subsequent screen presentations during the same session, the playback speed for the problem is really low (about 1/20).

+8
ios objective-c rotation avfoundation avcapturesession
source share
1 answer

Try this code:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; -(void)orientationChanged:(NSNotification *)notif { [_videoPreviewLayer setFrame:_viewPreview.layer.bounds]; if (_videoPreviewLayer.connection.supportsVideoOrientation) { _videoPreviewLayer.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; } 
+3
source share

All Articles