web-dev-qa-db-ja.com

ディレクトリ内のビデオファイルの合計時間を取得する

.tsファイルのリストがあります。

out1.ts ... out749.ts   out8159.ts  out8818.ts

これらのすべてのファイルの合計時間(実行時間)を取得するにはどうすればよいですか?

31
k961

ここには.tsがありませんが、これは.mp4で機能します。 ffprobeffmpegの一部)を使用して、秒単位で時間を取得します。例:

ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4 
275.690000

現在のディレクトリにあるすべての.mp4ファイルについて:

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \;
149.233333
130.146667
275.690000

次に、paste to 出力を渡すbcに使用して、合計時間を秒単位で取得します。

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
555.070000

したがって、.tsファイルの場合、次のことを試すことができます。

find . -maxdepth 1 -iname '*.ts' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc

ここにあるビデオファイルで機能する別のツールはexiftoolです。例:

exiftool -S -n Inception.mp4 | grep ^Duration
Duration: 275.69
exiftool -q -p '$Duration#' Inception.mp4
275.69

現在のディレクトリにあるすべての.mp4ファイルの全長:

exiftool -S -n ./*.mp4 | awk '/^Duration/ {print $2}' | paste -sd+ -| bc
555.070000000000
exiftool -q -p '$Duration#' ./*.mp4 | awk '{sum += $0}; END{print sum}'
555.070000000000

また、出力を別のコマンドにパイプして合計をDD:HH:MM:SSに変換することもできます。回答 こちら を参照してください。

または、exiftoolの内部ConvertDurationを使用します(ただし、比較的新しいバージョンが必要です)。

exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
                    }' ./*.mp4| tail -n1
0:09:15
58
don_crissti

これは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計算機にパイプします

6
jmunsch

@ 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を使用して期間を出力し、欠落している出力ファイルに関するエラーを無視して、代わりに期間の行のエラー出力を検索します。ロケールのすべての側面を標準Cロケールに強制してffmpegを呼び出すので、ローカライズされた出力メッセージについて心配する必要はありません。

次に、_grep | grep | head | tr | awk_の代わりに単一のawkを使用しています。そのawk呼び出しは、_Duration:_を含む(できれば一意の)行を探します。コロンをセパレータとして使用すると、そのラベルはフィールド1、時間はフィールド2、提出された分3、秒フィールド4になります。秒の後のコンマは、awkを気にしないようですが、誰かがそこで問題を抱えている場合、ffmpegawkの間のパイプラインに_tr -d ,_を含めることができます。

ここでslmからの部分です:pasteを使用して改行をプラス記号に置き換えていますが、末尾の改行に影響を与えていません(_tr \\n +_とは異なり、 aこの回答の以前のバージョン )。これにより、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日からの秒数としてこれを使用します。結果の「日付」は、年間通算日、時刻、およびナノ秒としてフォーマットされます。その年の日から1を減算します。ゼロ秒を入力すると、その年の1970年の1日目に既に到達しているためです。ゼロから始まる年のカウントを取得する方法はないと思います。

最後のsedは、余分な末尾のゼロを取り除きます。 TZ設定は、うまくいけばUTCの使用を強制し、夏時間がreally大規模なビデオコレクションに干渉しないようにします。 1年以上のビデオがある場合でも、このアプローチは機能しません。

4
MvG

受け入れられた答えから離れて、従来のUNIXリバースポリッシュツールを使用します。

{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
         -show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc

783.493000

例:追加中+およびp次に、それを dc にパイプすると、合計が得られます。

1
A T

さて、これらすべてのソリューションには少しの作業が必要です。

  1. 目的のフォルダに移動して右クリック->他のアプリケーションで開く

  2. 次に、VLCメディアプレーヤーを選択します。

  3. これにより、いずれかの動画の再生が開始されますがその後
  4. ctrl + Lを押すと、動画の再生リストと左上隅のどこかに表示されます合計時間が表示されます

ここに例があります

1. List item

2 . enter image description here

3 . enter image description here

ツールバーのすぐ下にPlaylist [10:35:51]と書かれているので、フォルダには10時間35分、51秒の期間が含まれています合計ビデオ

現在のフォルダーにサブディレクトリがあるので、期間を再帰的に計算する必要がありました。

find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1

0
iMitwe
$ find -iname '*.ts' -print0 |\
xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null |\
Perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t += $1) && printf "%02d:%02d:%02d:%02d\n",$t/86400,$t/3600%24,$t/60%60,$t%60'

MPlayerがインストールされていることを確認してください。

0
ryanmjacobs

Ubuntuがffmpegの代わりにlibavを出荷するので:

#!/bin/sh
for f in *.mp4; do
    avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc

MvG のアイデアに大きく基づいています

0
Ahed Eid