Mejoras en FFmpeg para un rendimiento de encoding superior
Aviso histórico: este artículo de 2015 describe el stack de FFmpeg
v2.2.3. Ese stack llegó al fin de su vida útil el 1 de febrero de 2020 y ya no se acepta. Consulta la documentación de Robots para conocer el valorffmpeg_stackrecomendado actualmente.
Transloadit es un equipo pequeño de ingenieros, es código, es una plataforma altamente escalable, es un conjunto de Robots peculiares a los que puedes pedirles que importen y conviertan medios. En el corazón de estos Robots suelen estar herramientas de código abierto que hacen el trabajo pesado. Una herramienta destaca en particular: FFmpeg.

Historia
Usamos FFmpeg desde que empezamos, allá por 2009. En ese entonces solo teníamos una versión, a la
que ahora llamamos v0.0.1. En 2011, patrocinamos a Stefano Sabatini,
miembro del equipo de desarrollo principal de FFmpeg, para que creara a medida una nueva versión
para nosotros, porque queríamos que nuestros clientes pudieran aplicar marcas de agua a archivos
webm, algo que no era posible en ese momento.
La tecnología siempre avanza rápido y el encoding de medios no es la excepción. Para mantenernos al día, tenemos que seguir actualizando FFmpeg. Al mismo tiempo, sin embargo, no queremos romper las configuraciones existentes de los clientes por problemas de compatibilidad con versiones anteriores. Transloadit ofrece cómodos ajustes preestablecidos, por ejemplo para optimizar un video para iPad, que se migran con relativa facilidad, pero también ofrecemos un control detallado del comportamiento de FFmpeg para usuarios avanzados. Sobre todo esta última categoría de clientes se molestaría, y con razón, si sus instrucciones detalladas dejaran de estar soportadas de repente por una actualización.
Múltiples versiones
El deseo de avanzar sin romper las configuraciones existentes nos llevó a diseñar un sistema en el que las nuevas versiones de nuestras herramientas de encoding pueden coexistir y su adopción es completamente voluntaria.
Hasta ahora, hemos introducido las siguientes versiones de stack:
v0.0.1el 13 de julio de 2009v1.0.0el 27 de abril de 2011v2.0.0el 7 de julio de 2013v2.1.0el 12 de noviembre de 2013v2.2.3el 3 de junio de 2014
Siempre hemos tenido compilaciones personalizadas, por eso publicamos una página dedicada que muestra todos los formatos y códecs soportados por stack.
Lanzamientos graduales
Con los años, hemos acumulado 9905 pruebas automatizadas, muchas de las cuales usan diffs visuales para asegurar que nuestro encoding funciona como se espera. Aun así, siempre aparece ese escenario raro en el que un usuario final raro produce un mp4 raro con un segundo stream de video raro que causa problemas para los que todavía no teníamos pruebas. Por supuesto, al final de ese día sí tendremos esas pruebas listas. 😄
Por esta razón, hasta ahora siempre hemos optado por hacer lanzamientos graduales de nuestras versiones de stack. Normalmente trabajamos junto a un puñado de clientes y, a medida que crece la confianza en la nueva compilación, empezamos a recomendarla a cada vez más clientes.
Con el tiempo, nuestra documentación recomendará esa versión como el stack preferido. Actualización orgánica.
Como nunca hemos declarado obsoleto un stack, este enfoque ha funcionado bien para nosotros y para nuestros clientes. Sin embargo, eso podría cambiar, y te explicamos por qué.
Obsolescencia
Hasta ahora, nunca hemos declarado obsoleto un stack. Sin embargo, la verdad es que con cada stack que añadimos, nuestros despliegues se vuelven un poco más lentos y nuestra carga de soporte al cliente aumenta ligeramente. Además, con cada actualización del sistema operativo que desplegamos en nuestros clústeres, los stacks antiguos se vuelven más difíciles de compilar y menos capaces de ejecutarse sin problemas. Aunque estamos migrando a contenedores, lo que ayudará con estos problemas de compatibilidad, eso no ayudará a reducir nuestra carga de despliegue, soporte y mantenimiento.
Por eso ahora estamos considerando declarar obsoleto nuestro stack de FFmpeg v1.0.0 de 2009 durante
el próximo año. Nos pareció mejor informarte de esto lo antes posible. Desde luego, no haremos nada
imprudente. Es solo porque pensamos en esto hoy que lo compartimos contigo en este momento.
Stack de FFmpeg v2.2.3
nota: nuestro versionado puede parecer SemVer, pero no lo es. Es un versionado interno de Transloadit que no tiene ningún significado semántico público. Cualquier versión puede romper la compatibilidad con versiones anteriores y debe tratarse como tal al actualizar.
Nuestra última versión de stack es la que más orgullo nos da. Claro, v1.0.0 puede haber estado más
tiempo en producción, y ciertamente se adelantó a su época 😄, pero hemos invertido más esfuerzo en
v2.2.3 que en ninguna otra versión. Ya lleva más de un año en producción. Ha visto más tráfico que
cualquiera de sus predecesores. Rara vez (nunca es una palabra peligrosa de la que preferimos
mantenernos lejos) vemos problemas con ella que se puedan achacar a que sea una mala compilación.
El hecho de que la usen algunos de nuestros mayores clientes empresariales, con los casos límite más extremos, nos ha dado la confianza para recomendar de todo corazón esta compilación a todos los clientes, para todas sus necesidades de encoding de audio y video.
Actualización
Considera estas instrucciones de ejemplo en las que las subidas entrantes se convierten al formato iPad, se extraen miniaturas de vista previa y todos los resultados se exportan luego a tu servidor privado vía SFTP:
steps:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
thumbnails:
use : "ipad"
robot : "/video/thumbs"
store:
use : [ ":original", "ipad", "thumbnails" ]
robot : "/sftp/store"
user : "transloadit-uploader"
host : "my.website.com"
path : "./transloadit-uploads"
url_template: "https://my.website.com/transloadit-uploads/${file.url_name}"
Estas instrucciones se han mejorado para facilitar la lectura, pero deben estar codificadas como JSON válido cuando se las envíes a nuestro servicio.
Para cambiar estas instrucciones de modo que usen nuestro último stack, añade un parámetro ffmpeg_stack
en los Steps de encoding:
steps:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
thumbnails:
use : "ipad"
robot : "/video/thumbs"
ffmpeg_stack: "v2.2.3"
store:
use : [ ":original", "ipad", "thumbnails" ]
robot : "/sftp/store"
user : "transloadit-uploader"
host : "my.website.com"
path : "./transloadit-uploads"
url_template: "https://my.website.com/transloadit-uploads/${file.url_name}"
¡Eso es todo! 😄
Puedes aplicar el parámetro ffmpeg_stack a los siguientes Robots:
No solo tu encoding será más rápido, sino que también disfrutarás de mayor calidad y podrás admitir más formatos de entrada que con cualquier versión anterior.
Salvedades
¿Demasiado bueno para ser verdad? Pues no, pero hay un par de cosas a las que prestar atención: el mapeo y los cambios en los nombres de los parámetros.
Mapeo
Todos los ajustes preestablecidos de v2.2.3 (como android o iphone) se han modificado para descartar
cualquier stream de datos y de subtítulos. Muy pocos clientes usaban esos streams, pero como antes
intentábamos darles un lugar en los archivos de salida, y a veces fallábamos al hacerlo, provocamos
sin querer muchos dolores de cabeza a la mayoría de nuestros clientes, que «solo quieren
resultados».
Si dependes de streams de datos o de subtítulos, aún puedes usar los ajustes preestablecidos de
v2.2.3 y aprovechar las otras mejoras de esta versión, pero tendrás que sobrescribir el parámetro
map con 0. De este modo, todos los streams de entrada encontrarán su lugar en el archivo de
salida, a costa de que algunos archivos rompan FFmpeg, ya que este intentará interpretar streams de
datos no soportados.
Un cliente reportó un problema con un archivo de entrada que tenía dos streams de video. Nuestros
ajustes preestablecidos de v2.2.3 intentarán dar un lugar en el archivo nuevo a todos los streams
de video y audio. Si solo te interesa un único stream de video y audio, configura el mapeo así:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
ffmpeg:
map: [
"0:v:0?"
"0:a:0?"
"-0:d"
"-0:s"
]
Aunque esto te da el mapeo más resistente, ten en cuenta que se descartaría un segundo stream del mismo tipo de medio.
Para ser honestos, eso no parece ser un problema para los usuarios finales en el 99 % de los casos que vemos, así que estamos considerando hacerlo el valor por defecto en los ajustes preestablecidos de nuestro próximo stack orientados a dispositivos portátiles.
Siempre recomendamos exportar archivos :original junto con los resultados del encoding, para que, si no
estás conforme con tu configuración, puedas reejecutar fácilmente la Assembly con nuevos
parámetros de encoding.
Cambios en los nombres de los parámetros
Donde antes FFmpeg trabajaba con un parámetro -b para el bitrate de video y -ab para el bitrate
de audio, ahora avanza hacia una sintaxis -b:v y -b:a. Esto también vale para muchos otros
parámetros, como -codec:v frente a -codec:a.
Además de ser más consistente, también te permite ser más expresivo. Por ejemplo, si solo quieres
especificar el códec del segundo stream de audio, podrías escribir -codec:a:1 (el primer stream tiene
el índice 0, así que el segundo es 1).
Así que, si quieres sobrescribir el bitrate de audio de un ajuste preestablecido ipad-high de
v2.2.3, debes tener en cuenta que ab ahora se ha convertido en b:a, o corres el riesgo de que
tus modificaciones al ajuste preestablecido no tengan efecto:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
ffmpeg:
"b:a": 144000
Conclusión
Estamos viendo grandes mejoras con nuestro último stack de FFmpeg. Es más rápido, ofrece mayor calidad, admite streaming en vivo adaptativo (HLS) y mucho más.
Recomendamos a todos nuestros clientes que empiecen a usarlo, aunque al principio sea solo para un pequeño porcentaje de sus Assemblies, y que nos reporten cualquier problema que encuentren más allá de las salvedades que señalamos.
Más adelante este año, dependiendo sobre todo de tus comentarios, planeamos declarar obsoleto
nuestro stack v1.0.0, que para entonces tendrá 7 años, ¡ocasión en la que sin duda brindaremos
juntos! 😄






