Dedicado a mis proyectos en Gambas ,un lenguaje de programación parecido al Visual Basic + Java pero ampliamente mejorado y...¡¡para gnu/linux!!.La potencia del gnu/linux sumada a la facilidad del Basic



Consultas, Desarrollo de programas y petición de presupuestos:



domingo, 27 de febrero de 2011

Usando ffmpeg: Convertidor a otros formatos de video gnu/linux


Usando ffmpeg...


Podemos convertir los archivos tipo .mpg a tipo .avi en nuestra terminal.


ejemplo de uso:


$ffmpeg -i test.mpg -y -f avi -b 1150 -s 320x240 -r 29.97 -g 12 -qmin 3 -qmax 13 -ab 224 -ar 44100 -ac 2 test.avi


Para mas información: manual de ffmpeg, escrito por iqpi aqui teneis un extracto del mismo:


[objetivos del manual]
  • Aprender a utilizar a fondo FFMPEG
  • Aprender a aplicar watermarks a nuestros vídeos
  • Automatizar la creación de nuestros vídeos. Desde la creación, hasta su publicación en youtube
[Material necesario]
  • svn
  • imagemagick
  • gimp
  • googlecl
  • Ganas de aprender
[Material del que os tenéis que deshacer]
  • Miedo a utilizar la consola de comandos. Es una herramienta muy potente. Aprovechemoslo.
Lo primero: La instalación de las herramientas.

Como buenos trabajadores que somos vamos a necesitar que nuestro taller (sistema) tenga las herramientas (programas) necesarias.

  • svn: nos servirá para bajar la última versión disponible de ffmpeg
Instalación: simplemente instalaremos el paquete svn

Una vez que hayamos instalado svn ejecutaremos los siguiente para obtener ffmpeg:

Código:
 svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
esto bajará la última versión disponible de las fuentes de ffmpeg.
A continuación nos cambiamos al directorio ffmpeg:

Código:
 cd ffmpeg
Una vez dentro del directorio hemos de configurar las opciones que queremos que tenga ffmpeg. Yo os aconsejo que las tenga todas, para ello ejecutamos lo siguiente:
Código:
./configure --enable-gpl --enable-libmp3lame --enable-libvorbis --enable-libfaac --enable-libxvid --enable-libx264 --enable-libvpx --enable-libtheora --enable-postproc --enable-shared --enable-pthreads --enable-x11grab --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libschroedinger --enable-libopenjpeg --enable-version3 --enable-nonfree --enable-runtime-cpudetect
A continuación ejecutamos: 
Código:
 make -jNumero_Nucleos+1
Dónde numero de nucleos + 1 como dice su nombre, es el número de núcleos de tu procesador + 1, si tienes un dual core entonces ahí pondrás 3, si tienes quadcore, entonces pondrás 5.

Esto permite que la compilación del programa utilice todos los núcleos del sistema, lo que hará que compilación sea mas rápida.

Después, como administrador ejecutas:

Código:
 make install
Para instalar ffmpeg.

Tras esto, FFMPEG quedará instalado y listo para poder usarse.
  • imagemagick
Instalamos el paquete imagemagick, lo necesitaremos para aplicar marcas de agua a nuestros vídeos.


  • Gimp
O cualquier otro programa de creación/edición de imágenes. Lo necesitaremos para crear nuestra marca de agua.
  • Googlecl
Este me ha llevado tiempo encontrarlo, pero es extremadamente útil pues nos va a permitir subir vídeos a youtube desde la línea de comandos.
Una vez que tenemos las herramientas. Pasamos a lo que realmente nos interesa. Aprender a utilizar ffmpeg.

  • ¿Cómo cambiar el formato de los vídeos?
¿Cuántas veces nos ha pasado que tenemos un vídeo que queremos subir a youtube y no hemos podido porque era muy pesado? ¿ o no queremos esperar media vida esperando a subir 2 gigas de vídeo con nuestras maravillosas conexiones?

La solución pasa por recodificar el vídeo a otro formato que comprima el vídeo y que no trastoque demasiado su calidad. ¿Cómo conseguir esto? desde la versión 0.6 podemos utilizar el contenedor .webm con vídeo codificado en VP8 y audio con theora ogg vorbis. Todo de código abierto.

Esto nos comprimirá el vídeo haciendo que ocupe menos, y manteniendo la calidad del vídeo. ¿Cómo hacerlo?

Código:
 ffmpeg -i Video_a_convertir -sameq Video_Convertido.webm
Tan simple como eso, con idicarle la extensión .webm FFMPEG ya sabe qué utilizar, y utilizará VP8 para video y vorbis para audio.

