¿Cómo obtengo el número de cuadros en un video en la línea de comando de Linux?

30

Tengo un archivo de video y quiero obtener la cantidad de cuadros de video que contiene. Puedo usar ffmpegpara obtener la duración del video y el FPS. Sin embargo, no puedo ver nada obvio para el número total de fotogramas.

En teoría, uno debería poder multiplicar la longitud (en segundos) por el FPS para obtener el número de fotogramas, pero en este caso la longitud (34.43 segundos) y la velocidad de fotogramas (29.97 fps) dan un no entero, lo que me hace Creo que estoy haciendo algo mal.

Necesito poder hacer esto en la línea de comando de una manera totalmente automática y no gráfica. También necesito que esto sea bastante exacto, y no una estimación (si eso es posible con archivos de video)

Intenté usar tcprobeen algunos archivos. Para algunos archivos AVI funciona, pero para algunos archivos VOB, la salida de tcprobe no tiene el número de fotogramas. Me sale esta salida:

[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]
Rory
fuente
su ecuación le dará una buena estimación aproximada; simplemente redondee el resultado de punto flotante hacia arriba. si necesita un número exacto de fotogramas, deberá examinar el archivo directamente; su estimación puede estar desviada en uno o dos en cualquier dirección debido a los detalles del códec de video.
quack quijote
¿son estos VOB todo en un archivo o VOB divididos en múltiples archivos al estilo DVD?
quack quijote
1
stackoverflow.com/questions/2017843/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

17

Esto es horrible, estúpido y lento, pero parece funcionar:

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

También funcionará correctamente en archivos truncados y secuencias sin procesar (es por eso que no obtiene nada para archivos .vob)

usuario23307
fuente
Eso es bastante bueno. En mi experiencia, no lleva tanto tiempo. Sin embargo, un archivo de 40 minutos tarda <3 segundos en ejecutarse. Recuerde que "^ M" no son los 2 caracteres ^ y M, debe presionar Control-V y luego ingresar. En lugar de su comando, utilicé: 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 Tu comando falla si no hay espacio después de "frames ="
Rory
1
En Ubuntu 12.04, versión ffmpeg git-2013-04-15-a4f03f0, puede omitir ambos | tr ^M '\n'y |tail -n 1. Además, no hay espacio después frames=no falla. (Tal vez algo ha cambiado en los últimos cuatro años.)
Camille Goudeseune
para mí este regreso cada vez valores diferentes
CAMOBAP
1
La solución Mediainfo funciona con VOB. Lo recomendaría en su lugar. root @ lanparty: / mnt / films # mediainfo --fullscan Bugs_Bunny.vob | grep -i frame \ count Conteo de cuadros: 175715 Conteo de cuadros: 183218
kevinf
32

ffprobe se puede usar para obtener información sobre un archivo multimedia:

ffprobe -select_streams v -show_streams input.avi

Obtendrá detalles sobre la transmisión:

nb_frames=159697

Busque nb_framescon grep:

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

Eso funciona para avi, mp4 y etc. Para algunos contenedores, no muestra un valor válido, por ejemplo, mpeg.

En ese caso, esto funciona ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l

Réplica
fuente
Buena idea. Modifiqué un poco el comando para que solo seleccione la transmisión de video y filtre la salida. Eso te da solo la cantidad de cuadros.
slhck
1
¡Felicitaciones por su segunda solución que funciona con MPEG-2!
malat
1
No funciona con contenedores MKV.
Cenk Alti
1
nb_frames = N / A en este archivo: web.archive.org/web/20180117220713/http://techslides.com/demos/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
Parece que el primer enfoque falla en los archivos codificados con VBR. El segundo enfoque es más confiable.
Élder Geek
16

Publiqué esto en otra pregunta . Usando la tcprobeherramienta (del transcodepaquete), el número de fotogramas se incluye en la información. Use el -iinterruptor para obtener un volcado de información del archivo:

$ 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

Tenga en cuenta que aquí se da el número de cuadros en dos líneas (segunda línea de salida y última línea de salida).

quijote curandero
fuente
Parece una buena respuesta y funciona para algunos archivos, pero para algunos archivos VOB que tengo, no tengo esos datos en la salida. He actualizado la pregunta con la salida que obtengo
Rory
Espero (pero no estoy seguro) que tcprobe esté examinando los encabezados de los archivos para esta información. Si no está incluido en el encabezado, es posible que tcprobe no intente calcularlo. buena pregunta; Ojalá tuviera una buena respuesta para ti.
quack quijote
Esto no parece funcionar en archivos codificados con VBR. No obtengo salida de conteo de cuadros. Obtengo resolución, relación de aspecto y velocidad de fotogramas.
Élder Geek
7

Descubrí que mediainfo --fullscan inputfile | grep "Frame count"funciona muy bien para la mayoría de los archivos.

Los sistemas basados ​​en Debian pueden instalarlo con apt-get install mediainfo

Si obtiene 2 líneas en lugar de una de salida, la primera línea es la pista de video y la segunda línea es la pista de audio. Parece que esto ocurre en archivos con audio de velocidad de bits variable.

Probado en muestras .mkv, .m4v, .mp4, flv, vob y .avi a la fecha de edición.

Fuentes: ¿Cómo recuperar la información del archivo de video desde la línea de comandos en Linux? y pruebas bajo los sabores de Ubuntu.

Puede encontrar mediainfo disponible para su sistema operativo aquí.

Elder Geek
fuente
4

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

