26

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?

asked Mar 29, 2009 at 20:23

4thSpace's user avatar

18

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?

answered Mar 29, 2009 at 23:09

4 Comments

Yeah -I got the sound/no video thing already. Awesome! How do you guard against multiple notifications? Will it crash if you handle multiple?

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.

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.

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.

7

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

answered Aug 15, 2009 at 22:47

davidcann's user avatar

davidcann

1,4491 gold badge17 silver badges18 bronze badges

1 Comment

i have tried this , but my memory consumption does not get down? does that mean memory is not released yet?

3

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

answered Apr 23, 2010 at 8:45

Mohan's user avatar

Mohan

3611 gold badge3 silver badges11 bronze badges

Comments

2

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

Yi Jiang's user avatar

Yi Jiang

50.2k16 gold badges139 silver badges137 bronze badges

answered Feb 4, 2010 at 16:35

Tiger's user avatar

Tiger

3931 gold badge5 silver badges13 bronze badges

Comments

0

I had the same problem and I just realized I set the notification method with object:nil (it was a copy paste).

I was having multiple notifications although I shouldn't have had any notifications at all.

Here is my new notification set up code that fixed all (see the object:moviePlayer):

[[NSNotificationCenter defaultCenter] addObserver:self 
                           selector:@selector(moviePlaybackDidFinish:) 
                           name:MPMoviePlayerPlaybackDidFinishNotification 
                           object:moviePlayer]; 

Hope that helps. Now all my code is working properly.

sth's user avatar

sth

231k56 gold badges289 silver badges370 bronze badges

answered Feb 17, 2010 at 12:40

mentat's user avatar

mentat

2,7681 gold badge21 silver badges42 bronze badges

Comments

0

This seemed to reduce the memory significantly. However for IOS 4.1 it seems fine.

- (void)videoFinishedCallback:(NSNotification *)aNotification
{
    thePlayer = [aNotification object];
    [[NSNotificationCenter defaultCenter]
    removeObserver:self
    name:MPMoviePlayerPlaybackDidFinishNotification object:thePlayer];

    thePlayer.initialPlaybackTime = -1;

    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
        [thePlayer pause]; 
    #endif

    [thePlayer stop];
    [thePlayer release];    
}

Salman Zaidi's user avatar

Salman Zaidi

9,95012 gold badges47 silver badges62 bronze badges

answered Sep 10, 2010 at 16:42

woot586's user avatar

woot586

3,98510 gold badges36 silver badges41 bronze badges

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.