Bagaimana cara mendapatkan jumlah frame dalam video di baris perintah linux?


30

Saya memiliki file video dan saya ingin mendapatkan jumlah bingkai video yang ada di dalamnya. Saya bisa menggunakan ffmpeguntuk mendapatkan panjang video dan FPS. Namun saya tidak dapat melihat sesuatu yang jelas untuk jumlah total frame.

Secara teori seseorang harus dapat mengalikan panjang (dalam detik) dengan FPS untuk mendapatkan jumlah frame, tetapi dalam kasus ini panjang (34,43 detik) dan framerate (29,97 fps) memberikan non-integer, yang membuat saya pikir saya melakukan sesuatu yang salah.

Saya harus dapat melakukan ini pada baris perintah dengan cara yang sepenuhnya otomatis dan non-grafis. Saya juga perlu ini cukup tepat, dan bukan perkiraan (jika itu mungkin dengan file video)

Saya mencoba menggunakan tcprobebeberapa file. Untuk beberapa file AVI berfungsi, tetapi untuk beberapa file VOB, output tcprobe tidak memiliki jumlah frame. Saya mendapatkan hasil ini:

[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]

persamaan Anda akan memberi Anda perkiraan kasarnya; bulatkan hasil floating-pt ke atas. jika Anda membutuhkan jumlah frame yang tepat, Anda perlu memeriksa file secara langsung - perkiraan Anda mungkin tidak aktif sebanyak satu atau dua arah karena keikutsertaan codec video.
Quack quixote

apakah ini VOB semua-dalam-satu-file atau VOB split-ke-banyak-gaya DVD?
quack quixote

Jawaban:


17

Ini mengerikan, dan bodoh, dan lambat, tetapi tampaknya berhasil:

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

Ini juga akan berfungsi dengan benar pada file terpotong dan aliran mentah (itulah sebabnya Anda tidak mendapatkan apa-apa untuk file .vob)


Cukup bagus. Dalam pengalaman saya, tidak butuh waktu lama. File 40 menit membutuhkan sekitar <3 detik untuk dijalankan. Ingat bahwa "^ M" bukan 2 karakter ^ dan M, Anda harus menekan Control-V, dan kemudian masukkan. Alih-alih perintah Anda, saya menggunakan: 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 Perintah Anda gagal jika tidak ada ruang setelah "frames ="
Rory

1
Di Ubuntu 12.04, ffmpeg versi git-2013-04-15-a4f03f0, Anda dapat menghilangkan keduanya | tr ^M '\n'dan |tail -n 1. Juga, tidak ada ruang setelah frames=tidak gagal. (Mungkin ada yang berubah dalam empat tahun terakhir.)
Camille Goudeseune

bagi saya ini mengembalikan setiap nilai waktu yang berbeda
CAMOBAP

1
Solusi Mediainfo bekerja dengan VOB .. Saya akan merekomendasikan itu sebagai gantinya. root @ lanparty: / mnt / films # mediainfo --fullscan Bugs_Bunny.vob | grep -i frame \ count Jumlah frame: 175715 Jumlah frame: 183218
kevinf

32

ffprobe dapat digunakan untuk mendapatkan info tentang file media:

ffprobe -select_streams v -show_streams input.avi

Anda akan mendapatkan detail tentang aliran:

nb_frames=159697

Cari nb_framesdengan grep:

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

Itu berfungsi untuk avi, mp4 dan lain-lain. Untuk beberapa kontainer, tidak menunjukkan nilai yang valid, misalnya mpeg.

Dalam hal ini, ini berhasil ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l


Ide bagus. Saya memodifikasi perintah sedikit sehingga hanya memilih aliran video, dan memfilter output. Itu memberi Anda hanya jumlah bingkai.
slhck

1
Selamat atas solusi kedua Anda yang bekerja dengan MPEG-2!
malat

1
Itu tidak bekerja dengan wadah MKV.
Cenk Alti


Tampaknya pendekatan pertama gagal pada file yang disandikan VBR. Pendekatan kedua lebih andal.
Penatua Geek

16

