Iphone 从视频中获取缩略图图像总是返回空值
我正在尝试从视频中获取第一个缩略图 我尝试了以下方法: 一个Iphone 从视频中获取缩略图图像总是返回空值,iphone,ios,objective-c,cocoa-touch,ios6,Iphone,Ios,Objective C,Cocoa Touch,Ios6,我正在尝试从视频中获取第一个缩略图 我尝试了以下方法: 一个 AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil]; AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; gen.appliesPreferredTrackTransform =
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(0.0, 600);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
NSLog(@"the error is %@: image is %@: url is %@: ",error,_mainThumbnail,[NSURL fileURLWithPath:_moviePath] );
但是,我的日志是:
the error is (null): image is (null):
url is file:///private/var/mobile/Applications/D1293BDC-EA7E-4AC7-AD3C-1BA3548F37D6/tmp/trim.6F0C4631-E5E8-43CD-BF32-9B8F09D4ACF1.MOV:
两个
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform=TRUE;
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
if (result != AVAssetImageGeneratorSucceeded) {
NSLog(@"couldn't generate thumbnail, error:%@", error);
}
_mainThumbnail.image = [UIImage imageWithCGImage:im];
NSLog(@"thumbnails %@ ",_mainThumbnail.image);
};
CGSize maxSize = CGSizeMake(320, 180);
generator.maximumSize = maxSize;
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
日志thumnails为空
为什么图像为空?我查看了其他论坛,他们建议使用fileURLWithPath——我已经在使用它了
我正在使用ios7我成功地使用了这个片段,从视频中获得了一个屏幕截图:
- (UIImage *)currentItemScreenShot
{
AVURLAsset *asset = (AVURLAsset *)playerItem_.asset;
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = YES;
CGImageRef thumb = [imageGenerator
copyCGImageAtTime:CMTimeMakeWithSeconds(0, 1.0)
actualTime:NULL
error:NULL];
UIImage *image = [UIImage imageWithCGImage:thumb];
CGImageRelease(thumb);
[imageGenerator release];
return image;
}
但是在我的例子中-我在应用程序中成功导入视频两秒钟后进行此操作。(它在图片方向上有问题,如果我在导入视频后执行此操作,有时会返回无图像或半图像)。您可以尝试此方法。它在给定的URL处获取视频的第一帧,并将其作为
UIImage
返回
- (UIImage *)thumbnailFromVideoAtURL:(NSURL *)url
{
AVAsset *asset = [AVAsset assetWithURL:url];
// Get thumbnail at the very start of the video
CMTime thumbnailTime = [asset duration];
thumbnailTime.value = 0;
// Get image from the video at the given time
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:thumbnailTime actualTime:NULL error:NULL];
UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return thumbnail;
}
该方法不检查错误,因为我使用它的代码没有问题,如果有任何错误,只返回nil
编辑:澄清
CMTime
值
CMTime
has
-将其视为视频的FPS(每秒帧数)(25 FPS->1s视频有25个视频帧)时间刻度
-混凝土框架的标识。在上面的代码中,这表示要对哪个帧进行缩略值
value = timescale * seconds_to_skip
这相当于
"Frame of the video to take" = "FPS" * "Number of seconds to skip"
如果你想以视频第二秒的第一帧为例,实际上你想跳过视频的第一秒。因此,您可以使用:
CMTime thumbnailTime = [asset duration];
thumbnailTime.value = thumbnailTime.timescale * 1;
另一种看法:你想跳过视频的前1秒,然后拍一张缩略图。也就是说,在每秒25帧时,您希望跳过25帧。所以
CMTime.value=25
(跳过25帧)。以防万一有人犯了和我一样的错误:
检查URL
是否使用适当的方法生成。您不应该因为文件的本地和webURL
s而获得通知
如果是本地视频文件,请使用以下代码:
NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
如果是来自互联网的视频文件,请使用以下代码:
NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
Swift接受答案的版本@Lukas Kukacka答案:
func thumbnailFromVideoAtURL(url: URL) -> UIImage?{
let asset = AVAsset(url: url)
// Get thumbnail at the very start of the video
var thumbnailTime: CMTime = asset.duration
thumbnailTime.value = 0
// Get image from the video at the given time
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true // this rotates the image to the correct position the camera took it in
do{
let imageRef = try imageGenerator.copyCGImage(at: thumbnailTime, actualTime: nil)
return UIImage(cgImage: imageRef)
}catch let err as NSError{
print(err.localizedDescription)
}
return nil
}
奖金
在下,让imageGenerator=AVAssetImageGenerator(资产:资产
)我添加了:
我有一个问题,我会记录在肖像,得到缩略图像,它会在景观返回。解决了这个问题。SWIFT 5.2版本:
NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
你可以找到我的原创文章,我从中获得灵感
重要注意事项:
NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
requestedTimeToleranceAfter和requestedTimeToleranceBefore应设置为.0,因为根据源代码,“生成图像的实际时间[…]可能与效率要求的时间不同”
appliesPreferredTrackTransform必须设置为TRUE(默认值为FALSE),否则会得到错误的旋转帧。当此属性设置为TRUE时,您将获得您在播放机中真正看到的内容。什么是
\u main缩略图
?您确定这不是nil
(因为看起来是这样的)?为什么不尝试直接记录thumb
(在第一个示例中)?在第一个示例中,在我看来好像从未设置过main缩略图。如果我想要第二个呢?我可以试试thumbnailTime.value=1吗?您需要视频的第2秒或第2帧的缩略图吗?为什么需要第二帧?第一个和第二个之间的差异约为0.04s@25FPS:-)但是:CMTime定义了拍摄缩略图的视频时间,而不是确切的帧数。我的代码使用了一个简单的前提,第一帧在时间0;-)所以为了得到特定的帧,你可能需要计算视频的FPS等,但这是一个不同的讨论,我是说第二秒。我是如何得到它的?请看一看这个问题:它比我在评论中给你的内容更详细。基本上,CMTime
docs说的是“值/时间刻度=秒”。。。因此,如果您设置thumbnailTime.value=thumbnailTime.timescale*1
(其中1是您要拍摄缩略图的视频的秒数),您应该大约有视频第二秒的第一帧时间(时间00h00m01s)我在这里找到了解决方案,成功导入是什么意思?好吧,在我的例子中,我拍摄了一个视频或从库中选择,然后将此视频导入应用程序(并保存在应用程序缓存目录中)-如果成功保存,则成功导入。可能会出现问题-视频损坏、内存不足或任何其他问题。