
ファイルのリストがあります.ts
。
out1.ts ... out749.ts out8159.ts out8818.ts
このすべてのファイルの合計期間(実行時間)をどのように取得できますか?
答え1
これはありませんが、.ts
(のみ.mp4
)すべてのビデオファイルに対して機能します。時間を秒単位で取得するには、(partial)を
使用します。たとえば、次のようになります。ffprobe
ffmpeg
ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4
275.690000
したがって、すべてのビデオファイルに対してループを使用して、合計時間を秒単位で計算できfor
ますawk
。
for f in ./*.mp4
do ffprobe -v quiet -of csv=p=0 -show_entries format=duration "$f"
done | awk '{sum += $1}; END{print sum}'
2735.38
出力をさらに処理して合計をに変換するには、DD:HH:MM:SS
回答を参照してください。ここ。
もう一つの方法はexiftool
内部があるviaですConvertDuration
。
exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
}' ./*.mp4 | tail -n1
0:45:35
答え2
ffmpeg
合計タイムアウト秒を使用して印刷します。
times=()
for f in *.ts; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
echo "${times[@]}" | sed 's/ /+/g' | bc
説明する:
for f in *.ts; do
「.ts」で終わる各ファイルを繰り返します。
ffmpeg -i "$f" 2>&1
出力をstderrにリダイレクトする
grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
分離時間
awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
時間を秒に変換
times+=("$_t")
配列に秒を追加
echo "${times[@]}" | sed 's/ /+/g' | bc
bc
各引数を拡張し、スペースを置き換えて通常のLinux計算機に接続します。
答え3
有線@jmunschの返信、paste
今学んだことを活用してみてください。@slmの答え、次のような結果が出ることがあります。
for i in *.ts; do LC_ALL=C ffmpeg -i "$i" 2>&1 | \
awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done | paste -sd+ | bc
jmunschと同様に、ffmpeg
持続期間を印刷し、欠落している出力ファイルのエラーを無視し、代わりに持続時間行のエラー出力を検索しました。ffmpeg
ローカライズされた出力メッセージについて心配する必要がないように、ロケールのすべての側面を標準Cロケールとして呼び出すように強制します。
awk
次に私は彼のgrep | grep | head | tr | awk
。このawk
呼び出しは含まれている(固有の)行を探しますDuration:
。コロンを区切り文字として使用すると、ラベルはフィールド 1、時間はフィールド 2、分はフィールド 3、秒はフィールド 4 です。秒後のカンマは私をいじめないようですがawk
、そこに問題がある人があればとの間のtr -d ,
パイプに含めることができます。ffmpeg
awk
今slmの一部:私は改行をプラス記号に置き換えましたが、末尾の改行にはpaste
影響しませんでした(例:tr \\n +
以前のバージョンこの答え)。これはに入力できる合計式を提供しますbc
。
同様の時間形式を処理するためのslmのアイデアに触発され、date
それを使用して結果の秒を分数部分を使用して日、時間、分、および秒にフォーマットするバージョンは次のとおりです。
TZ=UTC+0 date +'%j %T.%N' --date=@$(for i in *.ts; do LC_ALL=C \
ffmpeg -i "$i" 2>&1 | awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done \
| paste -sd+ | bc) | awk '{print $1-1 "d",$2}' | sed 's/[.0]*$//'
内部は$(…)
昔と同じです。この@
文字を表示として使用し、1970年1月1日以降の秒数として使用します。結果「日付」は、年、時間、およびナノ秒の形式で指定されます。 0秒を入力すると、すでに1970年の初日になるため、日付から1を減算します。私は年の日付をゼロから始める方法がないと思います。
最終結果はsed
不要な末尾ゼロを除去した。設定TZ
では、夏時間が妨げられないようにUTCを強制する必要があります。本物大規模なビデオコレクション。ただし、1年以上の動画がある場合、この方法は機能しません。