Suma la duración. Podría ser más elegante con sed / awk y qué no.

De nuestras pruebas puedo decir que por ahora ha demostrado ser el mejor y más confiable. Obtiene un conteo de cuadros preciso y una duración exacta. Incluso con framerate variable que todas las otras herramientas como mediainfo parecen ir gaga.

Guillaume Blain
fuente
3

Descubrí que la cantidad de fotogramas es en realidad el doble de la duración de fps * (no sé por qué, me encantaría saberlo).

En un guión mío, tengo:

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

Y sí, por alguna razón tengo que obtener la parte entera. No tiene sentido, pero este script siempre ha logrado convertir mis videos correctamente hasta ahora.

Phaphink
fuente
Debido a que FPS significa cuadros por segundo (o tirador en primera persona: D) y si hay 30 FPS, simplemente multiplíquelo por cuántos segundos hay en el video.
John T
Sí, John, podría resolverlo, pero eso no explica por qué tengo que multiplicarlo por 2 para obtener la cantidad correcta de cuadros ... En mi caso, después de calcular la cantidad de cuadros, lancé ffmpeg en el fondo y analizó los registros para hacer una barra de progreso. Los registros muestran cuántos fotogramas han pasado en la conversión. Una vez que se convirtió todo el video, el frame # fue int (segundos * fps * 2), de ahí mi código, pero me gustaría saber por qué ;-)
--aphink
eso es curioso; el tcproberesultado en mi respuesta da el número de fotogramas como exactamente segundos * fps (redondeado hacia arriba). Espero que estés viendo un capricho de ffmpeg. ¿Has intentado analizar el archivo con otras herramientas para ver si muestran la misma cantidad de fotogramas?
quack quijote
Hmmm ... interesante. Probé un video y obtuve seconds*fps=1001.59y tcprobe=1002. Entonces, obviamente, tcprobeme dice que no necesito multiplicar por dos. ¿Por qué entonces ffmpeg me da un número que es dos veces mayor en los registros cuando se está convirtiendo?
phaphink
2
¿Es metraje entrelazado? Si es así, hay dos campos por cuadro, y podría darte la cantidad de campos.
stib
3

Probado en Ubuntu.

melt icecap.mp4 -consumer xml
  • melt- melt fue pensado como una herramienta de prueba para el marco MLT, pero también es un potente editor de video orientado a la línea de comandos multipista. También podría usarse como un reproductor multimedia minimalista para archivos de audio y video.

  • -consumerid [: arg] [nombre = valor] *
    Establecer el consumidor (sumidero)

  • xml - Establezca el consumidor (sumidero) en salida con formato xml

  • <property name="length">nnnn</property>- muestra el número de cuadros, donde nnnnse reemplaza por un número entero que es igual al número de cuadros

Si no tiene melt, puede instalarlo en Ubuntu y otros sistemas basados ​​en Debian con sudo apt-get install melt

neoneye
fuente
1
Esto es muy corto, ¿desea ampliar lo que hace, por qué funciona, etc.?
David
Esto funciona bien en archivos h264 mp4 que no proporcionan el número de cuadros a través de mediainfo -fullscan filename.
Élder Geek
3

Directamente con mediainfo, sin grep, sin esperas, sin nada:

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

Para otra información ver mediainfo --info-parameters

xenoide
fuente
0

Puede hacerlo agregando y multiplicando los valores que obtiene de ffprobe.

Nota: ffprobe es parte de libav (avconv), la versión para Linux de ffmpeg.

#your command -
 ffprobe man.avi

Cuando haga esto, obtendrá el número de fotogramas por segundo y también la duración del clip.

Convierta la duración del clip a segundos y multiplique ese valor por el número de cuadros / segundo.

Recuerde redondear el número al más cercano.

JJAtairu
fuente
En Ubuntu 14.04 LTS ffprobeno está disponible, pero hay algo que se llama avprobeen libav-tools(que también proporciona avconv). Pero a mi lado no imprime ningún número de cuadros, al menos no para los formatos que probé. Simplemente imprime, lo que avprobe -iimprime también, y esto es solo algunas partes menores sobre el formato, lamentablemente. Incluso con -v debugeso, solo me da algunas buenas propiedades de mi hardware y software instalado, pero ni una sola información interesante sobre el archivo / flujo a sondear. Tal vez se esconde en algunas de las innumerables opciones disponibles. ¿Quién sabe?
Tino
@Tino ffprobe está disponible como parte del paquete ffmpeg. avconv es una bifurcación de ffmpeg y causó cierta confusión. Ver: stackoverflow.com/questions/9477115/…
Elder Geek
@ElderGeek Para Ubuntu 14.04 LTS no hay ffmpegen los repositorios oficiales. El enlace que proporcionó correctamente lo indica: FFmpeg regresó en Ubuntu 15.04 "Vivid Vervet". . Sin embargo, la situación ahora cambió ya que 16.04 LTS está fuera.
Tino
@Tino Eso es un hecho. Sin embargo, no igualaría que no esté disponible con no existe en los repositorios. Notarás
Elder Geek
0

linux

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

rubí

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

El mejor método: (Directo calculando los parámetros correctos, confirmado por 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"

Resultado ->

r_frame_rate=24000/1001
duration=8177.794625

Cálculo ->

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

Prueba ->

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

aquí

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

Salida

video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
shareeditdeleteflag
Gerard Wensink
fuente
Obtengo r_frame_rate = 25/1 duración = N / A
Elder Geek