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

July 8, 2010

The API and overall approach for working with MPMoviePlayerController 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 a MPMoviePlayerController 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 named loadstate, 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.

93 comments

Fantastic! Perfect timing for me! :)

by Dylan on Jul 8, 2010. Reply #

Hello, great article… can you explain how to display the movie in the vertical?

by Helder Luis on Jul 9, 2010. Reply #

Helder, I’ll write a post next week with the code changes to play in portrait. In the mean time it’s quite easy if you want to make the change…remove the code for rotating the view and change the movie player frame size.

by John Muchow on Jul 9, 2010. Reply #

Hi!

Thanks for the great tutorial. I’ve been struggling with a problem getting video to play for a couple of hours and you’ve definitely helped me out. Keep up the great work – I know I’ll be subscribing to your feed.

Can’t wait to read the next tutorial!

by Brandon Ballentine on Jul 9, 2010. Reply #

This is such good information–thank you! Other sources I’ve come across say (un)helpful things like ‘Check out the documentation” or “see the page that enumerates differences between iOS 3.x and 4.0″, etc. I’m a freshman / sophomore developer (not quite green, but not a programmer by training). Your accessible approach is exactly what I need. You should consider writing a book!

by JackW on Jul 10, 2010. Reply #

A couple questions about this code…it’s really great…except:

1. When I first launch it (from your example code) the “Done” button doesn’t appear. I can tap where the “Done” button is supposed to be and it works fine but I need it to show up right away. If I stop the video and relaunch it (without closing out of the program) then the “Done” button will appear on the second time…any suggestions?

2. How can I add a background to the first page (the one with the green button). I tried adding replacing
“[[self view] setBackgroundColor:[UIColor grayColor]];” with [[self view] setBackgroundImag…;” but that doesn’t work…any suggestions since you don’t have a .xib file on your example…thanks!

by Kevin on Jul 11, 2010. Reply #

I have the same issue with the Done button on the movie player, however, it does show up on a device (must be a simulator issue).

You can add a background to the current view using something similar to this:

UIImageView *background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SomeImage.png"]];
[[self view] addSubview:background];

by John Muchow on Jul 11, 2010. Reply #

I created a new project and copied the code over and it works just great! You are a genius for this code because you are the only one that I’ve seen anywhere on the internet that has cracked this cookie!

by Kevin on Jul 11, 2010. Reply #

Great, timely tip; many thanks!

I have one issue, however, on os4 (not tested on 3.x): On both the device and in the simulator, once the movie has finished playing, the status bar is no longer visible. The following work-around restores the status bar:

- (void) moviePlayBackDidFinish:(NSNotification*)notification {
:
:
[self dismissModalViewControllerAnimated:YES];

// For some reason the status bar disappears after the movie has played. This restores it:
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}

However, the view which should be displayed directly beneath the status bar, is now _covered_ by the status bar. It is visible because the status bar is translucent, but this is still not satisfactory. Obviously I would prefer it if the layout weren’t messed up by the full-screen playback.

Any suggestions?

by Mike on Jul 12, 2010. Reply #

Mike, I agree, earlier versions of the SDK seemed to handle all this properly, based on the current setting of the status bar. Seems the system should manage all this without the need to hide/show as I did in the example. If this is how the status bar now operates, the only solution that comes to mind is to manage the hiding/showing as needed by your app. Sorry I don’t have a more reasonable approach…suggestions are welcome.

by John Muchow on Jul 12, 2010. Reply #

Any ideas how to display the video on the TV out port using the Apple Composite cable?

by Bart Burkhardt on Jul 12, 2010. Reply #

Perfect timing for me too!

I was having trouble with the new MPMoviePlayerViewController – a LOT…

Thanks.

by Johnnie G. on Jul 12, 2010. Reply #

Hi John,
Great post, thanks. Any idea on the leak that shows up in instruments when running the code. I think it might be a framework leak but would be interested in your thoughts.

Also I think MPMoviePlayerViewController is much easier for 3.2+ you just need to sub class MPMoviePlayerViewController and set shouldAutorotateToInterfaceOrientation to return UIInterfaceOrientationIsLandscape(toInterfaceOrientation)

Cheers,
Andrew

by Andrew H on Jul 13, 2010. Reply #

Great code, thank you so much!

I have noticed the code works fine when it’s on the first view of a tabbar application, but not when on any subsequent tabs, so odd.

Any idea what’s going on with it that could cause this?

I have reused the exact same code on a simple view based application, or the first view shown in a tabbar application, but moving that view the the second, third etc.. view of a tabbar results in the MPMoviePlayerController interface appearing and loading the file, but it will not play and hitting the play icon flashes to the pause icon and back, but never plays the video. You can scrub the video and see that it has loaded, but it will not play.

by John on Jul 14, 2010. Reply #

Sounds like something is amiss relating to the movie player and adding its view to the current view controller…

by John Muchow on Jul 14, 2010. Reply #

How can I change it to used live stream?

For exemple, how to play this url http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8” ?

Thxs!

by Wagner Salazar on Jul 14, 2010. Reply #

Something close to this should work for accessing a remote file/stream:

NSURL *movieURL = [NSURL URLWithString:@"http://pathToMovie"];
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];

