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**
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.
In one of my projects I did what you did, and it worked for me. Two differences in my project :
My step-by-step :
UIBackgroundModes
in the plist file,Register to the NotificationCenter for MPMoviePlayerPlaybackDidFinishNotification
and MPMoviePlayerPlaybackStateDidChangeNotification
with the following code :
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(playbackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:moviePlayer];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(playbackEnded:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
It works like a charm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With