我想把一個影片剪成這樣10分鐘左右的部分。
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 01.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 02.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 03.mp4
有了for
它就會這樣。
for i in `seq 10`; do ffmpeg -i video.mp4 -ss 00:${i}0:00 -t 00:10:00 -c copy ${i].mp4; done;
但它僅在持續時間低於一小時的情況下才有效。如何在 bash shell 中將數字轉換為時間格式?
答案1
BASH 對於這個問題來說還不錯。您只需要使用非常強大但未充分利用的date
命令。
for i in {1..10}; do
hrmin=$(date -u -d@$(($i * 10 * 60)) +"%H:%M")
outfile=${hrmin/:/-}.mp4
ffmpeg -i video.mp4 -ss ${hrmin}:00 -t 00:10:00 -c copy ${outfile}
done
date
命令解釋
date
帶有-d
標誌允許您設置哪個您想要顯示的日期(而不是預設的目前日期和時間)。在本例中,我透過@
在整數前添加符號將其設定為 UNIX 時間。本例中的整數是以十分鐘為單位的時間(由 BASH 內建計算器計算:)$((...))
。
此+
符號表示date
您想要指定顯示結果的格式。在我們的例子中,我們只關心小時 ( %H
) 和分鐘 ( %M
)。
最後,將-u
顯示為 UTC 時間而不是本地時間。這在本例中很重要,因為當我們給它 UNIX 時間時,我們將時間指定為 UTC(UNIX 時間始終為 UTC)。如果您未指定 ,則數字很可能不會從 0 開始-u
。
BASH 變數替換解釋
這個date
命令給了我們我們所需要的東西。但檔案名稱中的冒號可能有問題/不標準。因此,我們將“:”替換為“-”。這可以透過sed
orcut
或命令來完成tr
,但是因為這是一個如此簡單的任務,為什麼當 BASH 可以做到時產生一個新的子 shell 呢?
這裡我們使用BASH的簡單表達式替換。為此,變數必須包含在大括號 ( ${hrmin}
) 內,然後使用標準的正斜線表示法。第一個斜杠之後的第一個字串是搜尋模式。第二個斜槓之後的第二個字串是替換。
BASH 變數替換和更多內容可以在以下位置找到http://tldp.org/LDP/abs/html/parameter-substitution.html。
答案2
它稍微複雜一些,但你可以在 bash 中輕鬆完成。下面的範例是一個 2 小時的視頻,您可以n<=11
相應地設定限制 ( ):
k=0;
i=00;
for ((n=0;n<=11;n++)); do
if [ $i -ge 60 ]; then
let k++; i=00;
fi;
ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4;
let i+=10;
done
echo
您可以透過在該行中添加一個來查看它的作用ffmpeg
:
echo "ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4";
這將打印:
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 000.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 010.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 020.mp4
ffmpeg -i video.mp4 -ss 00:30:00 -t 00:10:00 -c copy 030.mp4
ffmpeg -i video.mp4 -ss 00:40:00 -t 00:10:00 -c copy 040.mp4
ffmpeg -i video.mp4 -ss 00:50:00 -t 00:10:00 -c copy 050.mp4
ffmpeg -i video.mp4 -ss 01:00:00 -t 00:10:00 -c copy 100.mp4
ffmpeg -i video.mp4 -ss 01:10:00 -t 00:10:00 -c copy 110.mp4
ffmpeg -i video.mp4 -ss 01:20:00 -t 00:10:00 -c copy 120.mp4
ffmpeg -i video.mp4 -ss 01:30:00 -t 00:10:00 -c copy 130.mp4
ffmpeg -i video.mp4 -ss 01:40:00 -t 00:10:00 -c copy 140.mp4
ffmpeg -i video.mp4 -ss 01:50:00 -t 00:10:00 -c copy 150.mp4
答案3
這是一個簡單的數學:小時數字是$((i%3600)
,分鐘數字是$((i/60%60))
,秒數字是$((i%60))
。要在需要的地方添加前導零,一個簡單的技巧是添加 100,然後去掉前導1
。如果您想避免前導零,請對檔案名稱執行相同的操作。
for i in $(seq 10); do
minutes=$((i / 60 % 60 + 100)); minutes=${minutes#1}
seconds=$((i%60)); seconds=${seconds#1}
i=$((i+100)); i=${i#1}
ffmpeg -i video.mp4 -ss $((i%3600):$minutes:$seconds -t 00:10:00 -c copy ${i}.mp4
done
答案4
我發現 ffmpeg 不僅接受 [HH:MM:SS] 作為時間戳格式,還接受簡單的秒數。
https://trac.ffmpeg.org/wiki/Seeking%20with%20FFmpeg
所以我可以這樣寫。
for i in `seq 10`; do ffmpeg -i video.mp4 -ss $((i*10*60)) -t 00:10:00 -c copy ${i].mp4; done;