佳为好友

转:Getting MPMoviePlayerController to Work with iOS4, 3.2 (iPad) and Earlier Versions of iPhone SDK

日期:2011.06.03

[自:此次升级的主要差别在于:
1,旧版本只能全屏。而新版可以在局部内显示。
2,新版本必须把view加入到某个view上才能看到。否则只有声音。
3,新版全屏播放的类的名字,应该是MPMoviePlayerViewController
4,The notification MPMoviePlayerContentPreloadDidFinishNotification has been deprecated. This notification was used in earlier versions to notify observers that a movie was loaded and ready to play.]

转:http://iphonedevelopertips.com/video/getting- mpmovieplayercontroller- to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html


Getting MPMoviePlayerController to Work with iOS4, 3.2 (iPad) and Earlier Versions of iPhone SDK

Posted on July 8, 2010 by John Muchow in Video


The API and overall approach for working withMPMoviePlayerController has changed just enough in the 3.2 SDK (iPad) and iOS4 SDK to cause working applications in earlier releases to be problematic when running on later SDKs. In this post I’ll walk through a short example of a movie player application that will work with 3.x, 3.2 and 4.0 SDKs.

In the next post, Display iPhone Movies in Portrait Mode, I’ll show how to create a movie player that runs in a view that is not fullscreen as well as how to show a few lines of code to display a movie in portrait mode – the one caveat here is that both of the tips in the second post will apply only to OS versions 3.2 and up.

What’s Changed with MPMoviePlayerController in 3.2 and 4.0?

There are any number of changes in the MPMoviePlayerController, however, a few standout as potential roadblocks to getting a movie to display:

- In 3.1 and earlier versions, MPMoviePlayerController was full-screen only. Playing a movie was straight-forward, create a player, initialize with a file (path or URL) and call a method to start playback – the rest was taken care of for you.

- With 3.2 and later, movies can playback in fullscreen or a custom view, as well as portrait or landscape.

- The notification MPMoviePlayerContentPreloadDidFinishNotification has been deprecated. This notification was used in earlier versions to notify observers that a movie was loaded and ready to play.

The Movie Application

The application in this post is quite simple, it consists of a view controller with nothing more than a button to start playback and a second view controller to manage aMPMoviePlayerController and the NSURL of the movie. The two views are shown in the figures below:

Primary View Controller

The interface definition for the primary view is shown below:

#import <UIKit/UIKit.h>   @class CustomMoviePlayerViewController;   @interface TestViewController : UIViewController {   CustomMoviePlayerViewController  *moviePlayer;   UIButton  *playButton; }   @end

CustomMoviePlayerViewController is the controller for managing the movie, we’ll look at that code in a moment.

In the code below we create the view, add a play button, create a method for processing a button press event and within loadMoviePlayer, we get a reference to the movie file and create an instance of the CustomMoviePlayerViewController, which will load and play the movie.

