Hemos hecho un vídeo que no tiene sonido a partir de imágenes generadas con ImageMagick, o a partir de una única imagen, o hemos concatenado vídeos con ffmpeg o... sea como sea, resulta que tenemos un vídeo sin audio.

Y queremos que tenga audio para que sea más agradable su visionado.

Pero hay veces que nos ha salido un vídeo más largo, otras veces más pequeño... generalmente, al montar un vídeo no sabemos antes de empezar la duración exacta de dicho vídeo. Y si lo hemos hecho automáticamente con scripts, menos. Así que queremos vacilar de ser hackers de ImageMagick, deberemos de buscar, de forma automática, una canción que dure exactamente lo mismo que el vídeo.
Y aquí viene de nuevo vinfo.sh a ayudarnos. Y youtube-dl también puede ayudarnos mucho, ya que podemos buscar canciones con licencia creative commons en YouTube y descargarlas en un directorio. Y usarlas justo en el momento que coincida su duración con la duración del vídeo que acabamos de hacer.

¿Vemos cómo?

Aquí está el código, bastante autodescriptivo si has leído los anteriores artículos. Pero con una salvedad: si los nombres de las canciones, o de cualquier otro fichero puede que contenga espacios vacíos, deberemos cambiar el separador de campo.

#!/bin/bash
 
# Script que recibe un vídeo como parámetro
# calcula su duración y busca en un directorio
# una canción que coincida en duración 
# y lo anexa. 
# Para mantener el nombre original el script
# creará una copia temporal que luego borrará. 
# Para poder enlazar la canción y referenciar 
# al autor, acabará el script escribiendo 
# el nombre del fichero de la canción. 
 
directoriocanciones="instrumentales"
 
# Cambia el separador de campo
IFS='
'
 
# Extrae el nombre del fichero 
# y la extensión del fichero pasado como parámetro
sinextension=${1%.*}
extension=${1##*.}
 
# Calcula la duración del audio del fichero pasado como argumento
duracion=$(./vinfo.sh duration $1)
duracionneta=${duracion:0:8}
 
echo "La duracion del video es "$duracion
 
# Crea el fichero temporal y borra el antiguo
 
nuevofichero=$sinextension"-temp."$extension
 
echo "El nuevo fichero será: "$nuevofichero
 
# Busca una canción en el directorio de canciones
# que tenga la misma duración que el vídeo
 
for i in $(ls $directoriocanciones)
do
    duracioncancion=$(./vinfo.sh duration "$directoriocanciones/$i")
    duracionnetacancion=${duracioncancion:0:8}
        echo "duracion video: "$duracionneta
        echo "duracion cancion: "$duracionnetacancion
        echo "cancion: "$i
 
    if [ "$duracionneta" = "$duracionnetacancion" ]
    then
 
        ffmpeg -i $1 -i "$directoriocanciones/$i" -c:v copy -c:a copy $nuevofichero
        rm $1
        mv $nuevofichero $1
        rm $nuevofichero
        echo $i
        break
    fi
done
Publicado en Multimedia

Concatenar vídeos con ffmpeg no da siempre los resultados esperados, depende de la versión, de los codecs instalados y varios factores que pueden hacer que el script que en un equipo funciona perfectamente, en otro ordenador no funcione tan bien.

Lo que nunca falla es ImageMagick -sic-. Así pues, voy a comentar un script que funcionaría, o debería funcionar, en todos los sistemas:

El objetivo es el mismo que el del artículo sobre cómo componer vídeos con fotografías y sonido:

Un script que reciba un fichero de audio como parámetro, por ejemplo un podcast, aunque podría ser cualqueir otro fichero de audio, con una duración variable y que se genere un vídeo con unos elementos básicos para un vídeo de YouTube:

  • Entradilla
  • Una imagen principal que se intercale con una cartela con las redes sociales o cualquier otra imagen, por ejemplo, una llamada a la acción de suscribirse al canal o cualquier otra imagen.
  • Pantalla final

 La imagen de la llamada a la acción o las redes sociales podría ser también una animación o una secuencia de vídeo. Su adaptación simplemente sería cambiar la imagen fija por un vídeo y copiar la parte de la entradilla. De hecho, si he combinado vídeo con imagen fija ha sido precisamente para que este script pueda ser germen para otras adaptaciones.

Y, de paso, ver en acción el contenido explicado en otros artículos:


La explicación del código está en estos artículos. El resto, en los comentarios del script:

 

