如何在shell腳本中將數字轉換為時間格式?

如何在shell腳本中將數字轉換為時間格式?

我想把一個影片剪成這樣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命令給了我們我們所需要的東西。但檔案名稱中的冒號可能有問題/不標準。因此,我們將“:”替換為“-”。這可以透過sedorcut或命令來完成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;

相關內容