iOS 7 MPMoviePlayerController seek forward button brings the video to the End and displays Black screen

谁都会走 提交于 2019-12-10 01:50:16

问题


I am facing an issue with MPMoviePlayerController in iOS 7. I enter the fullscreen and then click (just a single tap) on seek forward button (>>|) , and the video playback ends and gives a black screen with a text "Loading" on the header.

I registered notification for "MPMoviePlayerPlaybackStateDidChangeNotification".

**[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayerPlaybackStateDidChange:)
                                                 name:MPMoviePlayerPlaybackStateDidChangeNotification
                                               object:self.player];**

It does not get fired on a single click of seek forward button.

Also on registration of "MPMoviePlayerPlaybackDidFinishNotification"

**[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayerPlaybackDidFinish:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:nil];**

I get "MPMovieFinishReasonPlaybackEnded" event fired on that single click of seek forward button. Any one knows the reason why? Is this a bug in apple?

I need to either stop this behavior of showing a black screen on single click , or just disable single click of seek forward button so that nothing happens.

Any one knows how to achieve this?


回答1:


I fixed this by removing the MPMoviePlayer object completely, setting it to nil, removing it from it's superview and re-adding it using the original video Url. Code below:

- (void)addPlayerForUrl:(NSURL *)url {
  self.player = [[MPMoviePlayerController alloc] initWithContentURL:url];
  self.player.view.frame = self.videoView.bounds;
  self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  self.player.controlStyle = MPMovieControlStyleDefault;
  [self.videoView insertSubview:self.player.view atIndex:0];

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(moviePlayerLoadStateDidChangedNotification:)
                                               name:MPMoviePlayerReadyForDisplayDidChangeNotification
                                             object:self.player];

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(moviePlayerPlaybackStateDidChangeNotification:)
                                               name:MPMoviePlayerPlaybackStateDidChangeNotification
                                             object:self.player];
}


#pragma mark - Notifications

- (void)moviePlayerLoadStateDidChangedNotification:(NSNotification *)notification {
  self.isVideoPreloaded = YES;
  self.videoPlayButton.hidden = YES;
  self.photoImageView.hidden = YES;
  self.videoLoadingImageView.hidden = YES;
}
- (void)moviePlayerPlaybackStateDidChangeNotification:(NSNotification *)notification {
      NSURL *url = self.player.contentURL;
      switch (self.player.playbackState) {
        case MPMoviePlaybackStateSeekingBackward:
        case MPMoviePlaybackStateSeekingForward:
          break;
        case MPMoviePlaybackStatePlaying:
          self.videoPlayButton.hidden = YES;

          if (!self.isVideoPreloaded) {
            self.videoLoadingImageView.hidden = NO;
            [self.videoLoadingImageView startAnimating];
          } else {
            self.videoLoadingImageView.hidden = YES;
          }
          break;
        case MPMoviePlaybackStatePaused:
        case MPMoviePlaybackStateStopped:
          self.videoPlayButton.hidden = NO;
          self.videoLoadingImageView.hidden = YES;
          [self.player endSeeking];
          [self.player.view removeFromSuperview];
          [self.player setFullscreen:NO];
          self.player = nil;
          [self addPlayerForUrl:url];
          break;
        default:
          break;
      }
    }

Notice how I keep the NSURL, right before the switch statement in the moviePlayerPlaybackStateDidChangeNotification. That way, I can re-initialize and re-add the MPMoviePlayer object.

Btw, my mpmovieplayer is on a tableviewCell if you're wondering. Hope this helps and let me know if you have questions. Good luck!




回答2:


MPMoviePlayerLoadStateDidChangeNotification will be called when you single tap on the fast-forward or rewind button. You should check the loadState and just give it the path to your video and prepareToPlay again.

- (void)moviePlayerLoadStateChanged:(NSNotification *)notification {

    MPMoviePlayerController *moviePlayer = notification.object;
    MPMovieLoadState loadState = moviePlayer.loadState;

    if(loadState == MPMovieLoadStateUnknown) {
        moviePlayer.contentURL = [NSURL fileURLWithPath:videoPath]
        [moviePlayer prepareToPlay];
    }

    .....
}



回答3:


The reason you're getting MPMovieFinishReasonPlaybackEnded is because playback reached the end of the video (sorry if this is obvious). So it seem's your seek forward actions are seeking all the way to the end of the video. You can check the playback state with MPMoviePlaybackStateSeekingForward.

A quick solution could be to create your own forward button that seek's ahead by a specified time (ie. 5 seconds). But perhaps this isn't the functionality you're looking for.



来源:https://stackoverflow.com/questions/19570838/ios-7-mpmovieplayercontroller-seek-forward-button-brings-the-video-to-the-end-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!