Search code examples
iosxcodempmovieplayercontrolleralassetslibrary

MPMoviePlayerController: Not playing video


I'm trying to use the MPMoviePlayerController to play a locally saved video however it is not working.

Here's my source:

self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[self.moviePlayer prepareToPlay];

CGRect frame = self.movieView.frame;
frame.origin = CGPointZero;

self.moviePlayer.view.frame = frame;

self.moviePlayer.allowsAirPlay         = NO;
self.moviePlayer.shouldAutoplay        = NO;
self.moviePlayer.movieSourceType       = MPMovieSourceTypeFile;
self.moviePlayer.scalingMode           = MPMovieScalingModeAspectFit;
self.moviePlayer.controlStyle          = MPMovieControlStyleEmbedded;
self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

[self.movieView addSubview:self.moviePlayer.view];

It does work when I have a URL like "assets-library://asset/asset.MOV?id=2C7D89F6-2211-4920-A842-30D773B075D6&ext=MOV" but when I have a URL like "file:///var/mobile/Media/DCIM/101APPLE/IMG_1454.mp4" it doesn't work.

I'm using the below code to get the users latest video and play it in the player:

- (void)mostRecentVideo:(void (^)(NSURL *url))completion
{
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];

PHVideoRequestOptions *options = [PHVideoRequestOptions new];
options.deliveryMode = PHVideoRequestOptionsDeliveryModeMediumQualityFormat;

[[PHImageManager defaultManager] requestAVAssetForVideo:lastAsset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
    if ([asset isKindOfClass:[AVURLAsset class]])
        completion(((AVURLAsset *)asset).URL);
}];
}

Solution

  • The same code worked for me, I used it like this. Since getting the url is an asynchronous operation, it is a must to update the UI on the main queue. Just put the code in viewDidAppear and try again.

    [self mostRecentVideo:^(NSURL *url){
        NSLog(@"did play!, url is %@",url);
        self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
        [self.moviePlayer prepareToPlay];
    
        CGRect frame = self.view.frame;
        frame.origin = CGPointZero;
    
        self.moviePlayer.view.frame = frame;
    
        self.moviePlayer.allowsAirPlay         = NO;
        self.moviePlayer.shouldAutoplay        = NO;
        self.moviePlayer.movieSourceType       = MPMovieSourceTypeFile;
        self.moviePlayer.scalingMode           = MPMovieScalingModeAspectFit;
        self.moviePlayer.controlStyle          = MPMovieControlStyleEmbedded;
        self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.view addSubview:self.moviePlayer.view];
        });
        [self.moviePlayer play];
    }];