MPMoviePlayerController seek forward in fullscreen

2020-04-05 07:46发布

There seems to be a problem with the MPMoviePlayerController where once you're in fullscreen mode and you hold down the fast forward button, letting it seek forward (playing at fast speed) all the way to the end of the video.

Thereafter the you just get a black screen and it's stuck. In other words it does not respond to any taps gestures and you can not get out of this situation. Has anyone else encountered this problem?

Is there anyway to work around it in code?

4条回答
再贱就再见
2楼-- · 2020-04-05 08:23

Ran into the same issue on iOS6. Managed to fix it by registering for the MPMoviePlayerPlaybackDidFinishNotification (as suggested by Leuguimerius) with the following implementation:

- (void)playbackDidFisnish:(NSNotification *)notif {
    if (self.player.currentPlaybackTime <= 0.1) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.player stop];
        [self.player play];
        [self.player pause];
        });
    }
}

Where self.player is the associated MPMoviePlayerController instance. The check against currentPlaybackTime serves to distinguish the more standard invocations of playbackDidFinish (where the movie is allowed to play at normal speed until its end) from those scenarios where the user fast forwards until the end. Stopping then playing and pausing results in a usable, visually consistent interface even when fast-forwarding to the end.

查看更多
倾城 Initia
3楼-- · 2020-04-05 08:24

It seems it's an iOS bug since fast backward to the very beginning won't cause the black screen but fast forward to the end will, and after that the 'play'/'pause' call to the video player never works. I temporarily fix this by adding protected logic into the scrubber refresh callback: let's assume that monitorPlaybackTime will be called in 'PLAY_BACK_TIME_MONITOR_INTERVAL' seconds period to refresh the scrubber, and in it I add a check logic:

NSTimeInterval duration = self.moviePlayer.duration;
NSTimeInterval current = self.moviePlayer.currentPlaybackTime;

if (isnan(current) || current > duration) {
    current = duration;
} else if (self.moviePlayer.playbackState == MPMoviePlaybackStateSeekingForward) {
    if (current + self.moviePlayer.currentPlaybackRate*PLAY_BACK_TIME_MONITOR_INTERVAL > duration) {
        [self.moviePlayer endSeeking];
    }
}

A workaround to solve the black screen, not perfect, hope it can help.

查看更多
小情绪 Triste *
4楼-- · 2020-04-05 08:36

None of the aforementioned solutions worked for me, so this is what I ended up doing:

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("moviePlayerLoadStateDidChange"), name: MPMoviePlayerLoadStateDidChangeNotification, object: nil)

func moviePlayerLoadStateDidChange() {
    let loadState = moviePlayerController?.loadState

    if loadState == MPMovieLoadState.Unknown {
        moviePlayerController?.contentURL = currentmovieURL
        moviePlayerController?.prepareToPlay()
    }
}

I think the issue is that when the seek foraward button is single pressed, it wants to skip to the next video, that's why a loading indicator appears. Listening for the load state change event, you can specify what the next video should be, and if you don't have any, you can just give it the same url.

查看更多
Lonely孤独者°
5楼-- · 2020-04-05 08:37

I'm guessing you are not handling the MPMoviePlayerPlaybackDidFinishNotification. You really should if you're not.

Still its unexpected for me that the movie player would go into a "stuck" state like you describe. I would more readily expect it to stop playback automatically and reset when it reaches the end. Anyway, I think your problem will go away if you observe the MPMoviePlayerPlaybackDidFinishNotification and handle the movie controller appropriately.

查看更多
登录 后发表回答