MPMoviePlayerController – Then and Now
September 10, 2010 at 8:50 pm Leave a comment
With iOS 3.2 a new class named MPMoviePlayerViewController was introduced. It completely changed the way movies were displayed all this while in the iPhone apps. MPMoviePlayerController was also changed considerably for good. This created one issue for the developers with existing apps using these classes and framework. Even if they decided to update, they still has to support users with iOS 3.1 and earlier. Here we create a Class MoviePlayer which detects users iOS version and creates appropriate object.
Below is the class header
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>
@class MoviePlayer;
@protocol MoviePlayerDelegate <NSObject>
- (void)videoPlayerDidPreLoad:(VideoPlayer *)player inView:(UIView *)v;
- (void)videoPlayerDidFinish:(VideoPlayer *)player;
@end
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
@interface MoviePlayerViewController : MPMoviePlayerViewController {
}
@end
#endif
@interface MoviePlayer : NSObject {
UIViewController *parentViewController;
id<VideoPlayerDelegate> delegate;
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
MPMoviePlayerController *animationPlayerController;
#endif
//On a 3.2 and > device, implement the MPMoviePlayerViewController
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
MoviePlayerViewController *animationPlayerViewController;
#endif
}
@property(nonatomic, assign) UIViewController *parentViewController;
@property(nonatomic, assign) id<moviePlayerDelegate> delegate;
- (void)play:(NSURL *)url;
- (void)stopPlaying;
- (void)resume;
- (void)pause;
@end
Note that we have inherited MPMoviePlayerViewController. This is to reimplement
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
The delegate of MoviePlayer should adopt the MoviePlayerDelegate protocol. parentViewController is the view controller on which the movie is to be played.
Below is the implementation of MoviePlayer
#import "MoviePlayer.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
@implementation MoviePlayerViewController
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
@end
#endif
@implementation MoviePlayer
@synthesize parentViewController;
@synthesize delegate;
- (id)init {
if([super init] == self) {
}
return self;
}
- (void)dealloc {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
[animationPlayerController release];
animationPlayerController = nil;
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
[animationPlayerViewController release];
animationPlayerViewController = nil;
#endif
[super dealloc];
}
- (void)movieFinishedCallback:(NSNotification *)notification {
//NSLog(@"Inside movie finished callback");
MPMoviePlayerController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerContentPreloadDidFinishNotification object:moviePlayer];
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:moviePlayer];
#endif
[delegate videoPlayerDidFinish:self];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
- (void)moviePreLoadedCallback:(NSNotification *)notification {
MPMoviePlayerController *moviePlayer = [notification object];
[moviePlayer play];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[delegate videoPlayerDidPreLoad:self inView:window];
}
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
- (void)movieLoadStateChangeCallback:(NSNotification *)notification {
MPMoviePlayerController *moviePlayer = [notification object];
if(moviePlayer.loadState == MPMovieLoadStateUnknown)
return;
//NSLog(@"Inside load change callback with load state = %d", moviePlayer.loadState);
[parentViewController presentModalViewController:animationPlayerViewController animated:NO];
[moviePlayer play];
[delegate videoPlayerDidPreLoad:self inView:animationPlayerViewController.view];
}
#endif
- (void)play:(NSURL *)url {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
animationPlayerController = [[MPMoviePlayerController alloc] initWithContentURL:url];
animationPlayerController.backgroundColor = [UIColor clearColor];
animationPlayerController.movieControlMode = MPMovieControlModeHidden;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePreLoadedCallback:) name:MPMoviePlayerContentPreloadDidFinishNotification object:animationPlayerController];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:animationPlayerController];
#endif
//On a 3.2 and later device, implement the MPMoviePlayerViewController
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
animationPlayerViewController = [[MoviePlayerViewController alloc] initWithContentURL:url];
if (animationPlayerViewController) {
animationPlayerViewController.view.backgroundColor = [UIColor clearColor];
MPMoviePlayerController *mController = animationPlayerViewController.moviePlayer;
mController.controlStyle = MPMovieControlStyleNone;
mController.view.frame = parentViewController.view.frame;
mController.shouldAutoplay = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieLoadStateChangeCallback:) name:MPMoviePlayerLoadStateDidChangeNotification object:mController];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:mController];
animationPlayerViewController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[mController setFullscreen:YES animated:NO];
}
#endif
}
- (void)stopPlaying {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
[animationPlayerController stop];
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
[[animationPlayerViewController moviePlayer] stop];
[parentViewController dismissMoviePlayerViewControllerAnimated];
#endif
}
- (void)pause {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
[animationPlayerController pause];
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
[[animationPlayerViewController moviePlayer] pause];
#endif
}
- (void)resume {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_1
[animationPlayerController play];
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_3_1
[[animationPlayerViewController moviePlayer] play];
#endif
}
@end
Code above is pretty much self explanatory for anyone who has used the Movie Player framework. We basically find out the iOS version and create appropriate movie player object. We find out when the movie is pre loaded or finished and pass this message on to the delegate.
The code below explains how the above class can be used any view controller class.
NSURL *url = [NSURL fileURLWithPath:movieFilePath]; moviePlayer = [[[MoviePlayer alloc] init] retain]; moviePlayer.parentViewController = self; moviePlayer.delegate = self; [moviePlayer play:url];
You’ll have to implement the delegate methods to handle various movie player events. In the delegate method
- (void)moviePlayerDidFinish:(AnimationPlayer *)player;
you can release your MoviePlayer object.
Entry filed under: Geeky stuff. Tags: iOS, iPhone, MPMoviePlayerViewController.
Trackback this post | Subscribe to the comments via RSS Feed