私はビデオストリーミングのアプリケーションに取り組んでいます。iOS5用のARCで構築されています。ビューを表示するには、MPMoviePlayerViewControllerを次のように使用します。
.h
@interface EpisodesTableViewController : UITableViewController<EpisodeUrlResolverDelegate> {
NSTimeInterval playbackTime;
EpisodeUrlResolver *episodeUrlResolver;
}
@property (strong, nonatomic) MPMoviePlayerViewController *player;
@end
.m
@implementation EpisodesTableViewController
@synthesize episodes, player;
- (void)viewDidLoad
{
[super viewDidLoad];
episodeUrlResolver = [[Soap4MeEpisodeUrlResolver alloc] init];
[episodeUrlResolver setDelegate:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground) name:@"WillEnterForeground" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground) name:@"WillEnterBackground" object:nil];
}
- (void)viewDidUnload
{
episodeUrlResolver = nil;
player = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"WillEnterForeground" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"WillEnterBackground" object:nil];
[super viewDidUnload];
}
- (void)url:(NSURL *)url WasResolvedForEpisode:(Episode *)episode {
player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
player.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
player.moviePlayer.allowsAirPlay = YES;
[self presentModalViewController:player animated:YES];
}
- (void)willEnterBackground {
if (player) {
playbackTime = player.moviePlayer.currentPlaybackTime;
}
}
- (void)willEnterForeground {
if (!player)
return;
if(player.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted || player.moviePlayer.playbackState == MPMoviePlaybackStateStopped || player.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
{
[self continuePlayback];
}
}
- (void)continuePlayback {
[self presentModalViewController:player animated:YES];
[player.moviePlayer setInitialPlaybackTime:playbackTime];
NSLog(@"%f", player.moviePlayer.initialPlaybackTime);
[player.moviePlayer play];
}
提示されたコードについてのいくつかの言葉:ビデオのURLが解決されたら、ビデオ再生用のMPMoviePlayerViewControllerオブジェクトを作成します。再生を開始します。次に、アプリがホームボタンでバックグラウンドになると、 MPMoviePlayerViewControllerは自動的に再生を一時停止し、画面から消えます(私にとっては奇妙な動作です)。そのため、アプリがバックグラウンドになるときに再生時間を節約し、アプリがフォアグラウンドに戻ったときに再生時間を復元して既存のMPMoviePlayerViewControllerを再度表示する必要があります。ユーザーがホームボタンを押してからアプリケーションに戻ると、正常に機能します。
ただし、ユーザーがデバイスをロックすると機能しません。willEnterBackground通知は、 applicationWillEnterForegroundが呼び出されたときに発生するため、ロックイベントの場合も呼び出されます。ただし、ユーザーがデバイスをロックした場合、ユーザーがホームボタンを押したときのように、MPMoviePlayerViewControllerが適切に閉じられませんでした。画面には表示されませんが、コードを呼び出します
[self presentModalViewController:player animated:YES];
例外をスローします
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <EpisodesTableViewController: 0x91b3950>.'
私はコントローラーを閉じるようにコードを変更しようとしました:
- (void)willEnterForeground {
if (!player)
return;
if(player.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted || player.moviePlayer.playbackState == MPMoviePlaybackStateStopped || player.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
{
if (self.presentedViewController) {
[self dismissViewControllerAnimated:YES completion:^{
[self continuePlayback];
}];
}
else {
[self continuePlayback];
}
}
}
これで、例外はスローされませんが、警告が表示されます
wait_fences: failed to receive reply: 10004003
また、完了ブロックが呼び出されることはありません。
背景/前景を適切に解決する方法は、モーダルに表示されたMPMoviePlayerViewControllerで引き続き再生しますか? 返信ありがとうございます。