Jak uzyskać czas trwania filmu w kilka sekund?

69

Jak mogę uzyskać czas trwania filmu w kilka sekund?

Co próbowałem:

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

To, co jest blisko, ale nie jest tak dokładne, 2383 to 39,71 minuty

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
użytkownik2783132
źródło

Odpowiedzi:

36

Aby uzyskać minuty, musisz podzielić 2383 sekundy przez 60.

39.7167

a następnie pomnóż część ułamkową .7167 przez 60, aby uzyskać pozostałe sekundy.

43.002

To 39 minut, 43 sekundy. Wygląda na to, że aplikacja podaje dokładną wartość.

Robert Harvey
źródło
95

Po prostu użyj ffprobebezpośrednio. Nie ma potrzeby sed, grepitp Istnieje kilka „okresy” można nabyć (w zależności od wejścia).

Czas trwania formatu (kontenera)

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

30.024000

Dodanie -sexagesimalopcji spowoduje użycie formatu jednostki czasu HOURS: MM: SS.MICROSECONDS:

0:00:30.024000

Czas trwania strumienia wideo

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

Powyższe polecenia pochodzą z FFmpeg Wiki: FFprobe Tips .

Z ffmpeg

Konieczne może być całkowite odkodowanie danych wejściowych, jeśli okaże się, że brakuje kontenera lub czasu trwania strumienia lub jest on niedokładny (być może z powodu uszkodzonego lub obciętego pliku).

$ 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

W tym przykładzie time=00:01:03.48jest czas trwania:

To, jak długo to zajmie, zależy oczywiście od złożoności dekodowania i czasu trwania danych wejściowych oraz możliwości komputera.

Llogan
źródło
Nie działają one dla plików .m2v, czy masz dla nich rozwiązanie
utdev
@utdev Zobacz sekcję „Z ffmpeg”.
llogan
Twoje trzecie rozwiązanie daje zły czas, moje wideo ma długość 01:19:00, ale polecenie zwraca mi czas = 01: 09: 15.32, czy
zgadujesz,
Bardzo przydatne czas trwania strumienia mediów. Dziękuję Ci.
Jesteśmy Borg,
Dla każdego używającego avprobe parametry są nieco inne: avprobe -v error -show_format_entry duration. \ Sample.mp4
Brad
32

Jeśli masz ffmpeg, powinieneś również mieć ffprobe:

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

To da również ułamki sekund, jeśli jest to problem, możesz dalej go przetwarzać za pomocą sed.

zła
źródło
jak mogę usunąć ułamek sekundy?
Tina J,
@ TinaJ Po prostu potokuj to printf, na przykład | xargs printf %.0f- to zwróci wartość całkowitą.
Ilia Rostovtsev
3

Dla mojego ffmpeg-0.6.5-1.el6.rf.x86_64, aby uzyskać tylko drugi, format polecenia ffprobe to:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 
Sunry
źródło
jak mogę usunąć ułamek sekundy?
Tina J,
3

Rozwiązanie z mplayerem, które daje sekundy bezpośrednio:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
Micke
źródło
2
mediainfo --Output='General;%Duration%' file.flv

To wyświetla czas trwania w milisekundach jako jedną wartość całkowitą. Nie ma potrzeby grep / cut / sed / ...

Josef Kufner
źródło
Dzięki - tego właśnie szukałem. Może być zainstalowany na MacOS zbrew install mediainfo
Alex K
0

Natknąłem się na problem uzyskiwania dziwnych i niepoprawnych metadanych z niektórych plików wideo, z którymi pracowałem i nie udało mi się znaleźć wzorca lub innego rodzaju obsługi za pomocą kodu i narzędzi takich jak ffmpeg, mp4box, ffprobe, mediainfo, mplayer, aby uzyskać rzeczywisty czas trwania filmu.

Określenie rzeczywistego czasu trwania wideo było wymaganiem dla projektu, nad którym pracowałem, a jedynym sposobem, aby uzyskać go zawsze poprawnie, było ponowne kodowanie pliku wideo przy użyciu ffmpeg i zmuszanie kodowanych plików do ignorowania metadanych oryginalnego pliku, takich jak:

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

(Może to działać szybciej, niż się spodziewasz. Zaskoczyło mnie to, ze względu na rodzaj zawartości i środowisko, z którego korzystałem, średni czas wynosił 2 sekundy)

... a następnie uzyskaj czas trwania za pomocą wybranego narzędzia. Lubię mediainfo, btw: - "PLIK mediainfo - Informacje =" Wideo;% Duration% "daje ci czas trwania w milisekundach.

satirio
źródło
Nie podałeś więcej informacji ani lepszego rozwiązania niż inne odpowiedzi
Sam
0

Jeśli potrzebujesz tylko zapytać o metadane:

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

[...]

streams.stream.0.duration="5221.146009"

[...]

Możesz to parsować:

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)

Ale jeśli chcesz uzyskać efektywny czas trwania kontenera, musisz go zdekodować:

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

Dekodowanie zajmie trochę czasu procesora, dopóki:

[...]

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

Następnie możesz go przeanalizować:

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"
Luchostein
źródło
-6

Jeśli chcesz mieć DOKŁADNY czas trwania, zapomnij o FFmpeg. Podaje jedynie oszacowanie na podstawie rozmiaru pliku i średniej przepływności. Znalazłem, w niektórych przypadkach, szacowany czas wolny od pracy 2x!

W systemie Linux, jeśli plik jest tworzony i modyfikowany tylko podczas wspomnianego nagrania wideo, alternatywnym rozwiązaniem byłoby użycie czasu utworzenia i ostatniej modyfikacji do obliczenia czasu trwania, jak w:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'
codechimp
źródło
5
Gdzie odkryłeś, że ffmpeg jest niedokładny?
aleb
4
% X to czas ostatniego dostępu. % Y jest czasem od ostatniej modyfikacji. Nie mówi to nic o długości filmu.
Joe Hillenbrand
1
To wydaje się być trollem
George Chalhoub,