Publi

Comprime o adapta tus vídeos con ffmpeg o avconv desde la línea de comando

Me encanta la idea de poder automatizar tareas. Y de hecho, un ordenador está pensado especialmente para eso, para realizar tareas complejas, rápido y con la menor asistencia posible por nuestra parte. La tarea de la que vengo a hablar hoy es la conversión de vídeo. Es una tarea computacionalmente intensa y, si los vídeos a convertir son muy largos, podemos dejar nuestro ordenador inútil durante bastante tiempo.

En este post vamos a ver algunas ideas de cómo automatizar la transcodificación de archivos de vídeo, es decir, cambiar el algoritmo con el que está codificado un vídeo (y casi siempre, comprimido también). Podemos hablar en este caso de vídeos codificados en H.264 que queremos pasar a VP8 o Theora. También podremos reducir los fotogramas por segundo, la resolución de los vídeos, o el ancho de banda del vídeo o el audio.

Screencast

Tenéis disponible un screencast con todas estas instrucciones. Es más, este post no es más que una transcripción del screencast, así que, si prefieres verlo en formato vídeo, aquí lo tienes:

Transcodificando

Aunque típicamente esta tarea se puede realizar con programas interactivos, con ventanas, y de forma muy amigable e intuitiva, con programas como VLC o Handbrake. Muchas veces es interesante utilizar programas en línea de comandos como ffmpeg que nos permitirán, por ejemplo, utilizar un ordenador remoto para realizar esta tarea. Este ordenador remoto puede estar en nuestra casa, un ordenador diferente al de trabajo, con más capacidad; si no tenemos prisa puede ser una Raspberry Pi, un móvil viejo o un NAS. En Universidades y algunas empresas disponen de equipos muy potentes para procesamiento de datos a los que nos podemos conectar desde nuestro puesto de trabajo o nuestra casa. Pero también podemos alquilar por unas horas un servidor y hacer el trabajo de conversión ahí; nuestro ordenador no se convertirá en un calefactor, los ventiladores no se pondrán a girar como si no hubiera un mañana y la vida útil de nuestro equipo será un poco mayor. Por otro lado el coste no será tan grande. En muchos lugares podemos contratar un VPS de 16 núcleos y 32Gb de RAM a menos de 50 céntimos por hora, esto puede ser una máquina más potente que la que cualquiera de nosotros podría tener en su casa. Eso sí, a la hora de contratar estos servicios deberíamos tener en cuenta que el tiempo total que debemos tener la máquina encendida será la suma del tiempo que tardaremos en enviar los vídeos originales más el tiempo de procesamiento más el tiempo que tardamos en descargarnos los vídeos convertidos. Si tenemos una buena conexión, no tendremos ningún problema. En el caso de los servidores, siempre podremos contratar una máquina poco potente para hacer las transferencias de datos, para que los tiempos de transferencia nos salgan a un céntimo por hora y no paguemos de más.

Bueno, tras estas ideas, vamos a empezar con lo más sencillo a la hora de convertir vídeos. Y en muchas ocasiones es lo primero que vamos a probar, para ver si nos convence el resultado. Yo suelo utilizar la herramienta para convertir vídeos descargados de mi cámara de vídeo. Es una cámara pequeña, de gama baja, pero graba en FullHD en un formato propietario, llamado AVCHD, cuya extensión suele ser MTS. El vídeo en realidad está comprimido en MPEG-4 parte 10, es decir, el códec H.264 y el audio en AC-3, aunque la implementación que hace la cámara de estos códecs, imagino que para ganar velocidad en la compresión, hace que los vídeos sean aptos para su reproducción, aunque hace muy lenta su edición. Esto es así porque cuando estamos editando, generalmente no vemos el vídeo seguido, sino que saltamos fotogramas para ver ciertas partes concretas del vídeo, vamos hacia atrás, hacia adelante, incluso un mismo vídeo está recortado y muchas veces suele ser un problema acceder a un fotograma concreto. Por otra parte, cuando aplicamos algún efecto de color o de realce, por ejemplo, necesitamos acceso al fotograma completo para aplicar el filtro, y cuando estamos reproduciendo un vídeo que está comprimido, generalmente sólo actualizamos las partes del vídeo modificadas entre un fotograma y el siguiente. Otro pequeño problema que surge, es que el vídeo ocupa bastante, por el mismo motivo de antes, la cámara no dispone de gran hardware, y para comprimir en tiempo real no puede aplicar algoritmos muy complejos.