 #!/bin/bash

function numerodesegundos()
{
    
    let horasdeaudio=${1:0:2}
    let minutosdeaudio=${1:3:2}    
    let segundosdeaudio=${1:6:2}
    
    echo $[ ($horasdeaudio*60*60) + ($minutosdeaudio*60) + $segundosdeaudio ]
}

function compruebaentradilla()
{
# Comprueba si la entradilla tiene su directorio
# y están los fotogramas desmontados ahí.
#
# Si no lo está, crea el directorio y
# desmonta los fotogramas de la entradilla

if [ ! -d $directorioentradilla ]
then
    mkdir $directorioentradilla
    ffmpeg -i $entradilla $directorioentradilla/fotograma%04d.png
else
    let contenido=$(ls $directorioentradilla | wc -l)
    if [ $contenido -eq 0 ]
    then    
        ffmpeg -i $entradilla $directorioentradilla/fotograma%04d.png
    fi
fi

fotogramasentradilla=$(ls $directorioentradilla | wc -l)
echo $fotogramasentradilla
}

# Extrae el nombre del fichero de audio pasado como parámetro quitando la extensión
sinextension=${1%.*}

# Calcula la duración del audio del fichero pasado como argumento
duracion=$(./vinfo.sh duration $1)


# Ficheros auxiliares
entradilla="entradilla.mp4"
directorioentradilla="entradilla"
imagenprincipal="fondopodcast.png"
redessociales="redessociales.png"
pantallafinal="pantallafinal.png"


# Calcula la duración en segundos del audio y el número de fotogramas necesarios para el vídeo
segundosdeaudio=$(numerodesegundos $duracion)
let totalfotogramas=$segundosdeaudio*24

fotogramasentradilla=$(compruebaentradilla)

# Calcula la duración de la entradilla
duracionentradilla=$(./vinfo.sh duration $entradilla)
segundosentradilla=${duracionentradilla:6:2}

# Calcula cuánto duran los contenidos extras con dos cortes para la cartela de redes sociales

let duracionextras=$segundosentradilla+5+5+20

# Calcula la diferencia entre los segundos de audio del fichero parámetro y los extras

let tiempototalarellenar=$segundosdeaudio-$duracionextras

# Como vamos a hacer dos cortes para la cartela de redes sociales, divide el tiempo entre 3

let tercio=$tiempototalarellenar/3
let fotogramastercio=$tercio*24

##############################################################################
#
# Los bloques de imágenes quedarán así:
# Entradilla -> del fotograma 1 hasta que se acaben los fotogramas de la entradilla
# Imagen Principal -> desde último fotograma entradilla + 1 hasta un tercio de los fotogramas restantes más
# Cartela Redes Sociales: 5 segundos x 24 fotogramas = 120 fotogramas
#
# Nuevo bloque de: Imagen principal + cartela redes sociales + imagen principal
# Este bloque hay que repetirlo a mano, con un while que compruebe los bloques
# no funciona el convert imagen.png png:- para pasárselo a ffmpeg
#
# Pantalla final: 20 segundos x 24 fotogramas = 480 fotogramas
#
##############################################################################

contador=1
let fotogramasredessociales=120
let fotogramaspantallafinal=480

# Calcula los finales de los bloques:

let finprimerbloque=$fotogramasentradilla+1+$fotogramastercio
let finsegundobloque=$finprimerbloque+1+$fotogramastercio
let fintercerbloque=$finsegundobloque+1+$fotogramasredessociales
let fincuartobloque=$fintercerbloque+1+$fotogramastercio
let finquintobloque=$fincuartobloque+1+$fotogramasredessociales
let finsextobloque=$finquintobloque+1+$fotogramastercio
let finseptimobloque=$finsextobloque+1+$fotogramaspantallafinal

for i in $(seq 1 $totalfotogramas)
do
    if [ $contador -le $fotogramasentradilla ]
    then
        imagen=$(ls $directorioentradilla | head -n $contador | tail -n 1)
        let contador++
    elif [ $contador -gt $fotogramasentradilla ] && [ $contador -le $finprimerbloque ]
    then
        imagen=$imagenprincipal
        let contador++
    elif [ $contador -gt $finprimerbloque ] && [ $contador -le $finsegundobloque ]
    then
        imagen=$redessociales
        let contador++
    elif [ $contador -gt $finsegundobloque ] && [ $contador -le $fintercerbloque ]
    then
        imagen=$imagenprincipal
        let contador++
    elif [ $contador -gt $fintercerbloque ] && [ $contador -le $fincuartobloque ]
    then
        imagen=$redessociales
        let contador++
    elif [ $contador -gt $fincuartobloque ] && [ $contador -le $finquintobloque ]
    then
        imagen=$imagenprincipal
        let contador++
    elif [ $contador -gt $finquintobloque ] && [ $contador -le $finsextobloque ]
    then
        imagen=$imagenprincipal
        let contador++
    elif [ $contador -gt $finsextobloque ] && [ $contador -le $finseptimobloque ]
    then
        imagen=$pantallafinal
        let contador++
    fi

