Conversión de marcos PNG a video a 1 FPS

21

Tengo cuadros de video en formato PNG a 1 FPS y estoy tratando de convertirlos en un video usando ffmpeg.

Si hago algo como esto:

ffmpeg -i data/input-%4d.png data/output.mp4

Obtengo un video a 25FPS, que es básicamente un avance muy rápido de la entrada (que se captura a 1FPS).

Si lo intento:

ffmpeg -i data/input-%4d.png -r 1 data/output.mp4

Me sale algo que VLC no quiere jugar :)

Ahora, si tomo el primer video (el FF) y aplico un filtro para ralentizarlo (por ejemplo -filter:v 'setpts=24.0*PTS'), puedo hacer que se reproduzca como un video de 1 FPS, pero, por supuesto, el precio es el tamaño del archivo. Está generando un montón de cuadros repetidos, supongo.

Entonces, la pregunta es ¿cómo creo un video que tiene exactamente 1 FPS y realmente se reproduce a esa velocidad? El formato de salida, por cierto, no es tan importante para mí.

Assaf Lavie
fuente
No estoy seguro ffmpeges lo suficientemente inteligente como para saber el códec de vídeo sólo de la extensión del archivo de formato contenedor, .mp4. Intente agregar -vcodec libx264 -vpre hqa la línea de comando, para indicarle el códec y los parámetros de codificación.
Warren Young
En realidad lo resolvió bien, y como mencioné, funcionó bien y solo produjo resultados extraños cuando agregué -r 1.
Assaf Lavie
Creo que puede tener mejor suerte con una respuesta de ffmpeg en stackoverflow.com o superuser.com .
Damien

Respuestas:

19

Si desea una línea para FFMPEG que genere un video que se reproduce a 1 fotograma por segundo, lo que desea hacer es especificar la velocidad de fotogramas para la entrada y la salida, de esta manera:

ffmpeg -r 1 -i datos / entrada-% 4d.png -pix_fmt yuv420p -r 10 datos / salida.mp4

Esto -r 1significa que el video se reproducirá a 1 de las imágenes originales por segundo.
Esto -r 10significa que el video se reproducirá a 10 cuadros por segundo.

(El -pix_fmt yuv420psolo está ahí para garantizar la compatibilidad con una amplia gama de programas de reproducción. Se requiere aquí, por ejemplo, para que el reproductor de Windows Media pueda reproducir el video).

Probé muchas velocidades de fotogramas de salida diferentes, y 10 parece ser el número más bajo que puede usar que todavía producirá un video que reproducirá VLC.

Por supuesto, el comando anterior significa que cada imagen original se está multiplicando, pero es un método más simple que el "ralentizar" que mencionó, y dependiendo del códec puede no producir un video mucho más grande que un verdadero 1-FPS vídeo.

Para probar esto, acabo de producir un verdadero video de 1 FPS, que salió a 2.24 kiB. Luego produje un video con las mismas imágenes de entrada pero salida a 24 FPS, y salió a 5,76 kiB. Eso es un poco más del doble del tamaño, y no se acerca a 24 veces el tamaño. :)

A.M
fuente
+1 en -pix_fmt. Fácil de olvidar, algunas personas insisten en usar WMP :-)
Smalltown2k
¿por qué querrías que el formato de salida sea 10 fps mientras que la entrada es solo 1? ¿No crearía 90% de marcos redundantes que son exactamente iguales?
Herbert
@Herbert crea fotogramas redundantes para que pueda obtener una velocidad de fotogramas de hasta 10, lo que se hace solo para que VLC no se queje , y visualmente no cambia el video. El codificador es lo suficientemente inteligente como para ver que los marcos son todos idénticos, por lo que no terminas con un archivo mucho más grande
chiliNUT
@chiliNUT claro, lo de los fotogramas clave, que no todos los formatos, pero la mayoría de los formatos sanos harán. ¡Gracias!
Herbert
5

Use ambos -frameratey-r

