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

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

    • 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.

  1. 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!

  2. 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!

  3. 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!

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

  4. 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!

  5. 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?

    • 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.

  6. Perfect timing for me too!

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

    Thanks.

  7. 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

  8. 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.

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

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

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

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

  10. 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.

  11. 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?

  12. 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?

  13. 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?

  14. @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

  15. @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.

  16. 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

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

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

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

  17. 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!

  18. 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

    • 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…

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

    ‘MPMoviePlayerContentPreloadDidFinishNotification’ is deprecated

    Any idea?

  20. 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.

  21. 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!

    • 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…)

  22. 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!

    • 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?

  23. 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.

  24. 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

  25. 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?

    • 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).

    • 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.

  26. 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.

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

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

  28. 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.

    • 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?

  29. 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…

  30. 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?

  31. 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.

    • 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…

  32. 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.

  33. 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

  34. 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.

  35. 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.

  36. i really want to thank you for this great work.

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

    thanks

  37. 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.

  38. 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

  39. 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).

  40. 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;
        }
      }
    }
  41. Many thanks for this example! All the best!!!

  42. 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.

  43. 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

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

  44. 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.

    • 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…

    • @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..

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

  46. 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.

    • 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.

  47. 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?

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

  48. 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..

  49. 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

  50. 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?

  51. 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?

    • [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?

      • [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

  52. 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.

  53. 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

  54. 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.

  55. 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?

  56. 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

  57. 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.

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

Comments are closed.