¿Cómo extraer un fotograma de un video cada N segundos a una imagen?

71

¿Cómo puedo convertir un archivo de video en una secuencia de imágenes, por ejemplo, un cuadro cada N segundos? ¿Puede mplayer o ffmpeg hacer esto? He usado MPlayer para tomar capturas de pantalla manualmente, pero me gustaría automatizar esto para un video largo.

Liam
fuente
Consulte esta pregunta relacionada sobre cómo elegir la calidad de las imágenes: stackoverflow.com/questions/10225403/…
Pierz,

Respuestas:

70

Es muy simple con ffmpeg, y puede generar un cuadro cada N segundos sin secuencias de comandos adicionales. Para exportar como una secuencia de imágenes, simplemente use myimage_%04d.pngo similar como la salida. El %0xdbit se convierte en un número entero de xdígitos rellenos con ceros de largo: el ejemplo que proporcioné se muestra como

  • myimage_0000.png,
  • myimage_0001.png,
  • myimage_0002.png

    etc.

Puede usar muchos formatos de imágenes fijas, png, jpeg, tga, lo que sea (consulte ffmpeg -formatsla lista completa).

Bien, ahora sabemos cómo exportar la película como una secuencia de imágenes, pero ¿no queremos exportar cada fotograma?

El truco es simplemente cambiar la velocidad de fotogramas de la salida a lo que queramos usando la -r nopción donde nestá el número de fotogramas por segundo. Sería 1 cuadro por segundo, sería -r 1un cuadro cada cuatro segundos, sería -r 0.25un cuadro cada diez segundos -r 0.1y así sucesivamente.

Entonces, para ponerlo todo junto, así es como se vería guardar un fotograma de input.movcada cuatro segundos output_0000.png, output_0001.pngetc.

ffmpeg -i input.mov -r 0.25 output_%04d.png

Tenga en cuenta que la -r 0.25opción va después de la -i input.movparte, porque controla la velocidad de fotogramas de la salida . Si lo coloca antes de la entrada, trataría el archivo de entrada como si tuviera la velocidad de fotogramas especificada.

Cambie el% xd a la cantidad de dígitos que necesite, por ejemplo, si el comando crearía más de 10,000 cuadros, cambie el %04da %05d. Esto también funciona para archivos de entrada que son secuencias de imágenes. Lee más aquí .

Usuarios de Windows : en la línea de comando, use%

ejemplo: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

En las secuencias de comandos CMD y BAT, use %%

ejemplo: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Entonces, doble %%en los scripts y solo %en la línea de comandos interactiva. Hacerlo mal en cualquier situación generará un error.

stib
fuente
¿Qué debo poner -rsi quiero exportar cada cuadro? Si conozco el FPS del video, supongo que lo ingreso, pero ¿y si no lo hago?
Tomáš Zato
44
No use la bandera -r en absoluto. Entonces FFMPEG usará la velocidad de fotogramas del archivo de entrada.
stib
2
Tenga en cuenta que realmente querrá usar jpegsesto, a menos que esté seguro pngde que es lo que quiere. En mi caso, los jpegs tenían unos 50 kb cada uno, y los pngs tenían unos 2 MB.
mlissner
55
La ventaja de pngs es la compresión sin pérdidas, por lo que si está utilizando la secuencia de imágenes como un intermedio y no le importa el tamaño extra, entonces es cuando podría usar png.
stib
Vale la pena añadir que -q:v 1es una opción muy útil en este caso como en superuser.com/questions/318845/...
Nikolay Shmyrev
27
mplayer -vo jpeg -sstep 5 file.avi

guardará un marco como un archivo jpeg cada 5 segundos.

Sin embargo, no se detendrá al final del archivo, continuará produciendo copias del último fotograma. Para evitar esto, encuentre la duración del video en segundos, utilizando otro reproductor o con mplayer:

mplayer -vo null -ao null -frames 0 -identify file.avi

y busque una línea como "ID_LENGTH = 147.00".