by John Muchow on Jul 14, 2010. Reply #

Followup for anyone interested, the problem with my tabbar application, was the first tab had AVAudioPlayers on it, and if they are in the preparetoplay state when you change views without stopping them the mpmovieplayercontroller will not work, it will just load the movie and bug out.

This helped me:
http://stackoverflow.com/questions/2807800/avaudioplayer-interferes-with-mpmovieplayer-on-ipad

by John on Jul 15, 2010. Reply #

Great article. Just exactly what I need to fix the issue in my app. Thanks a bunch :)

by Felix on Jul 15, 2010. Reply #

That is a great tutorial and it helped me so much. But, I am trying to load the movie from a webserver and I can’t seem to get it right. Could you suggest a fix or point out my fault. XD

Original Code from TestViewController.m

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

}

My modified code:

- (void)loadMoviePlayer {

// path URL
NSString *path = [[NSString alloc] initWithFormat: @”http://www.fourhorsemeniphonegames.com/Movie-1.mp4″];

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

}

Thank you.

by Mike Whitney on Jul 16, 2010. Reply #

It seems like if you play a video for the first time, the video does not let you seek and does not have the “done” button. Those components are there after the first playback finishes. Ay idea on why it’s like this?

by Dave on Jul 17, 2010. Reply #

Fantastic post!

I am trying to use this to play both streaming audio and video – we have a video feed and a separate feed with audio podcasts – it is working fine in 3.1. Now if I try overlaying buttons, they display but they do not respond to touches. Also if an audio only stream is playing vs video, a slightly different status bar displays with no “Done” button. The control bar has a different format than before as well and is centered in the middle vs up top.

Any ideas how I can get audio behaving the same as video and how I can have a clickable overlay button?

by Jamie on Jul 18, 2010. Reply #

I have the same problem as Dave with the video not having a “Done” button. It will stop the video if you tap in the place where it would be if it were visible. The second or third time you play a video it appears OK. Does anyone have a solution?

by Donal O'Danachair on Jul 21, 2010. Reply #

@Mike

I also noticed the issue with the Status Bar. Your solution only puts it back on screen. You need to also change the style. Do the following:

// For some reason the status bar disappears after the movie has played. This restores it:
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

Check from Apple reference for the correct syntax. Anyway the change above will COMPLETELY restore your status bar (I guess you want the default style – white and opaque – not black and translucent).

This solution worked for me.

Regards,
Theodor

by Theodor on Jul 22, 2010. Reply #

@Mike Whitney

The example’s initWithPath method is specifically trying to play a file.
movieURL = [NSURL fileURLWithPath:moviePath];

So, passing in a webaddress will not work that you. You need to change that line to
movieURL = [NSURL URLWithString:moviePath];

That should get your player to play the URL.

by anis on Jul 22, 2010. Reply #

Thanks for this working example of a movie player in an iPhone iOS4 app (works for me under iOS4.1).

But, I’m still exploring the mysteries of this new movie playing API.
I added a different movie to the Resources — a movie with soft subtitles — and I changed the path to the movie resource appropriately in -[TestViewController loadMoviePlayer].

The new movie played, but the movie’s (second, larger) control bar omitted the little bubble that gives the user control over the soft subtitles ( “Subtitles: Off; English; Spanish; …” );

I changed one line in -[CustomMoviePlayerViewController readyPlayer]:

// Set movie player layout
//[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setControlStyle:MPMovieControlStyleEmbedded]; // Necessary for soft subtitles?
[mp setFullscreen:YES];

Presto! Soft subtitles work.
What manual should I have read to expect that?

Thanks,
Don

by DonB on Jul 22, 2010. Reply #

Have you figured out a way to have one of the subtitles on as a default?

by Benedicte on Mar 6, 2012. Reply #

No. Sorry.

by DonB on Mar 6, 2012. Reply #

Thanks for the reply! I find there is little documentation on this.

by Benedicte on Mar 6, 2012. Reply #

Benedicte, could you share with me the subtitle documentation for MP.
Thanks

by Duy on Sep 28, 2012. Reply #

I can’t remember finding much…

by Benedicte on Sep 28, 2012. Reply #

I have fixed the problem with the missing “Done” button. By trial and error I found that you set the control style to default first, then fullscreen, before playing the video, like this:

[mp setControlStyle:MPMovieControlStyleDefault];
[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp play];

No, I’ve no idea why this works!

by Donal O'Danachair on Jul 26, 2010. Reply #

Donal O’Danachair can you tell me where you put the code i can make it work i have the same problem with the buttons
any suggestion

by Julio Kohlberg on Jul 31, 2010. Reply #

Julio, I believe you get these warning as you are building with a newer release of Xcode and the SDK. The methods has been replaced in the new tools and thus the compiler is notifying you of this. For this specific example, getting the movie player to work with both OS’s version, I don’t believe there is a simple way around this warning…

by John Muchow on Aug 2, 2010. Reply #

I get two warnings about methods being deprecated, for example:

‘MPMoviePlayerContentPreloadDidFinishNotification’ is deprecated

Any idea?

by Julio Kohlberg on Jul 31, 2010. Reply #

To rotate the iOS4 movieplayer, it’s enough to subclass the MPMoviePlayerViewController and make shouldAutorotateToInterfaceOrientation return YES for landscape orientations only and then user presentModalViewController on it. The code posted with the transformations might not work correctly if the user rotates the device.

by Adrian Pflughaupt on Aug 2, 2010. Reply #

John, thanks for this example, exactly what I needed!
I wanted to ask, when I play a movie on my phone running iOS4, there’s a fade-in effect when the movie starts, but there’s no fade-out effect when the movie ends anymore, and it really kills the transition from movie to game in my app. Do you know of any way to turn this effect back on?

Thanks!

by Adam on Aug 8, 2010. Reply #

Adam, I don’t know of a way to enable the transition. You could create your own transition when the movie player view is shown, using any of the built-in transition effects (curl, cross-fade…)

by John Muchow on Aug 8, 2010. Reply #

Hi,
I am still facing two error for 3.0 as
1. MPMovieLoadStateUnknown undeclared
2. MPMoviePlayerLoadStateDidChangeNotification undeclared

Let me know if anyone can help.

Thanx in advance!

by Jack on Aug 10, 2010. Reply #

Jack, regarding the 3.0 errors, this code examples assume you are using Xcode 3.2.x or later, are you using an earlier release?

by John Muchow on Aug 12, 2010. Reply #

John, this is the absolute best description for enabling video on ios4 i’ve seen. You have done a fantastic job explaining correctly how to manage the changes in ios4 and get video to show on the iphone, unlike the many articles that lead people down a dead end. Amazing work, thank you, and i will look forward to your future posts because i will know it’s from a reliable source, and thanks for the link to the code too.

by Alex Rodriguez on Aug 10, 2010. Reply #

great tutorial. Just as suggestion.. could you make a ‘simple tutorial just to show how to play 2-3 short video sequences directly after each other (so it looks like one video, without any breaks, so we dont see the background even for a second) … :0

by chris on Aug 11, 2010. Reply #

still great tut, i just tested right now to make a video an endless loop. It looks with this tut i even have no glitches (so i would see the background).. i just place [mp play]; into moviePlayBackDidFinish and commented the other code in it (removing observer). Looks amazing, the video loops several times.. but than unexpected it just pause (after 3-4 loops). no crash, but pause. I just can click play to continue. Any idea so it comes really an endlessloop?

by chris on Aug 11, 2010. Reply #

Chris, I don’t know of a means to play videos in sequence, using the same player. Although a hack of sorts, you could create more than one player, one for each video and code the app such that you hide/show the players as needed to achieve the effect you are after (definitely not an ideal solution).

by John Muchow on Aug 11, 2010. Reply #

Chris, for OS 3.2 and greater there is a property of the movie player, repeatMode which you can set to MPMovieRepeatModeOne and the movie will repeat when finished.

by John Muchow on Aug 11, 2010. Reply #

HI John

i just love your work its great it has worked for me perfectly.

but i have a question:

i want to add info button somewhere whlie the vide is playing, and if clicked it we display UIWeb view with content from URL at the buttom of the player while the video still running. i dont know if this doable or no, and if yes how. can you please advise.

regards.

by Waleed on Aug 11, 2010. Reply #

Waleed, since the CustomMoviePlayerViewController is a UIViewController, you can add any buttons or other controls you like.

by John Muchow on Aug 12, 2010. Reply #

can you just advise me how i can overlay a UIWebview over the video player using CustomMoviePlayerViewController

by waleed on Aug 12, 2010. Reply #

Waleed, this post Add Rounded Corners and Border to UIWebview shows how to create a webview and add it as a subview to a view controller.

by John Muchow on Aug 12, 2010. Reply #

Hi John,

Thank you very much for taking the time to post this example. I have looking for something like this for a week… Going crazy. This is absolutely the best.

I am brand new to XCode and the iPhone and I am building interfaces using xib files. You don’t use it in this example since you create the view and buttons with code instead of Interface Builder. I want to build an app that uses a xib file so I can add a TableView so the user can pick the video they want to see.

Is there any easy way I can modify your code so that the first view is created in Interface Builder so I can add the TableView.

I would really appreciate any insight you might have. Sorry I not that swift with this stuff yet.

Thanks again.

James R.

by James R on Aug 13, 2010. Reply #

James, I wish I could be of more help, unfortunately I use the code only approach (no IB) for all my projects. Anyone else have a code example that may be helpful?

by John Muchow on Aug 13, 2010. Reply #

I have applied to ipad running well.
Has been very helpful.

Thank you.

by brainchaos on Aug 29, 2010. Reply #

Mike

I’m developing for the iOS 4 and I ran into the same issue with the status bar covering the 20px of the view stopped playing, and I my done button wasn’t showing as well.

So I did some changes on John’s class and it works fine no for iOS 4.

Fot the done Button I used the solution suggested by Donal:

[mp setControlStyle:MPMovieControlStyleDefault];
[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp play];

For the status bar issue and the white gap I was seeing while the movie was being played, here is my fix:

On moviePlayerLoadStateChanged Change the following (Change the first 0 to 20, this is the size of the status bar)
[[self view] setBounds:CGRectMake(20, 0, 480, 320)];

And change moviePlayBackDidFinish (So you hide the status bar before dismissing the modal, which will get your view behind the modal to stop the strange behaviour)

- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];

