Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

thumbnailImageAtTime: now deprecated - What's the alternative?

Until iOS7 update I was using...

UIImage *image = [moviePlayer thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];

...with great success, so that my app could show a still of the video that the user had just taken.

I understand this method, as of iOS7 has now deprecated and I need an alternative. I see there's a method of

- (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option

though how do I return the image from it so I can place it within the videoReview button image?

Thanks in advance, Jim.

****Edited question, after trying notification centre method***

I used the following code -

[moviePlayer requestThumbnailImagesAtTimes:times timeOption:MPMovieTimeOptionNearestKeyFrame];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MPMoviePlayerThumbnailImageRequestDidFinishNotification::) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:moviePlayer];

I made the NSArray times of two NSNumber objects 1 & 2.

I then tried to capture the notification in the following method

-(void)MPMoviePlayerThumbnailImageRequestDidFinishNotification: (NSDictionary*)info{

UIImage *image = [info objectForKey:MPMoviePlayerThumbnailImageKey];

Then proceeded to use this thumbnail image as the button image as a preview.... but it didn't work.

If you can see from my coding where I've went wrong your help would be appreciated again. Cheers

like image 796
Jim Tierney Avatar asked Sep 30 '13 23:09

Jim Tierney


3 Answers

Managed to find a great way using AVAssetImageGenerator, please see code below...

AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:partOneUrl options:nil];
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generate1.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *one = [[UIImage alloc] initWithCGImage:oneRef];
[_firstImage setImage:one];
_firstImage.contentMode = UIViewContentModeScaleAspectFit;

Within header file, please import

#import <AVFoundation/AVFoundation.h>

It works perfect and I've been able to call it from viewDidLoad, which was quicker than calling the deprecated thumbNailImageAtTime: from the viewDidAppear.

Hope this helps anyone else who had the same problem.

* **Update for Swift 5.1 ****

Useful function...

    func createThumbnailOfVideoUrl(url: URL) -> UIImage? {
        let asset = AVAsset(url: url)
        let assetImgGenerate = AVAssetImageGenerator(asset: asset)
        assetImgGenerate.appliesPreferredTrackTransform = true

        let time = CMTimeMakeWithSeconds(1.0, preferredTimescale: 600)
        do {
            let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil) 
            let thumbnail = UIImage(cgImage: img)
            return thumbnail
        } catch {
          print(error.localizedDescription)
          return nil
        }
    }
like image 135
Jim Tierney Avatar answered Nov 19 '22 20:11

Jim Tierney


The requestThumbnailImagesAtTimes:timeOption: method will post a MPMoviePlayerThumbnailImageRequestDidFinishNotification notification when an image request completes. Your code that needs the thumbnail image should subscribe to this notification using NSNotificationCenter, and use the image when it receives the notification.

like image 5
Greg Avatar answered Nov 19 '22 20:11

Greg


The problem is that you have to specify float values in requestThumbnailImagesAtTimes.

For example, this will work

[self.moviePlayer requestThumbnailImagesAtTimes:@[@14.f] timeOption:MPMovieTimeOptionNearestKeyFrame];

but this won't work:

[self.moviePlayer requestThumbnailImagesAtTimes:@[@14] timeOption:MPMovieTimeOptionNearestKeyFrame];
like image 2
sash Avatar answered Nov 19 '22 20:11

sash