Getting Thumbnail * .mov iOS Video

I want to get a thumbnail of a video (* .mov) that was made with an iPhone / iPAD. I am trying to use the AVFoundation library for this and get this error:

couldn't generate thumbnail, error:Error Domain=AVFoundationErrorDomain Code=-11822 "Cannot Open" UserInfo=0x15d90a30 {NSLocalizedDescription=Cannot Open, NSLocalizedFailureReason=This media format is not supported.} 

the code:

 NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDir=[paths objectAtIndex:0]; NSString *videoPath=[documentDir stringByAppendingPathComponent:[NSString stringWithFormat:@"videos/%@.mov",videoName]]; AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:videoPath options:nil]; AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generator.appliesPreferredTrackTransform=TRUE; CMTime thumbTime = CMTimeMakeWithSeconds(0,30); AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){ if (result != AVAssetImageGeneratorSucceeded) { NSLog(@"couldn't generate thumbnail, error:%@", error); } self.img.image=[UIImage imageWithCGImage:im]; }; CGSize maxSize = CGSizeMake(320, 180); generator.maximumSize = maxSize; [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler]; 

I recorded a video with my application and I want to show their thumbnail.

+7
ios iphone video avfoundation video-thumbnails
source share
4 answers

Here it is ... (Rose from this link - Getting a video snapshot for a thumbnail )

 - (UIImage *)thumbnailImageFromURL:(NSURL *)videoURL { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL: videoURL options:nil]; AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; NSError *err = NULL; CMTime requestedTime = CMTimeMake(1, 60); // To create thumbnail image CGImageRef imgRef = [generator copyCGImageAtTime:requestedTime actualTime:NULL error:&err]; NSLog(@"err = %@, imageRef = %@", err, imgRef); UIImage *thumbnailImage = [[UIImage alloc] initWithCGImage:imgRef]; CGImageRelease(imgRef); // MUST release explicitly to avoid memory leak return thumbnailImage; } 
+14
source share

I don't have enough reputation for comments, but the above example is missing CGImageRelease(imageRef) ...

The final method should look like this:

 - (UIImage*)loadImage { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset]; NSError *err = NULL; CMTime time = CMTimeMake(1, 60); //Grab image CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err]; NSLog(@"err==%@, imageRef==%@", err, imgRef); UIImage* finalImage = [[UIImage alloc] initWithCGImage:imgRef]; CGImageRelease(imageRef); return finalImage; } 

Took me to understand ... So maybe this will help someone.

+2
source share

You can generate fast in two ways: 1. AVAssetImageGenerator 2. MPMoviePlayerController

 1. func generateThumnail(url : NSURL) -> UIImage{ var asset : AVAsset = AVAsset.assetWithURL(url) as AVAsset var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) assetImgGenerate.appliesPreferredTrackTransform = true var error : NSError? = nil var time : CMTime = CMTimeMake(1, 30) var img : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error) var frameImg : UIImage = UIImage(CGImage: img)! return frameImg } 2. override func viewDidLoad() { super.viewDidLoad() var moviePlayer : MPMoviePlayerController! = MPMoviePlayerController(contentURL: moviePlayManager.movieURL) moviePlayer.view.frame = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y, width: self.view.frame.size.width, height: self.view.frame.height) moviePlayer.fullscreen = true moviePlayer.controlStyle = MPMovieControlStyle.None NSNotificationCenter.defaultCenter().addObserver(self, selector: "videoThumbnailIsAvailable:", name: MPMoviePlayerThumbnailImageRequestDidFinishNotification, object: nil) let thumbnailTimes = 3.0 moviePlayer.requestThumbnailImagesAtTimes([thumbnailTimes], timeOption: .NearestKeyFrame) } func videoThumbnailIsAvailable(notification: NSNotification){ if let player = moviePlayer{ let thumbnail = notification.userInfo![MPMoviePlayerThumbnailImageKey] as? UIImage if let image = thumbnail{ /* We got the thumbnail image. You can now use it here */ println("Thumbnail image = \(image)") } } 
+1
source share

You need to check if each video segment is in the video track.

 + (UIImage*)getVideoPreViewImage:(AVAsset *)asset atTimeSec:(double)timeSec { if (!asset) { return nil; } AVAssetTrack *videoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject; NSArray<AVAssetTrackSegment *> *segs = videoTrack.segments; if (!segs.count) { return nil; } CMTime currentStartTime = kCMTimeZero; for (NSInteger i = 0; i < segs.count; i ++) { if (!segs[i].isEmpty) { currentStartTime = segs[i].timeMapping.target.start; break; } } CMTime coverAtTimeSec = CMTimeMakeWithSeconds(timeSec, asset.duration.timescale); if (CMTimeCompare(coverAtTimeSec, asset.duration) == 1 || CMTimeCompare(coverAtTimeSec, currentStartTime) == -1) { coverAtTimeSec = currentStartTime; } AVAssetImageGenerator *assetGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; assetGen.requestedTimeToleranceBefore = kCMTimeZero; assetGen.requestedTimeToleranceAfter = kCMTimeZero; assetGen.appliesPreferredTrackTransform = YES; NSError *error = nil; CGImageRef image = [assetGen copyCGImageAtTime:coverAtTimeSec actualTime:NULL error:&error]; if (error) { return nil; } UIImage *videoImage = [UIImage imageWithCGImage:image]; CGImageRelease(image); return videoImage; } 
0
source share

All Articles