[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

[self dismissModalViewControllerAnimated:YES];
}

Hope this helps…

by Luis Dal Bello on Sep 1, 2010. Reply #

Great Tutorial :)

Unfortunately, I still got a problem. I’ve been trying to remove the status bar which always appears when the movie is played in fullscreen, but for some reason,
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
doesn’t work at all.

So far, It seems to me removing this status bar is impossible.

Does anyone have a clue about this?

by Setblue on Sep 7, 2010. Reply #

This worked great for me. However, I did have issues on the device whereby rotating it while the video was playing would cause the statusbar to jump to it’s portrait position and stay there until you closed the video. I got around this by observing UIApplicationDidChangeStatusBarOrientationNotification in the controller and setting it back to UIInterfaceOrientationLandscapeRight.

by Daniel Wood on Sep 10, 2010. Reply #

To solve statusBar orientation problem just add the code below into CustomMoviePlayerViewController.m file.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

This worked for me perfectly.

The problem is
statusBar orientation of your view that contains your MPMoviePlayerController is Portrait by default. So you must override the default orientation with LandscapeRight.

Thanks for all replies that guided me for the other issues.
Happy coding…

by Dogan Coruh on Jan 21, 2011. Reply #

Found that, but fail to do the right change to your code
https://devforums.apple.com/message/247015

