題 將視頻文件分成幾個段


我目前正在使用ffmpeg來切片視頻文件。我通過名為ffmpeg_split.sh的腳本自動化了該過程。雖然這非常慢,但是將視頻分割成等效設置是有效的。唯一的問題是它有幀速率問題。下面的邪惡湯推薦了一種方法來做所有這些使用 segment 在ffmpeg。我嘗試了這個,但它沒有給我相應的持續時間段。

UPDATE

每個evilsoup使用此命令來分割視頻:

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 8 -f segment output%03d.mp4

舊: 

以下是使用腳本切片視頻的語法: ffmpeg_split.sh -s test_vid.mp4 -o video-part%03d.mp4 -c 00:00:08

結果

my_split_script.sh

input.mp4 – Duration 00:01:20
#EXTINF:10,
Output01.mp4
#EXTINF:10,
Output02.mp4
#EXTINF:10,
Output03.mp4
#EXTINF:9,
Output04.mp4
#EXTINF:10,
Output05.mp4
#EXTINF:10,
Output06.mp4
#EXTINF:11,
Output07.mp4
#EXTINF:10,
Output08.mp4
real    0m30.517s #execution time

ffmpeg的

input.mp4 – Duration 00:01:20
#EXTINF:10,
Output01.mp4
#EXTINF:10,
Output02.mp4
#EXTINF:6,
Output03.mp4
#EXTINF:10,
Output04.mp4
#EXTINF:10,
Output05.mp4
#EXTINF:7,
Output06.mp4
#EXTINF:10,
Output07.mp4
#EXTINF:9,
Output08.mp4
real    0m7.493s #executition time

4
2017-10-04 14:10


起源


缺少基本信息:您的腳本究竟做了什麼?你能在這裡發帖嗎?另外,請注意,在執行流複製時,ffmpeg只能在I幀中拆分。但是,如果您的腳本重新編碼該文件,它可以在任何地方進行虛擬分割。 - slhck
@slhck我的原始腳本將視頻拆分為等效的段。例如 -c 8 將視頻分成8秒的片段。它不會重新編碼,這就是為什麼某些段最後會有一個靜止圖像的原因。這是我正在起訴的腳本的鏈接: 腳本 。怎麼辦呢?是否可以在不需要腳本的情況下完成所有這些操作? - Code_Ed_Student
@Code_Ed_Student它們可能長度相同,但正如您所報告的那樣,段之間存在重複信息。分離器為您處理所有這些(最好的)。如果您想了解更多,那麼閱讀視頻編碼本身可能是值得的。 - dstob


答案:


您可以直接從ffmpeg執行此操作,而無需使用腳本。基本上每當你使用時 ffmpeg segment,它將繼續並儘力分割接近您為每個細分指定的時間。這是基於 key_frames 它會找到最近的關鍵幀並在那里切割。為了剪切精確的片段,您需要重新編碼整個視頻。

ffmpeg -i input.mp4 -c:v libx264 -crf 22 -map 0 -segment_time 9 -g 9 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*9)" -f segment output%03d.mp4

你需要閱讀 -crf-sc_threshold 和 -force_key_frames。在wiki中 ffmpeg的


7
2017-10-12 19:47



這有效!但重新編碼視頻只需要很長時間 - Code_Ed_Student
GOP大小為9非常低,不確定這是否值得推薦。 - slhck
@Code_Ed_Student這取決於您的應用程序。如果您從不希望丟包或幀解碼問題的媒體播放目標,請使用最長10秒的較大GOP(例如, -g 250在25fps)。對於自適應流媒體(例如DASH,HLS),段可能只有一秒長,因此GOP大小將等於FPS。但肯定不過是FPS,因為它效率低下。 - slhck
它只是視頻每秒幀數的第二倍。如果你的視頻有25 fps且你想要10秒的GOP,你需要GOP大小為250. @Code_Ed_Student - slhck
請詳細說明“expr:gte(t,n_forced * 9)”? - Dr.jacky


ffmpeg 實際上可以做到這一點,使用 段復用器

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 8 -f segment output%03d.mp4

你一定要閱讀文檔並玩一下以獲得最佳結果(默認設置對於大多數用途來說足夠好,但不會讓你100%準確分割)。


通常,如果您需要從文件中獲取持續時間等信息,最好使用 ffprobe,捆綁在一起 ffmpeg  - 它將信息打印成一堆 key=value 對,使其更容易處理。

ffprobe -show_format file.mp4 | grep -F duration | cut -d= -f2
## or, if you want hh:mm:ss format:
ffprobe -show_format -sexagesimal file.mp4 | grep -F duration | cut -d= -f2

......但是,我認為依靠它可能會更好 ffmpeg自己的選擇,而不是shell腳本(效率低得多,因為它需要調用許多實例 ffmpeg)。


6
2017-10-04 15:21



如何確保使用準確性 ffmpeg -segment_time 而不是較慢的腳本過程? - Code_Ed_Student