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