Search code examples
iosuitableviewmpmovieplayercontroller

Playing MPMoviePlayerController in UITableViewCell causes app to freeze and crash


In an app I am working with, we are adding an MPMovePlayerController to a UITableViewCell and then auto playing it. The problem is, calling prepareToPlay and/or play causes the app to freeze, CPU maxes out, RAM continuously increases, and the app will of course crash after a little while. If I comment out prepareToPlay and play that does not occur, but then all I see is a black box with no playback controls.

We create the MPMoviePlayerController in cellForRowAtIndexPath and store it into an array, as we may have multiple videos in the table, and need to be able to play the right video upon tapping one or stop one on demand. When the table is loaded for the first time, videos load and play without issue. Users can add a video via a modal view controller presentation, which will reload the table after adding the video to the data source. The problem only arrises after users add a new video.

I tried storing a property for the player in the cell itself, but that did not resolve the issue. I've tried calling stop before setting the contentURL as was suggested elsewhere, which also didn't help. Also tried 4 different videos each a different format, in case it was a corrupt video. I'm not sure what the problem is.

//Table view controller:
@interface {
    NSMutableArray *arrayOfMoviePlayers;
}

viewDidLoad {
    arrayOfMoviePlayers = [NSMutableArray new];
}

cellForRowAtIndexPath {
    MyTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]init];
    [arrayOfMoviePlayers addObject:moviePlayer];

    cell = [[MyTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell" withDictionary:dict withMoviePlayer:moviePlayer];
    return cell;
}

//Cell subclass:
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withDictionary:(NSDictionary*)dict withMoviePlayer:(MPMoviePlayer *)moviePlayer {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        moviePlayer.view.frame = self.contentView.bounds;
        [self.contentView addSubview:moviePlayer.view];

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(queue, ^{
                NSString* fileURL = dict[@"video"][@"url"]; //may be remote or local
                dispatch_async(dispatch_get_main_queue(), ^{
                    [moviePlayer stop];
                    [moviePlayer setContentURL:[NSURL fileURLWithPath:fileURL]];

                    //next lines cause high CPU, RAM, eventual crash
                    [moviePlayer prepareToPlay];
                    [moviePlayer play];
                });

            });
    }
    return self;
}

Some details of the crash:

Crashed Thread:        0  Dispatch queue: com.apple.main-thread
Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_PROTECTION_FAILURE at 0x00007fff5291bd80

Solution

  • The issue was due to an invalid URL to the video file. While the URL existed, it was not correct.