Explicación de opciones:

  • -i ---> Indica el Vídeo fuente original
  • -sameq ---> el vídeo de salida conserva la calidad del original (importante, seleccionar siempre) para evitar pérdidas.
  • Mas formatos de audio, vídeo y contenedores
Un vídeo no es mas que una sucesión de imágenes con una o varias pistas de audio, por lo que, para tener un único archivo multimedia necesitamos meter las imágenes y el audio en un contenedor.

  • Formatos de vídeo
Actualmente hay muchos, son los que codifican las imágenes. A día de hoy los que mas nos interesan son los siguientes:
  • mpeg4 --> admite aceleración por hardware
  • h264 ---> admite aceleración por hardware (cerrado)
  • x264 ---> igual que h264 pero abierto
  • VP8 --> alta calidad de código abierto (nuevo)
  • theora --> alta compresión de código abierto
Para forzar la utilización de un tipo de códec de vídeo utilizaremos la siguiente opción:
Código:
 -vcodec Codec_que_queremos
Si no sabemos qué códec utilizar, no pondremos nada, o pondremos:
Código:
 -vcodec copy
que utilizará el mismo códec que el video fuente.
  • Formatos de audio
Al igual que los formatos de vídeo, tenemos bastantes formatos de audio. ¿Cuáles nos interesarán mas a nosotros:
  • FLAC ---> no tiene pérdidas, admite multicanal, código libre
  • AAC ---> similar a FLAC pero no se si es libre.
  • ogg --> cuando queramos comprimir el audio, es el mas recomendado, código abierto.
Para forzar el uso de un determinado códec utilizaremos la siguiente opción:
Código:
 -acodec codec
Si no sabemos cual usar, no pondremos nada, o usaremos la opción 
Código:
 -acodec copy
  • Contendedores
Es dónde "estarán metidos" el vídeo y el audio. ¿Cuántos hay? Bastantes también, pero a día de hoy los mas relevantes son:
  • mkv--> admite FULLHD y es de código abierto
  • mp4--> admite FULLDH
  • webm --> admite FULLHD y es el ideal para vp8
Hasta no hace mucho, el contenedor flv era muy utilizado gracias a youtube, pero desde que youtube permite subir vídeos en .mkv, .mp4, y, recientemente en .webm, no tiene sentido que se siga utlizando .flv.

¿Cómo escoger contenedor? pues es tan fácil como poner la extensión de archivo adecuada, que quieres mkv, pues el fichero de salida será: video-de-salida.mkv
Y así con todos. Muy simple.

  • Cambiar la resolución de un vídeo:
Para cambiar a la resolución deseada basta con pasar la opción 
Código:
 -s [ancho]x[alto]
en pixels

Muchas veces querremos agrandar un vídeo. Por ejemplo, yo que tengo un monitor de 17" TFT de resolución 1280x1024 formato 5:4 me gusta que mis tutoriales estén disponibles en fullHD, de modo que para conseguirlo sería:

Código:
ffmpeg -i Video_Entrada -sameq -s 1920x1080 -aspect 16:9 video_salida
Dónde la opción -aspect detalla que la salida estará en formato panorámico.

Esto lo que hará será estirar la imagen con una calidad bastante buena y apenas se nota pérdida de calidad, en este caso. La pérdida de calidad se sitúa en el 10% que al ojo humano no se nota, lo que notaremos será que está un poco estirado. Pero la calidad será estupenda.

Para minimizar la pérdida de calidad, a mi me gusta utilizar esta opción:

Código:
-pix_fmt rgb48le
esto lo que hace es cambiar el formato del pixel, del original predeterminado que contiene solo 16 bits de información, por otro que contiene 48 bits de información.

Evidentemente, si tenemos un vídeo cuya resolución original es de 320x240, si pretendemos pasarlo a 1080 la pérdida de calidad va a ser mas que notable, a pesar de no haberlo probado personalmente, pero creo que me puedo aventurar.
  • Convertir un vídeo en imágenes
con este comando lograremos conseguirlo:
Código:
 ffmpeg -i Video -sameq -r 25 fotograma%d.png
explicación:
  • -r 25 establece los fotogramas por segundo, sacara 25 imagenes por segundo (podemos cambiar el valor a nuestro gusto)
  • fotograma%d.png la salida será fotograma1, fotograma2...., %d muestra una cuenta ascendente.
  • Convertir secuencia de imágenes en vídeo
Con el comando:
Código:
ffmpeg -i fotograma%d.png -sameq video.mkv
Tendremos un video hecho con imágenes pero sin audio.
Inconveniente Necesitaremos que las imágenes estén nombradas como fotograma1 fotograma2 ... en cuenta ascendente. No necesariamente ha de llamarse fotograma, puede ser 1 2 3 4 5 ... en ese caso, en lugar de hacer fotograma%d.png, hacemos:

