Generating thumbnail from video - ios7

11,304

Solution 1

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];

Solution 2

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];

Solution 3

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.

Share:
11,304
plasmaTonic
Author by

plasmaTonic

Updated on June 04, 2022

Comments

  • plasmaTonic
    plasmaTonic almost 2 years

    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).