Establecer el tiempo de visualización de fotogramas individuales en FFmpeg

Tengo un conjunto de imágenes que extraje de una animación GIF con el fin de mejorarlas (lo que hice), pero ahora que es el momento de convertir las imágenes fijas en un video (voy a usar webm para una salida de mayor calidad ) Me he encontrado con un problema. El formato GIF permite que se muestren fotogramas individuales durante una cantidad de tiempo artificial y esta animación GIF específica utiliza esa función, y la mayoría de los fotogramas se muestran durante 125 milisegundos, pero algunos permanecen en la pantalla hasta 3000 milisegundos. Entonces, solo generar un video con una velocidad de cuadro establecida no funcionará, ya que rompería el flujo de la animación; Necesito una forma de importar los datos de duración del cuadro del archivo GIF original y codificar los cuadros modificados y extraídos en un video usando esos datos.

¿Hay alguna manera de hacer esto con FFmpeg o tal vez una combinación de FFprobe y FFmpeg? Ejecuté el GIF ffprobe -show_framesy parece que la información que necesito es pkt_duration_timela que muestra la duración del cuadro.

@Gyan Gracias por señalarme en la dirección correcta. Publiqué una respuesta a mi pregunta a continuación.

Respuestas (1)

Me llevó bastante tiempo buscar en Google y hacer pruebas y errores, pero finalmente descubrí cómo hacer esto. Gracias a Gyan por señalarme en la dirección correcta.

Traté de hacer más del proceso como frases ingeniosas, pero siempre se convirtió en un desastre no funcional y no depurable. Si cree que podría escribir esto, hágalo, pruébelo y luego publíquelo como una nueva respuesta.


Imprima pkt_duration_timela línea y guárdela en un archivo:

ffprobe -show_frames input.gif | grep pkt_duration_time= >frames.txt

Modifique la línea al formato que requiere el filtro concat de FFmpeg:

sed 's/pkt_duration_time=/duration /g' frametimes.txt >frametimes.txt

Imprima una lista de sus archivos de entrada (marcos) ubicados folder/y modifique la lista para que tenga el formato que requiere el filtro concat de FFmpeg:

ls --quoting-style=shell folder/ >filenames.txt && sed -i -e 's/^/file /' filenames.txt

Combine su archivo de tiempo de fotogramas y el archivo de nombres de archivos en un archivo concat que acepte FFmpeg:

paste -d \\n filenames.txt frametimes.txt > folder/concatfile.txt

Guardamos el archivo concat donde se encuentran los archivos de entrada porque, de lo contrario, FFmpeg no lo aceptará. Una cosa más antes de que podamos codificar el video: los datos del último cuadro deben estar presentes en el archivo concat dos veces por alguna razón. No tengo una CLI para eso, así que simplemente copie y pegue manualmente.

Ahora podemos usar FFmpeg para convertir los archivos de imagen en un video animado con los tiempos de cuadro correctos:

cd folder/

ffmpeg -f concat -safe 0 -i concatfile.txt -pix_fmt yuv420p -c:v libvpx-vp9 -b:v 0 -cpu-used 0 -tile-columns 2 -row-mt 1 -lag-in-frames 25 -threads 16 -crf 35 ../output.webm

  • El -safe 0cambio es necesario porque, de lo contrario, FFmpeg se queja de los nombres de archivo no seguros. Al menos lo hizo en mi caso, posiblemente porque los nombres de los archivos contenían corchetes.

  • El -pix_fmt yuv420pgarantiza que se utilice el espacio de color correcto. Si omite esto, se usará un espacio de color que no es estándar para video web y, en el caso de VP9, ​​el archivo resultante usará el Perfil 1, que no tiene un soporte de decodificación de hardware tan amplio como el Perfil 0. Podría usar -profile:v 0para Asegúrate de que esto no suceda sin que te des cuenta.

El resto de los parámetros son funciones de control de calidad y velocidad para libvpx-vp9. Recuerde usar al menos -b:v 0, de lo contrario, CRF no se comportará como cabría esperar. También tenga en cuenta que se requiere configurar -tile-columnsy -threadsmanualmente, de lo contrario, la codificación se limita a un solo hilo.