Código:
 %d.png
  • Silenciar un vídeo
Con el siguiente comando, conseguiremos tener un vídeo sin sonido:
Código:
 ffmpeg -i VideoEntrada -sameq -an VideoSalida
  • Extraer audio de un vídeo
Si queremos extraer el audio para modificarlo, y luego reinsertarlo, entonces os recomiendo que lo extraigáis en FLAC para que no haya pérdida de calidad:
Código:
 ffmpeg -i video -sameq AudioVideo.flac
Si queremos extraer el audio del videoclip que nos han prestado para ponerlo como tono del móvil:
Código:
 ffmpeg -i Video -sameq -ab 320k audioVideo.mp3
Explicación de opciones extras:
  • -ab --> audio bitrate, cuanto mas grande mas calidad
  • Insertar Nuevo audio a un vídeo
Para ello debemos tener previamente un vídeo silenciado.
Código:
 ffmpeg -i Video -i NuevoAudio -sameq VideoConNuevoAudio
Hemos de tener en cuenta que el vídeo resultante será tan largo como lo que mas dure, es decir, si el audio es mas largo que el vídeo, tendrá la duración del audio, y viceversa.
  • Unir varios videos en uno
Para ello necesitamos primero convertir los vídeos a mpeg. Luego haremos:
Código:
 cat Video1 Video2....VideoN > VideoFinal
  • Acortar un video
Para esto tenemos 2 maneras: La primera se tratar de cortar un trozo del principio, es decir, queremos que el nuevo vídeo empiece en el segundo 26 del vídeo original. Para ello:
Código:
 ffmpeg -i VideoOrignal -sameq -ss 26 VideoFinal
Otra opción es que queramos que el vídeo dure 10 minutos justos entonces le pasaremos la opción -t 600
Código:
 ffmpeg -i VideoOriginal -sameq -t 600 VideoFinal
  • Grabar nuestro escritorio
Con el siguiente comando, conseguiremos grabar nuestro escritorio mientras que trabajamos con él, además, de grabar también nuestra voz por el micrófono para ir dando instrucciones.
Código:
 ffmpeg -async 1 -f alsa -i plughw:0,0  -f x11grab -pix_fmt rgb48le -r 25 -s [ancho]x[alto] -i :0.0 -b 25000k VideoSalida
explicación de opciones:
  • -async 1 --> hace que el audio y el vídeo vayan sincronos
  • -f alsa --> le decimos que queremos grabar desde un dispositivo alsa
  • -i plughw:0,0 --> así es como se identifica mi micrófono, el vuestro puede variar
  • -f x11grab --> esto le indica al programa que quiere grabar la X (entorno gráfico)
  • -pix_fmt rgb48le --> simplemente utiliza un pixel que puede almacenar mas información que uno "normal"
  • -r 25 indica que se tomarán 25 imágenes por segundo
  • - [ancho]x[alto] le dice el tamaño de la imagen, no puede ser mayor que la resolución de tu monitor.
  • -i :0.0 --> esta es la pantalla de la que se va a grabar, si solo tienes una, será identificada como aquí.
  • -b 25000k le estoy indicando que quiero un bitrate de 25000k


Y hasta aquí de momento, el uso "en bruto de ffmpeg" mas adelante os contaré como aplicar filtros, o lo mas interesante, dibujar marcos, o recortar los marcos de las películas.
Pero pasamos a:

Creación de nuestra watermark (marca de agua) 

Muchos os preguntaréis qué carallo es esto de la marca de agua. Os lo voy a explicar. Por desgracia para nosotros (creadores de contenido) hay muchos que se quieren aprovechar de nuestro trabajo cuando hacemos un vídeo para llevarse ellos el mérito, o llevarse las posibles ganancias.
La marca de agua lo que nos permite es "firmar" el vídeo digitalmente de modo que siempre se va a saber que es nuestro, pues la marca es imborrable.

Es como cuando ves una película en la televisión que aparece el símbolo de la cadena en la que la están echando.
Nosotros nos vamos a crear nuestro propio sello que evitará que otros se aprovechen de nuestro vídeo declarándonos autores insustituibles del material.
Esto no quiere decir que evitemos que otros usen nuestro vídeo, pero así todo el mundo sabrá quien es quien lo ha hecho.

Para ello con gimp por ejemplo nos vamos a crear una imagen de resolución igual a la de nuestro vídeo, pero con fondo transparente. Y en ella en una esquina, o dónde mas nos guste, pondremos nuestro logo, o lo que mas os guste a vosotros.
Consejo Debe ser lo suficientemente grande para que se vea, pero lo suficientemente pequeño para que no estorbe y estar colocado en una esquina preferiblemente.

