【发布时间】:2024-01-14 03:01:01
【问题描述】:
我正在构建一个使用 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 属性来显示/隐藏这些图层。
【问题讨论】:
-
确实,您不应该释放您的播放器(这是一个控制器),除非您已将其添加到控制器层次结构中,但您也不想只是泄漏它。可能您想让它成为您的自定义视图控制器或您的应用程序委托的属性。我不清楚您将预览视图(包含预览层的视图)与播放器视图交换的技术。预览和播放器视图都是详细视图的子视图吗?视图层次结构是如何排列的并不完全清楚。
-
为了比较,我有一个测试应用程序,我写了一段时间来玩这个(尽管它使用 AVPlayerLayer 而不是 MPMoviePlayerController,以及一个自定义按钮来开始/停止电影)。我有一个带有两个选项卡的选项卡视图:一个用于播放器,一个用于预览/记录。我与您类似地设置了预览。设置播放器层看起来像......好吧,我不能把它放在评论中,但 AV Foundation Programming Guide 会引导读者完成它。
标签: ios uiview mpmovieplayercontroller avfoundation avcapturesession