    convert $imagen png:-
done | ffmpeg -f image2pipe -i - pistadevideo.mp4

ffmpeg -i pistadevideo.mp4 -i $1 -c:v copy -c:a copy $sinextension.mp4
rm pistadevideo.mp4

 

 

Publicado en Multimedia

Si queremos hacer un vídeo con una imagen fija y un audio, por ejemplo, para subir un podcast a YouTube, una opción sencilla es que lo haga ffmpeg directamente:

ffmpeg -loop 1 -y -i imagen.png -i podcast.mp3 -shortest video.mp4

Quizá nos de pereza escribirlo siempre, máxime si para hacer el mp3 del podcast hemos utilizado una cadena larga para el nombre con palabras clave para ser encontrados en el buscador de YouTube y no somos excesivamente aficionados al tabulador o a usar history, podemos hacer un script:

#!/bin/bash

sinextension=${1%.*}

ffmpeg -loop 1 -y -i fondopodcast.png -i $1 -shortest $sinextension.mp4

 

De esta manera, le pasamos como parámetro el fichero donde tengamos el podcast y crea con el mismo nombre y extensión .mp4 una pista de vídeo y la imagen que usemos habitualmente como fondo para los podcasts.

Pero esto nos permite únicamente trabajar con una imagen. Podríamos intentar con:

ffmpeg -loop 1 -y -i imagen.png -i imagen2.png -i podcast.mp3 -shortest video.mp4

Pero no incluye la segunda imagen. Otra opción es:

ffmpeg -i *.png -i podcast.mp3 video.mp4

Pero tampoco nos hace un vídeo interesante si queremos meter una imagen de 20 segundos como pantalla final para YouTube, alguna entradilla y alguna imagen de fondo variada, por lo que tenemos que elaborar un poco más el script.

Volvemos a usar el vinfo.sh de de Gaspar Fernández que podemos descargar desde su web: https://poesiabinaria.net/2016/02/como-extraer-duracion-fotogramas-bitrate-y-fps-de-un-video-para-nuestros-scripts/

Y con ese script y ffmpeg, hacemos un shell script que automatice la generación de una pista de vídeo con imágenes para poder subir un podcast a YouTube:

#!/bin/bash

function numerodesegundos()
{
    
    let horasdeaudio=${1:0:2}
    let minutosdeaudio=${1:3:2}    
    let segundosdeaudio=${1:6:2}
    
    echo $[ ($horasdeaudio*60*60) + ($minutosdeaudio*60) + $segundosdeaudio]
}

sinextension=${1%.*}
duracion=$(./vinfo.sh duration $1)

entradilla="entradilla.mp4"
imagenprincipal="fondopodcast.png"
redessociales="redessociales.png"
pantallafinal="pantallafinal.png"


# Clip con las redes sociales
ffmpeg -loop 1 -f image2 -i $redessociales -vcodec libx264 -t 5 redessociales.ts

# Salida con la pantalla final
ffmpeg -loop 1 -f image2 -i $pantallafinal -vcodec libx264 -t 20 salida.ts

# Calcula la duración de la entradilla
duracionentradilla=$(./vinfo.sh duration $entradilla)
segundosentradilla=${duracionentradilla:6:2}

# Convierte la entradilla en .ts
ffmpeg -i $entradilla entradilla.ts

# Calcula cuánto duran los contenidos extras con dos cortes para la cartela de redes sociales

let duracionextras=$segundosentradilla+5+5+20

# Calcula cuántos segundos dura el audio pasado como parámetro

segundosdeaudio=$(numerodesegundos $duracion)

# Calcula la diferencia entre los segundos de audio del fichero parámetro y los extras

let tiempototalarellenar=$segundosdeaudio-$duracionextras

# Como vamos a hacer dos cortes para la cartela de redes sociales, divide el tiempo entre 3

let tercio=$tiempototalarellenar/3

# Y crea la pieza de vídeo con la imagen principal del podcast con esa duración:

ffmpeg -loop 1 -f image2 -i $imagenprincipal -vcodec libx264 -t 5 imagenprincipal.ts

# Monta una pista de vídeo con las piezas generadas hasta ahora:

ffmpeg -i "concat:entradilla.ts|imagenprincipal.ts|redessociales.ts|imagenprincipal.ts|redessociales.ts|imagenprincipal.ts|salida.ts" -c copy pistadevideo.ts

# Conviértelo en mp4

ffmpeg -i pistadevideo.ts -acodec copy -vcodec copy pistadevideo.mp4

# Monta el vídeo final con la pista de video generada con las imágenes y el podcast

ffmpeg -i pistadevideo.mp4 -i $1 -c:v copy -c:a copy $sinextension.mp4

# Borra todos los ficheros auxiliares generados

rm redessociales.ts
rm entradilla.ts
rm salida.ts
rm imagenprincipal.ts
rm pistadevideo.ts

 

Pueden comprobar cómo quedan los podcast con estas cartelas en mi canal. Y si les ha servido este tutorial, les gusta el mundo audiovisual y el software libre, o simplemente, si les apete, pueden suscribirse:

Publicado en Multimedia

Para saber la duración de un vídeo en un script y usar esa información para tabajar con ella, podemos usar ffmpeg, avconf o un script de Gaspar Fernández disponible desde su web: https://poesiabinaria.net/2016/02/como-extraer-duracion-fotogramas-bitrate-y-fps-de-un-video-para-nuestros-scripts/

Y como en el script el autor indica claramente:

# Do whatever you want with this code.

Vamos a darle uso a esa libertad y usarlo para evolucionar su uso:

Almacenar la duración de un vídeo en una variable

Antes de nada, deberemos copiar al directorio de trabajo ese script y darle permisos de ejecución:

chmod + vinfo.sh

Con esto ya podremos invocarlo desde nuestros scripts y recoger la duración de los vídeos en variables:

duracion=$(./vinfo.sh duration $video)

Extraer algunos fotogramas por minuto de una serie de vídeos

Queremos hacer uno o más vídeos a partir de los brutos tomados en un evento, los típicos recursos que se utilizan mucho en las noticias, en los resúmenes de los eventos o para promocionar un evento a partir de los eventos anteriores. Y además, como nos encanta trabajar con ImageMagick queremos extraer fotogramas para luego meterle efectos y hacer más espectaculares esos clips.

Pues aquí tenemos una posible solución:

#!/bin/bash

# Script que recorre un directorio con brutos de vídeo
# Por cada minuto de duración del vídeo extrae de un punto aleatorio
# tres bloques de 200 fotogramas cada uno
# Guardará esos bloques en un nuevo directorio empaquetados en subdirectorios
# cuyo nombre será igual al nombre del bruto donde se ha extraído sin extensión

directoriooriginales="halloween"
directoriodestino="fotogramas-"$directoriooriginales

for i in $(ls $directoriooriginales)
do
    # Quita la extensión del nombre del fichero original
    # para que el directorio se llame igual
     # y tener así una referencia en caso de tener que volver a usar el original
    sinextension=${i%.*}

