【问题标题】:Extract thumbnail from video url从视频网址中提取缩略图
【发布时间】:2013-09-13 00:02:48
【问题描述】:

我必须从视频(来自 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)}

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

【问题讨论】:

  • 你找到解决办法了吗?
  • @anna565 你找到解决方案了吗?我有同样的错误,但不知道为什么会发生。
  • @aykutt 您找到解决方案了吗?我有同样的错误,但不知道为什么会发生。

标签: iphone ios objective-c avplayer


【解决方案1】:

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

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

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

【讨论】:

  • 你应该指定...添加了标签。
  • 抱歉我添加了标签
【解决方案2】:

如果您使用的是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 "The 操作无法完成“(OSStatus错误-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];

【讨论】:

  • 谢谢,但我已经有一个 AVPlayer,而不是 MPMoviePlayer
  • @Anna565 :在我的答案中检查 更新
  • 我知道如何从 AVPlayer 中提取缩略图,问题是我使用的方法有时有效,但有时会出错。这就是问题
  • @Anna565 :检查我答案中的最后一行。
  • 是的,但是如果使用 fileURLWithPath: 而不是 URLWithString: 该方法会在 url 的末尾添加一个“--file://localhost/”,这会使 url 无效。
【解决方案3】:

如果你使用的是 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

【讨论】:

  • 这与我使用过的代码完全相同,有时也可以,但有时我会出错并且没有生成缩略图
  • @Anna565 是的,有时有效,有时无效。为什么会出现这个错误?
  • @sam,我不确定。您是否尝试过异步然后返回邮件线程?
【解决方案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);
            }

【讨论】:

  • treid 这个,但它不起作用!我正在使用 hls 知道有什么问题吗?
  • “不工作”是什么意思?什么操作系统版本?什么设备?
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    我可以通过以下方法解决同样的问题。

    斯威夫特 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)
            }
        })
    }
    

    【讨论】:

    • 谢谢!!!这个答案已经解决了出现在慢速互联网连接上的类似问题,但我应该在 DispatchQueue.main.async 中调用完成处理程序
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2018-06-14
    • 2012-12-06
    • 2017-02-16
    • 2014-11-20
    • 2011-07-20
    相关资源
    最近更新 更多