Así que, si queremos recomprimir el vídeo, podemos ejecutar este comando:

ffmpeg -i origen.MTS destino.mp4

Dependiendo de la longitud del vídeo tardará más o menos, porque está realizando una recompresión de audio y vídeo. Así que, a partir de ahora, si queremos ver el resultado, podremos seleccionar, por ejemplo 5 segundos de vídeo:

ffmpeg -i origen.MTS -t 00:00:05 destino.mp4

En otras ocasiones tal vez necesitemos varios minutos de vídeo para una vista previa, podremos hacerlo modificando el tiempo del parámetro -t , los dos primeros números serán horas, los dos siguientes minutos y los siguientes segundos. Del mismo modo podemos poner un punto y elegir centésimas de segundo, tal vez el tiempo de vídeo no sea exacto, pero se redondeará al fotograma completo más próximo.

Ya que estamos comprimiendo con MPEG-4 parte 10 o H.264, aquí podemos utilizar los presets, o configuraciones predefinidas del formato. Básicamente elegiremos la dedicación del procesador a la compresión del vídeo. Es decir, cuanto más tarde la compresión, menos espacio ocupará el vídeo, estará más comprimido, habiendo aplicado más técnicas para reducir dicho espacio, todo ello, con una calidad equivalente. Del mismo modo, si comprimimos el vídeo a máxima velocidad, el resultado ocupará más. Esto lo podemos hacer de la siguiente manera:

ffmpeg -i origen.MTS -preset ultrafast destino.mp4

Con esta configuración, mi vídeo de 8 segundos, ha tardado 5 segundos en comprimirse, y ocupa unos 14Mb, en cambio, si hacemos:
ffmpeg -i origen.MTS -preset veryslow destino.mp4

Mi ordenador tarda 1 minuto y 50 segundos, y el fichero final ocupa 8Mb, que es algo más de la mitad que el anterior. Tal vez en estos vídeos cortos no se note, y no compense la pérdida de tiempo, pero en vídeos de una hora o más sí que hay gran diferencia.

Cambiando códecs

Claro, ffmpeg vale para mucho más que para recomprimir vídeos. Por ejemplo, si estos vídeos, queremos reproducirlos en un reproductor que tiene unos cuantos años, seguramente el H.264 sea demasiado para ellos, aunque podemos utilizar la parte 2 del estándar, que usualmente era la implementada en códecs como DivX o Xvid a principios de siglo. Para el audio podremos utilizar el códec MP3 (que no es más que la capa de audio de MPEG-1, lanzada en 1993):

ffmpeg -i origen.MTS -c:v mpeg4 -c:a libmp3lame destino.mp4

Como vemos, -c (implicará cambio de códec), si utilizamos -c:v cambiaremos el códec de vídeo, y si utilizamos -c:a cambiaremos el de audio.

Tal vez con esta configuración no obtengamos mucha calidad. Esta calidad podemos aumentarla, por un lado, utilizando más bits por segundo, de la siguiente forma:

ffmpeg -i origen.MTS -c:v mpeg4 -b:v 9000K -c:a libmp3lame -b:a 128K destino.mp4

En este caso, estaremos utilizando 9000kilobits por segundo, algo más de un megabyte por segundo para vídeo, y 128Kbits por segundo, que son 16Kb por segundo para audio. Como vemos dos puntos v y a determinan si hablamos de audio o vídeo.

Esta compresión siempre será con pérdidas. Aunque estemos trabajando en un formato digital, al final es como cuando copiábamos cintas VHS hace muchos años, una copia de una copia siempre perdía calidad. Del mismo modo, aquí estamos descomprimiendo un vídeo grabado con pérdidas, y al cambiar el algoritmo de compresión, estamos introduciendo otras pérdidas diferentes. Existen algoritmos de compresión sin pérdidas de los que hablaremos más adelante.

