Uno de los mejores compañeros de viaje de ImageMagick a la hora de procesar vídeo es ffmpeg.
ffmpeg es un programa de edición de vídeo que permite, desde la línea de comandos crear vídeos, editarlos, extraer el audio, combinar una pista de audio y otra de vídeo generadas individualmente en una mismo fichero... Tiene todas las funcionalidades de cualquier programa de edición de vídeo (la mayoría de los programas de edción de vídeo en modo gráfico se basan en ffmpeg para procesar vídeos y lo que hacen es que visualmente sea un poco más amigable) con la ventaja de ser en modo consola, por lo que permite automatizar procesos y usarlo en scripts, como contrapartida, es un poco farragoso de usar y no tan cómodo de trabajar como Kdenlive, OpenShot, Pitivi u otro programa gráfico.
Pero ahora vamos a ver cómo sacarle mucho partido en combinación con ImageMagick descomponiendo un vídeo en fotogramas para poder procesar individualmente cada uno de ellos con IM, componiendo una serie de fotogramas en vídeo y generando un vídeo al vuelo en un script sin tener que almacenar los fotogramas en el disco y luego generar el vídeo que, como comenté al explicar qué son convert y mogrify, muchas veces nos genera un gran quebradero de cabeza cuando hacemos un vídeo procesando uno a uno los fotogramas con ImageMagick.
Descomponer un vídeo en fotogramas
Para descomponer en fotogramas un vídeo le tenemos que indicar a ffmpeg el fichero de entrada con -i y los ficheros de salida con, al igual que cuando generamos nuevas imágenes con crop, el formato de salida se lo daremos con un prefijo, el indicador del formato del numeral con % y la extensión del fichero. Algo así como:
ffmpeg -i video.mp4 fotograma%04d.png
Lo que nos generará es una serie de fotogramas que se llamarán fotograma0001.png, fotograma0002.png... ya que le hemos indicado:
- Un prefijo según un patrón. En este caso "fotograma"
- Que añada un número correlativo en cada fotograma de cuatro dígitos (%04d)
- Un formato. En este caso, al indicarle la extensión .png generará los fotogramas en formato PNG.
Componer un vídeo a partir de una secuencia de imágenes
Del mismo modo que podemos descomponer en fotogramas un vídeo, podemos componer un vídeo a partir de fotogramas. Para que el vídeo tenga el orden correcto de fotogramas, lo mejor es que sigan el patrón que he comentado antes: el mismo prefijo, números correlativos y con la misma cantidad de dígitos y la misma extensión. Esto no es obligatorio, ya que podríamos indicarle que generase un vídeo, por ejemplo, con todos los pngs de un directorio (*.png), pero molesta mucho ver cómo un vídeo que has tardado horas en renderizar falla el orden de algún fotograma simplemente por no haber nombrado con un patrón claro los fotogramas. Así que haremos las cosas bien y seremos más felices:
ffmpeg -i fotograma%04d.png video.mp4
En general, con este comando genera un vídeo a partir de los fotogramas, aunque, como digo, si le decimos exactamente cómo queremos el vídeo, lo hará exactamente como queremos. Así que le podemos añadir alguna opción para que haga el vídeo a nuestro gusto:
-r $fotogramasporsegundo
: con la opción -r le indicamos el ratio de fotogramas por segundo que queramos que tenga el vídeo.
-s $anchuraX$altura
: con -s indicamos el tamaño del vídeo
-aspect $ancho:$alto
: el aspecto del fotograma, por ejemplo, 16:9. Opción que la inico aquí más a modo de curiosidad que por practicidad, ya que si le indicamos el tamaño, le estamos indicando el aspecto.
-c:v $codecdevideo
: con -c:v le indicamos el códec de vídeo con el que queremos que renderice el vídeo (Nota: -c:a es para audio -c:v es para vídeo)
-pix_fmt $formatodelpixel
: -pix_fmt permite seleccionar el formato de píxel. Podemos ver todos los formatos seleccionados con ffmpeg -pix_fmts que nos muestra el nombre de formato de píxel, los bits por píxel de ese formato y los componentes NB (el número de componentes de una imagen, por ejemplo, los tres canales RGB).
Componer al vuelo un vídeo a través de los fotogramas generados
Para componer un vídeo al vuelo a través de fotogramas generados en un script con convert, le debemos indicar a convert en lugar de un nombre de fichero, que los codifique como png:- y a ffmpeg, que recoja los ficheros con image2pipe. Quedaría algo así:
#!/bin/bash
for i in $lista
do
convert imagen.png -$parametro $valor png:-
done | ffmpeg -f image2pipe -i - video.mp4
Aquí también le podemos indicar a ffmpeg los valores que deseemos para ajustar su trabajo a nuestras necesidades.
Nota: Gracias a Gaspar Fernández (https://poesiabinaria.net) por sus indicaciones con image2pipe.