by Sylvain on Sep 16, 2010. Reply #

This example doesn’t play when targeted at an iPad device running iOS 3.2.1.

What I’m seeing is:

The movie control comes up fine with the movie. But when I hit the play button, the movie immediately stops playing.

Is anyone else seeing this problem? Has anyone solved this?

Thanks.

by Jay Koutavas on Sep 20, 2010. Reply #

Hi,
I have implemented this logic in my application (it has title bar and bottom navigation tab bar as well).
However when the movie plays full screen, the top and bottom bars are visible ON TOP of the movie

I have tried to hide them, get rid of them etc – no luck
Can you provide any guidance?

Thanks for your help

by Shailesh on Sep 23, 2010. Reply #

This really works great! I had been chasing a problem of getting video to play correctly for a day and looked at several supposed “solutions” but this is the first one that actually worked.

One weird thing, in the simulator, the “Done” button does not show up the first time that you play the video. If you click where the button should be, it works, but the button is invisible. It shows up the second time you play it. This is only an issue in the simulator. Works fine on a device.

Thanks for the info.

by Steve Fish on Oct 3, 2010. Reply #

It’s seem to be a bug in the code.

If you pinch in an out with your finger (zoom mode) the Movie Player crashes…
Do you have a solution for this?
Do you have implemented a UIPinchGestureRecognizer to override the problem?

