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

Wie erhält man die Videodauer in Sekunden?

Wie kann ich die Videodauer in Sekunden erhalten?

Was ich versucht habe:

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

Das was nahe dran, aber es ist nicht so genau, 2383 ist 39,71 Minuten

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

Antworten (9)

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

Verwenden Sie einfach ffprobe direkt. Keine Notwendigkeit für sed, grep, usw. Es gibt mehrere “Dauern”, die Sie erfassen können (abhängig von Ihrer Eingabe).

Format (Container) Dauer

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

30.024000

Durch Hinzufügen der Option -sexagesimal wird das Zeiteinheitenformat HOURS:MM:SS.MICROSECONDS verwendet:

0:00:30.024000

Video-Stream-Dauer

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

Die obigen Befehle sind aus FFmpeg Wiki: FFprobe Tips .

Mit ffmpeg

Möglicherweise müssen Sie die Eingabe komplett dekodieren, wenn Sie feststellen, dass der Container oder die Streamdauer fehlen oder ungenau sind (möglicherweise aufgrund einer beschädigten oder abgeschnittenen Datei).

$ 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

In diesem Beispiel ist time=00:01:03.48 die Dauer:

Wie lange dies dauert, hängt natürlich von der Komplexität und Dauer der Dekodierung Ihrer Eingabe und den Fähigkeiten Ihres Computers ab.

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

Um Minuten zu erhalten, müssen Sie 2383 Sekunden durch 60 dividieren.

39.7167

und dann den Bruchteil .7167 mit 60 multiplizieren, um die restlichen Sekunden zu erhalten.

43.002

Also sind es 39 Minuten und 43 Sekunden. Die Anwendung scheint Ihnen einen genauen Wert zu liefern.

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

Wenn Sie ffmpeg haben, sollten Sie auch ffprobe haben:

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

Das ergibt auch Bruchteile von Sekunden, wenn das ein Problem ist, können Sie das mit sed weiter weg verarbeiten.

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

Dies gibt die Dauer in Millisekunden als einzelnen Integer-Wert aus. Kein Bedarf für grep/cut/sed/…

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

Lösung mit mplayer, die direkt Sekunden liefert:

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

Für meine ffmpeg-0.6.5-1.el6.rf.x86_64, um nur die zweite, ffprobe Befehlsformat ist:

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

Wenn Sie nur die Metadaten abfragen wollen:

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

[…]

streams.stream.0.duration="5221.146009"

[…]

Sie können es also parsen:

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)

Wenn Sie jedoch die effektive Dauer des Containers abfragen möchten, müssen Sie es dekodieren:

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

Es wird einige CPU-Zeit zum Dekodieren benötigen, bis:

[…]

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

Dann können Sie es parsen:

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"
0
0
0
2017-06-01 01:01:24 +0000

Ich stieß auf das Problem, einige seltsame und falsche Metadaten von einigen Videodateien zu erhalten, mit denen ich arbeitete, und ich konnte nicht erfolgreich sein, ein Muster oder irgendeine Art der Handhabung mit Code und Tools wie ffmpeg, mp4box, ffprobe, mediainfo, mplayer zu finden, um die tatsächliche Dauer des Videos zu erhalten.

Die Ermittlung der tatsächlichen Dauer des Videos war eine Anforderung für ein Projekt, an dem ich arbeitete, und der einzige Weg, den ich fand, um es immer richtig zu machen, war, die Videodatei mit ffmpeg neu zu kodieren und die kodierten Dateien zu zwingen, die Metadaten der Originaldatei zu ignorieren, wie:

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

(Dies könnte schneller laufen als Sie erwarten. Ich war überrascht, für die Art von Inhalt und in der Umgebung, die ich benutzte, betrug die durchschnittliche Zeit 2 Sekunden)

… und dann die Dauer mit einem Tool Ihrer Wahl ermitteln. Ich mag mediainfo, btw: - “mediainfo FILE –Inform="Video;%Duration%” gibt Ihnen die Dauer in Millisekunden.

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

Wenn Sie eine akkurate Dauer wünschen, vergessen Sie FFmpeg. Es gibt nur eine Schätzung basierend auf der Dateigröße und der durchschnittlichen Bitrate. Ich habe festgestellt, dass in einigen Fällen die geschätzte Dauer um das Doppelte abweicht!

Unter Linux, wenn die Datei nur während der besagten Videoaufnahme erstellt und geändert wird, wäre eine alternative Lösung, die Erstellungs- und letzte Änderungszeit zu verwenden, um die Dauer zu berechnen, wie in:

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