How to release MPMoviePlayerController?
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];
}
Related videos on Youtube
4thSpace
Updated on July 09, 2022Comments
-
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 over 15 yearsYeah -I got the sound/no video thing already. Awesome! How do you guard against multiple notifications? Will it crash if you handle multiple?
-
Admin over 15 yearsYou'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 over 15 yearsYou 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 over 14 yearsi have tried this , but my memory consumption does not get down? does that mean memory is not released yet?
-
leolobato about 14 yearsSometimes 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.