简体   繁体   中英

Extract thumbnail from video url

I have 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 have an error with copyCGImageAtTime and the thumbnail is not generated. The error is: 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 the link which I have read a solution but if a use fileURLWithPath: instead of URLWithString: the method add to the end of the url an "-- file://localhost/" that invalidates the url. So I don't know what I can do.

If you are using MPMoviePlayerController then you can use this code to generate thumbnail from 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, player will start autoplaying audio. So, you have to stop the player with this code :

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

Update :

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

The Error is probably due to use of URLWithString . I think you should use -fileURLWithPath instead of URLWithString .

Sample Code :

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

I'm trying as well to grab a screenshot from an HLS variable bitrate stream, IE M3U8, and none of the methods provided here worked for me.

I did succeed at the end. First you need to attach an AVPlayerItemVideoOutput to your 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 when you wanna grab the 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);
            }

AVAssetImageGenerator does not work for HSL videos.

I was able to get an image from the HSL video using the sample code below.

Sample code :

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

on one of my app i've captured an image from the video url like this:

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

just passing the url object as videoURL and with the use of MPMoviePlayerController i successfully able to have the image all the time. hope you too will be able to do this with this simple code

If you are using AVPlayer, you can get the 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM