MPMoviePlayerViewController running in background and using Remote Controls
I'm currently running on iOS 4.3.5 and trying to get my MPMoviePlayerViewController
to continue playing after entering background.
I implemented everything as it is described on
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
and
http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/RemoteControl/RemoteControl.html
I have also set the UIBackgroundMode to audio
.
My custom MPMoviePlayerViewController class is called like this from a TabBarApplication:
NSURL *streamUrl = [NSURL URLWithString:STREAM_URL];
self.playerViewController = [[CustomMoviePlayerViewController alloc] initWithContentURL:streamUrl];
// Register for the playback finished notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.playerViewController.moviePlayer];
// Present
[self presentMoviePlayerViewControllerAnimated:self.playerViewController];
// Play the movie!
self.playerViewController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
[self.playerViewController.moviePlayer prepareToPlay];
[self.playerViewController.moviePlayer play];
Inside my CustomMovePlayerController
looks like the following:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
-(void)viewWillAppear:(BOOL)animated {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
-(void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
[super viewWillDisappear:animated];
}
-(BOOL)canBecomeFirstResponder {
return YES;
}
-(void)remoteControlReceivedWithEvent:(UIEvent *)event {
[super remoteControlReceivedWithEvent:event];
NSLog(@"remoteControlReceived");
NSLog(@"%d", [[AVAudioSession sharedInstance] isActive]);
if (event.type == UIEventTypeRemoteControl) {
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[self.moviePlayer play];
break;
case UIEventSubtypeRemoteControlPause:
[self.moviePlayer pause];
break;
default:
break;
}
}
}
The main problem with my MPMoviePlayerViewController is, that it doesn't respond to the remoteControlReceivedWithEvent
message, why is that? Am I subclassing the wrong thing? Does my Tabbar based app prevent me from doing that?
Last but not Least - applicationDidFinishLaunchingWithOptions
contains following:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
I just can't figure out what's missing... all help is greatly appreciated!
I think I can answer both questions :)
The background issue:
What file format are you trying to play? My app has been using a MPMoviePlayerViewController for background audio for a while, but recently had reports that it wasn't playing in the background anymore.
Turns out it was AAC files; they're podcasts with chapters and cover art per chapter... iOS 5 added improved support for them, but it must make the MPMoviePlayerViewController think it's playing video. Background video was turned off around iOS 4.3, from what I can find.
Try it with a plain MP3 file, that still works for me. I'm about to log the AAC problem as a bug with Apple.
The remote control issue:
Both the lock screen and notification bar remote control buttons send the UIEventSubtypeRemoteControlTogglePlayPause
event, not play and pause separately. So I handle events like this:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
if (controller.playbackState == MPMusicPlaybackStatePlaying) {
[controller pause];
} else {
[controller play];
}
break;
//etc
}
精彩评论