使用 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
- Using ffmpeg to cut up video | Stack Exchange
- How can I use ffmpeg to split MPEG video into 10 minute chunks? | Stack Exchange
- Using FFMpeg to cut a video into 2 minute clips | Stack Exchange
- Trim-cut-video-using-start-endtime-reencoding-ffmpeg
- 用ffmpeg將MP4檔案分段 | Mirochiu’s coding note
Copyright announcement:
Photo by Ralston Smith on Unsplash
首先感谢发表,其次在使用中发现了一些问题,并寻找到了解决方案。
关于本文中 “給定時間切割影片 (開始時間及結束時間)” 相关代码,-i 参数应该在首位,否则在截止时间比较大的时候会失效,会按照剪辑长度剪辑