Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating thumbnail from video - ios7

I am using this for reference: Getting thumbnail from a video url or data in IPhone SDK

The method is using the MPMoviePlayerController class instead of the AVFoundation, and I think I want to use that as well because the people said that MPMoviePlayer way is faster than the AVFoundation way.

The problem is, the method used to create the thumbnails, [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame] is deprecated in iOS 7.0.

By looking at the apple docs, the remaining supported ways to create thumbnails are by the methods (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option and (void)cancelAllThumbnailImageRequests. But, as the method signatures dictate, these methods return nothing. So how do I access the UIImage thumbnail created by these methods?

If it helps, this is what I have so far in terms of code:

    self.videoURL = info[UIImagePickerControllerMediaURL];
    NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];

    //Create thumbnail image
    MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
    [player requestThumbnailImagesAtTimes:@[@1] timeOption:MPMovieTimeOptionNearestKeyFrame];
   //UIImage *thumbnail = ???

How do I get a UIImage reference to the thumbnail?

EDIT I figured out how to create a notification for the thumbnail image request (using this question as reference). However, I realise that this method works asynchronously from the main thread, and so my notification handler method doesn't seem to ever be called.

This is what I have now.

    self.videoURL = info[UIImagePickerControllerMediaURL];
    NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];
    MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleThumbnailImageRequestFinishNotification:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:player];
    [player requestThumbnailImagesAtTimes:@[@1] timeOption:MPMovieTimeOptionNearestKeyFrame];

And then my handler method:

-(void)handleThumbnailImageRequestFinishNotification:(NSNotification*)notification
{
    NSDictionary *userinfo = [notification userInfo];
    NSError* value = [userinfo objectForKey:MPMoviePlayerThumbnailErrorKey];
if (value != nil)
{
    NSLog(@"Error creating video thumbnail image. Details: %@", [value debugDescription]);
}
else
{
    UIImage *thumbnail = [userinfo valueForKey:MPMoviePlayerThumbnailImageKey];
}

But the handler never gets called (or so it appears).

like image 488
plasmaTonic Avatar asked Oct 14 '13 20:10

plasmaTonic


3 Answers

Try this way.

import AVFoundation framework 

in *.h

#import <AVFoundation/AVFoundation.h>

in *.m

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:self.urlForConevW options:nil];
AVAssetImageGenerator *generateImg = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *error = NULL;
CMTime time = CMTimeMake(1, 65);
CGImageRef refImg = [generateImg copyCGImageAtTime:time actualTime:NULL error:&error];
NSLog(@"error==%@, Refimage==%@", error, refImg);

UIImage *FrameImage= [[UIImage alloc] initWithCGImage:refImg];
like image 71
sankalp Avatar answered Oct 18 '22 23:10

sankalp


Here is a code to make a thumbnail of the video and save the images to the DocumentDirectory..

//pass the video_path to NSURL
NSURL *videoURL = [NSURL fileURLWithPath:strVideoPath];

AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generator.appliesPreferredTrackTransform = YES;

//Set the time and size of thumbnail for image
NSError *err = NULL;
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
CGSize maxSize = CGSizeMake(425,355);
generator.maximumSize = maxSize;

CGImageRef imgRef = [generator copyCGImageAtTime:thumbTime actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];

//And you can save the image to the DocumentDirectory
NSData *data = UIImagePNGRepresentation(thumbnail);

//Path for the documentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[data writeToFile:[documentsDirectory stringByAppendingPathComponent:currentFileName] atomically:YES];
like image 29
Hardik Thakkar Avatar answered Oct 19 '22 00:10

Hardik Thakkar


If your URL is to an HTTP live stream, then it won't return anything, per the docs. For a file URL, I found that I had to start the request after playing the movie, or it would never get called.

like image 30
Chris Garrett Avatar answered Oct 18 '22 22:10

Chris Garrett