MPMoviePlayerController background audio issue in

2019-03-27 23:23发布

问题:

I have an App that does the pretty standard operation: It plays audio (streamed or in filesystem) when the app is in 1) Foreground mode, 2) Screen locked state 3)Background mode. This was working fine in all iOS prior to iOS5.

I have been using MPMoviePlayerController (Because it can play streamed and local file system audio) I have the following setup:

  1. info.plist has Background Mode set to "Audio"
  2. I have Audiosession setup as shown at http://developer.apple.com/library/ios/#qa/qa1668/_index.html

    NSError *activationError = nil;
    AVAudioSession *mySession = [AVAudioSession sharedInstance];
    [mySession setCategory: AVAudioSessionCategoryPlayback error: &activationError];
    if (activationError) { /* handle the error condition */ }
    [mySession setActive: YES error: &activationError];
    if (activationError) { /* handle the error condition */ }
    
  3. I have background timer enabled that gets stopped at the end of audio playback UIBackgroundTaskIdentifier newId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

  4. I have the Moveplayer's useApplicationAudioSession = NO
  5. I have subscribed to the following events to detect and handle various playback state and to start a new audio file at the end of current file. MPMoviePlayerLoadStateDidChangeNotification MPMoviePlayerPlaybackDidFinishNotification MPMoviePlayerPlaybackStateDidChangeNotification MPMoviePlayerNowPlayingMovieDidChangeNotification

Problem:

With this the audio starts to play and when the application is put to background state or if the phone is locked, the audio continues to play. But, after when I start another audio file, I start getting PlaybackDidFinishNotification immediately with the state set to Playback ended (But the file was never played)

The same code plays audio files in foreground mode (After the current audio file ends, the next file is started without any problem)

Is there anything new in iOS5 I should be doing to get this to work? I read through the MPMoviePlayerController class reference and I couldn't see anything specific for iOS5.

Thanks in advance.

回答1:

Finally figured out the issue. This is solved in this post in apple dev forums (needs login to see). That post was applicable to AVPlayer but also fixes the problem with MPMoviePlayerController as well.

Basically, this is an excerpt from that post:

your app must support remote control events! These are the audio controller interface prex/nex/play/pause on the left of the multitask switcher taskbar (not sure about the proper name of the thing). You to this ensuring your view becomes First Controller and then calling

> [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

in viewDidLoad. Once you do this, your Player will no longer return NO!!



回答2:

My situation was different and I'm only answering here (and in the other SO question) to help future searchers on this error message. This does not answer the original question.

My app plays a sound OR a song but when I first coded it could play both. And in testing I always tested with a song. I played the song in the usual way:

    self.musicQuery = [MPMediaQuery songsQuery];
    [_musicQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:selectedSongID forProperty:MPMediaItemPropertyPersistentID comparisonType:MPMediaPredicateComparisonEqualTo]];
    [_musicQuery setGroupingType:MPMediaGroupingTitle];
    [_myPlayer setQueueWithQuery:_musicQuery];

    [_myPlayer play];

Weeks passed and I started testing with the sound, played with AVAudioPlayer. My app started freezing for 5 seconds and I'd get the MediaPlayer: Message playbackState timed out message in the Console.

It turns out that passing a query that was empty was causing the freeze and the message. Changing my app's logic to only play a song when there was a song to play fixed it.