    # Calcula la duración del vídeo
    duracion=$(./vinfo.sh duration $directoriooriginales/$i)
    horas=${duracion:0:2}
    minutos=${duracion:3:2}

    # Extrae los fotogramas y almacénalos en directorios numerados
    # consecutivamente con el mismo nombre que el vídeo origina + numeral
    let numeral=1
    for min in $(seq 0 $minutos)
    do    
        for tercios in $(seq 1 3)
        do
            let seg=$(shuf -i 0-59 -n 1)
            mkdir $directoriodestino/$sinextension$numeral    
            
            ffmpeg -i $directoriooriginales"/"$i -ss 00:$min:$seg -vframes 200 $directoriodestino/$sinextension$numeral/captura%03d.png
            let numeral++

        done
    done
done

 

Otros usos de este script:

Buscar una canción que se ajuste al tamaño de un vídeo para usarla como banda sonora
Recortar una canción para que se ajuste a la duración de un vídeo
Crear una pista de vídeo a partir de una cartela que se ajuste a la duración de un podcast

Publicado en Multimedia

Estoy haciendo una serie de tutoriales de GIMP 2.10 y quería mostrar cómo van cambiando las imágenes al cambiar los valores de los deslizadores de las distintas herramientas que forman GIMP.

Una opción es capturar la pantalla con recordMyDesktop o ffmpeg y colgarlo tal cual. El problema de esto es que el entorno de GIMP ocupa un espacio que hace que la imagen se vea pequeña. Así que prefiero hacer un efecto PiP (Picture in Picture). Es decir, superponer una imagen, en este caso, la caja de la herramienta sobre otra imagen más grande, en este caso, la imagen que va cambiando según los valores dados en la caja de la herramienta.

Podría capturar la pantalla y con un editor de vídeo, por ejemplo, Kdenlive, duplicar la pista y hacer dos "crops": uno con la imagen y otro con la herramienta, superponer ambas y montar el vídeo. Aparte de que el proceso de edición es farragoso, debería también hacer muchas veces clic con el ratón. Demasiado trabajo... seguro que ImageMagick me permite hacer el mismo resultado con menos esfuerzo. Veamos cómo hacerlo:

1.- Para el primer ejemplo, he cogido la primera herramienta del menú de Color de GIMP. Y me aparece que los deslizadores van del -100 al 100. Así que, en lugar de hacer 201 clic con el ratón, voy a hacer un bucle con una secuencia del 0 al 200.

2.- En cada iteración voy a capturar la pantalla completa con import y hacer dos recortes con crop, por un lado, la imagen que va cambiando y por otro, la herramienta de turno, en este caso, "Balance de color".

3.- Como quiero que el vídeo esté en formato HD, paso la imagen a un tamaño de 1920x1080 píxeles.

4.- Superpongo las imágenes con composite y hago clic para aumentar el valor.

5.- Le digo a ffmpeg que haga un vídeo con todos los fotogramas

6.- Y borro las imágenes sobrantes

Ya he escrito previamente sobre todas las instrucciones de este script a excepción de xdotool, que es un comando para simular el manejo del ratón a través de línea de comandos. Permite cliquear con los distintos botones, mover la ruleta, mover el cursor, hacer doble clic... En este caso, como únicamente quiero que haga un clic con el botón izquierdo, usaré:

xdotool click 1

 

Así es como queda el script:

#!/bin/bash

for i in $(seq 0 200)
do
    import -w root pantallazo.png
    convert pantallazo.png -crop 1308x735+172+214 lienzo$1$i.png
    convert pantallazo.png -crop 412x501+1497+242 -background Transparent -gravity Center -extent 600x600  deslizador$1$i.png

