從視頻中截取指定數量的圖片?
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 output.jpgffmpeg -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
。