AVCaptureVideoPreviewLayer平滑方向旋转

Jor*_*dan 14 iphone avfoundation ios

我正在尝试禁用任何可识别的方向旋转到AVCaptureVideoPreviewLayer,同时仍保持任何子视图的旋转.AVCaptureVideoPreviewLayer确实具有方向属性,更改它确实允许图层正确显示任何方向.然而,旋转涉及AVCaptureVideoPreviewLayer的一些时髦旋转,而不是像在相机应用程序中那样保持平滑.

这就是我如何使方向正常工作,减去轮换中的故障:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    _captureVideoPreviewLayer.frame = self.view.bounds;
    _captureVideoPreviewLayer.orientation = [[UIDevice currentDevice] orientation];
}
Run Code Online (Sandbox Code Playgroud)

如何保持此图层像Camera应用程序一样,同时保持其子视图的旋转?

另外,顺便说一下,我已经看到在AVCaptureVideoPreviewLayer上折旧了orientation属性,而且应该使用AVCaptureConnection的videoOrientation属性,但我不认为我有AVCaptureConnection可以在这里访问(我只是显示了屏幕上的相机).我该如何设置它以访问videoOrientation?

Ant*_*tox 12

在包含预览图层的视图上使用仿射变换可创建平滑过渡:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    if (cameraPreview) {
        if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
            cameraPreview.transform = CGAffineTransformMakeRotation(0);
        } else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
            cameraPreview.transform = CGAffineTransformMakeRotation(M_PI/2);
        } else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
            cameraPreview.transform = CGAffineTransformMakeRotation(-M_PI/2);
        }
        cameraPreview.frame = self.view.bounds;
    }
}
Run Code Online (Sandbox Code Playgroud)

willAnimateRotationToInterfaceOrientation在旋转动画块中调用该函数,因此在此处更改属性将与其余旋转动画一起生成动画.此功能已在iOS 6中逐步淘汰,并替换为处理设备旋转的新方法,因此现在可以使用,但不是最佳解决方案.


Kal*_*Kal 10

这是一个老问题,但由于它没有一个公认的答案,而且我在过去的几天里一直在处理这个问题,我想我会发布答案.

诀窍基于设备方向更改旋转视频,是无法旋转AVCaptureVideoPreviewLayerAVCaptureConnection在所有.

更改AVCaptureConnection(AVCaptureVideoPreviewLayer方向已弃用)的方向总是导致动画变化的丑陋.在视频旋转后,您仍然需要变换预览图层.

正确的方法是使用a AVAssetWriter来编写视频和音频数据..然后AVAssetWriterInput在开始录制时应用转换.

以下是Apple对此的一个模糊 -

从AVCaptureVideoDataOutput接收旋转的CVPixelBuffers

要请求缓冲区旋转,客户端在AVCaptureVideoDataOutput的视频AVCaptureConnection上调用-setVideoOrientation :. 请注意,物理旋转缓冲区确实会带来性能成本,因此只有在必要时才请求轮换.例如,如果您希望使用AVAssetWriter将旋转视频写入QuickTime影片文件,则最好在AVAssetWriterInput上设置-transform属性,而不是在AVCaptureVideoDataOutput中物理旋转缓冲区.

变换的应用类似于上面发布的代码.

  1. 您注册了设备方向更改.
  2. 根据新设备方向跟踪要应用的变换.
  3. 按下记录时,设置AVAssetWriterInput并对其应用变换.

希望这能帮助那些正在寻找答案的人.


jos*_*rth 2

我能够使用以下代码来完成此操作:

当您需要相机时进行设置:

preview = [[self videoPreviewWithFrame:CGRectMake(0, 0, 320, 480)] retain];
[self.view addSubview:preview];
Run Code Online (Sandbox Code Playgroud)

功能videoPreviewWithFrame

- (UIView *) videoPreviewWithFrame:(CGRect) frame {
  AVCaptureVideoPreviewLayer *tempPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]];
  [tempPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
  tempPreviewLayer.frame = frame;

  UIView* tempView = [[UIView alloc] init];
  [tempView.layer addSublayer:tempPreviewLayer];
  tempView.frame = frame;

  [tempPreviewLayer autorelease];
  [tempView autorelease];
  return tempView;
}
Run Code Online (Sandbox Code Playgroud)