Por ejemplo, para tener un video final que se parece a 1FPS:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
    -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Esto es similar a lo que es convertir cuadros PNG a video a 1 FPS | Unix & Linux Stack Exchange dice, pero necesitaba en -frameratelugar de -rque funcione.

Esto se menciona en la wiki en: http://trac.ffmpeg.org/wiki/Slideshow#Framerates

Establece la velocidad de fotogramas de salida 30, que VLC puede manejar, y copia cada imagen 30 veces, de modo que el video de salida parece estar a 1 FPS. Ver también: Problemas de reproducción en VLC con video de baja fps de imágenes usando ffmpeg | Desbordamiento de pila

VLC puede reproducir el video normalmente.

Probado en Ubuntu 16.10, VLC 2.2.4, ffmpeg3.0.5, en un directorio con 10 PNG.

Ver también: /programming/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente
¿Cuál es la diferencia entre -ry -framerate?
Royi
@Royi Realmente no lo sé, excepto que es lo único que funcionó para mí :-) Pero si lograste extraerlo de las manpáginas, avísame ;-) Una cita significativa es "-r Como un Opción de entrada, ignore las marcas de tiempo almacenadas en el archivo y, en su lugar, genere marcas de tiempo suponiendo una velocidad de fotogramas constante fps. Esto no es lo mismo que la opción -framerate utilizada para algunos formatos de entrada como image2 o v4l2 (solía ser la misma en versiones anteriores de FFmpeg). En caso de duda, utilice -framerate en lugar de la opción de entrada -r ".
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3

¿Qué pasa si aumenta su segundo ejemplo ligeramente de la siguiente manera:

$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4

La -r 1necesidad de venir antes de los archivos .png, no después.

De la documentación de FFmpeg :

Como regla general, las opciones se aplican al siguiente archivo especificado. Por lo tanto, el orden es importante y puede tener la misma opción en la línea de comando varias veces. Cada ocurrencia se aplica al siguiente archivo de entrada o salida.

slm
fuente
Por desgracia, esto no funciona. Sin embargo, mencionar que el pedido es importante me ahorró mucho tiempo. Gracias.
Mohammed Noureldin
0

Este es un error en VLC (que todavía existe en la versión 3.0.6). Después de algunos experimentos, me di cuenta de que VLC se bloquea para videos con FPS de menos de 10 . Entonces, todos los videos con 10 FPS o más no deberían ser un problema. Por lo tanto, actualmente no hay una forma limpia de obtener un video con 1 FPS que se pueda reproducir en VLC ( no te rindas, sigue leyendo ).

Una solución alternativa es, como se muestra en la respuesta anterior, simular el efecto de 1 FPS duplicando las imágenes (cuando en realidad tenemos un FPS igual a 10 o más, lo cual está bien para VLC).

Ejemplo: si tiene una carpeta con 12 imágenes y desea generar un video con 1 FPS (que se puede reproducir en VLC), debe duplicar cada imagen varias veces (digamos 10 veces) y luego decirle a FFMPEG para generar un video de 10 FPS. De esta forma, obtendremos un video con un total de cuadros de 120, donde cada imagen se reproducirá durante 1 segundo (ya que se duplica 10 veces), lo cual es simplemente falso para 1 FPS.

Prefiero usar el fpsparámetro en lugar de-r (que se muestra en otra respuesta), que en algunos casos puede ser problemático (de acuerdo con la documentación oficial ).

ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv

Como la entrada -frameratees más baja que la salida fps, FFMPEG duplicará fotogramas para alcanzar la velocidad de fotogramas de salida deseada (que es 10 según el comando anterior).

También es importante notar que el orden de -frameratey -vf fpses importante , ya que esta configuración se aplicará al siguiente video (entrada o salida) mencionado. Eso es de acuerdo con los documentos oficiales :

Las opciones se aplican al siguiente archivo especificado. Por lo tanto, el orden es importante ...

Mohammed Noureldin
fuente