Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating AV video preview area and other elements when using AV Foundation

I had started a project using UIImagePickerController to capture still images. I had abandoned using this simple mechanism because of the poor interaction between overlays and just-captured images. The problem was as follows: If you have an overlay active, and snap a photo, the just snapped image rotates around to do an aspect fill in the portrait orientation, when the user is presented the option to use or retake the image. When this occurs, there is no way to dismiss the overlay, or rotate the overlay to correspond to the new still image preview orientation. Not good.

I decided to attempt to re-implement the still image capture behavior of UIImagePickerController using the various mechanisms from AV Foundation. This has been surprisingly easy to set up, but I still have some lingering issues:

1) I want to re-orienting mechanism to be similar to how the UI works in the standard UIImagePickerController. In this controller, as you know, the button bar always stays fixed to the bottom of the portrait orientation, regardless of how the phone is rotated. Within this button bar, the glyphs in the buttons themselves rotate, but everything else remains fixed. The overlay controls, for flash set, camera toggle, and options, does reorient. How can I get this tab bar to remain pinned while rotating these other elements? Is there a way to exclude certain elements from rotation?

2) Upon doing the automatic reorientation, I want the AVVideoCaptureLayer to always remain live and occupy the entire screen. When the device performs the reorientation rotation, this layer gets sized strangely (shrunk down) and the video feed itself is off by 90 degrees. So apparently this layer is being rotated but not to the full screen dimension, and the video feed itself isn't behaving as expected. I want the video to remain fixed and occupying the full screen through the full rotation, with up always being up, and no resizing of the preview during rotation. But I also want to be able to do as in item 1, with certain elements reorienting.

Any sample code illustrating how to achieve this is greatly appreciated.

like image 662
Skip Haughay Avatar asked Dec 21 '22 11:12

Skip Haughay


1 Answers

just found out that using the orientation property on AVCaptureVideoPreviewLayer is deprecated. here is an updated solution (although the previous solution shared by @Jaret Ward was much less work :) :

use the recommend approach of changing it with setVideoOrientation in AVCaptureConnection. I would add a call to this in viewDidAppear and in one of your rotation callbacks.

//setup a connection to the preview layer
AVCaptureConnection *connection;
connection = [self.videoPreviewLayer connection];
[connection setVideoOrientation:[self avOrientationForDeviceOrientation:[[UIDevice currentDevice] orientation]]];

//translate the orientation
 - (AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation)deviceOrientation {

AVCaptureVideoOrientation result = deviceOrientation;
if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
    result = AVCaptureVideoOrientationLandscapeRight;
else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
    result = AVCaptureVideoOrientationLandscapeLeft;
else if( deviceOrientation == UIDeviceOrientationPortrait)
    result = AVCaptureVideoOrientationPortrait;
else if( deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
    result = AVCaptureVideoOrientationPortraitUpsideDown;
return result;
}
like image 80
CocoaEv Avatar answered Dec 31 '22 13:12

CocoaEv