Extract thumbnail from video

I need to extract a thumbnail from a video (from url) and I use this code:

NSString *stringUrl = video.stringurl; NSURL *url = [NSURL URLWithString:stringUrl]; AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil]; AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset]; [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero]; [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero]; CGImageRef imageRef = [imageGenerator copyCGImageAtTime:playerCurrentTime actualTime:&actualtime error:&error]; UIImage *thumbnail = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); 

But sometime I had an error with copyCGImageAtTime, and the thumbnail was not generated. Error: Error save image Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed"(OSStatus error -12792.)", NSLocalizedFailureReason=An unknown error occurred (-12792)}

Here is a link that I read, but if using the URLLith_ath file: instead of URLWithString: the method adds "file: // localhost /" to the end of the URL, which invalidates the URL. So I don’t know what I can do.

+6
source share
6 answers

If you use MPMoviePlayerController , you can use this code to generate thumbnails from the video URL.

 NSString *stringUrl = video.stringurl; NSURL *url = [NSURL URLWithString:stringUrl]; MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:url]; UIImage *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame]; 

But, using this code, the player will start auto-playing sound. So you must stop the player with this code:

 //Player autoplays audio on init [player stop]; 

Update:

Image save error Domain error = AVFoundationErrorDomain Code = -11800 "operation could not be completed" (OSStatus error -12792.) ", NSLocalizedFailureReason = An unknown error occurred (-12792)}

The error is probably related to using URLWithString . I think you should use -fileURLWithPath instead of URLWithString .

Code example:

 NSString *stringUrl = video.stringurl; NSURL *vidURL = [NSURL fileURLWithPath:stringUrl]; AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset]; NSError *err = NULL; CMTime time = CMTimeMake(1, 60); CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err]; UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; 
+5
source

I am also trying to capture a screenshot from the bit rate stream of the HLS variable, IE M3U8, and none of the methods suggested here worked for me.

I succeeded in the end. First you need to attach AVPlayerItemVideoOutput to the player:

  self.playerAV = [AVPlayer playerWithURL:localURL]; NSDictionary* settings = @{ (id)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] }; AVPlayerItemVideoOutput* output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings]; [self.playerAV.currentItem addOutput:output]; 

Now that you want to capture a screenshot:

  CVPixelBufferRef pixelBuffer = [output copyPixelBufferForItemTime:player.currentTime itemTimeForDisplay:nil]; CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; CIContext *temporaryContext = [CIContext contextWithOptions:nil]; CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer))]; image = [UIImage imageWithCGImage:videoImage]; image = [image cropImageToSize:maxSize withProportionDiffLargerThan:IMAGE_PROPORTION_DIFF]; if ( videoImage ) { CGImageRelease(videoImage); } 
+4
source

AVAssetImageGenerator does not work for HSL video.

I managed to get the image from the HSL video using the sample code below.

Code example:

 CMTime currentTime = _player.currentItem.currentTime; CVPixelBufferRef buffer = [_videoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil]; CIImage *ciImage = [CIImage imageWithCVPixelBuffer:buffer]; UIImage *thumbImage = [UIImage imageWithCIImage:ciImage]; 
+3
source

in one of my applications, I captured a video image as follows:

 MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:videoURL]autorelease]; UIImage *thumbnail = [player thumbnailImageAtTime:0.0 timeOption:MPMovieTimeOptionNearestKeyFrame]; 

just passing the url object as videoURL, and with MPMoviePlayerController I can successfully have the image all the time. I hope you can do it with this simple code too

+2
source

If you use AVPlayer, you can get a thumbnail like this:

 AVAsset *asset = [AVAsset assetWithURL:sourceURL]; AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset]; CMTime time = CMTimeMake(1, 1); CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL]; UIImage *thumbnail = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); // CGImageRef won't be released by ARC 
+2
source

I was able to solve the same problem using the following approach.

Swift 4.1

 func createThumbnailForVideo(atURL videoURL: URL , completion : @escaping (UIImage?)->Void) { let asset = AVAsset(url: videoURL) let assetImgGenerate = AVAssetImageGenerator(asset: asset) assetImgGenerate.appliesPreferredTrackTransform = true let time = CMTimeMakeWithSeconds(1, preferredTimescale: 60) let times = [NSValue(time: time)] assetImgGenerate.generateCGImagesAsynchronously(forTimes: times, completionHandler: { _, image, _, _, _ in if let image = image { let uiImage = UIImage(cgImage: image) completion(uiImage) } else { completion(nil) } }) } 
0
source

Source: https://habr.com/ru/post/953487/


All Articles