开发者

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
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