WhatsApp 视频作为 Gif 以编程方式在 Android 上共享
Posted
技术标签:
【中文标题】WhatsApp 视频作为 Gif 以编程方式在 Android 上共享【英文标题】:WhatsApp video as Gif sharing on Android programatically 【发布时间】:2017-12-07 04:18:39 【问题描述】:如何将 mp4 视频文件转换为 WhatsApp gif 文件(在应用程序 UI 中简单地显示为 gif,但内部是特定的 mp4 格式)以用于 android 共享意图,被 whatsapp 识别为这种类型的媒体聊天应用???
我搜索了很多,但我找不到任何来自 WhatsApp 文档的信息(反正他们没有这种文档)或任何与我有相同问题的开发人员。
我有什么:
我发现,如果您在十六进制编辑器上阅读它们,whatsapp "gif" mp4 文件的开头会显示一个 loop 值,所有文件都有这个值。删除此值使 whatsapp 接收为常规视频(不共享为 gif)。
如何使用 ffmpeg 编码添加此值? (使用此值手动编辑我的 mp4 文件会损坏文件,也许我必须修复一些我还不知道的 mp4 标头索引...)
十六进制的前 80 个字节(从 mp4 结构的“moov”原子开始到开始):
00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 0000 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65 00 00 04 9F 6D 6F 6F 76
由 WhatsApp 生成的简短 mp4 文件在内部(在应用程序中)显示为 Gif(具有不同的 UI):
https://www.dropbox.com/s/kpynmx1bg3z76lz/VID-20171024-WA0009.mp4?dl=0
【问题讨论】:
loop 值是多少字节?向我们展示(粘贴)此类文件的前 32 个字节。 @VC.One 我已经用新信息更新了答案......问题是我无法编辑另一个 mp4 文件来添加这个原子而不损坏文件。 loop 原子有 12 个字节,4 个带有大小信息,8 个带有循环,前四个字节和最后一个字节为空。有时 beam 原子在循环原子之后。 不敢相信安静。看看我的回答是否对你有帮助。询问有关 MP4 字节的任何信息。就我个人而言,我不使用 WhatsApp,因此您必须测试我所说的内容。首先尝试使用编辑后的 MP4(不考虑音轨偏移),因为它可以在浏览器中播放... 【参考方案1】:"...问题是我不能编辑另一个 MP4 文件来添加这个原子 不会损坏文件。
在 WhatsApp 中测试这个small_VC1edit.mp4。如果它符合您的要求,请继续阅读...
制作可播放的 MP4:
使用原始small.mp4作为编辑示例(下载文件并使用十六进制编辑器打开)。
1) 在空白字节数组中,添加所示 WhatsApp 样式 MP4 标头的前 72 个字节。
00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 00 01 00 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65
您已显示 80 个字节,但还不需要最后 8 个字节(这 8 个字节中的四个值对于您的输出文件也必须不同)。
2) 计算增量。
请注意(新)WhatsApp 标头为 72 个字节(moov
atom 之前)。
请注意(原始)Small.mp4 有 160 字节的标头(在 moov
原子之前)。
所以只需使用这个逻辑(a 或 b):
a) 如果 WhatsApp 标头大于输入 MP4:delta = ( WhatsApp_header - input_MP4_header)
b) 如果输入 MP4 标头大于 WhatsApp:delta = ( input_MP4_header - WhatsApp_header )
因此,对于具有 160 个标头字节的输入 small.mp4(接下来是 moov 的 SIZE 的 4 个字节(如 00 00 0D 83
),然后是 moov 的 NAME 的另外 4 个字节(如 6D 6F 6F 76
或 utf-8 “moov
”的文本)。
我们可以说:160 MP4 bytes - 72 WhatsApp bytes = Delta of 88
。
如果您删除这些原始的 160 个字节并用较短的 72 个 WhatsApp 字节替换它们,它们将减少 88 个字节,现在必须在 MOOV
数据的另一部分中考虑这些字节。该部分是STCO
原子。
3) 用新的偏移量更新 STCO
原子:
在 small.mp4 中,STCO
原子从偏移量 1579 开始(如 73 74 63 6F
)。前 4 个字节(偏移量:1575 到 1578)是 stco
的 SIZE 字节(如 00 00 00 B8
),即十进制值 184。这个总 SIZE 字节长度也包括了这 4 个 SIZE 字节。
从 stco
的 NAME 字节 73 74 63...
的起始字节 73
跳过 12 个字节,因此跳过这些:
73 74 63 6F 00 00 00 00 00 00 00 2A
现在您可以使用新的delta
值顺序更新每个 32 位整数(4 个字节)的偏移量。但是要更新多少偏移量?
atomEditTotal = ( (stco_SIZE - 16) / 4); //gives 42 //PS: Minus by 16 is to trim off non-offset bytes.
因此有 42 个条目需要编辑。我们的Delta
为 88 所以对于每个整数,我们读取值,将其减去 88,然后将其写回同一位置的新值,再重复 41 次(使用 While
循环和 @987654347 @条件到break;
循环)。
对于测试,假设文件损坏,如果您编辑第一个条目,它应该足以显示视频的第 1 帧(如果是非音频文件)。
PS: 编辑 small.mp4 的 STCO 偏移后,只需删除其起始 160 字节并将剩余的 MP4 字节连接/连接到 72 字节 WhatsApp 标头的后端/末尾。将数组另存为新文件并测试。
【讨论】:
以上是关于WhatsApp 视频作为 Gif 以编程方式在 Android 上共享的主要内容,如果未能解决你的问题,请参考以下文章