影音剪輯 / 使用 ffmpeg 分割影片 (指定開始及結束時間或固定時間長度分割)

影音剪輯 / 使用 ffmpeg 分割影片 (指定開始及結束時間或固定時間長度分割)

使用 ffmpeg 可以很有效率地完成很多影片或聲音檔的剪輯動作,安裝 ffmpeg 就不多做討論了可以參考這篇 安裝 ffmpeg 以指令進行影音剪輯,剪輯影像和聲音檔的方式是一樣的,以下就以 mp4 檔為範例。

依據給定的時間切割影片

▍ 給定時間切割影片 (開始時間及時間長度)

ffmpeg 基本的影片分割指令僅需給定開始時間時間長度即可:

ffmpeg -ss 00:00:30.0 -i input.mp4 -c copy -t 00:01:00.0 output.mp4
ffmpeg -ss 30 -i input.mp4 -c copy -t 60 output.mp4

其中 -ss 參數指定起始時間、 -t 指定時間長度,上面範例是從影片第 30 秒開始,並切割時間長度為 1 分鐘 (60秒),也就是切割從 30 秒至 90 秒的影片。可以接受 timestamps 格式 HH:MM:SS.xxx 或秒數 s.msec 兩種時間格式 (如上範例)。

-i-c 則為來源檔案及編碼,這裡輸入 input.mp4 檔案並且不重新編碼 (copy)。

▍ 給定時間切割影片 (開始時間及結束時間)

另外也可以明確指定開始及結束時間切割影片,使用 -to 參數:

ffmpeg -ss 00:00:30.0 -i input.mp4 -c copy -to 00:01:30.0 output.mp4
ffmpeg -ss 30 -i input.mp4 -c copy -to 90 output.mp4
▍ 給定時間切割影片並重新編碼

這邊也可以給定編碼資訊分別對影像及聲音重新編碼,以下範例給定影像編碼 libx264 並且不對聲音編碼:

ffmpeg -ss 30 -i input.mp4 -c:v libx264 -c:a copy -t 60 output.mp4

固定時間長度自動分割整個影片

這邊如果我們希望將一個影片檔案,依照給定的固定時間長度將整個檔案分割成數的小檔案,只需要加入 segment 參數即可。

▍ 固定時間長度自動分割

以下範例將 input.mp4 檔案以每 30 秒切割出一個檔案,也就是除了最後一個剩餘的片段之外,其他全部都是 30 秒的長度:

ffmpeg -i input.mp4 -c copy -segment_time 30 -f segment output%03d.mp4

同樣的我們是輸入 input.mp4 和輸出 output.mp4 並且不重新編碼,參數設定指定分割長度 -segment_time 為 30 秒、-f 參數指定將檔案自動分割。

需注意的是輸出檔案的檔名,其中我們在檔名中加入 %03d 即輸出的分割影片會自動以三碼數字編碼 (即 C 語言的數字格式),也就是 output000.mp4 ~ output999.mp4。萬一切出的檔案數量超過編碼所能容納的數量,例如三碼僅能容納 1000 個分割檔,超出去的檔案會自動回到 000 開始重新編碼,那就會覆蓋掉前面的檔案。

另外提醒一下,因為影片必須切在 Keyframe 上,所以這樣的切割未必會 100% 精準在我們設定的時間點上,可以參考 segment documentation 說明文件。

▍ 固定時間長度自動分割並加入優化參數 (推薦使用!!)

由於影片分割會遇到許多狀況,如上面提到的 Keyframe 問題,所以我們可以加入一些參數優化分割的結果。

ffmpeg -i input.mp4 -c copy -segment_time 30 -f segment -segment_start_number 1 -individual_header_trailer 1 -break_non_keyframes 1 -reset_timestamps 1 output%03d.mp4

這邊加入的參數以下說明:

-segment_start_number 1預設檔名序號是從 000 開始,這邊指定由 001 起始
-break_non_keyframes 1強制分割在設定的時間點上,不一定要在 keyframe 上
(必須說…還是不是 100% 精準)
-individual_header_trailer 1避免分割後的檔案無法個別用播放器播放 (1: true flag)
-reset_timestamps 1避免分割後的檔案無法個別用播放器播放 (1: true flag)
▍ 限制分割數量

如果只想產出固定的分割數量,可以加入 -segment_wrap 參數:

ffmpeg -i input.mp4 -c copy -segment_time 30 -f segment -segment_start_number 1 -individual_header_trailer 1 -break_non_keyframes 1 -reset_timestamps 1 -segment_wrap 10 output%03d.mp4

上面範例限制只產出 10 段分割檔,無論原始影片有多長,當產出第 11 個片段的時候就會自動覆蓋掉第 1 個分割檔,如此循環下去。所以產出的檔名也會從 output001.mp4 至 output010.mp4 後,又自動回到 output001.mp4 並覆寫。

Reference