Una vez que la tenemos, la guardamos como imagen PNG, por ejemplo logo.png

Después, utilizaremos el programa imagemagick para fusionar nuestro logo, con nuestro vídeo.
Pero con esto tenemos un problema:
Imagemagick solo permite fusionar imágenes, y una cada vez.

El proceso es el siguiente:

Código:
 composite -dissolve 100% -gravity south logo.png Imagen.png NuevaImagenConLogo.png
Entonces, ¿cómo lo hacemos con nuestro vídeo?
Fácil, vamos a extraer cada fotograma del vídeo y le vamos a aplicar a cada fotograma el logo, luego vamos a montar el vídeo de nuevo a partir de las nuevas imágenes.

Problema: Muy bien, pero un vídeo son 25 imágenes por segundo lo que implica que un vídeo de 10 minutos de duración son 25 x 60 x 10 = 15000 imágenes.
Aplicar a mano nuestro logo a 15000 imágenes es una barbaridad, y, por qué no decirlo, una jodida locura. Imaginemos que que ejecutarlo cada vez nos lleva 1 segundo siendo muy optimistas, tardaríamos 15000 segundos que en términos humanos son: mas de 4 horas sin parar. Y encima luego tenemos que montar el vídeo que para mas inri no tendrá sonido.

Pero por eso Dios bajó de los cielos y creó los scripts . A continuación, os voy a dejar un script que hace lo siguiente:

  1. Extrae el audio del vídeo original
  2. Convierte el vídeo a fotogramas
  3. Procesa cada fotograma y le aplica la marca de agua
  4. muestra una cuenta de cuántas imágenes lleva hechas del total, y calcula el tanto por ciento que lleva completado
  5. Monta el video a partir de las nuevas imágenes
  6. Inserta el audio al vídeo
  7. Borra toda la basura generada, es decir, todas las imágenes.
Y es el siguiente:

Código:
#!/bin/bash

ffmpeg -i VIDEO -sameq Audio.flac
ffmpeg -i VIDEO -sameq fotograma%d.png

ls *.png | grep fotograma > listado
mkdir NuevosFotogramas

NUMIMAGENES=$(ls *.png | grep fotograma | wc -l)
CONTADOR=0

while read IMAGEN
do
    PORCENTAJE_COMPLETADO=$(echo "$CONTADOR"*100/"$NUMIMAGENES" | bc )
    CONTADOR=$(echo "$CONTADOR" + 1 | bc )
    composite -dissolve 100% -gravity south logo.png "$IMAGEN" NuevosFotogramas/"$IMAGEN"
    echo "Procesadas "$CONTADOR" de "$NUMIMAGENES". "$PORCENTAJE_COMPLETADO"% Completo" 
done < listado

ffmpeg -i NuevosFotogramas/fotograma%d.png -sameq  VIDEO_CON-LOGO_NO-AUDIO.mkv
ffmpeg -i VIDEO_CON-LOGO_NO-AUDIO.mkv -i Audio.flac -sameq VIDEO_FINAL_CON-LOGO.mkv

rm -r NuevosFotogramas
rm -f fotograma*.png
rm -f listado
echo "ya esta todo terminado Presiona una tecla para salir"
read TECLA
Tenéis que tener en cuenta que donde pone VIDEO es vuestro video original y que el logo tiene que tener la ruta de dónde se encuentre vuestro logo
el resto no es necesario que lo toquéis.

Para que veáis el resultado, os voy a mostrar dos vídeos
Este primero no tiene huella digital

Y este es el resultado tras haber aplicado la marca de agua de la forma que os he explicado


AVISO: este proceso es bastante lento, puede demorarse fácilmente algunas horas para vídeos de una duración de 15 minutos.

ATENCIÓN En una nueva versión del script publicada un poco mas abajo se optimiza para trabajar utilizando todos los núcleos disponibles, estando optimizado para procesadores de 4 núcleos.
De esta forma el proceso en mi caso pasa de tardar mas de cuatro horas, a tardar una hora.

En una futura versión se optimizará para cualquier procesador. Pero dadme tiempo.

Y bueno, ya no me queda mas tiempo, en otro rato cuando pueda, os explico como modificar el script para que además, el propio script se encargue de colgar en vídeo en youtube sin que tengáis que hacer nada vosotros.

Espero que os sea de utlidad 






Saludos


Nota:
6/12/2011:
Convertir .avi a .mpeg
ffmpeg -i videoorigen.avi -target pal-dvd videofinal.mpg