2013-09-25 19:35:33 +0000 2013-09-25 19:35:33 +0000
75
75

動画の持続時間を秒単位で取得する方法は?

動画の持続時間を秒単位で取得するにはどうすればいいですか?

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

試してみました。

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

これは近いですが、あまり正確ではありません。

回答 (9)

105
105
105
2015-07-26 22:07:37 +0000

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 がデュレーションです。

これにどれくらいの時間がかかるかは、もちろん入力のデコードの複雑さと持続時間、およびコンピュータの能力に依存します。

35
35
35
2013-09-25 19:41:05 +0000

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

39.7167

そして端数部分の.7167を60で割って残りの秒数を求めます。

43.002

ということで、39分43秒です。アプリケーションは正確な値を出しているように見えます。

34
34
34
2013-09-25 21:10:07 +0000

ffmpeg があれば、ffprobe もあるはずです。

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

これは秒数も表示されます。

3
3
3
2018-05-05 08:00:38 +0000
mediainfo --Output='General;%Duration%' file.flv

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

3
3
3
2013-09-25 19:56:50 +0000

mplayerで秒数を直接表示するようにしました。

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
3
3
3
2014-06-16 22:06:49 +0000

ffmpeg-0.6.5-1.el6.rf.x86_64の場合、2つ目だけを取得するために、ffprobeコマンドのフォーマットは以下のようになります。

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p'
0
0
0
2019-08-30 19:39:55 +0000

メタデータをクエリするだけなら

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

その後、次のように解析することができます。

0
0
0
2017-06-01 01:01:24 +0000

私が作業していたいくつかの動画ファイルから奇妙で不正確なメタデータを取得するという問題に出くわしました。

動画の本当の長さを特定することは、私が作業していたプロジェクトの要件でしたが、常に正しい長さを取得する唯一の方法は、ffmpegを使用して動画ファイルを再エンコードし、エンコードされたファイルが元のファイルのメタデータを無視するように強制することでした。

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

(これは思ったよりも速く動くかもしれません。

0x1&

…のように、エンコードされたファイルを元のファイルのメタデータを無視するようにしています。mediainfo FILE –Inform=“Video;%Duration%"はミリ秒単位でデュレーションを表示してくれます。

-6
-6
-6
2015-04-27 01:59:24 +0000

正確なデュレーションが必要な場合は、FFmpegを忘れてください。それはファイルサイズと平均ビットレートに基づいた推定値を与えるだけです。私は、いくつかのケースでは、推定された持続時間が2倍もずれていることを発見しました!

Linuxでは、ファイルがビデオ録画中にのみ作成・修正される場合、別の解決策としては、次のように作成時間と最終修正時間をデュレーションの計算に使用することができます。

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