附加视频的自定义缩略图(不是提取)- IOS,AVFoundation

Attach custom thumbnail for a video (not extract) - IOS, AVFoundation

我使用 AVFoundation 生成视频。之后,我使用 Photos Framework 将视频写入 Photos 库(然后获取 PHAsset 的实例)。

我想为添加的 PHAsset(视频的最后一帧)设置自定义缩略图,但找不到解决方案。 如何为添加的视频附加自定义缩略图?当我打开时,我想在照片应用程序中看到我的自定义缩略图。

此外,我知道如何使用 AVAssetImageGenerator 从视频中获取一些图像,但我想在照片应用程序中查看我的缩略图。

如果您正在编写应用程序的一部分来浏览照片库并显示缩略图,那么您应该能够按如下方式执行此操作:

  1. 获取 PHAsset
  2. 使用 requestAVAssetForVideo 从 PHAsset 请求 AVasset
  3. 在您需要时使用 AVAssetImageGenerator 和 copyCGImageAtTime 方法生成缩略图

需要注意的一件事是,在视频中定时和选择特定帧是一件棘手的事情 science/art - 从时间中准确获得您想要的帧可能很困难。

此外,视频必须至少部分解码才能获得图像 - 上述方法旨在利用框架有效地执行此操作,但即使是高效的视频解码也需要时间和功率。

如果您说您希望视频显示在 iOS 上的标准 'Photos' 应用中,并带有您分配给它们的自定义缩略图,那么我不确定您该怎么做.

要将自定义缩略图添加到您的 MP4:

方法 1:使用 AVMutableMetadataItem...

查看此 Question 中的代码是否对您有帮助。

AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keySpace = AVMetadataKeySpaceCommon;
item.key = AVMetadataCommonKeyArtwork;
item.value = UIImageJPEGRepresentation([[UIImage alloc] initWithContentsOfFile:[[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@".image"]]);

[newMetadataArray addObject:item];
assetWrtr.metadata = newMetadataArray;

[assetWrtr startWriting];
[assetWrtr startSessionAtSourceTime:kCMTimeZero];

另请参阅此 Apple forum Post。阅读整个线程以了解代码和用法的上下文。

方法 2:手动写入字节...

Short version :

找到以下原子(标签)... moov 转到 udta 转到 meta 然后 ilst 在这里,只需添加一个 covr atom(24 字节)后跟 jpeg 图像的字节(字节 FF D8FF D9)。更新 moovudta[= 的大小条目(32 位整数) 16=]covr 以反映新添加的字节)。而已。完成的。

Expanded version :

( note / recommended ):
• 理想情况下在十六进制编辑器(d/load 一个免费的)中检查测试 MP4 以遵循如下所述的字节。

阅读:Apple's Quicktime Format specs and Cimmaron System's MP4 atoms guide

1) Find moov bytes...

(在十六进制编辑器中查看时)您的 MP4 字节应如下所示。

00 00 00 20 66 74 79 70 69 73 6F 6D 00 00 02 00     ... ftypisom....
69 73 6F 6D 69 73 6F 32 61 76 63 31 6D 70 34 31     isomiso2avc1mp41
00 00 00 08 66 72 65 65 00 00 99 70 6D 64 61 74     ....free..™pmdat

这些是开始字节,重要部分 是字节 6D 64 61 74 表示 mdat(作为 ASCII 字符,在显示的字节视图的右侧)。我不使用 iOS 所以我希望它先 mdat 然后 moov 被放置接近文件末尾,在这种情况下,很容易添加额外的字节而不会损坏文件。 如果您在文件的前 64 个字节 中看到 mdat,那么您可以按照我下面的建议继续操作。

edit:(如果默认情况下还没有这样)如果你的 exportSession 设置有:

exportSession.shouldOptimizeForNetworkUse = NO; 

要查找 moov,请读取 ASCII 字母 "mdat" 之前的前 4 个字节(作为一个整数)。在上面的示例中,这是一个 00 00 99 70 的 4 字节整数(= 39280 字节)。 这意味着6D开始跳过总共39280 + 8个字节.. 64.. 61 等等。一旦跳过,接下来的 4 个字节应该是 6D 6F 6F 76(ASCII 中的 "moov")。注意这个 offset/position 作为 moov beginning.

2) Add covr bytes...

moov开始,阅读以下字节搜索:

  • 查找条目 udta 作为字节 75 64 74 61。注意供以后参考:this position - 4 作为 udta size pos.
  • 的开始
  • 查找条目 meta 作为字节 6D 65 74 61
  • 查找条目 ilst 作为字节 69 6C 73 74。注意供以后参考:this position - 4 作为 ilst size pos.
  • 的开始

注意:如果未找到上述任何条目,则必须创建这些字节。检查此 atoms guide 的第 14 页以了解上面的原子需要哪些字节(值)。

  • ilst的末尾添加四个零字节00 00 00 00(稍后将更新为总数covr尺寸)。作为参考,将这 4 个字节的位置记为 covr size pos.
  • 通过将 bytes/integer 写为 63 6F 76 72.
  • 添加条目 covr
  • 添加字节 00 00 ED EA 64 61 74 61 00 00 00 0D 00 00 00 00 然后它就可以用于 JPEG 图像字节了。

3) Add JPEG bytes...

粘贴 JPEG 图像的字节。这些字节以 FF D8 开头并以 FF D9 结尾。请注意这些字节的总量为 jpeg 大小.

4) Update sizes...

  • for covr : 转到 covr size pos 的开头,替换四个 00 00 00 00 字节jpeg size + 20 计算的十六进制结果。
  • for ilst :转到 ilst size pos 字节的开头,用十六进制结果替换这四个字节current ilst size + covr size + 4计算..
  • for udta :转到 udta size pos 字节的开头,用十六进制结果替换这四个字节current udta size + covr size + 4计算..

conclusion

通过在 program/tool 中启用一些 缩略图视图 来测试 MP4 文件。您应该会看到 jpg 现在用作编辑后的 ​​mp4 文件的图标。

PS:我不会为 iOS 编写代码(没有 SwiftObjective-C 知识)所以我无法向您展示示例代码,只能提供建议关于创建字节。此任务甚至可以使用 十六进制编辑器 手动完成。作为 iOS 编码员,最主要的是能够将字节写入现有文件并重新保存为新文件名(或在代码完善后进行覆盖)。