Jak uzyskać liczbę klatek w filmie w wierszu poleceń systemu Linux?


30

Mam plik wideo i chcę uzyskać liczbę klatek wideo, które się w nim znajdują. Mogę użyć, ffmpegaby uzyskać długość filmu i FPS. Jednak nie widzę nic oczywistego dla całkowitej liczby ramek.

Teoretycznie należy mieć możliwość pomnożenia długości (w sekundach) przez liczbę klatek na sekundę, aby uzyskać liczbę klatek, ale w tym przypadku długość (34,43 sekundy) i liczba klatek na sekundę (29,97 kl./s) dają liczbę całkowitą, co czyni mnie myślę, że robię coś złego.

Muszę być w stanie to zrobić w wierszu poleceń w całkowicie zautomatyzowany i nie graficzny sposób. Potrzebuję również, aby było to dość dokładne, a nie szacunkowe (jeśli jest to nawet możliwe w przypadku plików wideo)

Próbowałem użyć tcprobeniektórych plików. W przypadku niektórych plików AVI to działa, ale w przypadku niektórych plików VOB wyjście tcprobe nie ma liczby ramek. Otrzymuję ten wynik:

[tcprobe] MPEG program stream (PS)
[tcprobe] summary for myfile.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
     aspect ratio: 4:3 (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
                   PTS=2199.3972, frame_time=33ms bitrate=7000 kbps
      audio track: -a 0 [0] -e 48000,16,5 [48000,16,2] -n 0x2000 [0x2000] (*)
                   PTS=2199.2763, bitrate=192 kbps
                   -D 3 --av_fine_ms 20 (frames & ms) [0] [0]

twoje równanie da ci dobre oszacowanie ballpark; wystarczy zaokrąglić wynik zmiennoprzecinkowy w górę. jeśli potrzebujesz dokładnej liczby klatek, musisz zbadać plik bezpośrednio - twoje oszacowanie może być wyłączone o jeden lub dwa w obu kierunkach ze względu na specyfikę kodeka wideo.
— quack quixote

czy te VOB typu „wszystko w jednym pliku” czy VOB typu „podzielone na wiele plików” w stylu DVD?
— quix quixote

Odpowiedzi:


17

To jest okropne, głupie i powolne, ale wydaje się działać:

ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1

Działa również bezpośrednio na obcięte pliki i surowe strumienie (dlatego nic nie dostajesz dla plików .vob)


To całkiem nieźle. Z mojego doświadczenia wynika, że ​​nie trwa to długo. Uruchomienie pliku trwającego 40 minut zajmuje jednak mniej niż 3 sekundy. Pamiętaj, że „^ M” to nie 2 znaki ^ i M, musisz nacisnąć Control-V, a następnie wprowadzić. Zamiast polecenia użyłem: ffmpeg -i somefile.avi -vcodec copy -f rawvideo -y / dev / null 2> & 1 | tr "^ M" '\ n' | grep '^ frame =' | perl -pe 's / ^ frame = \ s * ([0-9] +) \ s. * $ / \ 1 /' | tail -n 1 Twoje polecenie kończy się niepowodzeniem, jeśli po „frames =” nie ma spacji
— Rory

1
W Ubuntu 12.04, wersja ffmpeg git-2013-04-15-a4f03f0, możesz pominąć zarówno | tr ^M '\n'i |tail -n 1. Ponadto, żadne spacja po frames=nie zawiedzie. (Może coś się zmieniło w ciągu ostatnich czterech lat.)
— Camille Goudeseune,

dla mnie ten zwrot za każdym razem inne wartości
— CAMOBAP

1
Rozwiązanie Mediainfo współpracuje z VOB .. Polecam to zamiast tego. root @ lanparty: / mnt / movies # mediainfo --fullscan Bugs_Bunny.vob | grep -i ramka \ liczba Liczba klatek: 175715 Liczba klatek: 183218
— kevinf

32

ffprobe można użyć do uzyskania informacji o pliku multimedialnym:

ffprobe -select_streams v -show_streams input.avi

Otrzymasz szczegółowe informacje o strumieniu:

nb_frames=159697

Poszukaj za nb_framespomocą grep:

ffprobe -select_streams v -show_streams input.avi 2>/dev/null | grep nb_frames | sed -e 's/nb_frames=//'

Działa to dla avi, mp4 itp. W przypadku niektórych kontenerów nie wyświetla prawidłowej wartości, np. Mpeg.

W takim przypadku to działa ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l


Dobry pomysł. Zmodyfikowałem nieco to polecenie, tak aby wybierało tylko strumień wideo i filtrowało dane wyjściowe. To daje tylko liczbę klatek.
— slhck

1
Gratulujemy drugiego rozwiązania, które współpracuje z MPEG-2!
— Malat

1
Nie działa z pojemnikami MKV.
— Cenk Alti


Wydaje się, że pierwsze podejście kończy się niepowodzeniem na plikach zakodowanych w VBR. Drugie podejście jest bardziej niezawodne.
— Starszy Geek

16

Wysłałem to na inne pytanie . Za pomocą tcprobenarzędzia (z transcodepakietu) liczba ramek jest zawarta w informacji. Użyj -iprzełącznika, aby uzyskać zrzut informacji z pliku:

$ tcprobe -i foo.avi
[tcprobe] RIFF data, AVI video
[avilib] V: 29.970 fps, codec=XVID, frames=38630, width=512, height=384
[avilib] A: 48000 Hz, format=0x55, bits=16, channels=2, bitrate=128 kbps,
[avilib]    53707 chunks, 21768720 bytes, VBR
[tcprobe] summary for foo.avi, (*) = not default, 0 = not detected
import frame size: -g 512x384 [720x576] (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
      audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x55 [0x2000] (*)
                   bitrate=128 kbps
           length: 38630 frames, frame_time=33 msec, duration=0:21:28.954

Zauważ, że liczba ramek jest podana tutaj w dwóch liniach (2. linia wyjściowa i ostatnia linia wyjściowa).


To wygląda na dobrą odpowiedź i działa na niektóre pliki, ale w przypadku niektórych plików VOB mam te dane wyjściowe. Zaktualizowałem pytanie o otrzymany wynik
— Rory,

spodziewam się (ale nie wiem na pewno), że tcprobe sprawdza nagłówki plików dla tych informacji. jeśli nie jest uwzględniony w nagłówku, tcprobe może nie podjąć próby jego obliczenia. dobre pytanie; chciałbym mieć dla ciebie dobrą odpowiedź.
— quack quixote

Nie działa to na pliki zakodowane w VBR. Nie otrzymuję danych wyjściowych zliczania klatek. Dostaję rozdzielczość, współczynnik kształtu i liczbę klatek na sekundę.
— Starszy Geek

7

Przekonałem się, że mediainfo --fullscan inputfile | grep "Frame count"działa ładnie dla większości plików.

Systemy oparte na Debianie mogą go zainstalować apt-get install mediainfo

Jeśli otrzymujesz 2 linie zamiast jednego wyjścia, pierwszy wiersz jest ścieżką wideo, a drugi wiersz jest ścieżką audio. Wygląda na to, że dzieje się tak w przypadku plików z dźwiękiem o zmiennej przepływności.

Testowane na próbkach .mkv, .m4v, .mp4, flv, vob i .avi na dzień edycji.

Źródła: Jak pobrać informacje o pliku wideo z wiersza poleceń w systemie Linux? i testowanie w wersjach Ubuntu.

Informacje o multimediach dostępne dla twojego systemu operacyjnego można znaleźć tutaj.


4

ffprobe -select_streams v -show_frames -count_frames INPUT_FILE | grep pkt_duration_time =

Dodaj czas trwania. Może być bardziej elegancki z sed / awk i co nie.

Z naszych testów mogę stwierdzić, że na razie okazało się, że jest najbardziej niezawodny. Otrzymasz dokładną liczbę klatek i dokładny czas trwania. Nawet przy zmiennej liczbie klatek na sekundę, którą wszystkie inne narzędzia, takie jak mediainfo, wydają się być gaga.


3

Przekonałem się, że liczba klatek jest w rzeczywistości dwa razy dłuższa niż fps * (nie mam pojęcia dlaczego, chętnie bym wiedział).

W moim skrypcie mam:

# Get duration and fps
duration=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Duration: \([^,]*\), start: .*/\1/p")
fps=$($FFMPEG -i $input 2>&1 | sed -n "s/.*, \(.*\) tb.*/\1/p")

hours=$(echo $duration | cut -d":" -f1)
minutes=$(echo $duration | cut -d":" -f2)
seconds=$(echo $duration | cut -d":" -f3)
# For some reason, we have to multiply by two (no idea why...)
# Get the integer part with cut
frames=$(echo "($hours*3600+$minutes*60+$seconds)*$fps*2" | bc | cut -d"." -f1)

I tak, z jakiegoś powodu muszę uzyskać część całkowitą. To nie ma sensu, ale ten skrypt do tej pory zawsze poprawnie konwertował moje filmy.


Ponieważ FPS oznacza liczbę klatek na sekundę (lub FPS: D), a jeśli jest 30 klatek na sekundę, wystarczy pomnożyć go przez liczbę sekund w filmie.
— John T

Tak John, mogłem to rozgryźć, ale to nie wyjaśnia, dlaczego muszę pomnożyć to przez 2, aby uzyskać odpowiednią liczbę ramek ... W moim przypadku, po obliczeniu liczby ramek, uruchomiłem ffmpeg w tło i przeanalizował dzienniki, aby utworzyć pasek postępu. Dzienniki pokazują, ile ramek przeszło podczas konwersji. Po przekonwertowaniu całego wideo ramka # była int (sekundy * fps * 2), stąd mój kod, ale chciałbym wiedzieć, dlaczego ;-)
— ℝaphink

to ciekawe; tcprobewyjście w mojej odpowiedzi daje # klatek jak dokładnie sekund * fps (w zaokrągleniu). spodziewam się, że widzisz dziwactwo ffmpeg. próbowałeś przeanalizować plik za pomocą innych narzędzi, aby zobaczyć, czy pokazują one tę samą liczbę ramek?
— quack quixote

Hmmm ... Interesujące. Próbowałem na wideo i dostałem seconds*fps=1001.59i tcprobe=1002. Więc oczywiście tcprobemówi mi, że nie muszę pomnożyć przez dwa. Dlaczego więc ffmpeg podaje mi liczbę dwukrotnie większą w dziennikach podczas konwersji?
— ℝaphink,

2
czy to jest materiał z przeplotem? Jeśli tak, są dwa pola na ramkę i może to oznaczać liczbę pól.
— stib

3

Testowane na Ubuntu.

melt icecap.mp4 -consumer xml
  • melt- melt miał być narzędziem testowym dla frameworka MLT, ale jest także potężnym edytorem wideo z wieloma wierszami poleceń. Może być również używany jako minimalistyczny odtwarzacz multimediów dla plików audio i wideo.

  • -consumerid [: arg] [name = wartość] *
    Ustaw konsumenta (sink)

  • xml - Ustaw konsumenta (zlew) na formatowanie xml

  • <property name="length">nnnn</property>- pokazuje liczbę ramek, gdzie nnnnjest zastąpiona liczbą całkowitą równą liczbie ramek

Jeśli nie masz stopu, możesz zainstalować go na Ubuntu i innych systemach opartych na Debianie sudo apt-get install melt


1
To jest bardzo krótkie, czy chcesz rozwinąć to, co robi, dlaczego działa itp.?
— David

Działa to dobrze na plikach MP26 h264, które nie zapewniają liczby ramek za pośrednictwem mediainfo -fullscan filename.
— Starszy Geek

3

Bezpośrednio z mediainfo, bez grep, bez czekania, bez niczego:

mediainfo --Inform='Video;%FrameCount%' $the_file

Inne informacje patrz mediainfo --info-parameters


0

Możesz to zrobić, dodając i mnożąc wartości otrzymane z ffprobe.

Uwaga: ffprobe jest częścią libav (avconv) - linuksowej wersji ffmpeg.

#your command -
 ffprobe man.avi

Gdy to zrobisz, otrzymasz liczbę klatek na sekundę, a także czas trwania klipu.

Konwertuj czas trwania klipu na sekundy i pomnóż tę wartość przez liczbę klatek / sekundę.

Pamiętaj, aby zaokrąglić liczbę do najbliższego.


Ubuntu 14.04 LTS na ffprobenie jest dostępny, ale jest coś, co nazywa avprobesię libav-tools(co zapewnia również avconv). Ale z mojej strony nie drukuje żadnej liczby ramek, przynajmniej nie dla formatów, które wypróbowałem. Po prostu drukuje, jakie avprobe -idrukuje, i to jest tylko kilka drobnych bitów na temat formatu, niestety. Mimo -v debugto mówi mi tylko kilka fajnych właściwości zainstalowanego sprzętu i oprogramowania, ale nie ma ani jednej interesującej informacji o pliku / strumieniu do sondowania. Być może ukrywa się w wielu dostępnych opcjach. Kto wie?
— Tino

@Tino ffprobe jest rzeczywiście dostępny jako część pakietu ffmpeg. avconv jest rozwidleniem ffmpeg i spowodował pewne zamieszanie. Zobacz: stackoverflow.com/questions/9477115/…
— Starszy Geek

@ElderGeek Dla Ubuntu 14.04 LTS nie ma ffmpegw oficjalnych repozytoriach. Link, który podałeś poprawnie, stwierdza: FFmpeg powrócił w Ubuntu 15.04 „Vivid Vervet”. . Sytuacja zmieniła się jednak po wydaniu 16.04 LTS.
— Tino

@Tino To jest rzeczywiście fakt. Jednak nie utożsamiam z niedostępnością nie istnieje w repozytoriach. Zauważysz, że jest dostępny dla Trusty (14.04) tutaj: ffmpeg.org/download.html
— Starszy Geek

0

linux

ffmpeg -i "/home/iorigins/Завантаження/123.mov" -f null /dev/null

rubin

result = `ffmpeg -i #{path} -f null - 2>&1`
r = result.match("frame=([0-9]+)")
p r[1]

-2

Najlepsza metoda: (bezpośrednio przez obliczenie odpowiednich parametrów, potwierdzone przez ffmpeg)

Cmd ->

ffprobe.exe -v error -select_streams v:0 -show_entries stream=r_frame_rate,duration -of default=nw=1 "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4"

Wynik ->

r_frame_rate=24000/1001
duration=8177.794625

Obliczanie ->

Frames=24000/1001*8177.794625=196071 (exactly... ;P)

Dowód ->

ffmpeg -i "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4" -f 

null /dev/null
ffmpeg version N-92938-g0aaaca25e0-ffmpeg-windows-pacman Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.0 (GCC)
  configuration: --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-pacman --enable-version3 --disable-debug --disable-w32threads --arch=x86_64 --target-os=mingw32 --cross-prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --enable-libcaca --enable-gray --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-libmysofa --enable-libaom --enable-libopenjpeg --enable-libopenh264 --enable-liblensfun --enable-nvenc --enable-nvdec --extra-libs=-lm --extra-libs=-lpthread --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-amf --enable-libmfx --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxavs --enable-avresample --extra-cflags='-march=core2' --extra-cflags=-O2 --enable-static --disable-shared --prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
  Duration: 02:16:17.91, start: 0.000000, bitrate: 2497 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 2397 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
  Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
    Stream #0:0(und): Video: wrapped_avframe, yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.43.100 wrapped_avframe
    Stream #0:1(und): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
      encoder         : Lavc58.43.100 pcm_s16le

Tutaj

frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x

Wydajność

video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
shareeditdeleteflag

Dostaję r_frame_rate = 25/1 czas trwania = nie dotyczy
— Starszy Geek
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.