    convert lienzo$1$i.png -resize 1920x1080 base.png
    composite -gravity SouthEast  deslizador$1$i.png base.png png:-
xdotool click 1
done | ffmpeg -f image2pipe -i - videos/$1.mp4

rm lienzo*
rm deslizador*

Y así queda el resultado:

Publicado en Multimedia
Sábado, 08 Septiembre 2018 22:27

Hacer un gif a partir de un vídeo de YouTube

¿Os han pedido alguna vez que tuiteeis algún gif de alguna película? A mi, sí. Hace unos minutos. Así que ya que voy a hacer un gif de una de mis películas favoritas, os cuento cómo hacerlo. Pero no es necesario que os pidan un gif de una película, si queréis hacer un gif a partir de un vídeo de YouTube, podéis seguir paso a paso este artículo. En caso de que tengáis el vídeo en vuestro ordenador, podéis obviar la parte de la descarga del vídeo.

Descargar el vídeo de YouTube

Para descargar un vídeo de YouTube, o casi de cualquier plataforma de vídeo, incluídas muchas plataformas de vídeos para adultos, tenemos un comando súper eficiente para ello: youtube-dl. Su uso más básico es para descargar un vídeo (si quieren que escriba un artículo explicando cómo descargar sólo audio o una lista de vídeos, escríbanlo en los comentarios). Y para descargar un vídeo no necesitamos ni parámetros ni nada más que el comando y la url del vídeo. Como yo quiero tuitear sobre Machete (como digo, me han pedido un gif de una de mis películas favoritas, así que elijo esta escena de Machete):

https://www.youtube.com/watch?v=DTyeEB-ra7w

Y lo descargo con:

youtube-dl https://www.youtube.com/watch?v=DTyeEB-ra7w

Extraer los fotogramas de la parte del vídeo que interesa

Como he visto el vídeo de YouTube y sé que la parte de la que quiero extraer los fotogramas va de 00:14 a 00:21 uso el comando:

ffmpeg -i Machete\ improvises-DTyeEB-ra7w.mp4 -ss 00:14 -t 8 machete%04d.jpg

Escribir un texto sobre los fotogramas

Voy a escribir dos frases: "Machete no manda mensajes" y "Machete improvisa". Para ver sobre qué fotogramas escribo cada una de las frases, voy a mirar dónde está el cambio de plano:

cambiodeplano.jpg

 

Hasta el fotograma machete0056.jpg voy a poner "Machete no manda mensajes" y en el resto, hasta el 200, "Machete improvisa":

#!/bin/bash

for i in $(seq 1 200)
do
    if [ $i -lt 10 ]
    then
        sufijo=000$i.jpg
    elif [ $i -lt 100 ]
    then
        sufijo=00$i.jpg
    else
        sufijo=0$i.jpg
    fi

