开发者

Weird behavior running MPMoviePlayerController in viewDidLoad

开发者 https://www.devze.com 2023-03-29 21:23 出处:网络
I\'m using the MediaPlayer framework to play a pretty sizeable movie (~200 MB) as soon as my application is launched. When I attempt to play the video in my viewDidLoad, breakpoints indicated that the

I'm using the MediaPlayer framework to play a pretty sizeable movie (~200 MB) as soon as my application is launched. When I attempt to play the video in my viewDidLoad, breakpoints indicated that the view was added however the video did not show up on the device.

I then set up a button to confirm that the video worked at all. Running the IBAction from the button showed no problems.

So then I was stumped. And I wondered if it had anything to do with the fact that the video was being called as soon as the application was launched. So I added a NSTimer with a delay of five seconds to the viewDidLoad call. Lo and behold, it worked fine. Can anyone shed any light on to why the video won't play unless there is an initial delay? Code below.

- (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]; 
}  


Try playing the movie in viewDidAppear: instead of viewDidLoad. At the point viewDidLoad is called, the view is not yet in the view hierarchy. You could still create the MPMoviePlayerController in viewDidLoad, just don't play it until the view actually appears.


I think the size of the video has something to do here. I tried doing the same thing with a smaller video and it works fine. It seems the video is loaded first and then played ( see this stack over flow question: MPMoviePlayerController not showing controls until video is loaded). Apparently, the 200 MB video takes 4-5 seconds to preload. Try the code that was'nt working with a video of smaller size. If it works fine, then it's definitely the size problem.

Edit: I found this in MPMoviePlayerController Class Reference "If you know the source type of the movie, setting the value of this property before playback begins can improve the load times for the movie content. If you do not set the source type explicitly before playback, the movie player controller must gather this information, which might delay playback." I notice you haven't declared source type. Add to that the size of the video, and you've got yourself 4-5 seconds of load time.

Also try this before playing [moviePlayerController prepareToPlay];


I had a different experience but moving the code in viewDidAppear: helped my case as well. I have IOS code that segues from one storyboard to another and once the segue is complete - in the viewDidLoad: I was initializing a periodic timer. The code for the timer is below [I was 'calling' startTimer in viewDidLoad:]:

// 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]];
}

What is interesting is that the when I call the startTimer in viewDidLoad: I can never observe the view on the iPhone change to the next controller - I can see the NSLog statement that shows the control came to

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

but the control does not go to the ViewController.

This behavior is independent of the timing of the periodic timer - setting low or high does not impact the problem. The observed problem goes away when I move the startTimer invocation to viewDidAppear:


This is followed by another set of challenge even when I move the timer code to viewDidAppear:. This code of having a regular timer - I have created this so that I can get the RSSI value for the Bluetooth Low Energy Connection. What I have observed is that I stop getting delegate callbacks for the Bluetooth delegate.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号