在viewDidLoad中运行MPMoviePlayerController的奇怪行为

时间:2011-08-21 18:32:13

标签: ios cocoa-touch mpmovieplayercontroller nstimer viewdidload

我正在使用MediaPlayer框架在我的应用程序启动后立即播放相当大的电影(~200 MB)。当我尝试在viewDidLoad中播放视频时,断点表示视频已添加,但视频未显示在设备上。

然后设置一个按钮以确认视频是否正常工作。从按钮运行IBAction显示没有问题。

所以那时我很难过。我想知道是否与应用程序启动后视频被调用的事实有关。所以我在viewDidLoad调用中添加了一个NSTimer延迟5秒。瞧,它运作良好。除非有最初的延迟,否则任何人都可以了解为什么视频无法播放?代码如下。

- (void)viewDidLoad {
      NSTimer *currentTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(playMovie) userInfo:nil repeats:NO];
        [[NSRunLoop mainRunLoop] addTimer:currentTimer forMode:NSRunLoopCommonModes];
      [super viewDidLoad];
}

-(IBAction)playMovie
{  
    NSString *filepath   =   [[NSBundle mainBundle] pathForResource:@"Speed" ofType:@"mov"];  
    NSURL    *fileURL    =   [NSURL fileURLWithPath:filepath];  
    MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];  

    [[NSNotificationCenter defaultCenter] addObserver:self  
                                             selector:@selector(moviePlaybackComplete:)  
                                                 name:MPMoviePlayerPlaybackDidFinishNotification  
                                               object:moviePlayerController];  

    [self.view addSubview:moviePlayerController.view];  
    moviePlayerController.fullscreen = YES;  
    [moviePlayerController play]; 
}  

3 个答案:

答案 0 :(得分:10)

尝试在viewDidAppear:而不是viewDidLoad中播放电影。在调用viewDidLoad点时,视图尚未在视图层次结构中。您仍然可以在viewDidLoad中创建MPMoviePlayerController,只是在视图实际出现之前不要播放它。

答案 1 :(得分:1)

我认为视频的大小在这里有所作为。我尝试用较小的视频做同样的事情,它工作正常。看起来视频首先被加载然后播放(参见流程问题的这个堆栈:MPMoviePlayerController not showing controls until video is loaded)。显然,200 MB视频预加载需要4-5秒。尝试使用不适合较小尺寸视频的代码。如果它工作正常,那肯定是尺寸问题。

编辑:我在MPMoviePlayerController Class Reference中找到了这个“如果您知道电影的源类型,在播放开始前设置此属性的值可以缩短电影内容的加载时间。如果您这样做在播放前未明确设置源类型,电影播放器​​控制器必须收集此信息,这可能会延迟播放。“我注意到您尚未声明源类型。再加上视频的大小,你有4-5秒的加载时间。

在播放[moviePlayerController prepareToPlay];

之前,请先尝试此操作

答案 2 :(得分:0)

我有不同的体验,但移动viewDidAppear:中的代码也有助于我的情况。我有IOS代码,从一个故事板到另一个故事板,一旦segue完成 - 在viewDidLoad:我正在初始化一个定期计时器。计时器的代码低于[我在'{1}}中'调用'startTimer:

viewDidLoad:

有趣的是,当我在viewDidLoad中调用startTimer时:我永远无法观察到iPhone上的视图更改为下一个控制器 - 我可以看到显示控件的NSLog语句来到

// Schedules a new timer, adds it to the current run loop and waits forever.
- (void) startTimer
{
    _timer = [NSTimer scheduledTimerWithTimeInterval: 10.0
                                              target:self
                                            selector:@selector(request)
                                            userInfo:nil
                                             repeats:YES];
//    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
//    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate distantFuture]];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
}

但控件不会转到ViewController。

此行为与周期性定时器的时序无关 - 设置低或高不会影响问题。当我将startTimer调用移动到- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

时,观察到的问题就消失了

即使我将计时器代码移动到viewDidAppear:,也会出现另一组挑战。这个代码有一个常规定时器 - 我创建了这个代码,这样我就可以获得蓝牙低功耗连接的RSSI值。我观察到的是我停止为蓝牙代表获得委托回调。