    if [ $i -lt 56 ]
    then
        convert machete$sufijo -gravity South -font Luxi-Sans-Bold -pointsize 50 -fill White -stroke Black -strokewidth 3 -annotate +0+0 "MACHETE NO MANDA MENSAJES" fotograma$sufijo
    else
         convert machete$sufijo -gravity South -font Luxi-Sans-Bold -pointsize 70 -fill White -stroke Black -strokewidth 3 -annotate +0+0 "MACHETE IMPROVISA" fotograma$sufijo
    fi
done

Optimizando la animación

En este caso, la mayoría de los fotogramas son iguales o muy parecidos, así que voy a borrar unos cuantos. Al contrario que con ffmpeg, a la hora de hacer imágenes animadas con ImageMagick la numeración puede contener saltos.

Y además, tenemos la posibilidad de optimizar las imágenes para que el fichero resultante pese menos con -layers Optimize, que podemos usarlo así:

convert fotograma0* -delay 5 -loop 0 -layers Optimize macheteimprovisa.gif

Podéis ver el resltado en Twitter:
https://twitter.com/hacemoswebserie/status/1038551976131350528

 

 

Publicado en Multimedia

Tenemos un vídeo, al que llamaremos video.mp4

Tenemos una pista de audio, a la que llamaremos audio.mp3

Tenemos una necesidad, que es unir la pista de audio al vídeo.

Tenemos un programa en nuestra shell, que es ffmpeg.

Combinamos todo:

ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a copy videoconaudio.mp4

Y ahora que tenemos la pista de audio y la de vídeo unidas, vamos a ver qué hemos hecho:

ffmpeg -> nombre del comando

-i video.mp4 -> definimos una entrada

-i audio.mp3 -> definimos otra entrada

-c:v copy -> definimos que no queremos cambiar el códec de vídeo (copia el que tiene la pista de vídeo)

-c:a copy -> definimos que no queremos cambiar el códec de audio (copia el que tiene la pista de audio)

videoconaudio.mp4 -> nombre del fichero que se generará con la unión de la pista de vídeo y la pista de audio.

Publicado en Multimedia

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.

Publicado en Multimedia

¡Atención! Este sitio usa cookies y tecnologías similares.

Si no cambia la configuración de su navegador, usted acepta su uso. Saber más

Acepto

Vea nuestra política de cookies y enlaces de interés aquí