从视频网址中提取缩略图

时间:2013-09-09 13:22:48

标签: iphone ios objective-c avplayer

我必须从视频中提取缩略图(来自网址),我使用此代码:

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

但有时我在copyCGImageAtTime时出错,并且没有生成缩略图。错误是:Error save image Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed"(OSStatus error -12792.)", NSLocalizedFailureReason=An unknown error occurred (-12792)}

这是我已经阅读过解决方案的link但是如果使用fileURLWithPath:而不是URLWithString:该方法将url添加到“ - file:// localhost /”,这会使网址。所以我不知道我能做什么。

6 个答案:

答案 0 :(得分:5)

如果您使用MPMoviePlayerController,则可以使用此代码从视频网址生成缩略图。

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

但是,使用此代码,播放器将开始自动播放音频。所以,你必须使用以下代码停止播放器:

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

更新:

  

错误保存图像错误域= AVFoundationErrorDomain代码= -11800“   操作无法完成“(OSStatus error -12792。)”,   NSLocalizedFailureReason =发生未知错误(-12792)}

错误可能是由于URLWithString的使用造成的。我认为您应该使用-fileURLWithPath代替URLWithString

示例代码:

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

答案 1 :(得分:4)

我也尝试从HLS变量比特率流中获取屏幕截图,I.E。 M3U8,这里提供的方法都不适用于我。

我最后成功了。 首先,您需要将AVPlayerItemVideoOutput附加到播放器:

 self.playerAV = [AVPlayer playerWithURL:localURL];

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

现在,当你想抓住截图时:

  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);
            }

答案 2 :(得分:3)

AVAssetImageGenerator不适用于HSL视频。

我可以使用下面的示例代码从HSL视频中获取图像。

示例代码:

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

答案 3 :(得分:2)

在我的某个应用中,我已经从视频网址中捕获了一张图片,如下所示:

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

只是将url对象作为videoURL传递并使用MPMoviePlayerController我成功地能够始终拥有该图像。希望你也可以用这个简单的代码来做到这一点

答案 4 :(得分:2)

如果您使用的是AVPlayer,则可以获得如下缩略图:

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

答案 5 :(得分:0)

我可以使用以下方法解决相同的问题。

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