Saya memposting ini pada pertanyaan lain . Dengan menggunakan tcprobealat (dari transcodepaket), jumlah bingkai termasuk dalam info. Gunakan -isakelar untuk mendapatkan info dump dari file:

$ 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

Perhatikan jumlah frame diberikan pada dua baris di sini (jalur output ke-2 dan jalur keluaran terakhir).


Itu terlihat seperti jawaban yang baik, dan berfungsi untuk beberapa file, tetapi untuk beberapa file VOB yang saya miliki, saya tidak memiliki data dalam output. Saya telah memperbarui pertanyaan dengan output yang saya dapatkan
Rory

Saya berharap (tetapi tidak tahu pasti) bahwa tcprobe sedang memeriksa header file untuk info ini. jika itu tidak termasuk dalam header, tcprobe mungkin tidak mencoba perhitungan untuk itu. Pertanyaan bagus; Seandainya aku punya jawaban yang bagus untukmu.
quack quixote

Ini tampaknya tidak berfungsi pada file yang disandikan VBR saya tidak mendapatkan output jumlah frame. Saya mendapatkan resolusi, rasio aspek dan frame rate.
Penatua Geek

7

Saya telah menemukan bahwa itu mediainfo --fullscan inputfile | grep "Frame count"bekerja dengan baik untuk sebagian besar file.

Sistem berbasis Debian dapat menginstalnya dengan apt-get install mediainfo

Jika Anda mendapatkan 2 baris daripada satu output, baris pertama adalah trek video dan baris kedua adalah trek audio. Tampaknya ini terjadi pada file dengan audio Variable Bit Rate.

Diuji pada sampel .mkv, .m4v, .mp4, flv, vob, dan .avi pada tanggal edit.

Sumber: Bagaimana cara mengambil informasi file video dari command line di Linux? dan pengujian di bawah rasa Ubuntu.

Anda dapat menemukan mediainfo tersedia untuk OS Anda di sini.


4

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

Jumlahkan durasi. Bisa lebih mewah dengan sed / awk dan apa yang tidak.

Dari pengujian kami, saya dapat mengatakan bahwa untuk saat ini telah terbukti menjadi yang terbaik yang paling dapat diandalkan. Anda mendapatkan jumlah yang tepat dan durasi yang tepat. Bahkan dengan framerate variabel yang semua alat lain seperti mediainfo tampaknya menjadi gaga.


3

Saya telah menemukan bahwa jumlah frame sebenarnya dua kali lipat durasi fps * (tidak tahu mengapa, saya akan senang mengetahui).

Dalam naskah saya, saya punya:

# 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)

Dan ya, untuk beberapa alasan saya harus mendapatkan bagian integer darinya. Ini tidak masuk akal, tetapi skrip ini selalu berhasil mengonversi video saya dengan baik sejauh ini.


Karena FPS adalah singkatan dari Frames Per Second (atau first person shooter: D) dan jika ada 30 FPS cukup gandakan dengan berapa detik dalam video.
John T

Ya John, saya bisa mengetahuinya, tapi itu tidak menjelaskan mengapa saya harus mengalikannya dengan 2 untuk mendapatkan jumlah frame yang tepat ... Dalam kasus saya, setelah saya menghitung jumlah frame, saya meluncurkan ffmpeg di latar belakang dan menganalisis log untuk membuat bilah kemajuan. Log menunjukkan berapa banyak frame yang telah lulus dalam konversi. Setelah seluruh video diubah, frame # adalah int (detik * fps * 2), maka kode saya, tapi saya ingin tahu mengapa ;-)
ℝaphink

itu aneh; yang tcprobeoutput dalam jawaban saya memberikan # frame sebagai persis detik * fps (dibulatkan ke atas). Saya berharap Anda melihat kekhasan ffmpeg. Sudahkah Anda mencoba menganalisis file dengan alat lain untuk melihat apakah mereka menunjukkan jumlah frame yang sama?
Quack quixote

Hmmm ... Menarik sekali. Saya mencoba pada video dan aku seconds*fps=1001.59dan tcprobe=1002. Jadi jelas, tcprobekatakan saya tidak perlu dikalikan dua. Lalu mengapa ffmpeg memberi saya nomor yang dua kali lebih besar di log ketika sedang mengkonversi?
ℝaphink

