シェルスクリプトで数値を時間形式に変換するには?

シェルスクリプトで数値を時間形式に変換するには?

このように映像を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;

ただし、持続時間が1時間未満の場合にのみ機能します。 bashシェルで数値を時間形式に変換するには?

答え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時間に設定しました。この例の整数は10分あたりの時間です(BASHに組み込まれた計算機で計算:)$((...))

この+記号は、date結果が表示される形式を指定したいことを示します。私たちの場合、時間(%H)と分()にのみ興味があります%M

最後に、-u現地時間ではなくUTC時間が表示されます。この場合、UNIX時間を指定したときに時間をUTCとして指定したため、これは重要です(UNIX時間は常にUTCです)。 1つを指定しないと、数字が0から始まらない可能性があります-u

BASH変数の代替説明

このdateコマンドは私たちに必要なものを提供します。ただし、ファイル名のコロンは問題があるか、標準ではない可能性があります。したがって、「:」を「-」に置き換えます。これはsedorcutコマンドを使用して行うことができますが、trこれは非常に簡単な作業なので、BASHで行うことができますが、なぜ新しいサブシェルを作成するのですか?

ここでは、BASHの単純な式の置き換えを使用します。これを行うには、変数を中括弧(${hrmin})で囲み、標準のスラッシュ表記に従う必要があります。最初のスラッシュの後の最初の文字列は検索パターンです。 2番目のスラッシュの後の2番目の文字列は代替文字列です。

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))、2番目の数字はです$((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;

関連情報