Thanks.

by Andrea on Oct 6, 2010. Reply #

i really want to thank you for this great work.

i have solved almost all my problem by visiting your website.

thanks

by waleed on Oct 11, 2010. Reply #

I also have the same problem that Andrea wrote about earlier.

When I pinch in an out with my fingers (zoom mode) the Movie Player crashes or tilts then gets stuck on that screen.

Is there a way to disable the pinch gesture?

Any suggestion will help.

Thanks in advance.

by John on Oct 11, 2010. Reply #

For those having issues with the pinch to zoom crashing the player, you need to implement [moviePlayBackDidFinish] and try stopping the movie and autoreleasing it there (instead of during allocation).

I looks like pinching out on the screen sends a [moviePlayBackDidFinish] notification to the view controller for some reason and the movie player is being autoreleased before we are finished using it (i.e. before we actually send it the stop message.

- (void) moviePlayBackDidFinish:(NSNotification*)notification {
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];

[moviePlayer stop];
[moviePlayer autorelease];

// Pop out view or perform anything else you need here
}

I got the tip from this link on StackOverflow: http://stackoverflow.com/questions/695307/how-to-release-mpmovieplayercontroller

by Rog on Oct 27, 2010. Reply #

Thanks for the great tutorial!

I have one issue:

The views of my app are all in portrait orientation, all view controllers are managed by a navigation controller. My app shows a default status bar. What I do to show the movie I do a

[navigationController presentModalViewController ...]

Now when I do a dismissModalViewControllerAnimated in the movie view controller my portrait view is shown, but the the status is white and the navigation controller has a wrong position.

Does anybody has a suggestion?

A self.wantsFullScreenLayout=YES; in my movie view controller did not help (I found this hint on the web).

by Tobi on Nov 25, 2010. Reply #

For those who’ve ran into problems with Pinch and Zoom, here is a block of code to try:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
  for (UITouch *touch in touches) 
  {
    NSArray *array = touch.gestureRecognizers;
    for (UIGestureRecognizer *gesture in array) 
    {
      if (gesture.enabled && [gesture isMemberOfClass:[UIPinchGestureRecognizer class]])
        gesture.enabled = NO;
    }
  }
}

by John Muchow on Dec 23, 2010. Reply #

This one worked for me!

by Daniel on Sep 20, 2011. Reply #

Many thanks for this example! All the best!!!

by Paulo Almeida on Jan 1, 2011. Reply #

This example is so good which is the one I’ve been looking for. However, there are some problems happened in my project with navigation controller.

I used the navigation controller as a menu list, and click one of the cell can go into the page which I composed of UIScrollView + UIPage Control + UIImageView + UIButton. The horizontal flicking page function will not work once I click “Done” with movie player. But if I click the upper-left navigation item to the menu list and go back to the page again by clicking one of the cell, then horizontal flicking page function will work again.

The other example I made which is the same thing with UIScrollView + UIPage Control + UIImageView + UIButton, but without navigation controller can function properly with the movie player code you provided.

What could be the possible reason causing the problem? If anyone knows please let me know, many thanks in advance.

by Lee on Jan 2, 2011. Reply #

Hi John, thanks for the tutorial.
I’m currently just targeting iOS 3.2 and above.

Everything works but it’s having an undesired flickering issue when I change between videos.
How can I get rid of that flicker?

I’ve tried the following:
1) Assigning different movie files to different instances of MPMoviePlayerController. It didn’t help
2) Putting a background picture at the bottom,(through Nib file) so its not complete dark. it didn’t help.
3) Allocate once, then set to different URL as different movies needed. It didn’t help
4) Realloc everytime when a different movie is called It didn’t help.

