模态全屏 iOS 8 后视频无法在 mpmovieplayercontroller 上播放

Posted

技术标签:

【中文标题】模态全屏 iOS 8 后视频无法在 mpmovieplayercontroller 上播放【英文标题】:Video doesn't play on mpmovieplayercontroller after modal fullscreen iOS 8 【发布时间】:2014-10-22 21:24:35 【问题描述】:

我有一个由两半组成的 UIViewController(它们实际上在 UIContainerViews 中)。一半包含一个 UIWebView,用于显示 PDF,另一半包含一个 UIView,用于流式传输视频。

有一个带有 UIWebView 的导航栏,带有一个 UIButton,当按下它时会在全屏模式下呈现一个模态 UIWebview:

- (IBAction)pressedFullscreenButton:(id)sender

  // pause the video view controller
  self.videoViewController.videoPlayer pause];

  // perform the segue - this is modal, full screen
  [self performSegueWithIdentifier:@"FullscreenSegue" sender:self];

所以我按下全屏按钮,视频暂停,我的 pdf/uiwebview 以模态全屏显示。当我关闭这个全屏视图控制器以返回我的分屏时,当我在视频上按播放时,音频播放,但视频没有,我无法为生活找出原因 - 任何帮助都是真的赞赏。

为了解决这个问题,这不是我的首选解决方案,我基本上是获取视频的当前时间,停止它,设置当前时间,播放视频并在视图控制器出现时立即暂停它。这是我的代码:

所以我使用了一个 MPMoviePlayerController,我将它封装到了一个名为 StandardVideoPlayer 的类中:

@implementation StandardVideoPlayer


-(id)initWithParentView:(UIView *)parent andAutoPlay:(BOOL)autoPlay andFullScreen:(BOOL)fullScreen andAnimated:(BOOL)animated

  // Call superclass's initializer
  self = [super init];
  if( !self || !parent)
  
    return nil;
  
  else
  
    if (!_moviePlayerController)
    
      _moviePlayerController = [[MPMoviePlayerController alloc] init];
    

    _moviePlayerController.controlStyle = MPMovieControlStyleDefault;
    [_moviePlayerController.view setFrame:parent.frame];
    [_moviePlayerController.view setCenter:parent.center];
    _moviePlayerController.allowsAirPlay = YES;
    _moviePlayerController.shouldAutoplay = autoPlay;
    [_moviePlayerController setFullscreen:fullScreen animated:animated];

    [parent addSubview: [self videoView]];
  

  return self;


-(void)loadFromFile: (NSString*) filePath;

  if (_moviePlayerController)
  
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
    [_moviePlayerController setContentURL:fileUrl];
    [_moviePlayerController prepareToPlay];
  


- (void)loadFromURL: (NSString*) urlString

  if ( [[ConnectionManager sharedInstance] canConnect] )
  
    if (_moviePlayerController)
    
      NSURL *url = [NSURL URLWithString:urlString];
      [_moviePlayerController setContentURL:url];
      [_moviePlayerController prepareToPlay];
    
  
  else
  
    [[ConnectionManager sharedInstance] displayConnectionWarningWithText:@"Ok" andDelegate:nil];

  



-(void)loadFromhtml:(NSString *)html

  // NSString *h = [NSString stringWithFormat:html, ]


-(void)play

  if (_moviePlayerController)
  
    [_moviePlayerController prepareToPlay];
    [_moviePlayerController play];
  


-(void)stop

  if (_moviePlayerController)
  
    [_moviePlayerController stop];
  


-(void)pause

  if (_moviePlayerController)
  
    [_moviePlayerController pause];
  


// use this to get the view form the moviePlayerController......
-(UIView*)videoView

  UIView *view = nil;
  if (_moviePlayerController)
  
    view = _moviePlayerController.view;
  

  return view;



@end

然后在视图控制器中我有:

@implementation VideoViewController

// lazy initialiser
- (StandardVideoPlayer*) videoPlayer

  if (!_videoPlayer)
  
    _videoPlayer = [[StandardVideoPlayer alloc] initWithParentView:self.view andAutoPlay:NO andFullScreen:NO andAnimated:YES];
  
  return _videoPlayer;


