6

我必须从视频(来自 url)中提取缩略图,并使用以下代码:

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

这是我已阅读解决方案的链接,但如果使用 fileURLWithPath: 而不是 URLWithString: 该方法会在 url 的末尾添加一个“--file://localhost/”,这会使 url 无效。所以我不知道我能做什么。

4

6 回答 6

5

如果您正在使用,MPMoviePlayerController那么您可以使用此代码从视频 URL 生成缩略图。

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

更新 :

保存图像时出错 Error Domain=AVFoundationErrorDomain Code=-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];
于 2013-09-09T13:27:38.910 回答
4

我也在尝试从 HLS 可变比特率流 IE 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);
            }
于 2015-07-05T13:22:03.037 回答
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];
于 2017-02-17T15:34:03.383 回答
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
于 2013-09-09T13:32:51.190 回答
2

在我的一个应用程序中,我从视频网址中捕获了一张图像,如下所示:

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

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

于 2013-09-09T13:26:41.953 回答
1

我能够通过使用以下方法解决相同的问题。

斯威夫特 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)
        }
    })
}
于 2019-09-20T12:26:28.173 回答