暗无天日

=============>DarkSun的个人博客

将视频转换成gif的方法

使用ffmpeg从视频文件中抽取帧

ffmpeg -i ${video} -r ${FPS} -vf scale=${height}:-1 output/frame-%4d.png

说明

其中 height 指定了输出图片的高度,单位为像素,而宽度则自动根据比率进行缩放。

FPS 指定一秒钟抽取多少帧, output/frame-%4d.png 指定存放帧图片的目录,文件名,以及图片格式

我们也可以不指定 FPS,直接使用 ffmpege -i ${vidoe} output/frame-%4d.png 将每一帧抽取出来,但由于视频文件的FPS可能很高,这样抽出来的图片内容会特别的大。

我们可以通过 ffprobe 来查看视频的 FPS 数:

ffprobe ~/github/baby/家/VID_20190410_202840.mp4 2>&1 |grep -i fps
Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuvj420p(pc, smpte170m), 1280x720, 14104 kb/s, SAR 1:1 DAR 16:9, 30.01 fps, 30 tbr, 90k tbn, 180k tbc (default)

使用convert将帧图片整合成gif文件

convert -delay ${delay} -loop ${num} output/*.png ${video}.gif

说明

其中 delay 指的每帧图片的间隔时间,单位为毫秒,该时间一般跟上面的 FPS 对应。比如 若 FPS5 则说明每秒产生5个帧,也就是说每个帧之间的间隔为0.2秒,也就是20ms,这样 delay 的值就应该是 20

另外 num 指定gif文件循环播放的次数, 0 表示无限循环

压缩gif文件

convert -fuzz 10% -layers Optimize ${video}.gif ${video}_optimized.gif

说明

在压缩过程中会大量消耗CPU和内存,因此不要在对体积庞大的gif进行压缩时可能会让系统Hang住。

另外,convert在处理图片的过程中会往临时目录中写入大量中间的处理文件,若 /tmp 目录不够大可能会提示 "convert: unable to write pixel cache",这种情况可以通过修改 MAGICK_TMPDIR 环境变量指向另一个空闲内存较多的分区目录。

关于优化gif文件的更详细说明,可以参见 ImageMagick v6 Examples -- Animation Optimization