Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone development mpmovieplayer crashing

I am working on an app that will let me play different videos on the iPad remotely with an iPhone. I have been following along with apples example for a video player but I've been having some troubles. The videos play just fine and I can get it to play from a variety of videos but switching between them a few times it will crash and i get this in the debugger:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An        AVPlayerItem cannot be associated with more than one instance of AVPlayer'
*** First throw call stack:
(0x380da8bf 0x37c261e5 0x30acbcb5 0x30abc1f7 0x30ac3bf3 0x30c93d55 0x30c95f7b 0x380ad2dd   0x380304dd 0x380303a5 0x37e07fcd 0x31bb0743 0x25e5 0x257c)

This is the code I am using to create the player:

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
if (player) {
    [self setMoviePlayerController:player];
    [self installMovieNotificationObservers];
    [player setContentURL:movieURL];
    [player setMovieSourceType:sourceType];
    [self applyUserSettingsToMoviePlayer];
    [self.view addSubview:self.backgroundView];
    [player.view setFrame:self.view.bounds];
    [player.view setBackgroundColor = [UIColor blackColor];
    [self.view addSubview:player.view];
}

And when the current movie is stopped I use:

[[self moviePlayerController] stop];

MPMoviePlayerController *player = [self moviePlayerController];
[player.view removeFromSuperview];

[self removeMovieNotificationHandlers];
[self setMoviePlayerController:nil];

Edit: So Ive now discovered it happens every time i try and switch a video for the 11th time. weird! I'm practically pulling my hair out.

like image 869
Jeff B Avatar asked Nov 15 '11 14:11

Jeff B


3 Answers

What fixed this problem for me was stopping the MPMoviePlayerController before doing the setContentURL.

    MPMoviePlayerController *streamPlayer;

    [streamPlayer stop];
    [streamPlayer setContentURL:[NSURL URLWithString:selectedStation]];
like image 164
RawMean Avatar answered Nov 03 '22 09:11

RawMean


In the implementation you have above, ARC doesn't know that the MPMoviePlayerController is finished and needs to be released.

Define MPMoviePlayerController in your .h file and make it accessible via a @property (and @synthesize).

@property (strong, nonatomic) MPMoviePlayerController * moviePlayerController;

Then take the result of your alloc & init and assign it to that. I.E.

self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
like image 1
Michael Dautermann Avatar answered Nov 03 '22 11:11

Michael Dautermann


you should just keep the moviePlayerController and if you want to play another video, just use

[self.moviePlayerController setContentURL:movieURL];

then in your notification callback:

- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
    self.moviePlayer = nil;
    [self initanothermovieplayerandplay];
}

and please do not remove the notification handler from notification center, only do this in dealloc method of your VC.

now let's add some fade when the movie play is done:

- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
    [UIView animateWithDuration:1
                      delay: 0.0
                    options: UIViewAnimationOptionCurveEaseIn
                 animations:^{
                     // one second to fade out the view
                     self.moviePlayer.view.alpha = 0.0;
                 }
                 completion:^(BOOL finished){
                       self.moviePlayer = nil;
                       [self initanothermovieplayerandplay];
                 }
}
like image 1
Allen Avatar answered Nov 03 '22 11:11

Allen