Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving thumbnail from video - Objective C

I have an application that uploads videos into a server and now what I am trying to create is a news feed to display those video post but by a thumbnail or frame of the video. So that once the user clicks the thumbnail the video will play.

I have the following code used to grab the video from the server and play it:

- (void)openVideo {

    NSString *videoURLString = @"http://myite.com/dev/iphone/uploads/t69566.mov";
    NSURL *videoURL = [NSURL URLWithString:videoURLString];
    MPMoviePlayerViewController *moviePlayerView = [[[MPMoviePlayerViewController alloc] initWithContentURL:videoURL] autorelease];

    [self presentMoviePlayerViewControllerAnimated:moviePlayerView];

} 

Now of coarse I am gong to make openVideo dynamic with the population of video post but I am stuck on taking this video and grabbing a frame or thumbnail and displaying it.

Suggestions? thoughts?

UPDATE:

I want to take a thumbnail from a video taken from server. which actually brings me to a question.

When the user first uploads the video, would it be better to just create a thumbnail there and upload it to my server and just associate that with the video on grabbing them to populate a news feed type?

like image 646
David Biga Avatar asked Mar 17 '14 18:03

David Biga


1 Answers

You can do it using the AVAssetImageGenerator. Rough code, copied and pasted from a working project (but might not be properly isolated):

  • _thumbnailView is an UIImageView to display the thumbnail.
  • _activityView is a UIActivityIndicatorView that gets hidden when the thumbnail finishes loading.

    AVPlayerItem *playerItem = [[AVPlayerItem playerItemWithURL:movieURL] retain];
    AVAssetImageGenerator *_generator;
    _generator = [[AVAssetImageGenerator assetImageGeneratorWithAsset:playerItem.asset] retain];
    [playerItem release];
    
    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
        if (result == AVAssetImageGeneratorSucceeded) {
            UIImage *thumb = [UIImage imageWithCGImage:image];
            [_thumbnailView setImage:thumb forState:UIControlStateNormal];
        } else {
            DLog(@"%s - error: %@", __PRETTY_FUNCTION__, error);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            _thumbnailView.hidden = NO;
            _playButton.hidden = NO;
            [_activityView stopAnimating];
        });
    };
    
    [_generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(30,30)]] completionHandler:handler];
    

Back to your question, in my opinion, a server side generated thumbnail is usually better, as servers have way more processing power. Also, in order to get this thumbnail you need to start downloading the actual video from the server.

Finally, not that you pass a CMTime parameter including a call to CMTimeMakeWithSeconds(). This might prove problematic, as you can easily hit a blank frame. This is why we are using 30 as the parameter, so we avoid that situation in our videos.

like image 129
pgb Avatar answered Oct 16 '22 23:10

pgb