Properly displaying and dismissing fullscreen MPMoviePlayerController in iOS 3.2 (iPad)
Here are how the events -> notifications work:
User presses 'Done' button
MPMoviePlayerWillExitFullscreenNotification
MPMoviePlayerDidExitFullscreenNotification
User presses 'Leave fullscreen' button on transport
MPMoviePlayerWillExitFullscreenNotification
MPMoviePlayerDidExitFullscreenNotification
- Note that playback does not stop
Movie reaches end
MPMoviePlayerPlaybackDidFinishNotification
with theMPMoviePlayerPlaybackDidFinishReasonUserInfoKey
set toMPMovieFinishReasonPlaybackEnded
- If you call
setFullscreen:NO animated:YES
on your MoviePlayerController instance from this notification, you'll then get theWillExit
andDidExit
notifications. - Note that you don't get the
PlaybackDidFinish
notification when the user presses the Done or Leave Fullscreen buttons.
So, typically, if you want to get rid of the MoviePlayer's view, you need to put [self.moviePlayerController.view removeFromSuperview]
in the DidExitFullscreen
notification handler. WillExitFullscreen
is too soon.
Here's my code:
- (void)willEnterFullscreen:(NSNotification*)notification { NSLog(@"willEnterFullscreen");}- (void)enteredFullscreen:(NSNotification*)notification { NSLog(@"enteredFullscreen");}- (void)willExitFullscreen:(NSNotification*)notification { NSLog(@"willExitFullscreen");}- (void)exitedFullscreen:(NSNotification*)notification { NSLog(@"exitedFullscreen"); [self.movieController.view removeFromSuperview]; self.movieController = nil; [[NSNotificationCenter defaultCenter] removeObserver:self];}- (void)playbackFinished:(NSNotification*)notification { NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; switch ([reason intValue]) { case MPMovieFinishReasonPlaybackEnded: NSLog(@"playbackFinished. Reason: Playback Ended"); break; case MPMovieFinishReasonPlaybackError: NSLog(@"playbackFinished. Reason: Playback Error"); break; case MPMovieFinishReasonUserExited: NSLog(@"playbackFinished. Reason: User Exited"); break; default: break; } [self.movieController setFullscreen:NO animated:YES];}- (void)showMovie { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; NSURL* movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tron" ofType:@"mov"]]; self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; self.movieController.view.frame = self.view.frame; [self.view addSubview:movieController.view]; [self.movieController setFullscreen:YES animated:YES]; [self.movieController play];}
Yes. That's great. There are really notifications mentioned above...
However, there are no MPMoviePlayerPlaybackWillFinishNotification somewhy!!!That's really a problem.
When you call the movie player as modal (no matter which of the following methods used presentViewController/presentModalViewController/presentVideoController), if you defined .fullScreen = YES, it's not expected to call MPMoviePlayerWillExitFullscreenNotification notification at all (obviously, because it's not cosidering we enter/exit from full screen, but only present/dismiss the controller).
But there are really no any notifications that the video is about to finish and close. That's needed (besides any other situations possible) to catch the moment when the transition of dismissing is started. (The transition, of course, starts before the MPMoviePlayerPlaybackDidFinishNotification called). And, at the same time, application:supportedInterfaceOrientationsForWindow: for previously shown controller is called before the notification, and there is no way to say the AppDelegate that our current controller must be shown already in another orientation.
So, since my video is fullscreen and also without any controls shown (this is kind of an intro, so I just until it finishes) my solution was just to have a timer which checks every short tick (0.1 seconds) what is the video current position... and it it's close to the end, then this is the moment for my own notification.