-->

MPMoviePlayerViewController playback video after g

2019-05-30 20:33发布

问题:

I have set App Plays Audio for Required background modes in my app's info.plist to keep the mpmovieplayerviewcontroller not dismissing after going to background. It did a great job. However, Apple has rejected my app's update recently, as I set that attribute.

Then I keep finding solutions for doing the same job but fail. To deal with it, I save the currentplaybacktime when the view controller receive UIApplicationDidEnterBackgroundNotification

-(void)willEnterBackground {
    NSLog(@"willEnterBackground");
    if (self.mp) {
        playbackTime = self.mp.moviePlayer.currentPlaybackTime;
        [self.mp dismissModalViewControllerAnimated:YES];
    }
}

And set the currentPlayBackTime after it receives UIApplicationWillEnterForegroundNotification:

- (void)willEnterForeground {
    NSLog(@"willEnterForeground");

    if (!self.mp)
        return;
    if(self.mp.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted || self.mp.moviePlayer.playbackState == MPMoviePlaybackStateStopped || self.mp.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
    {
        [self continuePlayback];
    }
}

- (void)continuePlayback {
    NSLog(@"%f", self.mp.moviePlayer.duration);
    NSLog(@"%f", playbackTime);
    [self.mp.moviePlayer stop];
    self.mp = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:[self.videos objectForKey:@"medium"]]] ;
    [self.mp.moviePlayer setInitialPlaybackTime:playbackTime];
    [self.mp.moviePlayer play];
    [self presentModalViewController:self.mp animated:YES];
}

It works, but with some trade off: As I re-init it, it lost the streamed video part. Users need to wait for streaming again.

And here comes my questions:

  1. Is there a way that keep streaming Youtube's video when the app is in background?
  2. or how to keep the streamed part?

It would play from the beginning of the video if I skip the line:

self.mp = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:[self.videos objectForKey:@"medium"]]] ;

in continuePlayBack method or I setCurrentPlayBackTime instead of setInitPlayBackTime.

回答1:

What you have discovered there is perfectly normal - weird, but normal. MPMoviePlayerController does only respect the initialPlaybackTime when being used on a fresh instance. I do actually urge you to file a bug-report on that issue as it is known since ages (iOS3) but not fixed.

There is no way to keep the buffer state and the solution you have drafted is pretty much the same that I am using in many apps.


Now directly answering your questions;

re 1) Yes and no. As you have discovered yourself, Apple did get very harsh on the UIBackgroundModes usage. Even though they clearly recommend using it for achieving uninterrupted AirPlay streaming (of video and audio content), they still reject apps when all they do is playing a video. That I also consider an epic failure on Apple's review team side. You might want to try to fight their rejection, quoting their own documentation:

Important: The UIBackgroundModes audio key will allow apps to stream audio or video content in the background using AirPlay.

From : http://developer.apple.com/library/ios/#qa/qa1668/_index.html

re 2) No (see introductional answer text)


Let me also tackle the issue from a different side...

If your problem actually is the fact that on iOS5 the device is going into sleep mode while streaming via AirPlay. Then, there is actually one possible workaround that at least works - even though it is nasty as hell...

You can register for MPMoviePlayerIsAirPlayVideoActiveDidChangeNotification and check the airPlayVideoActive within the hooked method. Once AirPlay is active, just prevent idling by setting [UIApplication sharedApplication].idleTimerDisabled = YES; Remember to do the reverse once AirPlay became inactive. All of this should only be needed on iOS5 as iOS6 fixed the idling issue while AirPlay is active.