在后台媒体播放期间响应MPMoviePlayerController通知

时间:2012-01-31 19:40:01

标签: iphone ios mpmovieplayercontroller multitasking avplayer

我有一个应用程序,可以从网络流式传输视频并使用MPMoviePlayerController对象播放,以便在设备上或通过AirPlay播放。

该应用支持后台操作,并在其plist文件中的所需UIBackgroundModes键中列出了“audio”选项。

通过AirPlay播放时,应用程序可以成功推送到后台,视频继续正常播放。到目前为止,非常好。

根据Apple documentation

  

包含音频键告诉系统框架它们应该   继续玩,并在应用程序进行必要的回调   适当的间隔。如果应用程序不包含此密钥,则任何音频   当应用程序移动到后台时,应用程序正在播放。

然而,这些回调并没有发生。

该应用程序使用两种类型的回调:与回传期间发送的通知MPMoviePlayerControllerAVPlayer相关的回调以及基于计时器的回调,这些回调监控播放位置和性能统计数据以进行监控。

看看Apple的笔记,我当然希望收到第一种回调类型,以便应用可以回复MPMoviePlayerPlaybackStateDidChangeNotificationMPMoviePlayerPlaybackDidFinishNotificationMPMoviePlayerLoadStateDidChangeNotification,但这不会发生

有没有人知道在后台AirPlay播放过程中是否可以接收这些内容?如果有,这是如何实现的?

**请注意:该应用程序在前台运行时可以正常工作,并且收到通知正常。只有当它被推到后台并通过AirPlay播放时才会收到通知。

同样,视频在后台正确播放AirPlay。它只是未收到的通知**

3 个答案:

答案 0 :(得分:4)

我有这个问题并且已经修复了它,虽然它是几个月前。如果这不起作用,我可以发送给我全班的电影播放。请注意,它使用的是导航控制器模型。

注意:这是在iPad 2上测试的,而不是在iPhone上测试。

我这样展示我的VC:

 - (IBAction)playMovie:(id)sender {

    MovieVC* movController = [[MovieVC alloc] initWithID:2];
    movController.view.backgroundColor = [UIColor blackColor];
    AppDelegate *appDel = [[UIApplication sharedApplication] delegate];

    [appDel.navigationController pushViewController:movController animated:NO];
    [movController release];
}

然后在我的MovieVC视图控制器类中,我设置了如下视频播放:

- (void)initMoviePlayer {

    mMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[self getMovieURL]];

    mMoviePlayer.allowsAirPlay = YES;   

    mMoviePlayer.view.frame = [self.view bounds];

    mMoviePlayer.view.backgroundColor = [UIColor clearColor];

    mMoviePlayer.shouldAutoplay = YES;

    mMoviePlayer.fullscreen = YES;

    mMoviePlayer.scalingMode = MPMovieScalingModeAspectFit;

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(moviePreloadDidFinish:) 
                                             name:MPMoviePlayerLoadStateDidChangeNotification 
                                           object:mMoviePlayer];

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(moviePlayBackDidFinish:) 
                                                  name:MPMoviePlayerPlaybackDidFinishNotification 
                                           object:nil];
}

如果它没有修复注释并且使用整个类文件进行编辑,那么这对我来说是固定的。

答案 1 :(得分:2)

在我的一个项目中,我做了你做过的事,这对我有用。 我的项目有两个不同之处:

  • 我不通过airPlay进行流式传输(仅限设备播放),
  • 我只是在播放音频文件。

我的一步一步:

  • 将音频选项添加到plist文件中的UIBackgroundModes
  • 使用以下代码注册到MPMoviePlayerPlaybackDidFinishNotificationMPMoviePlayerPlaybackStateDidChangeNotification的NotificationCenter:

    [[NSNotificationCenter defaultCenter]
                    addObserver:self
                       selector:@selector(playbackStateChanged:)
                           name:MPMoviePlayerPlaybackStateDidChangeNotification
                         object:moviePlayer];
    
    [[NSNotificationCenter defaultCenter]
                    addObserver:self
                       selector:@selector(playbackEnded:)
                           name:MPMoviePlayerPlaybackDidFinishNotification
                         object:moviePlayer];
    

它就像一个魅力。

答案 2 :(得分:0)

为了完整性,我应该补充一点,目前我认为这个问题没有解决办法。

我已经通过技术支持直接与Apple讨论过,并且没有实际的解决方法。

需要此功能才能让应用程序定期记录有关流播放的统计信息。虽然当应用程序位于前台时,在设备屏幕和AirPlay上播放视频时这很好,但是在后台无法使用该应用程序。

我使用的解决方案是在所有类型的播放期间禁用空闲计时器,然后使用以下方式重新启用:

[UIApplication sharedApplication].idleTimerDisabled = YES;

[UIApplication sharedApplication].idleTimerDisabled = NO;

虽然这不是原始问题的解决方案,但这是首先避免问题的解决方法。