Manipulación en batch de videos

Creo que todo el mundo puede coincidir que las herramientas básicas de todo Linux (ls, cat, find, xargs, ...) resultan realmente impresionantes. Especialmente en manos expertas. NO es mi caso.

Sin embargo creo que resulta útil ir aprendiendo a combinar diversas herramientas. Ayer me asaltó un problema y vi la oportunidad de resolverlo fácilmente con estas herramientas y, porque no, practicar un poco al respecto.

El problema era el siguiente: disponia de alrededor de 25 videos en formato AVI más otros 25 ficheros MP3 con una pista de audio para dichos videos. Los videos ya venian con dos pistas de audio, pero yo queria esa tercera pista (que tenia en un fichero externo).

El primer objectivo era, por tanto, generar nuevos ficheros de video con la pista de audio deseada.

Además, los nombres de los ficheros contenian un exceso de caracteres bastante alto. ¿Podria aprovechar para limpiar un poco los nombres de los ficheros?

Los nombres seguian más o menos el siguiente formato:

aaaaaaaaaaaaaaaaaa DxDD bbbbbbbbbbbbb [ccccccccc] ddddddddddddd.avi (o.mp3)

Donde 'aaaaa' era una cadena de carácteres fija para todos los ficheros, D eran números diferentes para cada video, y los otros 4 grupos (b, c y d) eran diversos carácteres alfanuméricos.

Lo primero es eliminar el prefijo común. Fácil, usamos el comando 'rename' con una expresión regular de sustitución de Perl:

rename 's/aaaaaaaaaaaaaaaa //' *.avi

Idem para los ficheros de audio. Con 'rename' podemos usar además la opción -n para simular como se renombraran los ficheros antes de hacerlo realmente.

Ahora el objetivo es dejar sólo los archivos con el siguiente formato:

DxDD bbbbbbbbbbbbb.avi

Para lo cual podemos usar de nuevo 'rename' con una expresión regular algo más complicada.

rename 's/(\dx\d\d[\w\s]+)\s\[.*\.(\w{3})$/$1.$2/' *

Básicamente capturamos el DxDD y los carácteres posteriores hasta el primer [, y lo guardamos para poder repetirlo luego (entre paréntesis). Luego capturamos el resto y guardamos finalmente la extensión (los 3 últimos carácteres tras el punto). Todo esto simplemente es convierte en $1.$2, o sea la primera parte capturada, un punto y la segunda.

Bien, ya tenemos los ficheros de audio y video con los nombre de fichero 'limpios'. Ahora, usamos FFmpeg para remultiplexar los videos con el nuevo audio. La idea es hacer algo como esto:

ffmpeg -i 'DxDD aaaaaaa.avi' -i 'DxDD aaaaaaa.mp3' -vcodec copy -acodec copy -map 0.0:0.0 -map 1.0:0.1 'DxDD aaaaaaaa mmm.avi'

Básicamente esta orden genera un avi sin modificar el audio ni el video, pero cambiando los canales de audio (opciones -map). Al resultado además queremos añadir un string fijo 'mmm'. Además tenemos que ejecutar la orden para cada uno de los 25 videos.

El resultado se consigue con una combinación de comandos: ls, cut y xargs.

ls -w1 *.avi | cut -d. -f1 | xargs -I '{}' ffmpeg -i '{}'.avi -i '{}'.mp3 -vcodec copy -acodec copy -map 0.0:0.0 -map 1.0:0.1 '{} mmm.avi'

¡Prueba superada!