FFMPEG 中級指南/影像序列
FFMPEG 具有強大的功能集,與從影像建立影片或從影片生成影像序列有關。
要從一組影像建立影片
ffmpeg -i image-%03d.png video.webm
要從影片建立一組影像
ffmpeg -i video.webm image-%03d.png
如果沒有給出更多引數,將使用一組預設值。例如,幀速率將為 25,編碼將從檔名推斷得出。
image-%03d.png 部分是一個檔名模式。此特定模式對應於 image-000.png、image-001.png、image-002.png,一直到 image-999.png。“%03d”表示三個零填充的十進位制數字的序列。關於檔名模式還有更多內容將在後面的部分中解釋。
使用影像序列工作的規範形式是使用 -f image2 引數,如下所示
ffmpeg -f image2 -i image-%03d.png video.webm
和
ffmpeg -i video.webm -f image2 image-%03d.png
但是 ffmpeg 在推斷這些資訊方面非常出色,因此本章將在所有示例中省略該引數,除非絕對必要。
ffmpeg -i image-%03d.png video.webm
這將建立一個名為 video.webm 的影片,它來自名為 image-000.png、image-001.png、image-002.png 的影像檔案,一直到最後一個按順序編號的三位數影像檔案。
影像和影片的編碼是從副檔名推斷出的。預設幀速率為 25 fps。影片寬度和高度取自影像。影像必須都具有相同的尺寸。
Ffmpeg 預計編號從 0(在本例中為 000)開始。如果您的檔案沒有從 000 開始,請使用引數 -start_number 告訴 ffmpeg 您的檔案的第一個數字
ffmpeg -start_number 100 -i image-%03d.png video.webm
同一個引數可以用來跳過一定數量的檔案並從某個數字開始。
編號必須是連續的。Ffmpeg 將在最後一個連續編號的檔名處停止。
例如,如果您有以下檔案
image-000.png image-001.png image-002.png image-005.png
那麼 ffmpeg 只會處理前三個檔案,忽略最後一個檔案。如果您有缺失的編號,您可以使用 glob 模式 或將所有剩餘檔案重新命名以填補空白。
預設幀速率為 25 fps。這意味著每張圖片顯示 1/25 秒。對於大多數人類的眼睛來說,這是一種速度,可以創造出流暢動畫的錯覺。如果您仍然希望每秒有更多幀,請使用 -framerate 引數
ffmpeg -framerate 60 -i image-%03d.png video.webm
如果您想製作幻燈片,則必須降低輸入幀速率。以下命令將顯示每張圖片 5 秒長
ffmpeg -framerate 1/5 -i image-%03d.png video.webm
可能需要強制提高影片幀速率
ffmpeg -framerate 1/5 -i image-%03d.png -r 30 video.webm
您可以使用 zoompan 過濾器製作每張圖片持續時間不同的幻燈片。在下面的示例中,每張圖片顯示 1 秒(25 幀),除了第 4 張圖片(列舉從 0 開始)顯示 3 秒(25+50 幀),第 6 張圖片顯示 5 秒(25+100 幀)。
ffmpeg -i image-%3d.jpg -vf "zoompan=d=25+'50*eq(in,3)'+'100*eq(in,5)'" test.mp4
您可以使用 zoompan 和 framerate 過濾器的組合來製作影像之間交叉淡入淡出的幻燈片。“A”是每張圖片顯示多長時間(不包括交叉淡入淡出持續時間)的持續時間(以秒為單位),“B”是交叉淡入淡出持續時間(以秒為單位)。
*此示例完全錯誤,只包含前 3 張圖片*
ffmpeg -i IMG_%3d.jpg -vf zoompan=d=(A+B)/B:fps=1/B,framerate=25:interp_start=0:interp_end=255:scene=100 -c:v mpeg4 -maxrate 5M -q:v 2 out.mp4
建立 mp4[1]
ffmpeg -framerate 60 -r 60 -i image%06d.png -pix_fmt yuv420p -profile:v high -level:v 4.1 -crf:v 20 -movflags +faststart output.mp4
- 對於 60 fps 以外的情況,更改幀速率和 r
- 輸入為 image000001.png、image000002.png、...、%06d 表示一個帶有六位數字的零填充數字,如果您的輸入影像命名方式不同,請更改
- -pix_fmt yuv420p 是大多數播放器相容所需的(預設值為 yuv444 甚至 rgb,大多數播放器根本無法很好地處理)
- -profile:v、-level:v 也會控制相容性設定,4k 可能需要更高的級別設定
- -crf:v 是質量與大小的控制,數字越小,質量越高,檔案大小越大,數字越大,質量越低,檔案大小越小,crf 20 的質量非常高,據我所知,每改變 6 個數字就會使檔案大小改變 2 倍
- -movflags +faststart 是流式傳輸所需的(否則,整個檔案必須下載才能開始播放)
- 如果您需要,ffmpeg 還可以新增/編碼音訊軌
ffmpeg -i video.webm image-%03d.png
這將從 video.webm 檔案中每秒提取 25 張圖片,並將其儲存為 image-000.png、image-001.png、image-002.png,一直到 image-999.png。如果幀數超過 1000 幀,則最後一幀將被剩餘幀覆蓋,只保留最後一幀。
影像和影片的編碼是從副檔名推斷出的。預設幀速率為 25 fps。影像寬度和高度取自影片。
每秒提取一張圖片
ffmpeg -i video.webm -vf fps=1 image-%03d.png
從特定時間提取一張圖片
ffmpeg -i video.webm -ss 00:00:10 -vframes 1 thumbnail.png
通常 ffmpeg 只有一個輸入檔案和一個輸出檔案,但是當我們要從一組影像建立影片時,我們就有一組輸入檔案。同樣,當從影片檔案提取影像時,也會有一組輸出檔案。檔名模式是一個偽檔名,用於描述一組檔名。
檔名模式大致有三種類型
| 模式型別 | 對應的檔名 | 描述 |
|---|---|---|
image-%03d.png
|
image-000.png image-001.png image-002.png ... image-999.png |
帶前導零的編號 |
image-%d.png
|
image-1.png image-2.png ... image-9.png image-10.png image-11.png ... image-99.png image-100.png ... |
不帶前導零的編號 |
image-*.png
(需要一個引數來啟用) |
image-a.png image-b.png image-c.png ... image-foo.png image-bar.png ... image-.png ... |
未編號或無規律模式 |
從技術上講,還有第四種形式:單個影像形式。但這只是一個簡單的特殊情況,在本節中將不再討論。
此模式
image-%03d.png
對應於以下檔名
image-000.png image-001.png image-002.png ... image-999.png
換句話說:字串 image- 後面跟著三位數字,後面跟著字串 .png。
檔名擴充套件機制的核心是字元 % 開始並以字元 d 結束的子字串。% 之前的部分和 d 之後的部分被逐字接收。% 到 d 之間的所有內容都將被替換為一個或多個數字。
一般形式為 %0Nd,其中 N 是一個大於零的數字,用於確定數字的數量。
注意:%0Nd 符號在許多程式語言中很常見。該符號之所以複雜是因為它被設計用來適應許多不同的用例。FFmpeg 開發者借用了這個符號並將其簡化為一個用例:數字位數。因此,它可能顯得過於複雜。
如果檔名本身包含 % 字元,則存在一個特殊情況。因為 % 字元在模式中具有特殊含義,因此需要小心。模式中的單個 % 字元將被解釋為要由數字替換的子字串的開頭。要指定文字 %,必須在模式中將其加倍。這在技術術語中稱為“轉義”字元。
例如,這個模式
image-%02d%%.png
對應於以下檔名
image-00%.png image-01%.png image-02%.png ... image-99%.png
如果檔名中的數字沒有用前導零填充,則模式為 %d。
此模式
image-%d.png
對應於以下檔名
image-1.png image-2.png ... image-9.png image-10.png image-11.png ... image-99.png image-100.png ...
如果檔名沒有使用數字編號或沒有以其他方式定期格式化,則可以使用 glob 模式。glob 模式必須使用引數 -pattern_type glob 啟用。請注意,這在 Windows 上不受支援。
帶有 glob 模式啟用的示例 ffmpeg 命令
ffmpeg -pattern_type glob -i "image-*.png" video.webm
此模式
"image-*.png"
對應於以下檔名
image-a.png image-b.png image-c.png
但也適用於以下檔名
image-foo.png image-bar.png
也適用於
image-.png
以及任何以字串 image- 開頭、後面跟著任何內容、最後以字串 .png 結尾的檔名。
一般來說,模式 * 對應於任何長度的任何內容,這意味著即使是空字串也是如此。
還有更多 glob 模式。例如,? 對應於任何單個字元。但我們這裡不會深入探討。感興趣的讀者可以在維基百科關於 glob (程式設計) 的頁面中找到更深入的資訊。
將 glob 模式放在引號中是必要的,否則 shell 會在執行命令之前擴充套件 glob。
例如,此命令中的 glob 模式
ffmpeg -pattern_type glob -i image-*.png video.webm
將由 shell 擴充套件為
ffmpeg -pattern_type glob -i image-foo.png image-bar.png video.webm
然後才執行。請注意,此命令具有不同的含義,因為現在 image-bar.png 是第二個檔名引數,而 video.webm 是第三個檔名引數。
當放在引號中時,shell 不會擴充套件 glob 模式
ffmpeg -pattern_type glob -i "image-*.png" video.webm
編號檔案具有明確定義的排序方式。在大多數情況下,人和計算機都一致同意如何對數字進行排序。對於帶有前導零的數字尤其如此。015 顯然比 110 先。沒有前導零會變得更加複雜。大多數計算機將 15 排在 110 之後。但這個問題可以透過 %d 符號解決。
當檔案不再使用數字編號或沒有定期編號時,事情會變得非常奇怪。例如,ae 應該排在 aaa 之前還是之後?計算機是確定性的,並且總是對如何排序事物有一個概念,但這種排序概念對於人類來說不一定有意義。
來自 glob 模式的檔案順序由 glob 系統呼叫決定。在大多數系統上,可以透過名為 LC_COLLATE 的環境變數來操作 glob 系統呼叫的排序概念。但這本書不會討論這一點。
對於少量檔案,可以透過讓 shell 擴充套件 glob 來檢查 glob 返回的順序。這是因為大多數 shell 使用與 ffmpeg 相同的 glob 系統呼叫。
在 shell 中鍵入此命令
echo image-*.png
將列印一個檔名列表。相同順序的相同列表將是 ffmpeg 處理的檔案列表,如果給定 glob 模式。
如果順序不令人滿意或數量過大,無法讓人類檢查,則最好的解決方法是將檔案重新命名為定期編號,然後使用 %0Nd 模式。
位於以下位置的精美 ffmpeg 手冊和維基
更具體地說,以下頁面
- http://www.ffmpeg.org/ffmpeg.html
- http://www.ffmpeg.org/faq.html#How-do-I-encode-single-pictures-into-movies_003f
- http://www.ffmpeg.org/faq.html#How-do-I-encode-movie-to-single-pictures_003f
- http://www.ffmpeg.org/ffmpeg-formats.html#image2-1
- http://www.ffmpeg.org/ffmpeg-formats.html#image2-2
- https://trac.ffmpeg.org/wiki/Create%20a%20video%20slideshow%20from%20images
- https://trac.ffmpeg.org/wiki/Create%20a%20thumbnail%20image%20every%20X%20seconds%20of%20the%20video