Below is the code that I have.

-(void)viewWillAppear:(BOOL)animated
{
NSString *urlStr = [[NSBundle mainBundle] pathForResource:@”intro.mov” ofType:nil];
NSURL *url = [NSURL fileURLWithPath:urlStr];
videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[self.view addSubview:videoPlayer.view];
videoPlayer.view.frame = CGRectMake(0, 0,320, 480);

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];

[videoPlayer play];
}

- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSString *urlStr = [[NSBundle mainBundle] pathForResource:@”loop.mov” ofType:nil];
NSURL *url = [NSURL fileURLWithPath:urlStr];

[videoPlayer setContentURL:url];

[videoPlayer play];
}

Thank you,
Tee

by Teepusink on Feb 2, 2011. Reply #

Hi I’m having the same problem, a small pause between videos. Has anyone found a workaround to this? Thanks ;)

by Brad on Jul 16, 2012. Reply #

Hi. Thanks for this article. It helped A LOT. I’ve been working through the Stanford University iPhone app development course on iTunes U, and was wondering why their video playback method didn’t work.

Unfortunately I’m having a bit of trouble with your code. I’ve modified it to load the video from an external URL (my webserver on the Internet) rather than a file. If I hit the Done button before the movie completely loads, then the next time I go to try and play it, the playback doesn’t start automatically. If I wait until the movie has completely loaded before hitting done, then everything works the way it should.

Any ideas? Please excuse me if this is an overly newbie-ish question, I’m still relatively new to iOS development.

by Donald Burr on Feb 13, 2011. Reply #

There seem to be a number of issues around the Done button, from not appearing in the simulator to other issues such as you mention. I don’t have a specific answer to your question, unfortunately. You could look to verify that all objects are released and any notifications are cleared if hitting Done before the movie starts. Also, look over some of the other comments in this post as others have had similar questions…

by John Muchow on Feb 13, 2011. Reply #

@Donald Burr.
I also faced the same problem and figured it out as:

in didFinisedPlayback notification method
add
[mp stop];

just before you unload the modal view..

by Gaurav Keshre on Jun 21, 2011. Reply #

I have white line when playing the video , it’s from the status bar i try to hide it no luck, any suggestion ?

by Maher on Mar 30, 2011. Reply #

I just downloaded the app. And it works as is. I will customize it to play my home webcam stream, if anyone wants to discuss (I will check back here). For now just want to send big thanks to John Muchow for posts like this one.

Dung.

by Dung Le on Apr 23, 2011. Reply #

I am intersted in your webcam experiment.
I tried modifing code for HTTP live stream. sirectly out of CCTV Camera.
However it does not work.
My addition are as bellow

movieURL= [NSURL URLWithString: @"http://173.113.89.74/cgi-bin/encoder?&GET_STREAM"];
mp.movieSourceType = MPMovieSourceTypeStreaming;

mp.view.backgroundColor = [UIColor clearColor];

the wiresharks logs says the data is being transfered. but what i see on iphone simulaor is just a black page.

by sachin on May 31, 2011. Reply #

I’m wondering what the difference is, if any, between the “MPMediaPlaybackIsPreparedToPlayDidChangeNotification” which is part of the MPMediaPlayback protocol, and the “MPMediaPlaybackIsPreparedToPlayDidChangeNotification” that you use?

by Paul on Jul 6, 2011. Reply #

Of course, I meant “MPMoviePlayerLoadStateDidChangeNotification” – i.e. what’s the difference between this and “MPMediaPlaybackIsPreparedToPlayDidChangeNotification”?

by Paul on Jul 6, 2011. Reply #

hi. Thanks for this tutorial.
i have made custom media control that is Next and Previous control(not forward and backward controls).
now i want to hide/unhide these controls as default controls do.
is there any possibility for that?

ThanQ in advance..

by Suhail Larik on Jul 6, 2011. Reply #

Hi John

Hi , Do you have any examples for streaming videos on a iPhone/ipad app , where
the video resides on the web server (php and MySQL).Any inputs would be highly
helpful

by Sandy on Aug 28, 2011. Reply #

I have been looking for an Xcode4 MoviePlayer tutorial and they are far and few in-between. Great post.

I got lost after the Primary View Controller.

Does this example use 2 .xib files? Meaning 1 xib to hold the button and another xib for the MoviePlayerController? And are we creating a .h & .m file for both xibs?

by Rhonda on Aug 31, 2011. Reply #

