0

我正在构建一个应用程序,使用AVCaptureVideoPreviewLayer显示视频预览图层。的设置已经非常直截了当,而且似乎运作良好:MPMoviePlayerController冻结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被添加到视图中,预览“冻结” - 它显示摄像机前面的任何内容的最后一帧,然后输入该代码块。我没有收到任何错误消息,也找不到任何来源问题

我注意到我没有发布播放器变量。任何尝试这样做都会破坏播放器,包括自动释放它,或试图释放它通知回调。然而,我不认为这个问题(尽管它本身可能是一个问题)是我的预览层的杀手之源。

我很感谢您对此问题的任何见解!

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

+0

这是真的,你不应该释放您的播放器(这是一个控制器),除非你把它添加到一个控制器层次结构,但你也不想只是泄漏了。可能你想让它成为你的自定义视图控制器的属性,或者你的应用程序委托。我并不清楚你使用播放器视图交换预览视图(包含预览图层的视图)的技巧。预览和播放器是否查看详细视图的子视图?视图层次结构的安排并不完全清楚。 –

+0

为了比较,我有一个测试应用程序,我写了一段时间回来玩这个(虽然它使用AVPlayerLayer而不是MPMoviePlayerController,以及自定义按钮来启动/停止电影)。我有一个带有两个选项卡的选项卡视图:一个用于播放器,一个用于预览/记录。我为你设置了预览。设置播放器图层看起来像......好吧,我不能将它放入注释中,但AV Foundation编程指南会引导读者完成它。 –

回答

0

经过无数次的挣扎后,我决定采用不同的解决方案。我一直将预览图层保存在内存中,并在将视图切换到detailView时运行。现在,我将取消预览图层并关闭记录会话,然后在用户返回时将其重新构建。它在重新初始化previewLayer时会导致大约一秒的延迟,但它正在工作,我认为这很好。

0

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

1

感谢这篇文章!经过3个小时的调试,我终于得到了我的应用程序。我使用了这里建议的第二种方法,它的工作非常好。

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