Responding to MPMoviePlayerController notifications during background media playback

reddersky picture reddersky · Jan 31, 2012 · Viewed 8.3k times · Source

I have an app that streams video from the net and plays it using an MPMoviePlayerController object for playback on the device or via AirPlay.

The app supports background operation and has the 'audio' option listed within the required UIBackgroundModes key in its plist file.

When playing over AirPlay, the app can successfully be pushed to the background and the video continues to play properly. So far, so good.

According to the Apple documentation:

Including the audio key tells the system frameworks that they should continue playing and make the necessary callbacks to the app at appropriate intervals. If the app does not include this key, any audio being played by the app stops when the app moves to the background.

However, these callbacks are not being made.

The app uses two types of callback: those associated with notifications MPMoviePlayerController and AVPlayer send during playback together with timer based callbacks that monitor the playback position and performance stats for monitoring purposes.

Looking at Apple's notes, I would certainly expect to receive the first type of callback so that the app can respond to MPMoviePlayerPlaybackStateDidChangeNotification, MPMoviePlayerPlaybackDidFinishNotification and MPMoviePlayerLoadStateDidChangeNotification, but this doesn't happen.

Does anyone know if it is possible to receive these during background AirPlay playback and, if so, how was this achieved?

**Please note: the app works correctly when running in the foreground and receives the notifications fine. It is only when pushed to the background and playing over AirPlay that the notifications are not received.

Likewise, the video plays over AirPlay in the background properly. It is only the notifications which are not received**

Answer

Dev2rights picture Dev2rights · Feb 11, 2012

I had this issue and have fixed it though it was a few months back. I could send you my entire class for movie playback if this doesn't work. Note it is using the navigation controller model.

NOTE: This is tested on iPad 2 not on the iPhone.

I show my VC like this:

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

Then in my MovieVC view controller class i set up the video playback like this:

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

This fixed it for me, if it doesn't fix comment and ill edit with the entire class file.