FFmpeg 视频转 GIF
Filtergraph
在 ffmpeg
命令中,可以使用 -filter
、-vf
、-af
或 -filter_complex
选项指定 filter graph
Filtergraph 由 filter chain 组成,语法如下:
filterchain_1;filterchain_2;...
filterchain 由 filter 连接而成,上一个 filter 的输出成为下一个 filter 的输入,语法如下:
filter_1,filter_2,...
filter 语法:
[in_link_1]...[in_link_N]filter_name@id=key1=value1:key2=value2:...[out_link_1]...[out_link_M]
key 可以省略,如果省略,则只能放在具名参数前面,实际参数会根据 filter 的定义分配
如果 value 的值是列表类型,则每个元素由 |
隔开
示例:
fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=1
等价于:
fps=10,scale=width=320:height=-1:flags=lanczos,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=1
Video 转 Gif
ffmpeg -ss 1 -t 9 -i foo.mp4 -vf "fps=10,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=1" -loop 0 output.gif
解释:
-
-ss 1: 从输入视频的第 1 秒开始处理。
-
-t 9: 从起始时间起提取 9 秒的内容(即从第 1 秒到第 10 秒)。
-
-i foo.mp4: 指定输入文件为
foo.mp4
。 -
-vf: 应用视频过滤器,后面跟着过滤器的详细设置。
过滤器的具体内容是:
- fps=10: 设置输出 GIF 的帧率为每秒 10 帧。
- split[s0][s1]: 将视频流分成两个相同的流,分别命名为
s0
和s1
。 - [s0]palettegen=stats_mode=diff[p]: 对第一个流
s0
生成一个调色板p
,使用差异统计模式来优化颜色。 - [s1][p]paletteuse=dither=bayer:bayer_scale=1: 对第二个流
s1
使用生成的调色板p
,并应用 Bayer 抖动(dithering),使 GIF 的色彩更平滑。
-
-loop 0: 指定 GIF 循环播放,
0
表示无限循环。 -
output.gif: 指定输出文件名为
output.gif
filter graph 可视化:
[s0] [p]
input ---> fps ---> split ------> palettegen -----> paletteuse ---> output
| ^
| [s1] |
+---------------------------------+
使用上面的命令创建 GIF 可能会遇到产生出来的 GIF 文件后面几帧有卡顿现象,这时可以使用两步法:
palette="/tmp/palette.png"
filters="fps=10"
# 1. 先生成调色板
ffmpeg -v warning -i foo.mp4 -vf "$filters,palettegen" -y $palette
# 2. 再结合调色板生成 GIF
ffmpeg -v warning -i foo.mp4 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y output.png