从视频中截取指定数量的图片
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 output.jpg
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 180 output.jpg
-vframes 180代表截取180帧,
实测后发现如果视频是60fps,那么会从第10秒截取到第13秒
-i input.mp4
:指定输入视频文件。-ss 00:00:10
:定位到视频的第10秒。-vframes 1
:指定只提取一帧。output.jpg
:输出截图文件。
从视频中提取多帧截图
ffmpeg -i input.mp4 -vf fps=1/60 output_%03d.jpg
-
fps=1/60
是fps=帧数/秒
的形式 -
1/60
表示 1 帧每 60 秒(即每分钟 1 张图),通常用于长视频中低频截图(比如做缩略图或监控抽帧)
截取多张图时,通配符文件名规则
output_%03d.jpg:输出文件命名格式,%03d表示三位数字编号
举例:
output_%03d.jpg
输出
output_001.jpg
output_002.jpg
output_003.jpg
从视频中提取特定时间段的截图
ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:00 -vf fps=1/10 output_%03d.jpg
-vf 是 -filter:v 的简写,表示对视频流使用视频滤镜。
fps=1/10 指每10秒提取一帧。意味着1分钟内截6张图
-ss 00:01:00
:开始时间,从第1分钟开始。-to 00:02:00
:结束时间,到第2分钟结束。-vf fps=1/10
:每10秒提取一帧,如果视频有1分钟,那么仅截图6张图
截图时长说明-t与-to区别
参数顺序影响行为
-t是相对时间(持续时间)和-to绝对时间
- 推荐将
-ss
和-t/-to
放在-i
之前:
这样 FFmpeg 会直接跳转到指定时间点(快速但不精确,依赖关键帧)。 - 将
-ss
放在-i
之后:
FFmpeg 会解码到指定时间点(速度慢但精确到帧)。 -
#举例说明 # 快速截取(依赖关键帧,可能不精确) ffmpeg -ss 10 -to 15 -i input.mp4 output.mp4 # 精确截取(逐帧解码,速度慢) ffmpeg -i input.mp4 -ss 10 -to 15 output.mp4
设置截图质量
如果需要提取高质量的截图,可以指定输出图片的质量:
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 -q:v 2 output.jpg
-q:v 2
:设置输出图片的质量,数值越小质量越高,范围是1-31。
截图并设置分辨率
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 -s 640x360 output.jpg
-s 640x360
:设置输出图片的分辨率为640x360。
关键帧限制:若视频关键帧间隔大,快速定位(-ss
在-i
前)可能无法精确到非关键帧。,所以为了精确,需要先-i然后再-ss
截取第5秒的第1帧(快速定位,可能不精确)
ffmpeg -ss 5 -i input.mp4 -vframes 1 -q:v 2 output.jpg
特点:-ss
在-i
前,优先用关键帧定位,速度快但可能不精确。
精确截取第5秒的帧(较慢但准确)
ffmpeg -i input.mp4 -ss 5 -vframes 1 -q:v 2 output.jpg
-
特点:
-ss
在-i
后,逐帧解码到指定时间,速度慢但更精确。
截取第5.5秒的帧(精确到小数)
ffmpeg -ss 5.5 -i input.mp4 -vframes 1 output.png
输出PNG格式并设置图片品质
ffmpeg -ss 5 -i input.mp4 -vframes 1 -compression_level 0 output.png
-compression_level:取值范围:0 到 9
含义:
0:最小压缩,生成的文件较大,但处理速度快
9:最大压缩,文件体积小,但处理速度慢
默认值:-compression_level 6
时间精度:支持毫秒级时间(如00:00:05.500
)
文件名通配符
ffmpeg -ss 5 -i input.mp4 -vframes 1 output_%03d.jpg
- 效果:生成
output_001.jpg
。 - 占位符说明:
%03d
:3位数字编号(如001
,002
)。%d
:无填充编号(如1
,2
)。
每秒截n张图
ffmpeg -i input.mp4 -r 7.5 -q:v 2 output_%03d.jpg
参数详解:
-r n表示一秒内我一共想提取n帧,也就是每秒的帧率,即fps
可理解为:视频的fps/n=每隔x帧截取一次图片
-
-r 7.5表示如果原视频是 30fps,每 4 帧截图一次,30/4= 7.5fps。
-
如果原视频是 60fps,每5帧截图一次,60/5=12
-
把视频直接做成gif
体积小
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../input.mp4 -filter_complex "[0:v]fps=20,scale=400:-1" output_20fps.gif
颜色质量高,体积适宜,需要分2步
第一步:生成调节板
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../coe33.mp4 -vf "fps=10,scale=400:-1:flags=lanczos,palettegen" palette.png
第二步:参考调班板生成图片
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../input.mp4 -i palette.png -filter_complex "[0:v]fps=20,scale=400:-1:flags=lanczos[x];[x][1:v]paletteuse" output_20fps.gif
以下命令无需预先生成调色板
#生成黑白色gif
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../input.mp4 -filter_complex "[0:v]fps=20,scale=400:-1,split[a][b];[a]palettegen=max_colors=2:reserve_transparent=0[p];[b][p]paletteuse=dither=floyd_steinberg" blackwhite.gif
#256色
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../input.mp4 -filter_complex "[0:v]fps=20,scale=400:-1,split[a][b];[a]palettegen=max_colors=256[p];[b][p]paletteuse=dither=floyd_steinberg" o256colors.gif
多个参数混用
./ffmpeg -ss 00:00:00 -to 00:00:10 -i ../input.mp4 -filter_complex "[0:v]fps=20,scale=400:-1:flags=lanczos,split[a][b];[a]palettegen=max_colors=256:stats_mode=diff[p];[b][p]paletteuse=dither=floyd_steinberg" o256colors.gif
上述代码的关键参数解析
-
split[a][b]
将视频流拆分为两个分支[a]
和[b]
,分别用于生成调色板和应用调色板。 -
palettegen=max_colors=256
max_colors=256
:设置调色板最大颜色数量(默认 256,GIF 支持的最大值)。- 若需减小文件体积,可降低此值(如
max_colors=128
)。
-
paletteuse=dither=floyd_steinberg
dither=floyd_steinberg
:使用高质量抖动算法(推荐保留颜色过渡)。- 若需减小体积,可改用
dither=none
或dither=bayer
。
dither=none表示不使用抖动,直接使用调色板中最接近的颜色替换原颜色。这会导致颜色过渡生硬,出现色带,但文件体积小,适合颜色简单的图像。
dither=bayer使用拜耳矩阵抖动,通过有序的图案扩散误差,模拟更多颜色。这种方法在低颜色深度下能减少色带,但可能引入可见的图案,体积比none大但比floyd_steinberg小。
实测发现生成gif体积排序是bayer>floyd_steinberg>none
如何选择?
- 优先体积:选
dither=none
(如生成文件大小敏感的 LOGO)。 - 优先画质:选
dither=floyd_steinberg
(误差扩散算法,更平滑)。 - 平衡方案:选
dither=bayer
(动态 GIF 或分辨率较高的静态图)。
dither=bayer时,bayer_scale可控制gif大小
paletteuse=dither=bayer:bayer_scale=0
./ffmpeg -ss 00:19:50 -t 5 -i ../input.mp4 -filter_complex "[0:v]fps=15,scale=700:-1:flags=lanczos,split[a][b];[a]palettegen=max_colors=128:stats_mode=diff[p];[b][p]paletteuse=dither=bayer:bayer_scale=5" output.gif
bayer_scale取值范围[0,5],实测发现0体积最大,5体积最小
缩小gif体积的方法
1上文中提到的调色板
2:使用 gifsicle
后处理压缩
# 安装 gifsicle(macOS: brew install gifsicle, Linux: apt-get install gifsicle)
gifsicle -O3 --lossy=80 input.gif -o output_compressed.gif
参数说明:
-O3:最高级别压缩优化。
--lossy=80:有损压缩(值越大,压缩率越高,画质损失越大)。
3:动态区域裁剪
-vf "crop=300:200:20:50" # 截取 300x200 区域(从坐标 x=20,y=50 开始)
-filter_complex后面也可以用crop
例如
./ffmpeg -ss 00:19:50 -t 5 -i ../input.mp4 -filter_complex "[0:v]scale=300:-1,crop=130:120:70:70" output.gif
避免 -fs
:除非接受尾部截断,否则不要使用 -fs
。