How to release MPMoviePlayerController?

28,382

Solution 1

What I've found is that the MPMoviePlayerController has to be sent the stop message before you can safely release it. So I do it in handlePlaybackEnd - first I stop it, then I autorelease it. Calling release doesn't seem to work too well:

- (void) moviePlayBackDidFinish : (NSNotification *) notification
{
  VideoPlayerController * player = notification.object;
  [player stop];
  [player autorelease];
}

The whole thing becomes a bit trickier in that the MPMoviePlayerPlaybackDidFinishNotification can get sent more than once, but calling stop/autorlease twice won't do you any good either. So you need to guard against that somehow.

Lastly, it seems to take a few iterations of the main run loop until you can safely create a new MPMoviePlayerController instance. If you do it too quickly, you'll get sound but no video. Great fun, huh?

Solution 2

To answer 4thSpace's comment on the answer above, you can remove the notification observer so you don't receive it multiple times:

- (void)moviePlayBackDidFinish:(NSNotification *)notification {
    MPMoviePlayerController *theMovie = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self
        name:MPMoviePlayerPlaybackDidFinishNotification
        object:theMovie];
    [theMovie stop];
    [theMovie release];
}

Solution 3

for iphone os 3.2 you need to call [moviePlayer pause]; before calling [moviePlayer stop];

Solution 4

Stopping and releasing was not enough for me if the player did not reach to its end.

My solution is setting the moviePlayer.initialPlaybackTime = -1 at the moviePlayBackDidFinish: before releasing it:

-(void)playMovie: (NSString *)urlString{ 
    movieURL = [NSURL URLWithString:urlString]; 
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; 
    moviePlayer.initialPlaybackTime = 0; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish: ) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer] ;

    moviePlayer.scalingMode = MPMovieScalingModeAspectFit; 
    moviePlayer.movieControlMode = MPMovieControlModeDefault;
    moviePlayer.backgroundColor = [UIColor blackColor];

    [moviePlayer play];
}

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

    moviePlayer.initialPlaybackTime = -1; 

    [moviePlayer stop]; 
    [moviePlayer release]; 
}
Share:
28,382

Related videos on Youtube

4thSpace
Author by

4thSpace

Updated on July 09, 2022

Comments

  • 4thSpace
    4thSpace almost 2 years

    I have a couple of views that access the movie player. I've put the following code in a method in AppDelegate for these views. They send in the filename to play. The code works fine but I know a release is required somewhere. If I add the last line as a release or autorelease, the app will crash once the user presses done on the movieplayer.

    MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] 
                     initWithContentURL:[NSURL fileURLWithPath:moviePath]];
    moviePlayer.movieControlMode = MPMovieControlModeDefault;
    [moviePlayer play];
    //[moviePlayer release];
    

    I get this error:

    objc[51051]: FREED(id): message videoViewController sent to freed object=0x1069b30

    Program received signal: “EXC_BAD_INSTRUCTION”.

    How should I be releasing the player?

  • 4thSpace
    4thSpace over 15 years
    Yeah -I got the sound/no video thing already. Awesome! How do you guard against multiple notifications? Will it crash if you handle multiple?
  • Admin
    Admin over 15 years
    You'll have to have some sort of flag: if it's not set, set it and release the player. If it's set, don't do anything.
  • Daniel Dickison
    Daniel Dickison over 15 years
    You could probably also store the MPMoviePlayerController as an ivar in the delegate. In the moviePlaybackDidFinish: method you can release the ivar and set it to nil instead of accessing notification.object. The second notification will send stop and autorelease to nil, which is fine.
  • Nnp
    Nnp over 14 years
    i have tried this , but my memory consumption does not get down? does that mean memory is not released yet?
  • leolobato
    leolobato about 14 years
    Sometimes I would still listen to audio from the video in the background after the user tapped the "Done" button. Autorelease the ivar player (instead of release) did the trick for me.