模态全屏 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 8中如何在UIWebView Player中接收全屏模式的通知?
UIWebView 和 MPMoviePlayerController
Swift 3、iOS 10+、xCode 8.3+、Quickblox - 在保持纵横比/视频分辨率的同时切换全屏远程流