2010-11-18 73 views
6

影片播放还不错,但在播放之前会有一个快速黑色闪光。这是由于将controlstyle设置为MPMovieControlStyleNone而导致的一个怪癖吗?MPMoviePlayerController在视频开始时会导致黑屏闪烁

NSString *url = [[NSBundle mainBundle] pathForResource:@"00" ofType:@"mov"]; 
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] 
    initWithContentURL:[NSURL fileURLWithPath:url]]; 

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
    selector:@selector(movieFinishedCallback:) 
    name:MPMoviePlayerPlaybackDidFinishNotification 
    object:player]; 

//---play video in implicit size--- 
player.view.frame = CGRectMake(80, 64, 163, 246); 
[self.view addSubview:player.view]; 

// Hide video controls 
player.controlStyle = MPMovieControlStyleNone; 

//---play movie--- 
[player play]; 

回答

6

显然电影矩形中有黑色闪光灯,直到足够的电影加载,因此它可以开始播放。这是我的解决方法:

  1. 创建一个UIImageView并将MPMoviePlayerController放入其中。这样,您可以将alpha设置为0.

  2. 只要您致电[player play];播放视频,设置一个0.5秒的定时器。

  3. 当时间完成,α更改为1

这将使游戏者为1/2秒(这隐藏了黑色闪光)不可见。

+1

我也有这个问题。但是这个解决方案很棘手,因为你不知道MPMovilePlayerController需要渲染视频的时间。所以它肯定会隐藏黑色闪光,但也是视频的开始。 更好的答案:http://stackoverflow.com/a/28079496/2327367 – LastMove 2015-09-09 10:34:53

2

或者干脆更改视图的颜色,这就是你实际看到...

player.view.backgroundColor =的UIColor colorWithRed:1绿1蓝:1阿尔法:0];

+0

我用[UIColor clearColor]做了同样的事情,它的工作完美。我现在可以看到我在后台使用的UIImageView,并且没有黑色闪光灯。 – christophercotton 2011-10-14 01:37:14

+0

nope,这没有工作 – yeahdixon 2013-10-18 20:01:21

+0

完全不工作 – jjxtra 2014-10-12 15:23:30

1

为避免黑色闪烁,请使用MPMoviePlayerViewController而不是MPMoviePlayerController。我认为这个类创建视图显示的背景,而不是视频加载(像MPMoviePlayerController那样)。

之前添加moviePlayerViewController.movi​​ePlayer.view到您的显示来看,你有一个白色子视图(或您的内容适当的一个子视图)添加到backgroundView,就像这样:

[moviePlayerViewController.moviePlayer.view setFrame:[displayView bounds]]; 

UIView *movieBackgroundView = [[UIView alloc] initWithFrame:[displayView bounds]]; 
movieBackgroundView.backgroundColor = [UIColor whiteColor]; 
[moviePlayerViewController.moviePlayer.backgroundView addSubview:movieBackgroundView]; 
[movieBackgroundView release]; 
2

我相信黑色闪光灯可能与MPMoviePlayerControllermovieSourceType属性有关。

如果您没有设置它,它将默认为MPMovieSourceTypeUnknown,这将导致用户界面延迟到文件加载完成。

尝试加入这一行:

初始化播放器后
player.movieSourceType = MPMovieSourceTypeFile; 

权。

+0

将movieSourceType设置为MPMovieSourceTypeFile没有帮助 – RainChen 2014-06-30 04:26:14

+0

我已经在使用SourceType,但避免黑屏的关键是将它放在“初始化播放器之后”。谢谢! – danielsalare 2015-07-17 00:25:50

19

我刚刚遇到了这个问题,并通过向默认的NSNotificationCenter添加一个观察者来确定它是否完全准备好播放,然后将该视图作为子视图添加到我的主视图中。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; 

...

if(moviePlayer.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK)) 
{ 
    [pageShown.view addSubview:moviePlayer.view]; 
    [moviePlayer play]; 
} 
+0

我想到了类似的东西,感谢您快速追踪我的想法......以上所有其他建议不适用于我的遗留代码+1〜! – dklt 2012-07-18 10:52:02

+0

虽然,也许最好先调用'play',然后添加子视图?我不知道在比赛结束后是否有足够的延迟,或者是否有帮助。 – Marty 2012-07-18 21:27:09

+0

这是行不通的?我现在尝试了2次,这对我来说不起作用。 – coolcool1994 2015-08-14 08:23:07

7

在IOS 6 mpmoviewplayer增加了一个新的属性:readyForDisplay

这是我在玩弄和到目前为止好:

  1. 创建mpmovieplayer,添加到舞台,隐藏它。
  2. 为播放状态的movieController
  3. 等待补充通知对的displayState更改,一旦它准备好节目的视频控制器:

    - (void)moviePlayerPlayState:(NSNotification *)noti { 
    
    if (noti.object == self.movieController) { 
    
        MPMoviePlaybackState reason = self.movieController.playbackState; 
    
        if (reason==MPMoviePlaybackStatePlaying) { 
    
          [[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerPlaybackStateDidChangeNotification object:nil]; 
    
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    
          while (self.movieController.view.hidden) 
          { 
           NSLog(@"not ready"); 
           if (self.movieController.readyForDisplay) { 
    
           dispatch_async(dispatch_get_main_queue(), ^(void) { 
            NSLog(@"show"); 
            self.movieController.view.hidden=NO; 
           }); 
    
           } 
           usleep(50); 
          } 
         }); 
        } 
    
    } 
    

    }

当播放状态变化到MPMoviePlaybackStatePlaying我们开始检查readyDisplayState进行更改。

3

创建视频,而无需addSubview和播放指令:

NSString *filepath = [[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"]; 
    NSURL *fileURL = [NSURL fileURLWithPath:filepath]; 
    MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL]; 
    [moviePlayerController.view setFrame:CGRectMake(80, 64, 163, 246)]; 
    moviePlayerController.controlStyle = MPMovieControlStyleNone; 

准备的视频播放,并添加通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; 
    [moviePlayerController prepareToPlay]; 

创建功能checkMovieStatus与addSubview和游戏指导:

- (void)checkMovieStatus:(NSNotification *)notification { 
    if(moviePlayerController.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK)) { 
     [self.view addSubview:moviePlayerController.view]; 
     [moviePlayerController play]; 
    } 
} 
+0

你需要调用prepareToPlay以获得MPMoviePlayerLoadStateDidChangeNotification回调(自iOS6以后改变?) – Lorenz03Tx 2016-07-27 20:51:42

1

这里很喜欢解决方案http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/ from iOS 6 您需要使用[self.movi​​ePlayer prepareToPlay];并抓住MPMoviePlayerReadyForDisplayDidChangeNotification使用[self.movi​​ePlayer play];

+0

这是我的解决方案。使用适当的事件似乎是解决这个问题的正确方法,我会写一篇教程,并在此处发布如何实现这一点。 – newshorts 2015-08-05 18:58:33

+0

更新 - 这里有一个教程的链接,更详细地解释这个:http:// iwearshorts。COM /博客/的MPMoviePlayerController黑色屏幕,当衰落/ – newshorts 2015-08-05 19:14:32