Otra forma de manejar la calidad en mpeg4 es con el parámetro -q (escala de calidad), en este caso debemos introducir un número entre 1 y 31. Siendo 1 la máxima calidad, ocupando mayor tamaño y 31 la menor calidad y menor tamaño. Este sistema utilizará una tasa de bits variable optimizando el resultado final, porque hay imágenes que se comprimen mejor que otras, hay ciertas imágenes que no necesitan mucha información para ser reproducidas, y hay otras que sí. Podemos fijarnos, por ejemplo, en televisión, cuando tiran confetti, o movimientos muy rápidos, vemos cómo momentáneamente se pierde calidad. Eso es porque las imágenes que nos envían necesitan más bits por segundo de los que se pueden transmitir por el canal (ya sean ondas, como la TDT, cable, o Internet). Para utilizar este parámetro lo podemos hacer así:

ffmpeg -i origen.MTS -c:v mpeg4 -q:v 5 -c:a libmp3lame -q:a 1 destino.mp4

Tenemos que tener cuidado con esto, porque la calidad máxima 1, además de tener pérdidas, puede producir un fichero de vídeo demasiado grande. Así que, a no ser que sea necesario, podemos tirar por un factor más grande.

Otra opción, si queremos utilizar formatos libre es utilizar Theora para vídeo y Vorbis para audio en un contenedor OGV de la siguiente manera:

ffmpeg -i origen.MTS -c:v libtheora -c:a libvorbis -q:v 10 -q:a 5 destino.ogv

En este caso, la calidad irá entre el 1 y el 10, siendo 1 la peor (y la que menos ocupa) y 10 la mejor (y la que más ocupa). También podemos optimizar vídeos utilizando Webm, que utiliza VP8 o VP9 para vídeo y opus o vorbis para audio. Podemos hacerlo así:
ffmpeg -i origen.MTS -c:v libvpx-vp9 -c:a libopus -crf 15 -b:v 0 destino.ogv

En este caso, especificamos la calidad con -crf (constant rate factor), donde especificamos un número entre el 0 y el 63, donde 0 es la máxima calidad. Además, especificamos -b:v 0 para que cada fotograma ocupe lo que tenga que ocupar para mantener la calidad. Si aquí especificamos un tamaño, estaremos estableciendo un tope superior de bits por segundo.

Convirtiendo para edición

Volviendo al tema de edición de vídeo. Aquí nos podemos encontrar con varias opciones. Y será cosa nuestra probar la que más nos conviene en cada caso, obteniendo calidad de imagen, velocidad de trabajo, velocidad de codificación y precisión diferentes. Iré explicando esto poco a poco.
Otro aspecto que dejo para otro vídeo es el de los proxys. Muchos editores de vídeo, nos permiten crear archivos temporales, mucho más rápidos para trabajar que los vídeos originales. De todas formas, en ocasiones viene bien un trabajo previo de los archivos de origen para facilitarnos el trabajo más adelante.

La primera opción que tenemos es una imagen por fotograma y olvidarnos de archivos de vídeo. Por un lado, la descompresión se acelerará mucho, ya que trataremos sólo con una compresión espacial, o compresión de imagen, quitándonos la compresión temporal del medio, o con una compresión de datos, en la que podremos trabajar sin pérdidas o, al menos, sin más pérdidas que las producidas por nuestra fuente de vídeo. Podríamos utilizar en este caso archivos png, tga, tiff (sin pérdidas), o también jpg (con pérdidas). Tendríamos una opción de JPEG sin pérdidas, pero muchos programas de edición no se llevan del todo bien con este formato. Aunque los formatos son algo antiguos, podemos manipularlos muy rápido, y tanto la compresión como descompresión de la información, nos permitirá trabajar con estos archivos sin problema.
Lo malo, es que los fotogramas, en el caso del PNG, un fotograma en FullHD puede ocupar unos 5Mb. Así que, imaginad, un minuto de vídeo a 25 fotogramas por segundo ocuparía cerca de 8Gb, lo cual puede no ser viable en muchos casos si no dispones de un disco duro grande sólo para editar. Incluso teniéndolo, no te recomiendo guardar más de 3 minutos seguidos en cada directorio, porque la cantidad de ficheros generada es enorme.