Resta 2 de la longitud y usa este valor para la -endposopción. Por ejemplo, para un video de 147 segundos:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi
Liam
fuente
esto suena como un error de mplayer. Buena solución.
quack quijote
¿Podría al menos mencionar en qué sistema operativo está utilizando este comando?
Tomáš Zato
Fue hace 5 años, pero probablemente era el último escritorio de Ubuntu en ese momento, Ubuntu 10.4.
Liam
¿Cómo puedo elegir pasos más cortos que 1s? Solo acepta enteros.
fcpenha
Hoy en día, mpv --vo=image --sstep=5 movie.mkvfunciona muy bien sin el error antes mencionado ( mpv es una bifurcación de mplayer) usando mpv 0.27.0 en Debian.
Adam Katz
11

Con ffmpeg, puede hacer lo siguiente:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

Este comando genera una miniatura de JPG de 320 × 240 en el cuarto segundo del video. Ponga esto en un script que cambie la hora y el nombre del archivo y ya está.

Más información: cree una imagen en miniatura cada X segundos del video

Nifle
fuente
Esto parece hacer lo que quiero, pero con un problema. Procesará el archivo desde el principio en cada iteración, volviéndose exponencialmente lento.
Liam
@Liam: ¿ayuda si deja solo el tiempo de compensación (configúrelo en 1) y use la -ss positionbandera para buscar más en el archivo? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle
1
@liam: pon el -ssantes del -ipara que la búsqueda ocurra antes de que el video de entrada se decodifique. Esto debería acelerarlo. fuente
quijote quack
2
Hay una manera mejor y mucho más rápida de hacerlo con ffmpeg. Vea mi respuesta a continuación.
stib
La solución de stib es la mejor OMI.
Griffin
8

Si buscas una especie de hoja de contactos y estás trabajando con un sistema operativo tipo Unix, puedes usar este elaborado script, llamado al punto Video Contact Sheet * NIX , short vcs .

En segundo plano, también usa ffmpeg(por defecto) o mplayer, por lo tanto, puede manejar muchos formatos de video. Automatiza el proceso de capturar imágenes fijas de la película y las compone en una imagen con algún encabezado y pie de página. Puede elegir, por ejemplo, cuántas capturas desea o, alternativamente, las diferencias de tiempo entre ellas.

Para un intervalo de 10 minutos, la invocación es así:

vcs -i 10m input.avi

Consulte la lista completa de opciones de línea de comandos para otros ajustes.

Aquí hay un ejemplo de hoja de contacto, tomada de la página de inicio :

ingrese la descripción de la imagen aquí

mpy
fuente
7

Con VLC 1.1.0 y superior, puede usar el filtro de video de escena:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

Lo anterior guarda 1 de cada 24 cuadros (--scene-ratio = 24), comenzando a las 00:00:10 y terminando a las 00:00:11.

Acabo de probar y confirmar que esto funciona con VLC 2.0.3 en una nueva instalación de Windows 8 (no tengo complementos de video o software adicionales).

Documentación completa: http://wiki.videolan.org/How_to_create_thumbnails

Miguel
fuente
2

VirtualDub puede hacer esto por ti

File-> Export->Image sequence

ingrese la descripción de la imagen aquí

Shevek
fuente
¿Esto guardará cada cuadro como una imagen?
Liam
Sí, cada cuadro.
Shevek
Necesito omitir la mayoría de los cuadros, la salida de todos los cuadros usará demasiado espacio de almacenamiento. Solo necesito un cuadro cada pocos segundos.
Liam
1

También puedes probar esto

desde la línea de comando VLC ...

vlc "C: \ YOUR \ file \ path \ file.avi" -V imagen --image-out-prefix = capname --image-out-ratio = 60

file.avi es el video que desea capturar, capname es el prefijo de las imágenes guardadas, es posible que desee jugar con la proporción (60 significa que se captura 1 de 60 imágenes) Puede agregar más comandos, por ejemplo --image-out-format jpeg guardará sus mayúsculas como jpegs en lugar de pngs, --snapshot-path le permite elegir dónde guardar sus mayúsculas.

Fuente de arriba

Nifle
fuente
Recibí este mensaje: no se pudieron cargar las opciones de la línea de comandos, verifique que sean válidas.
Liam
En Ubuntu, recibí este mensaje: opción desconocida o falta el argumento obligatorio `--image-out-prefix = capname '
Liam
1

Puede omitir marcos en VirtualDub. Simplemente use la opción "Decimate By" ubicada en el menú Video -> Frame Rate. Por ejemplo, si configura "Decimar por 100", utilice Archivo -> Exportar -> Secuencia de imagen, guardará solo cada 100 cuadros.

Alex
fuente