MPMoviePlayerController Black Screen When Fading

Let’s say you want to animate a new view controller in and immediately start playing a video. You might things it’s as easy as taking a static image of the first frame of the video as the background and then crossfading the video overtop when it’s ready to play…right?

Kinda.

This was a 24 hour bug for me. I kept seeing this black screen before the video loads. I tried adjusting alphas, delays before playing the video, even changing the background color of the view of the video itself! Nothing worked.

Normally many of these solutions would seem right! It turns out you need to look far back in time to find the solution. In IOS 6, MPMoviePlayerController was given a new event to catch. For those of us using “MPMoviePlayerLoadStateDidChangeNotification” you’re doing it wrong… You see this load event is telling you when the video content is loaded and can play all the way through, however, it does NOT tell you when your movie is ready for the display to handle it.

There’s a new-ish notification to watch out for, it’s called: “MPMoviePlayerReadyForDisplayDidChangeNotification” and it’s your silver bullet. This thing only fires after the video has loaded…and is ready for the display!

Set everything up like you normally would, ad your observer:

[pastacode lang=”c” message=”” highlight=”” provider=”manual”]

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieReadyForDisplayChanged:) name:MPMoviePlayerReadyForDisplayDidChangeNotification object:nil];

[/pastacode]

Then add your handler:

[pastacode lang=”c” message=”” highlight=”” provider=”manual”]

- (void) movieReadyForDisplayChanged: (NSNotification *) sentNotification
{
    if (player.loadState & (MPMovieLoadStatePlaythroughOK)) {
        [UIView animateWithDuration:0.1 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
            // animation
            [[player view] setAlpha:1.0];
        } completion:^(BOOL finished) {
            // done
            [player play];
        }];
    }
}

[/pastacode]

Now your video should only fade in when it’s ready for display. After fading, you actually call “play” on the controller.

I’ll make a video and post it later…

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.