Anybody know how to manually stop the movie? I’ve tried a bunch of things but basically I end up with a black screen. I’m assuming the view isn’t being shutdown right.

I thought [mp stop] would do it through notifications, but no joy. I also tried manually calling [self movePlaybackDidFinish] but that was no different than just calling stop.

Any ideas?

by DaveA on Sep 14, 2011. Reply #

[mp stop] will give you a black screen, as it stops the video altogether, and you end up seeing the background view of the MPMoviePlayerController. Have you tried [mp pause] instead?

by Bob on Sep 15, 2011. Reply #

[mp pause] literally just pauses the video. So I get the last frame that was displayed on screen. I want the entire video to shutdown and the modal view to be removed (which is why I tried calling moviePlaybackDidFinish directly).

Basically I want what’s underneath the video to be displayed. I guess a good question is what does the “done” button do and how do I simulate that? The done button does exactly what I want to do.

-Dave

by DaveA on Sep 15, 2011. Reply #

Hello,
Thanks for this wonderful tutorial :D

However i have problem with what i want from my app.
I want to create an app that can open audio file from the website (mp3 audio file).

My Structure of my apps,
tabbarcontroler as rootview, then navigation controller -> a page with page control + UIScroll view -> have detail controller (show description and a button to play the podcast).

What i want from my custom media player is look like this.
http://img404.imageshack.us/img404/8462/photooct16102252pm.png

As you can see it is an audio file but play with media player like movie player. I want the background to be customize also.
From this tutorial also, i’ve got problem with status bar and my navigation tab. im using modalView but not get rid of the navigation. I’ve tried answers in above question also.

by Edric on Oct 16, 2011. Reply #

Hi,
Thanks for this good tutorial.
I have successfully ran the code and it worked perfect.
but I have a strange problem:
I recorded a video using my iPhone camera with type of : .mov.
when I tried to play it using your code, the app terminates suddenly.
the video format : H.264, AAC (360 × 480).
also I tried movieplayer sample code on apple.com but no success.
I can play it using the internal iPhone video player with no problem.
also i tried “AVPlayer” free app, IT CAN PLAY THE VIDEO.
I tried converting the video to m4v, and it worked. but I want to play it without any conversion.
I ggogled a lot but no success, can you please help me.

Thanks

by Kaveh on Oct 30, 2011. Reply #

Hello ,

I am facing one problem while plying video , i am giving my video fram size 320x 100, i am not added full screen mode code,but when video is showing full screen option,if we click that its playing in full screen mode my frame size is changing, i want fix my frame size 320×100,i tried in notification methods willenterFullscreen mode also i given my frame sizes still its going full screen mode ,i don’t want play in full screen mode,Can you help in this ,Thanks in advance.

by narresh on Nov 7, 2011. Reply #

Does anybody know how to make the function similar to iPhone Youtube App?

For example, the youtube video will play automatically after clicking the navigation cell and click the “Done” button or the video finishes the playing and will go back to navigation cell.

Can I use the MPMoviePlayerController to import the youtube video?

by David Lee on Nov 17, 2011. Reply #

HI,

Great tutorial thank you very much.

I’m having an issue which nobody seems to have commented about so im not sure if its something thats only happening to me. The reason i started looking at your code is because m using MPMoviePlayerController in my App, for some strange reason when playing a streaming video on my ipad/phone irrespective of how long i play it for, once it stops or i stop it myself in profiler the Live bytes do not seem to drop and keep on incrementing every time i play a video. Im also finding the same issue when playing audio files. I thought it may be something im doing however, im finding the same issue with your example.

Can you someone please tell me why this may be happening? Is it normal hence why nobody has pointed it out? I know its not a memory leak and its probably something with buffering but ive hit a brick wall and I have no idea what to do.

I found the following link on stackoverflow and it seems that others are having similar issue but i cannot find a solution. Can someone please help me?

http://stackoverflow.com/questions/3384388/mpmovieplayercontroller-still-leaking

by David on Nov 22, 2011. Reply #

Thanks a lot!!

by KK on Dec 7, 2011. Reply #

It?s actually a cool and useful piece of info. I am glad that you simply shared this helpful info with us. Please stay us up to date like this. Thank you for sharing.

by Blu Ray Movie Downloads on Jan 12, 2012. Reply #

It is really very good code , for freshers like me…

by jilani on Feb 24, 2012. Reply #

Leave a Comment