ビデオの長さを秒単位で取得する方法は?


69

ビデオの長さを秒単位で取得するにはどうすればよいですか?

私が試したこと:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

これは近いですが、それほど正確ではありません。2383は39.71分です

ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383

回答:


36

分を取得するには、2383秒を60で割る必要があります。

39.7167

次に、小数部.7167に60を掛けて残りの秒を取得します。

43.002

つまり、39分43秒です。アプリケーションは正確な値を提供しているようです。


96

ffprobe直接使用するだけです。必要性いいえsedgrepなど、あなたが(あなたの入力に応じて)を取得することができるいくつかの「期間」があります。

フォーマット(コンテナ)期間

$ ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4

30.024000

-sexagesimalオプションを追加すると、HOURS:MM:SS.MICROSECONDS時間単位形式が使用されます。

0:00:30.024000

ビデオストリームの長さ

$ ffprobe -v error -select_streams v:0 -show_entries stream=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4
30.000000

上記のコマンドはFFmpeg Wiki:FFprobe Tipsからのものです。

ffmpeg

コンテナーまたはストリームの継続時間が欠落または不正確である(ファイルの破損または切り捨てが原因である可能性がある)場合は、入力を完全にデコードする必要があります。

$ ffmpeg -i input.mp4 -f null -
  …
  frame= 1587 fps=0.0 q=0.0 Lsize=N/A time=00:01:03.48 bitrate=N/A

この例でtime=00:01:03.48は、期間です。

もちろん、これにかかる時間は、デコードの複雑さと入力の期間、およびコンピューターの機能によって異なります。


これらは.m2vファイルでは機能しません。解決策もありますか?
utdev

@utdev「With ffmpeg」セクションを参照してください。
llogan

あなたの第三の溶液が私に間違った時間を与え、私のビデオが1時19分00秒の長さを持っていますが、コマンドは私の時間= 01を返します:09:15.32を、あなたはなぜこれが起こっている推測していない
utdev

メディアストリームの長さが非常に便利です。ありがとうございました。
私たちはボルグです

avprobeを使用する場合、パラメーターはわずかに異なります。avprobe-v error -show_format_entry duration。\ Sample.mp4
Brad

32

持っている場合ffmpeg、以下も持っている必要がありますffprobe

ffprobe -i input.file -show_format | grep duration
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

これは、sedを使用してさらに処理できる問題である場合、数分の1秒を提供します。


秒の小数部分を削除するにはどうすればよいですか?
ティナJ

@TinaJのprintfようにパイプするだけで| xargs printf %.0f-整数値を返します。
イリアロストフツェフ

3

ffmpeg-0.6.5-1.el6.rf.x86_64の場合、2番目を取得するためのffprobeコマンド形式は次のとおりです。

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 

秒の小数部分を削除するにはどうすればよいですか?
ティナJ

3

秒を直接与えるmplayerを使用したソリューション:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'

2
mediainfo --Output='General;%Duration%' file.flv

これは、ミリ秒単位の期間を単一の整数値として出力します。grep / cut / sed /の必要はありません...


おかげで-これはまさに私が探していたものでした。でMacOSにインストールできますbrew install mediainfo
Alex K

0

作業中のビデオファイルから奇妙で不正確なメタデータを取得する問題に遭遇し、ffmpeg、mp4box、ffprobe、mediainfo、mplayerなどのコードとツールを使用してパターンやあらゆる種類の処理を見つけることができませんでした。ビデオの実際の長さを取得します。

ビデオの実際の継続時間を特定することは、私が取り組んでいるプロジェクトの要件であり、常に正しい方法を見つけるための唯一の方法は、ffmpegを使用してビデオファイルを再エンコードし、エンコードされたファイルに元のファイルのメタデータを無視させることでした:

ffmpeg -i INPUT_FILENAME -acodec copy -vcodec copy -map_metadata -1 OUTPUT_FILENAME"

(これは予想よりも速く実行される可能性があります。コンテンツのタイプと使用している環境では、平均時間が2秒だったので驚きました)

...そして、選択したツールを使用して期間を取得します。btw:mediainfoが好きです:-"mediainfo FILE --Inform =" Video;%Duration% "は、ミリ秒単位で期間を示します。


他の回答よりも多くの情報やより良い解決策を提供しなかった
サム

0

メタデータのクエリのみが必要な場合:

ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4

[...]

streams.stream.0.duration="5221.146009"

[...]

だからあなたはそれを解析することができます:

while read -r; do
  if [[ "$REPLY" =~ ^streams\.stream\.([0-9])+\.duration=\"([^"]+)\"$ ]]; then
    echo -E Duration of stream "${BASH_REMATCH[1]}": "${BASH_REMATCH[2]}"
  fi
done < <(ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4)

ただし、有効なコンテナーの期間を取得するには、デコードする必要があります。

AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2

次の状態になるまで、デコードにCPU時間を要します。

[...]

frame=130527 fps=53271 q=-1.0 Lsize=N/A time=01:27:01.12 bitrate=N/A speed=2.13e+03x
video:152014kB audio:40790kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

次に、それを解析できます。

if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"

-6

正確な期間が必要な場合、FFmpegを忘れてください。ファイルサイズと平均ビットレートに基づいた推定値のみを提供します。場合によっては、推定持続時間が2倍オフになることがわかりました。

Linuxでは、上記のビデオ録画中にのみファイルが作成および変更される場合、代替ソリューションは、次のように作成時間と最終変更時間を使用して期間を計算することです。

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'

5
ffmpegが不正確だとどこで見つけましたか?
アレブ

4
%Xは最終アクセス時刻です。%Yは最後に変更されてからの時間です。これは、ビデオの長さについては何も言いません。
ジョーヒレンブランド

1
これは荒らしのようです
ジョージチャラウブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.