0

Howdy! I'm writing an iPad app, and I need to be able to play a video when a UIView loads. However, I was getting a BAD_EXC_ACCESS if I try to message my MPMoviePlayerController anywhere after I initialize it. I removed the MPMediaPlayerController from my *.h file, then declared it entirely in the implementation file, and now I'm getting the message at the bottom below my code. There are no issues in Build and Analyze about memory leaks (or any issues, for that matter), and I cannot find any posts about this. Here's my code:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }

 NSString *url = [[NSBundle mainBundle] pathForResource:@"p0600c0100cmpintro" ofType:@"m4v"];
 MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
 NSLog(@"%@", movie);
 movie.view.frame = CGRectMake(5, 0, 1035, 768);
 movie.view.contentMode = UIViewContentModeScaleToFill;
 [[movie view] setCenter:CGPointMake(movie.view.center.x-10, movie.view.center.y)];
 [movie setControlStyle:MPMovieControlStyleNone];
    [movie setShouldAutoplay:YES];
 [[self view] addSubview:[movie view]];

    return self;
    }

The NSLog of "movie" gives "MPMoviePlayerController: 0x1b77f0", but then the error message upon crash is "* -[MPMoviePlayerController playbackState]: message sent to deallocated instance 0x1473a0". Help?

Jacob
  • 926
  • 1
  • 14
  • 25

4 Answers4

0

According to the documentation it looks like the frame of the movie view needs to match the view of its parent. Also try moving your code out of the initWithNibName:bundle: into viewDidLoad:

- (void)viewDidLoad {
     [super viewDidLoad];

     UIView *movieContainer = [[UIView alloc] initWithFrame:CGRectMake(5, 0, 300, 400)];
     //Do any other positioning of the view you would like

     NSString *path = [[NSBundle mainBundle] pathForResource:@"p0600c0100cmpintro" ofType:@"m4v"]; 
     NSURL *url = [NSURL fileURLWithPath:path];
     MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:url];
     movie.view.frame = movieContainer.bounds;  //Make sure this is the bounds of its parent view
     movie.scalingMode = MPMovieScalingModeFill;
     movie.controlStyle = MPMovieControlStyleNone;
     movie.shouldAutoplay = YES;

     [movieContainer addSubview:movie.view];
     [self.view addSubview:movieContainer];

     [movieContainer release];
}

One last suggestion would be to keep a reference of the movie so that you can dealloc it once the view controller gets deallocated

Joe
  • 56,979
  • 9
  • 128
  • 135
  • No good. I still get the error "message sent to deallocated instance
    ". But now I get a nice blank white page instead of the app crashing. This is because I moved the code into the viewDidLoad method.
    – Jacob Dec 20 '10 at 22:40
0

I would suggest creating your MoviePlayer in viewDidLoad, then in viewDidAppear make the movie play, for best results.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
  • The problem is occurring when I try to allocate and init the MPMoviePlayerController. I have no idea why. I have another video in my app that I played, and I switched its content with the video I'm currently fighting with, and it played perfectly fine. – Jacob Dec 20 '10 at 22:51
  • Then it would seem theres an issue with the video itself? – WrightsCS Dec 20 '10 at 23:02
  • Ah, my meaning was misunderstood. The video I'm having trouble with played fine in the first one's spot. I managed to make the first frame of the video appear, but if I set shouldAutoplay to YES, it gives me the "deallocated" message again and crashes the app. If I try to send "movie" the "play" message, I get the "deallocated" message. – Jacob Dec 20 '10 at 23:40
0

Alright, so I have another MPMoviePlayerController instance which was being deallocated earlier, but when I try to create another instance of MPMoviePlayerController, all the messages sent to this one were being sent to the deallocated instance, resulting in the memory problem. So I just removed the part where I released the first instance, and it works perfectly fine. My question now is this: is there a way to deallocate this first instance so that it isn't a burden on memory when it isn't needed? I feel that there should be a more elegant solution to this problem. I will need to play videos frequently in this application.

Jacob
  • 926
  • 1
  • 14
  • 25
0

I found the solution a number of weeks ago and forgot about this post. I wasn't successfully releasing the MPMoviePlayerController. For those curious, in order to release an MPMoviePlayerController, we must first remove the notification from the NSNotificationCenter (if one was set), stop the movie (even if it's done playing), THEN release it. I wasn't doing this earlier in the application with my first MPMoviePlayerController, so it was trying to reference the deallocated instance. When the movie is done playing, here is the code to release the movie successfully:

[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:movie];
[movie.view removeFromSuperview];
[movie stop];
[movie release];
Jacob
  • 926
  • 1
  • 14
  • 25