Quería compartir y comentar unas pruebas que he realizado con ffmpeg.
En realidad, lo hago para tener un documento que agrupe lo que he aprendido de FFMPEG y para que me sirva cuando todo esto se me olvide (posiblemente mañana).
Una de las cosas que más me interesaba era encontrar virtudes y aspectos que lo hicieran superior a otras aplicaciones de codificación de vídeo como Adobe Encoder, Compressor, HandBrake o MPEG Streamclip. Buscaba alguna carácterística que lo hiciera diferente al resto ya sea porque escala vídeo a más calidad, porque es más rápido o porque ofrece más calidad por menos peso de archivo. Las aplicaciones con las que comparo FFMPEG son muy buenas. Las he usado, trabajo con ellas a diario y hacen muy bien su trabajo.
En este post no pretendo enseñar el manejo de FFMPEG ya que hay muchos recursos en la red. Lo que me interesa ahora es fijarme en sus características generales.
La primera gran diferencia es el entorno gráfico. Todas las aplicaciones son sencillas de usar y tienen un entorno gráfico que facilita el manejo. FFMPEG no tiene entorno gráfico y se opera desde el terminal. Por tanto la primera consideración es que es menos práctico y más complejo.
NOTA: Para instalar FFMPEG en Mac hay que instalar XCode y Homebrew. Hay muchas referencias en la red.
CODECS
El primer punto interesante es que admite y trabaja con casi todos los codecs conocidos. Al ser software de código abierto pensé que solo usaría codecs libres como en HandBrake pero en Mac trabaja bien con prores y puede multiplexar en .mov perfectamente.
En el caso de usar FFmpeg en Linux la cosa cambia porque no usa los codecs privativos de Apple y otras marcas. Por ejemplo, para H264 utiliza la librería libx264. Otros codecs de código abierto son mp4, VP8 y Theora
La lista de codecs es muy grande. Para verla:
ffmpeg -codecs
Para ver formatos:
ffmpeg -formats
En HandBrake solo se utilizan los formatos Matrioska .mkv y .mp4 y los codecs h264, h265 VP8 y Theora.
En Mac, FFMPEG puede emplear muchos codecs pero no puede exportar a prores 4444. Solo podremos exportar prores 422, no otros tipos de prores como HQ o 4444.
Lo que sí podemos es usar prores 4444 de entrada y pasarlo a cualquier otro formato o mantenerlo como está.
Ejemplo de paso de cualquier formato a prores:
ffmpeg -i INPUT.avi -c:v prores OUTPUT.mov
Si queremos trabajar en alta calidad en Mac hay muchas posibilidades. He probado hacer archivos .mov en Animation y funciona perfectamente:
ffmpeg -i INPUT -codec:v qtrle -codec:a copy OUTPUT.mov
Otra posibilidad es usar el v408. -c:v v408. Es un codec 444 muy bueno pero muy pesado. Un segundo de vídeo en prores 4444 pesa unos 35Mb, con -c:v qtrle (animation) pesa 133 Mb y con -c:v v408 pesa 215 Mb.
CALIDAD
Hay casos en los que queremos mantener la calidad del vídeo, no procesarlo, y simplemente añadirle un audio. Entonces tendremos que escribir -c:v copy. Con esta instrucción indicamos que el codec de vídeo se mantenga igual. Ej:
ffmpeg -i INPUT.mov -i AUDIO.aif -c:v copy -c:a copy OUTPUT.mov
Si queremos conservar la calidad de un vídeo podemos usar –qscale 0. Es el sustituto, tal vez, del obsoleto -sameq
-qscale lo he probado con un archivo .mov Animation y he generado un .mpg de bastante calidad y mucho menos peso. Aparentemente parece no haber perdido calidad aunque sabemos que sí. El vídeo de 1s en Animation pesaba 117 Mb y el resultante en mpg es de 6Mb. Con algo más de banding (normal) en el mpg y cierta pérdida de calidad aunque aceptable para la pérdida de peso que supone.
ffmpeg -i INPUT.mov -qscale 0 OUTPUT.mpg
Animation .mov:
.mpg:
Otras opciones interesantes relacionadas con la calidad de la imagen y audio:
-hq Activa los settings high quality
-c:v -c:a o -codec:v -codec:a Dos formas de forzar el codec que utilizará de salida.
-pix_fmt Formato del pixel. Introduciendo este código podemos ver listado de opciones: ffmpeg -pix_fmts
Si trabajamos en Mac con FFMPEG es importante incluir en las conversiones que hagamos a H264, la opción -pix_fmt yuv420p ya que eso nos permite que el vídeo resultante se pueda ver en Quick Time sin problemas. Si no hacemos esto solo lo podremos ver en VLC. Como dicen por ahí: «…make sure the pixel format is compatible with dumb players»
-qp 0 Máxima calidad. En mis pruebas va de 0 a 70, a partir de 70 no comprime más. Se usa como opción lossless
-b:v o -b:a Bit rate para vídeo y audio. Tasa de bits o tasa de transferencia.
Para H264 podemos codificar en CBR o VBR (bit rate o tasa de bits constante o variable) para ello usamos -crf en constante o -pass 1 y -pass 2 si queremos hacer la codificación de dos pasadas en bit rate variable.
La diferencia entre constante o variable es que con VBR se optimiza más la compresión a base de comparar los cambios en la película y lo hace en uno o dos pases (mejor 2), por lo tanto, conseguimos la misma calidad con menos peso. Si no nos importa lo que ocupe el archivo usaremos CBR.
Ojo a lo que dicen los de Adobe:
«Al comparar archivos CBR y VBR del mismo contenido y del mismo tamaño, puede hacer las siguientes generalizaciones: Un archivo CBR se puede reproducir con más fiabilidad en una gama de sistemas más amplia porque la velocidad de datos fija exige menos del reproductor de medios y el procesador del equipo. Sin embargo, un archivo VBR suele tener una calidad de imagen superior porque VBR se adapta la cantidad de compresión al contenido de la imagen»
Con ambos métodos y teniendo settings similares, podemos conseguir la misma calidad. Sabemos que en VBR pesará menos, luego, a dos archivos que pesen igual, uno en CBR y otro en VBR, el de VBR tendrá más calidad.
Ejemplo usando tasa de transferencia constante.
ffmpeg -i INPUT.mov -c:v libx264 -crf 28 OUTPUT.mp4
La tasa de bits variable también es llamada ABR (Average bit rate)
Ejemplo sencillo de tasa de bits variable:
ffmpeg -i INPUT.mov -c:v libx264 -b:v 1000k OUTPUT.mp4
Con tasa mínima y máxima:
ffmpeg -i INPUT.mov -c:v libx264 -b:v 4000k -minrate 1000k -maxrate 4000k -bufsize 1835k out.mp4
Para codificar con tasa de bits constante en libx264 usaremos -crf de 0 a 51 siendo 0 la más alta calidad (lossless) y 51 la más baja. Normalmente se recomienda de 18 a 28. Si usamos -pix_fmt yuv420p no podremos usar -crf 0, tendremos que usar a partir de 1.
Para hacernos a la idea de tamaños, un vídeo de 1s con -cbf 18 pesa 2.2Mb, con -cbf 1 pesa 17Mb, con -cbf 28 pesa 896kb. 20s de vídeo con -cbf 18 son 61Mb, con -cbf 28 son 15Mb, con -cbf 40 son 4.2Mb.
Para comparar, en ffmpeg, un -cbf de 38-37 equivale en el Adobe Encoder a un CBR de 2Mbps.
En la red hay muchos ejemplos de codificación en h264 en tasa de bits constante y variable.
COMPRESIÓN DEL ARCHIVO/VELOCIDAD
Como he ido descubriendo, FFMPEG tiene muchísimas posibilidades y opciones.
Para optimizar la compresión de un vídeo existen presets que nos facilitan bastante el trabajo.
Los presets marcan la velocidad de codificación. Cuanto más lento, más y mejor comprime; el archivo será menos pesado. No afecta a la calidad. Tipos: ultrafast, superfast, veryfast, faster, fast, medium (the default), slow, slower, veryslow. Por tanto un ultrafast tendrá la misma calidad pero pesará más que un veryslow.
Ejemplo de un lossless en H264 multiplexado en Matrioska y preset rápido (pesará más):
ffmpeg -i INPUT.mov -c:v libx264 -preset ultrafast -qp 0 OUTPUT.mkv
Ejemplo de un lossless en H264 multiplexado en Matrioska y preset lento (pesará menos):
ffmpeg -i INPUT.mov -c:v libx264 -preset veryslow -qp 0 OUTPUT.mkv
Compruebo que FFMPEG es bastante rápido al codificar vídeo y audio. En términos generales creo que supera al Encoder, por lo menos en H264.
Ya que hablo de rapidez quiero comentar que me ha asombrado la velocidad con la que codifica FCPX en H264. Sin duda, creo que es el más rápido. Ni Premiere ni Encoder lo superan en esto.
FILTROS
Otro campo que conviene investigar son los filtros. Con ffmpeg -filters podremos ver el listado de filtros. Existe bastante documentación sobre el tema.
Esta es la lista de filtros que considero más interesantes:
Filters:
T.. = Timeline support
.S. = Slice threading
..C = Command support
A = Audio input/output
V = Video input/output
N = Dynamic number and/or type of input/output
| = Source or sink filter
… copy V->V Copy the input video unchanged to the output.
… null V->V Pass the source unchanged to the output.
… nullsink V->| Do absolutely nothing with the input video.
… concat N->N Concatenate audio and video streams.
TS. dctdnoiz V->V Denoise frames using 2D DCT.
TS. noise V->V Add noise.
T.. hqdn3d V->V Apply a High Quality 3D Denoiser.
T.. owdenoise V->V Denoise using wavelets.
… compand A->A Compress or expand audio dynamic range.
T.. codecview V->V Visualize information about some codecs
… dejudder V->V Remove judder produced by pullup.
… deshake V->V Stabilize shaky video.
… field V->V Extract a field from the input video.
… format V->V Convert the input video to one of the specified pixel formats.
T.. gradfun V->V Debands video quickly using gradients.
T.. il V->V Deinterleave or interleave fields.
… interlace V->V Convert progressive video into interlaced.
… kerndeint V->V Apply kernel deinterlacing to the input.
… mcdeint V->V Apply motion compensating deinterlacing.
T.. w3fdif V->V Apply Martin Weston three field deinterlace.
TS. yadif V->V Deinterlace the input image.
… mpdecimate V->V Remove near-duplicate frames.
… palettegen V->V Find the optimal palette for a given stream.
… paletteuse VV->V Use a palette to downsample an input video stream.
… pixdesctest V->V Test pixel format definitions.
… split V->N Pass on the input to N video outputs.
… scale V->V Scale the input video size and/or convert the image format.
… super2xsai V->V Scale the input by 2x using the Super2xSaI pixel art algorithm.
.S. xbr V->V Scale the input using xBR algorithm.
.S. hqx V->V Scale the input by 2, 3 or 4 using the hq*x magnification algorithm.
.S. signalstats V->V Generate statistics from video analysis.
… mandelbrot |->V Render a Mandelbrot fractal.
… mptestsrc |->V Generate various test pattern.
… smptehdbars |->V Generate SMPTE HD color bars.
… testsrc |->V Generate test pattern.
… avectorscope A->V Convert input audio to vectorscope video output.
… showcqt A->V Convert input audio to a CQT (Constant Q Transform) spectrum video output.
… showspectrum A->V Convert input audio to a spectrum video output.
Como se puede ver con los filtros tenemos muchas posibilidades. Estabilizar vídeo, añadir ruido, generar vectorscopios…
He probado los filtros de escalado para comprobar si alguna de las opciones utiliza un algoritmo milagroso que consigue ampliar la imagen sin pérdida alguna. He realizado la prueba con un vídeo pal ampliando a 2k. Lo he escalado con Adobe Encoder, con Mpeg Streamclip y con 4 métodos de escalado de FFMPEG. Ninguno es milagroso. Todos dan un resultado similar, incluido el Encoder. El único que destaca un poco es el procesado con Mpeg Streamclip porque parece que gana más de nitidez añadiendo algo de sharpen, pero es el que más rompe los colores. Por tanto no hay milagro. Aunque FFMPEG tiene un mínimo de 4 métodos de escalado, ninguno supera a Encoder.
Original en Pal
Escalado con Encoder
Escalado con Mpeg Streamclip
Escalado con FFMPEG scale
Escalado con FFMPEG super2xsai
Escalado con FFMPEG xbr
Escalado con FFMPEG hqx
OTRAS OPCIONES
Al ser un programa abierto, las posibilidades son ilimitadas.
Podemos añadir pista de subtítulos, generar vídeo sin audio, hacerlo a partir de secuencia de imágenes, generar frames negros al comienzo de vídeo o al final, insertar textos, insertar un código de tiempo, rotar, escalar, cambiar aspecto, cropear, unir varios clips, separar las pistas de vídeo y audio…
PARA ACABAR YA DE UNA VEZ…
FFMPEG tiene muchas posibilidades. Podemos tener un control total en el proceso de codificación.
Calidad del vídeo de salida. No he encontrado diferencias en calidad de imagen con otras aplicaciones de codificación de vídeo. Utilizando bien los parámetros del Encoder podemos conseguir la misma calidad de vídeo que con FFMPEG. Posiblemente encontremos alguna diferencia en cuanto a velocidad de codificación entre las distintas aplicaciones pero dependerá de los parámetros que introduzcamos. La única ventaja de FFMPEG en cuanto a calidad es que podemos usar más parámetros para garantizar una calidad óptima.
Para usuarios de Mac que tienen posibilidad de usar Encoder o Compressor, la opción de uso de FFMPEG es incómoda y más lenta en la introducción de parámetros y no por ello consiguen mejores resultados. Aún así, hay funciones de FFMPEG como unir un vídeo y audio o insertar un timecode que se pueden realizar de manera más rápida y eficaz con FFMPEG.
Un aspecto importante para usuarios de Mac: FFMPEG es de código abierto y libre, por tanto, es accesible y podemos programar scripts en Mac que automaticen ciertas operaciones de FFMPEG. Entonces sí que FFMPEG se puede convertir en una herramienta rápida, cómoda y muy potente.
Si el usuario es de Linux la cosa está clara. FFMPEG es su mejor y más potente herramienta. No conozco ninguna aplicación con entorno gráfico, salvo HandBrake, que ofrezca buenas posibilidades y un buen control de los parámetros de codificación.
Como usuario de Debian y CentOs lo tengo claro.