MPMoviePlayerViewController后台交易。从背景返回到前景后如何继续播放?

时间:2012-08-13 08:17:46

标签: objective-c ios mpmovieplayercontroller

我正致力于视频流的应用。它是使用ARC for iOS5构建的。 要显示视图,我以这种方式使用 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? 谢谢你的回复。

1 个答案:

答案 0 :(得分:2)

我解决了这个问题。

方法 -willEnterBackground 应如下所示:

- (void)willEnterBackground {
    if (player) {
        playbackTime = player.moviePlayer.currentPlaybackTime;
        [self dismissModalViewControllerAnimated:NO];
    }
}

当应用进入后台模式时,我们必须手动关闭 MPMoviePlayerViewController 。 注意只使用

[self dismissModalViewControllerAnimated:NO];

而不是

[self dismissMoviePlayerViewControllerAnimated];

那是因为 MPMoviePlayerViewController 显示为

[self presentModalViewController:player animated:YES];