0

我正在构建一个使用 AVCaptureVideoPreviewLayer 显示视频预览层的应用程序。它的设置非常简单,而且似乎运行良好:

newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:[[self captureManager] session]];
CGRect tmpRect = CGRectInset(recordingView.bounds, 3, 3);
[newCaptureVideoPreviewLayer setFrame:CGRectInset(tmpRect, 3, 3)];
CALayer *viewLayer = [recordingView layer];
[newCaptureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[viewLayer insertSublayer:newCaptureVideoPreviewLayer below:[[viewLayer sublayers] objectAtIndex:0]];
[self setCaptureVideoPreviewLayer:newCaptureVideoPreviewLayer];
[newCaptureVideoPreviewLayer release];

后来,我遇到了一种情况,用户可以使用 MPMoviePlayerController 将包含预览层的视图与显示包含录制视频的视图交换。我是这样设置的(前面的代码块来自 UIViewController 的 viewDidLoad: 方法,这是在同一个控制器中,作为它自己更改视图的方法的一部分:

MPMoviePlayerController * player = [[MPMoviePlayerController alloc] initWithContentURL:url];
[player.view setFrame:[detailView playerView].bounds];  // player's frame must match parent's

player.view.backgroundColor = [UIColor clearColor];
player.shouldAutoplay = NO;
player.fullscreen = NO;
player.scalingMode = MPMovieScalingModeAspectFit;

[[detailView playerView] addSubview:player.view];

问题是当 MPMoviePlayerController 添加到视图中时,预览“冻结”——它显示了在进入此代码块之前相机前面的任何内容的最后一帧。我没有收到任何错误消息,也找不到任何问题的根源。

我确实注意到我没有释放player变量。任何这样做的尝试都会破坏播放器,包括自动释放它,或尝试在通知回调中释放它。但是,我不认为这个问题(虽然它本身可能是一个问题)是杀死我的预览层的根源。

如果您对这个问题有任何见解,我将不胜感激!

更新:@boredastronaut 在下面询问我如何在这里设置视图。我有一个控制器运行所有视图。在我的应用程序中,我有预览层,并且在同一个位置,包含播放器的视图。所有视图都加载到 -loadView: 中,我使用hidden属性来显示/隐藏这些图层。

4

3 回答 3

1

感谢这篇文章!经过 3 小时的调试,我终于让我的应用程序运行起来。我使用了这里建议的第二种方法,效果很好。

if([self.capMan.session isInterrupted]) { [self.capMan.session startRunning]; }

于 2013-04-26T04:16:57.957 回答
0

经过不小的挣扎后,我选择了不同的解决方案。在将视图切换到 detailView 时,我一直将预览层保存在内存中并运行。现在,我要关闭 previewLayer 并在它离开屏幕时完全关闭录制会话,然后在用户返回时再次构建它。它在重新初始化 previewLayer 时会导致大约一秒钟的延迟,但它正在工作,我认为这很好。

于 2011-10-15T01:23:16.260 回答
0

您可以只检查预览层的会话是否正在运行,如果没有,则调用startRunning会话的方法。

于 2012-05-15T08:26:59.167 回答