我正在尝试为视频文件创建缩略图:
- (UIImage*) thumbnailForVideoAtURL: (NSURL*) videoURL
{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
CGImageRef imageHandle = [generator copyCGImageAtTime:kCMTimeZero actualTime:NULL error:NULL];
if (imageHandle) {
UIImage *frameImage = [UIImage imageWithCGImage:imageHandle];
CFRelease(imageHandle);
return frameImage;
} else {
return nil;
}
}
问题是视频文件存储在content-addressable store中,没有扩展名。当资产被创建时,这似乎会抛出AVURLAsset
,但在读取帧图像时,我会收到以下错误:
Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo=0x167170 {NSLocalizedFailureReason=This media format is not supported., NSUnderlyingError=0x163a00 "The operation couldn’t be completed. (OSStatus error -12847.)", NSLocalizedDescription=Cannot Open}
这是在某处记录或提及的吗?我无法相信我真的被迫通过文件名传递文件格式信息。 options
初始化程序的AVURLAsset
参数看起来是提供文件类型的好地方,但根据文档似乎没有任何支持。
PS。我已经测试了代码,具有正确扩展名的相同文件会生成缩略图。
答案 0 :(得分:12)
最后,我暂时创建了一个文件的硬链接,并为硬链接提供了正确的扩展名。虽然这是一个黑客,我希望看到一个更好的解决方案。我submitted a bug report反对AVURLAsset
,希望Apple可以添加该功能,以便从options
词典中读取文件格式信息。
答案 1 :(得分:4)
我相信我在iOS7中找到了解决方法。 诀窍是使用AVAssetResourceLoader。 将包含您创建的方案的虚拟URL传递给AVURLAsset,这将导致调用AVAssetResourceLoaderDelegate,例如: 'myscheme://random.com/file.mp4' 正如您在我创建的URL中看到的那样,它具有.mp4扩展名,这将允许AVPlayer正确打开文件,只要您正确地执行下一步。
现在实现AVAssetResourceLoaderDelegate以使用实际的URL,即“http://actual.com/file” 现在数据将正确传递到AVPlayer,而不会抱怨无法打开那种类型的文件格式。
答案 2 :(得分:3)
快速回答:
let filePath = ###YOU SET THIS###
let fileManager = NSFileManager.defaultManager()
let documentsURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .AllDomainsMask).last!
let tmpURL = documentsURL.URLByAppendingPathComponent("tmp.caf")
_ = try? fileManager.removeItemAtURL(tmpURL)
_ = try? fileManager.linkItemAtURL(fileURL, toURL: tmpURL)
完整答案Obj-C:
NSString *filePath = ###YOU SET THIS###
NSFileManager *dfm = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *tmpPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"tmp.caf"];
[dfm removeItemAtPath:tmpPath error:nil];
[dfm linkItemAtPath:filePath toPath:tmpPath error:nil];
现在AVURLAsset
将与tmpPath
一起使用。
答案 3 :(得分:0)
ORDER