Iphone 使用AV基础旋转AV视频预览区域及其他元素

Iphone 使用AV基础旋转AV视频预览区域及其他元素,iphone,ios,avfoundation,orientation-changes,Iphone,Ios,Avfoundation,Orientation Changes,我启动了一个项目,使用UIImagePickerController捕捉静态图像。我已经放弃使用这个简单的机制,因为覆盖层和刚刚拍摄的图像之间的交互很差。问题如下:如果覆盖处于活动状态,并捕捉照片,则当用户看到使用或重新拍摄图像的选项时,刚刚捕捉的图像会旋转以在纵向方向上进行纵横比填充。出现这种情况时,无法关闭覆盖,也无法旋转覆盖以对应于新的静态图像预览方向。不太好 我决定使用AV基金会的各种机制来重新实现UIIVIEPPEICKER控制器的静态图像捕获行为。设置起来非常容易,但我仍然有一些挥之

我启动了一个项目,使用UIImagePickerController捕捉静态图像。我已经放弃使用这个简单的机制,因为覆盖层和刚刚拍摄的图像之间的交互很差。问题如下:如果覆盖处于活动状态,并捕捉照片,则当用户看到使用或重新拍摄图像的选项时,刚刚捕捉的图像会旋转以在纵向方向上进行纵横比填充。出现这种情况时,无法关闭覆盖,也无法旋转覆盖以对应于新的静态图像预览方向。不太好

我决定使用AV基金会的各种机制来重新实现UIIVIEPPEICKER控制器的静态图像捕获行为。设置起来非常容易,但我仍然有一些挥之不去的问题:

1) 我希望重新定向机制,使其类似于标准UIImagePickerController中的UI工作方式。正如您所知,在该控制器中,无论手机如何旋转,按钮栏始终固定在纵向的底部。在此按钮栏中,按钮中的图示符本身会旋转,但其他所有内容都保持不变。覆盖控件(用于闪光灯设置、相机切换和选项)会重新定向。在旋转这些其他元素时,如何使此选项卡栏保持固定状态?有没有办法从旋转中排除某些元素

2) 在进行自动重新定向时,我希望AVVideoCaptureLayer始终保持活动状态并占据整个屏幕。当设备执行重新定向旋转时,该层的大小会奇怪地变小(缩小),视频馈送本身会关闭90度。很明显,这一层正在旋转,但没有达到全屏尺寸,视频馈送本身的行为也没有达到预期。我希望视频在整个旋转过程中保持固定并占据整个屏幕,up始终处于up状态,并且在旋转过程中不调整预览的大小。但我也希望能够像第1项一样,对某些元素进行重新定向


非常感谢演示如何实现这一点的任何示例代码。

我在自己的努力中遇到了类似的问题,最终放弃了试图影响视频流的想法。相反,我专注于AVCaptureVideoPreviewLayer本身,并提出了以下解决方案:

- (void)orientationChangedMethod {
    self.previewLayer.orientation = [[UIDevice currentDevice] orientation];
    self.previewLayer.frame = self.view.bounds;
}
其中,orientationChangedMethod是对self.previewLayer的(非常有用)代码的一种填充,而self.previewLayer是对我的AVCaptureVideoPreviewLayer实例的引用


自iOS 6以来,此答案已被弃用

刚刚发现在AVCaptureVideoPreviewLayer上使用orientation属性是不推荐的。这是一个更新的解决方案(尽管@Jaret Ward共享的以前的解决方案工作量要小得多:):

使用建议的方法在AVCaptureConnection中使用setVideoOrientation进行更改。我会在ViewDidDisplay和您的一个轮换回调中为此添加一个调用

//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;
}

通过设置视频预览层连接的方向属性。

这只是@CocoaEv回答的更清晰版本。除了使方向固定为函数而不是方法之外,它还使用了较新的点语法

self.videoPreviewLayer.connection.videoOrientation = AVOrientationFromDeviceOrientation([UIDevice currentDevice].orientation);

AVCaptureVideoOrientation AVOrientationFromDeviceOrientation(UIDeviceOrientation deviceOrientation) {
    if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
        return AVCaptureVideoOrientationLandscapeRight;
    else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
        return AVCaptureVideoOrientationLandscapeLeft;
    else if( deviceOrientation == UIDeviceOrientationPortrait)
        return AVCaptureVideoOrientationPortrait;
    else if( deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
        return AVCaptureVideoOrientationPortraitUpsideDown;
    else
        return deviceOrientation;
}

非常感谢。很好的解决方案。我刚刚完成了一系列变换和帧大小调整。您的解决方案要简单得多。做得好。刚刚发现在AVCaptureVideoPreviewLayer上使用orientation属性是不推荐的。我用更新的解决方案更新了下面的答案。再次感谢@Jaret Ward!这个答案在iOS 6中被弃用。