- (void) viewDidLoad

  [super viewDidLoad];

  self.initialised = NO;
  self.wasPDFScreen = NO;
  self.isFullScreen = NO;
  [self.spinner stopAnimating];
  self.spinner.hidesWhenStopped = YES;

  [GlobalStore sharedInstance].videoViewController = self;


-(void) willEnterFullScreen

  self.isFullScreen = YES;


-(void)loadStateChanged

  MPMovieLoadState state = [self.videoPlayer.moviePlayerController loadState];
  if (state & MPMovieLoadStatePlayable)
  
    [self.spinner stopAnimating];
  


-(void) customInit

  if (!self.initialised)
          
    [self.view setBackgroundColor:[UIColor blackColor]];
    [self.videoPlayer.videoView setBackgroundColor:[UIColor blackColor]];

    // set a border
    CGFloat borderWidth = 1.0f;

    self.videoPlayer.videoView.frame = CGRectInset(self.videoPlayer.videoView.frame, -borderWidth, -borderWidth);
    self.videoPlayer.videoView.layer.borderColor = BORDER_COLOUR;
    self.videoPlayer.videoView.layer.borderWidth = borderWidth;

    self.view.frame = CGRectInset(self.view.frame, -borderWidth, -borderWidth);
    self.view.layer.borderColor = BORDER_COLOUR;
    self.view.layer.borderWidth = borderWidth;

    // set this to be able to exit the video player properly
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(willEnterFullScreen)
                                                 name:MPMoviePlayerWillEnterFullscreenNotification
                                               object:_videoPlayer.moviePlayerController];

    // set this to be able to start/stop the spinner
 [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(loadStateChanged)
                                                 name:MPMoviePlayerLoadStateDidChangeNotification
                                               object:_videoPlayer.moviePlayerController];

    // make sure the views are always at the front
    [self.view bringSubviewToFront:self.videoPlayer.videoView];
    [self.view bringSubviewToFront:self.spinner];

    self.initialised = YES;
  


-(void)viewDidAppear:(BOOL)animated

  [super viewDidAppear:animated];

  [self customInit];


-(void) viewWillAppear:(BOOL)animated

  [super viewWillAppear:animated];

  [self.spinner stopAnimating];

  if (_videoPlayer && self.wasPDFScreen)
  
    NSTimeInterval time = [self.videoPlayer.moviePlayerController currentPlaybackTime];
    if (time != 0)
    
      // So to ge the video to play properly, i have to uncommment the lines below, but this loses the cache and isn't quite as smooth as i would like.

      //[self stopVideo];
      //self.videoPlayer.moviePlayerController.currentPlaybackTime = time;
      //[self.videoPlayer.moviePlayerController prepareToPlay];
      //[self.videoPlayer.moviePlayerController play];
      //[self.videoPlayer.moviePlayerController pause];
    
  

  self.isFullScreen = NO;
  self.wasPDFScreen = NO;


-(void)viewDidDisappear:(BOOL)animated

  [super viewDidDisappear:animated];

  // only stop the video when we mean to - not when we go into full screen mode
  if (!self.isFullScreen && !self.wasPDFScreen)
    [self stopVideo];


- (void)playVideo

  [self.spinner startAnimating];

    [self.videoPlayer loadFromURL:@"someurl"];    

    // and play!!
    [self.videoPlayer play]; 


-(void)stopVideo

  [self.videoPlayer stop];


@end

【问题讨论】:

【参考方案1】:

我最终实现了一个 AV Kit 视图控制器。完美运行。

【讨论】:

以上是关于模态全屏 iOS 8 后视频无法在 mpmovieplayercontroller 上播放的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 上禁用全屏自动播放

在iOS 8中如何在UIWebView Player中接收全屏模式的通知?

手机看视频不是全部能全屏,怎么处理?

UIWebView 和 MPMoviePlayerController

Swift 3、iOS 10+、xCode 8.3+、Quickblox - 在保持纵横比/视频分辨率的同时切换全屏远程流

iOS开发之--全局解决模态弹出不全屏展示问题