💡阅读指南

前面我们已经把抖音视频保存下来,也把视频里的声音整理成文字。这一节再换一个方向:从视频里截出一小段,做成可以嵌入文章、教程和演示材料的 GIF 动图。正文只讲思路和取舍,具体执行交给配套 Skill。

🎬
本节附有教学视频 #25

该视频为课程站点内嵌片段,未收录于本地离线包;如需观看请回到线上课程对应课时。

4.1 很多时候只需要一小段

把视频做成 GIF 的场景其实不少。有人用它做教程,有人用它截表情包,也有人只是想把一段有意思的画面放进文章里。这里不展开所有用法,先看最常见的两类。

一种是做展示。写文章或做分享时,我们经常需要说明「一个东西是怎么动起来的」。静态截图只能展示一个瞬间,表现力有限;放一整段视频又太重,读者还得点开播放。GIF 正好卡在中间。它能把一个短过程展示出来,又不需要读者额外操作。比如从第 12 秒到第 15 秒,某个按钮点击后界面怎么变化,使用一张 GIF 就能把变化表达清楚。

另一种是分享片段。抖音上经常刷到一些好笑的瞬间,或者一个很适合拿来当梗的表情。直接保存成视频发给别人,文件大,播放也麻烦;截成一两秒的短 GIF,反而更轻。

无论哪种场景,做 GIF 的第一步都是先想清楚要截哪一小段。片段越长,文件越大,循环播放时也越拖沓。一般来说,3 秒左右最舒服。到了 5 秒以上,就要开始控制尺寸和帧率;超过 10 秒以后,通常就不太像 GIF 该做的事了。

这也是配套 Skill 一开始要求填写起止时间的原因。它不是让 Hermes 随便截一个片段,而是让用户把“我要展示哪一瞬间”表达清楚。

4.2 抖音页面里的视频不好直接剪

如果我们手上有一个普通的 mp4 文件,那么把它转成 GIF 并不复杂:使用 ffmpeg 截取一段,再按指定宽度和帧率输出,就能得到动图。

我们之前已经掌握了怎么把视频保存到本地。但在这个场景里,先把整条视频下载下来,我认为没有太大必要。如果只是为了截取 3 秒左右的 GIF,还要先保存完整视频,其实很浪费资源。

那能不能不保存视频,直接截取呢?

可以,但也有一些小问题。

浏览器里确实有视频在播放,但 Hermes 不一定能拿到一个稳定的 mp4 地址。前面保存视频时已经见过这个问题:页面上的 <video> 元素可能指向短时间有效的直链,也可能指向 blob: 开头的临时地址。

我做过一轮小测试,连续测了 6 个抖音视频,拿到的都是 blob: 地址。至少在这组样本里,把“找到真实下载链接”作为默认路径并不是一个稳定的方法。

既然浏览器已经能播出视频,不妨直接在页面里录下目标片段。对抖音这种页面来说,这条路往往更稳定。

4.3 captureStream

浏览器里的 <video> 元素不只是一个画面,它还可以把正在播放的内容变成一条媒体流。captureStream 做的就是这件事:从页面里正在播放的视频拿到一条流,再交给浏览器的录制器保存成临时片段。

它的好处是绕开了最不稳定的部分。只要页面能正常播放,Hermes 就能把指定片段录下来。

但这里有一个很容易踩的坑。视频跳到指定时间点之后,并不是立刻就能开始录。浏览器还要完成 seek,也就是把播放位置真正切过去。如果 Hermes 只是等一个固定秒数就开录,偶尔会录到黑屏,或者录出来的片段前面是空的。

更稳定的做法是等 seeked 事件。这个事件出现,说明视频已经跳到目标时间点。等它出现以后再开始录制,录到的内容才会落在我们要的那几秒上。

录完以后,怎么把录制出来的临时片段取回本地,也很有讲究。也许最先想到的办法,就是直接在页面里触发下载,但 Chrome 有时会拦住这类下载。

一种比较好的方法是,让 Hermes 把录制结果转成 base64 再取回本地解码。这样稍微绕一点,却比点击下载更可靠。

4.4 GIF 的难点在体积和观感之间

把片段拿到手以后,剩下的才是普通的视频转 GIF。这里真正要权衡的是体积和观感。

GIF 没有现代视频编码那样高效。同样是 3 秒画面,如果背景一直在变,人物动作也比较多,文件会明显变大。口播类视频尤其容易这样:画面里既有人,又有字幕和滤镜,最后生成的 GIF 可能比静态演示大好几倍。

帧率和输出宽度,是最先要看的两个参数。帧率越高,动作越顺畅,文件也越大;输出宽度越大,细节越清楚,体积也跟着涨。短片段可以稍微放宽一点,比如 3 秒以内用更高帧率和更大输出宽度。片段一长,就要主动降下来。

💡帧率

一帧,就是视频里的一个画面。帧率说的就是,一秒钟里会连续放出多少个这样的画面。帧率高一点,动作看起来更顺畅,但文件通常也会更大;帧率低一点,文件会小一些,动作也会显得没那么连贯。

这里不用追求“越清晰越好”。GIF 不是拿来替代原视频的,它的作用只是让读者更快看懂一个动作。只要动作清楚,文字能看见,文件又不会大到拖慢页面,就已经够用了。

还有一个细节是调色板。直接把视频压成 GIF,颜色很容易脏,渐变也会出现明显的块状痕迹。更好的做法是让 ffmpeg 先根据这段视频生成一张调色板,再用这张调色板输出 GIF。它多跑一遍,但颜色会更稳定,文件大小也更容易控制。

4.5 抖音 GIF Skill

这种复杂的、需要反复使用的操作最好是沉淀为 Skill。

配套 Skill 已经把这些经验整理好了。它会先打开抖音页面,判断视频源类型。能拿到直链时,就直接截取;遇到更常见的 blob: 地址,就改用 captureStream 录制。拿到片段之后,再用双通调色板生成 GIF,最后保存到桌面。

💡配套 Skill

本节对应的 Skill 已放在资料包中:

  • profile/douyin-skills/douyin-gif.md

实践时可以直接对 Hermes 输入:

Text
请参考 profile/douyin-skills/douyin-gif.md,
把这个抖音视频的 00:12 到 00:15 做成 GIF,
默认保存到桌面:
https://v.douyin.com/xxxxxxx/

如果这段内容是口播或真人出镜,生成后可以看一下文件大小。如果生成出来的 GIF 太大,就让 Hermes 把帧率降到 10,或者把输出宽度改成 360。GIF 只需要把关键动作讲清楚,不需要把整条视频的质感都搬过来。

4.6 ■ 学点英语

中文 English 音标 说明
GIF 转换 GIF Conversion /dʒɪf kənˈvɜːrʒən/ 把视频片段转换成 GIF 动图的过程
帧率 Frame Rate /freɪm reɪt/ 视频每秒显示的画面帧数
视频片段 Video Clip /ˈvɪdioʊ klɪp/ 从完整视频中截取的一小段内容
尺寸缩放 Resize /ˌriːˈsaɪz/ 改变图片或视频宽高的处理操作