Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I release the MPMoviePlayerController but the memory allocation and the living objects are still higher than before the object allocation. However if I reallocate the object it doesn't leak more. My application actually uses a lot of media files and the memory consumption is high. I would like to free up completely the unneeded memory to avoid memory warnings.

Movie player release:

        player.initialPlaybackTime = -1;
        [player.view removeFromSuperview];
        [player stop];
        [player release];

Movie player alloc:

    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video0_hd.mov" ofType:nil]];
    player = [[MPMoviePlayerController alloc] initWithContentURL:url];
    player.view.frame = placeholder.frame;
    [self.view addSubview:player.view];
    [player play];
share|improve this question

3 Answers 3

up vote 4 down vote accepted

I also had this issue.

The cache used by the iPad for preloading the video stream, was not emptied completely. So each time, this page with the video player was cleaned up and released, the allocated memory after cleanup still contained the cached memory. For big video's, this could be up to 50 MB.

This is actually not a memory leak:

If the page was opened again, the cache was re-allocated. But still frustating as you want a clean exit situation, meaning when this page is left and cleaned up, all memory used by this page should be released, including the memory used for caching the video stream....!

After some serious tweeking, this sequence of commands seems to do the job:

======================

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:myMoviePlayer];        

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerDidExitFullscreenNotification
                                                  object:myMoviePlayer];        

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerLoadStateDidChangeNotification
                                                  object:myMoviePlayer];

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMovieDurationAvailableNotification
                                                  object:myMoviePlayer];        
    [myMoviePlayer pause];
    myMoviePlayer.initialPlaybackTime = -1;
    [myMoviePlayer stop];
    myMoviePlayer.initialPlaybackTime = -1;
    [myMoviePlayer.view removeFromSuperview];
    [myMoviePlayer release];

=================================

In steps:

1 - REMOVE all notifiers you are using for your movie player.

2 - Pause the movie

3 - set the Playback time to start

4 - stop the movie

5 - set the Playback time again to start

6 - now remove the movie View

7 - and finally release the movie player

Resulting in my case in also the video cache memory being released on my iPad (OS 4.2.) and leaving a clean allocated memory situation, equal to the size before the page with the video player was openen. So same enter and exit memory.

Hope this helps......

share|improve this answer
    
I will try this :) –  Cesar Aug 8 '12 at 10:01
    
hi.. i am getting this error _itemFailedToPlayToEnd: { kind = 1; new = 2; old = 0; } .. i tried your code.. but not works... some times the video playing.. some times i am getting this error for the same video @ladhani –  Vidhyanand Nov 17 '13 at 7:18

Have you tried Build and Analyze (Build>Build and Analyze), this could show you the exact line memory is leaking (if any).

Right now, I've got a feeling the problem is where you define the NSURL.

share|improve this answer
1  
It's an autorelease object, the problem it's not there, for sure. –  Cesar Aug 2 '10 at 2:03
    
Agreed... you only release what you specifically alloc / init ..everything else is not your responsibility, especially if it's a convenience class. Apple autoreleases those –  iWasRobbed Aug 2 '10 at 2:07

Are you running this code on a device or on the simulator? The simulator gives a bunch of false leaks (such as in AudioToolbox, CoreVideo, etc.). Also, the simulator seems to cache the entire video and not release it properly whereas the device buffers only what it needs along the way.

I tested your code on the simulator with an mp4 video and I had similar results to what you were saying (10 live objects each time a video was played, with none dying... 20mb allocated, and 5mb left even after releasing). The living objects and memory allocation would keep growing and growing on the simulator.

However, on my iPhone (with a 20mb video) it only allocated 900kb of memory total for the app, with no appreciable change when starting/stopping/releasing the video. It always stayed right around 900kb for the 10 times I tested it (starting/stopping/releasing).

Looks like just another time you can't trust the simulator.

The code I was testing with:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"SomeMovieFile" ofType:@"mp4"]];

MPMoviePlayerController *newPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];

self.player = newPlayer;  
[newPlayer release];

[self.view addSubview:player.view];  // for my example, I didn't set the frame location, but no difference that would do
[player play];

Then in another button I stopped it and released the player:

[player.view removeFromSuperview];    
player.initialPlaybackTime = -1;
[player stop];
self.player = nil;  // this is just a habit of mine.. calling stop should unload the buffers though
[player release];
share|improve this answer
1  
You should actually avoid the "player=nil; [player release];" because you are technically releasing "nil", not the allocated player, which could potentially cause a leak. –  pop850 Aug 2 '10 at 2:33
    
Actually, setting the object to nil will release the old value of the object and then set the object value to nil. Just like with any other object though, you still have to release anything you explicitly alloc / init.. I think you are getting confused with only setting an object to nil and then not releasing it. In that scenario, you are leaking the object since you still have a pointer to some object in memory that never gets deallocated. –  iWasRobbed Aug 2 '10 at 2:57
    
Acutally this code it's tested on an iPad, and the memory allocation has never been release completely. Anyway, if you tested the code you posted and you din't had any memory leaks it's courious, You set to nil the pointer before release the object. –  Cesar Aug 2 '10 at 3:01
    
Hmm.. I'm testing on an iPhone 4. I've heard of issues with iOS 3.2 and having to call [player pause]; prior to stopping the player. Since I don't have an iPad, I can't be sure if that'd help you or not. Like I said, calling [player stop]; is supposed to clear the buffers of data, but I just have a habit of setting to nil just in case. It should work either way. Also, make sure you are adding all necessary frameworks (that sometimes fixes strange leaks). –  iWasRobbed Aug 2 '10 at 3:09
    
@IWasRobbed: all necessary frameworks ? it's not enough #import <MediaPlayer/MediaPlayer.h> ? –  Cesar Aug 2 '10 at 4:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.