Con este ejemplo podemos sacar el audio en MP3 por un lado, y el vídeo separado en una secuencia de imágenes PNG:

ffmpeg -i origen.mkv destino.mp3 destino_%04d.png

Vemos que el nombre de archivo es un poco raro, con %04d estamos diciéndole que utilice números consecutivos para cada fotograma, y si el número no tiene 4 dígitos complete con ceros a la izquierda, por ejemplo 0001, 0002, 0003, 0004, etc. Debemos hacer una estimación del total de fotogramas que vamos a generar, porque si son más de 9999, hasta ese número, los nombres de archivo tendrán 4 dígitos y a partir del 10000 tendrán 5 dígitos. Esto puede ser un problema para la detección de secuencias de imágenes de algunos programas.

Otro formato interesante es MJPEG, o Motion JPEG. Básicamente es un archivo de vídeo que encierra fotogramas comprimidos en JPEG, tendremos pérdidas, pero el formato JPEG es algo muy trabajado y optimizado prácticamente en todos lados, podremos trabajar con la secuencia de imágenes muy rápidamente. Este formato se ha usado durante mucho tiempo en cámaras, tarjetas capturadoras y otros dispositivos que comprimían vídeo en tiempo real por hardware. Aunque es un formato antiguo, lo bueno es que es muy rápido de codificar y decodificar, que es lo que nos interesa:

ffmpeg -i origen.mp4 -c:a libmp3lame -c:v mjpeg -q:v 0 destino.mjpeg

La calidad la podemos poner desde 0 a 32, aunque a partir de 2 asegura compatibilidad con más programas y dispositivos, aunque, con más pérdidas.

Otra opción interesante es el formato HuffYUV, que también es capaz de comprimir vídeo sin pérdidas, aunque produce archivos muy grandes:

ffmpeg -i origen.mp4 -c:a libmp3lame -pix_fmt rgb24 -c:v huffyuv destino.avi

Tal vez este algoritmo produzca archivos sólo aptos para edición, porque la reproducción puede que no se pueda hacer en tiempo real. Además, en muchos casos, es necesario especificar el formato del pixel, ya que el espacio de color del códec no es el mismo que el espacio de color de origen, y eso puede causar que la imagen sea vea mal.

También podríamos utilizar una variante de HuffYuv, implementada por FFMPEG, llamada ffvhuff, mucho más rápida tanto en su compresión, como en su descompresión. Aunque imaginad, 8 segundos de vídeo ocupan unos 250Mb. ¡Preparad los teras para almacenar vídeo!

ffmpeg -i origen.mp4 -c:a libmp3lame -c:v ffvhuff destino.avi

Otro formato interesante para editar, aunque con pérdidas es MPEG-2, con el que podemos hacer un vídeo sólo con codificación intra-frame, consiguiendo que los accesos a fotograma sean muy rápidos, así como la reproducción de vídeo a un coste bajo de procesador.

ffmpeg -i origen.MTS destino.mp3 -c:v mpeg2video -q:v 0 -qmin 1 -intra destino.m2v

Como hemos intentado tener las menores pérdidas posibles, el fichero resultante ocupa unos 90Mb sin audio (para 8 segundos). Aunque, eligiendo -q:v 2, la calidad perceptual no es tan distinta, y ocupa la mitad, 45Mb. Con MPEG-2, y con otros formatos de compresión con pérdidas tenemos que tener especial cuidado porque los fotogramas producidos no son exactamente iguales a los originales aunque visualmente no notemos diferencia, sobre todo, si en la edición que vamos a hacer vamos a aplicar máscaras o vamos a incorporar elementos en 3D. Si utilizamos el MPEG2 para que la edición sea rápida y luego incorporamos los mismos efectos en el vídeo original, tal vez los resultados no sean los esperados.

Otros códecs que podemos utilizar son DNxHD o UT-Vídeo. El primero, es un códec propietario de Avid que da muy buenos resultados y es muy rápido. De hecho utiliza una compresión intra-frame muy parecida a JPEG. Podemos probarlo así:

ffmpeg -i origen.mkv -b:v 120M -c:v dnxhd -c:a libvo_aacenc destino.mov

El audio, en este caso, lo he almacenado utilizando AAC.

El segundo, es un códec libre y sin pérdidas, muy parecido a HuffYuv, aunque con mejores tasas de compresión. Pensado para comprimir mucho y en tiempo real, de todas formas, los vídeos al ser sin pérdidas y codificación intra-frame, van a ser muy grandes. Unos 200Mb para 8 segundos de vídeo.

Y, ¿por qué no? Podemos utilizar H.264 sin pérdida. Podemos utilizarlo si la edición no es muy intensa (tipo, recortar y colocar, con poca o ninguna corrección de color y como mucho alguna transición entre clips) y tenemos un buen equipo con bastante RAM, ya que muchos programas de edición guardan fotogramas en caché para tener un acceso más rápido. Podemos hacer algo parecido a esto:

ffmpeg -i origen.mts -c:v libx264 -preset ultrafast -x264-params keyint=1 -crf 0 -c:a ac3 destino.mp4

Podemos ver que el vídeo sin pérdidas en H.264 puede ir un poco lento, incluso termina ocupando prácticamente lo mismo que con otros códecs. Lo bueno es que podemos ir aplicando una pequeña pérdida para reducir drásticamente el tamaño del archivo. Dicha pérdida tenemos que evaluarla nosotros, para ver cuánto es comprensible para nosotros. Es decir, la cámara ha introducido pérdidas y al recomprimir voy a introducir más pérdidas, pero tal vez no introduzca muchas y el resultado va a tener buena calidad al fin y al cabo. Podemos probar aumentar el crf a 5 o 6 (reduciendo un 40% el tamaño del archivo), cuando la documentación normalmente dice que 17 es un valor en el que se pueden empezar a apreciar pérdidas en el vídeo. Todo esto es cuestión de probar.
Lo que sí es importante es el keyint=1 que especifica que todos los fotogramas se compriman enteros, al eliminar la compresión entre fotogramas conseguimos que el acceso a fotogramas concretos sea un poco más rápido.

Esto lo podemos probar si hacemos:

ffprobe destino.mp4 -select_streams v -show_frames -show_entries frame=pict_type

Observamos que todos los frames sonde tipo I.

Seguiremos con la conversión de vídeo

Espero que les haya gustado esta introducción a ffmpeg para convertir vídeo entre diferentes formatos. Espero que me dejéis dudas y comentarios tanto en Youtube, como en el blog. En la próxima entrega hablaré sobre la aplicación de filtros sobre los vídeos con ffmpeg, así que, suscribíos al canal para no perderos nada. ¡Os espero!

Foto principal: unsplash-logoDenise Chan

También podría interesarte....

Para descargar videos de la red, si utilizas Windows, recomiendo usar Freemake Video Downloader. El programa proporciona descarga instantánea de vídeos y música desde YouTube y otros sitios web. Puede guardar el vídeo en el formato original o convertirlo a otro formato (MP4, MP3, AVI, 3GP, FLV, WMV, MKV) sin pérdida de calidad. Además, puede limitar la velocidad de descarga y restaurar las descargas interrumpidas. Intente bajar clips de YouTube usando esta herramienta simple y poderosa.

There are 4 comments left Ir a comentario

  1. compartiendobits /
    Usando Mozilla Firefox Mozilla Firefox 58.0 en Ubuntu Linux Ubuntu Linux

    Muy interesante, la verdad.

    Gracias por compartir este tipo de información.

    Saludos.

  2. Region /
    Usando Google Chrome Google Chrome 24.0.1312.70 en Windows Windows 8

    Gaspar Fernández, thanks so much for the post.Much thanks again. Really Cool.

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 57.0 en Linux Linux

      Thanks

  3. FredP /
    Usando Google Chrome Google Chrome 24.0.1312.70 en Windows Windows 8

    Gaspar Fernández, thanks so much for the post.Really thank you! Keep writing.

Leave a Reply