- (void)loadView {   // Setup the view   [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];   [[self view] setBackgroundColor:[UIColor grayColor]];   [[self view] setUserInteractionEnabled:YES];     // Add play button    playButton = [[UIButton alloc] initWithFrame:CGRectMake(53, 212, 214, 36)];       [playButton setBackgroundImage:[UIImage imageNamed:@"playButton.png"] forState:UIControlStateNormal];   [playButton addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];       [[self view] addSubview:playButton];   }   - (void)buttonPressed:(UIButton *)button {   // If pressed, play movie   if (button == playButton)     [self loadMoviePlayer];	 }   - (void)loadMoviePlayer {     // Play movie from the bundle   NSString *path = [[NSBundle mainBundle] pathForResource:@"Movie-1" ofType:@"mp4" inDirectory:nil];     // Create custom movie player      moviePlayer = [[[CustomMoviePlayerViewController alloc] initWithPath:path] autorelease];     // Show the movie player as modal   [self presentModalViewController:moviePlayer animated:YES];     // Prep and play the movie   [moviePlayer readyPlayer];     }

Notice that the movie for this example is loaded from the application bundle. Also, once the custom movie player is created, the view is shown as a modal view.

Custom Movie Player View Controller

The interface definition for the movie view controller is below:

@interface CustomMoviePlayerViewController : UIViewController  {   MPMoviePlayerController *mp;   NSURL  *movieURL; }   - (id)initWithPath:(NSString *)moviePath; - (void)readyPlayer;   @end

The initialization code is where the movie player and associated URL are created. The primary goal of the initialization is to create the NSURL needed by the movie player.

- (id)initWithPath:(NSString *)moviePath {   // Initialize and create movie URL   if (self = [super init])   {     movieURL = [NSURL fileURLWithPath:moviePath];         [movieURL retain];   }   return self; }

The code to create the player and setup the notifications is where we start to deal with the differences in how the movie player works on various OS versions. Notice below the call to respondsToSelector, this is the Apple recommended way to check for feature availability, versus looking for a specific OS version.

For devices running 3.2 and above, the movie player controller has a method namedloadstate, if this exists we can access a few additional methods to set the player to fullscreen as well as request the movie to begin preloading.

Equally important is the distinction of which notification to setup – see lines 16 and 24.

You can read more about managing different OS version in this post Developing iPhone Apps with iOS4 SDK, Deploying to 3.x Devices

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 
- (void) readyPlayer {    mp =  [[MPMoviePlayerController alloc] initWithContentURL:movieURL];     // For 3.2 devices and above   if ([mp respondsToSelector:@selector(loadState)])    {     // Set movie player layout     [mp setControlStyle:MPMovieControlStyleFullscreen];     [mp setFullscreen:YES];       // May help to reduce latency     [mp prepareToPlay];       // Register that the load state changed (movie is ready)     [[NSNotificationCenter defaultCenter] addObserver:self          selector:@selector(moviePlayerLoadStateChanged:)          name:MPMoviePlayerLoadStateDidChangeNotification          object:nil];   }     else   {     // Register to receive a notification when the movie is in memory and ready to play.     [[NSNotificationCenter defaultCenter] addObserver:self          selector:@selector(moviePreloadDidFinish:)          name:MPMoviePlayerContentPreloadDidFinishNotification          object:nil];   }     // Register to receive a notification when the movie has finished playing.    [[NSNotificationCenter defaultCenter] addObserver:self          selector:@selector(moviePlayBackDidFinish:)          name:MPMoviePlayerPlaybackDidFinishNotification          object:nil]; }

The next two chunks of code are for each of the selectors, one for each notification. The code below is for earlier OS versions – nothing more than removing the notification and asking the movie to play.

/*--------------------------------------------------------------------------- * For 3.1.x devices * For 3.2 and 4.x see moviePlayerLoadStateChanged:  *--------------------------------------------------------------------------*/ - (void) moviePreloadDidFinish:(NSNotification*)notification  {   // Remove observer   [[NSNotificationCenter 	defaultCenter]      removeObserver:self     name:MPMoviePlayerContentPreloadDidFinishNotification     object:nil];     // Play the movie    [mp play]; }

For the notification generated in 3.2 and above, there are a few more details to tend to:

/*--------------------------------------------------------------------------- * For 3.2 and 4.x devices * For 3.1.x devices see moviePreloadDidFinish: *--------------------------------------------------------------------------*/ - (void) moviePlayerLoadStateChanged:(NSNotification*)notification  {   // Unless state is unknown, start playback   if ([mp loadState] != MPMovieLoadStateUnknown)   {     // Remove observer     [[NSNotificationCenter defaultCenter]        removeObserver:self       name:MPMoviePlayerLoadStateDidChangeNotification        object:nil];       // When tapping movie, status bar will appear, it shows up     // in portrait mode by default. Set orientation to landscape     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];       // Rotate the view for landscape playback     [[self view] setBounds:CGRectMake(0, 0, 480, 320)];     [[self view] setCenter:CGPointMake(160, 240)];     [[self view] setTransform:CGAffineTransformMakeRotation(M_PI / 2)];        // Set frame of movie player     [[mp view] setFrame:CGRectMake(0, 0, 480, 320)];       // Add movie player as subview     [[self view] addSubview:[mp view]];          // Play the movie     [mp play];   } }

Beyond removing the notification, we also adjust the status bar, rotate the view, set the frame of the movie player, add the movie player as a subview in the view controller and wrap it all up by asking the movie to play.

Note: MPMoviePlayerViewController is also an option over creating your own view controller as I’ve done here.

Source Code

The easiest way to see all this working is to download the source code and step through the code in the debugger.


+++++

posted on 2012-12-30 11:21 佳为好友 阅读(283) 评论(0)  编辑 收藏 引用 所属分类: UI


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

留言簿(1)

随笔分类

搜索

最新评论

评论排行榜