2
Apakah itu rekaman yang saling terkait? Jika demikian ada dua bidang per bingkai, dan itu bisa memberi Anda jumlah bidang.
stib

3

Diuji di Ubuntu.

melt icecap.mp4 -consumer xml
  • melt- melt dimaksudkan sebagai alat uji untuk kerangka kerja MLT, tetapi juga merupakan editor video berorientasi baris perintah multitrack yang kuat. Itu juga bisa digunakan sebagai media player minimalis untuk file audio dan video.

  • -consumerid [: arg] [name = value] *
    Atur konsumen (wastafel)

  • xml - Atur konsumen (wastafel) ke output terformat xml

  • <property name="length">nnnn</property>- menunjukkan jumlah frame, di mana nnnndiganti dengan angka integer yang sama dengan jumlah frame

Jika Anda belum mencair, Anda dapat menginstalnya di Ubuntu dan sistem berbasis Debian lainnya sudo apt-get install melt


1
Ini sangat singkat, apakah Anda ingin memperluas apa yang dilakukannya, mengapa itu bekerja, dll?
David

Ini berfungsi dengan baik pada file h264 mp4 yang tidak menyediakan framecount via mediainfo -fullscan filename.
Penatua Geek

3

Langsung dengan mediainfo, tanpa grep, tidak menunggu, tidak ada apa-apa:

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

Untuk informasi lainnya, lihat mediainfo --info-parameters


0

Anda dapat melakukan ini dengan menambahkan dan mengalikan nilai yang Anda dapatkan dari ffprobe.

Catatan: ffprobe adalah bagian dari libav (avconv) - versi linux dari ffmpeg.

#your command -
 ffprobe man.avi

Ketika Anda melakukan ini, Anda akan mendapatkan jumlah frame per / detik dan juga durasi klip.

Konversi durasi klip ke detik dan gandakan nilainya dengan jumlah bingkai / detik.

Ingatlah untuk mengumpulkan angka ke yang terdekat.


Pada Ubuntu 14.04 LTS ffprobetidak tersedia, tapi ada sesuatu yang disebut avprobedi libav-tools(yang juga menyediakan avconv). Tetapi di sisi saya itu tidak mencetak sejumlah bingkai, setidaknya tidak untuk format yang saya coba. Itu hanya mencetak, apa yang avprobe -imencetak juga, dan ini hanya beberapa bit kecil tentang format, sayangnya. Bahkan dengan -v debugitu hanya memberitahu saya beberapa properti bagus dari perangkat keras dan perangkat lunak saya diinstal, tetapi tidak sedikit pun informasi menarik tentang file / stream untuk diselidiki. Mungkin ia bersembunyi di beberapa opsi yang tersedia. Siapa tahu?
Tino

@Tino ffprobe memang tersedia sebagai bagian dari paket ffmpeg. avconv adalah fork dari ffmpeg dan menyebabkan kebingungan. Lihat: stackoverflow.com/questions/9477115/…
Penatua Geek

@ElderGeek Untuk Ubuntu 14.04 LTS tidak ada ffmpegdalam repositori resmi. Tautan yang Anda berikan menyatakan dengan benar: FFmpeg kembali di Ubuntu 15.04 "Vivid Vervet". . Namun situasi sekarang berubah ketika 16,04 LTS keluar.
Tino

@Tino Itu memang fakta. Namun saya tidak akan menyamakan tersedia dengan tidak ada di repositori. Anda akan mengetahui bahwa itu tersedia untuk Trusty (14.04) di sini: ffmpeg.org/download.html
Penatua Geek

0

linux

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

rubi

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

-2

Metode terbaik: (Langsung dengan menghitung parameter yang tepat, dikonfirmasi oleh 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"

Hasil ->

r_frame_rate=24000/1001
duration=8177.794625

Perhitungan ->

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

Bukti ->

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

Sini

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

Keluaran

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

Saya mendapatkan r_frame_rate = 25/1 durasi = N / A
Penatua Geek
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.