Aprimorando o FFmpeg para um desempenho de codificação superior
Aviso histórico: este artigo de 2015 descreve o stack FFmpeg
v2.2.3. Esse stack chegou ao fim de vida (End of Life) em 1º de fevereiro de 2020 e não é mais aceito. Consulte a documentação do Robot para ver o valor deffmpeg_stackrecomendado atualmente.
A Transloadit é uma pequena equipe de engenheiros, é código, é uma plataforma altamente escalável, é um bando de Robots peculiares aos quais você pode pedir para importar e converter mídia. No coração desses Robots, muitas vezes estão ferramentas de código aberto que fazem o trabalho pesado. Uma ferramenta se destaca em particular: FFmpeg.

Histórico
Usamos o FFmpeg desde que começamos, lá em 2009. Naquela época, tínhamos apenas uma versão, que hoje
chamamos de v0.0.1. Em 2011, patrocinamos o desenvolvedor do núcleo do FFmpeg
Stefano Sabatini para criar sob medida uma nova versão para nós, porque queríamos que nossos clientes
pudessem aplicar marca-d’água em arquivos webm, algo que não era possível na época.
A tecnologia sempre avança rápido, e a codificação de mídia não é exceção. Para nos mantermos atualizados, precisamos continuar atualizando o FFmpeg. Ao mesmo tempo, porém, não queremos quebrar as configurações existentes dos clientes por problemas de compatibilidade com versões anteriores. A Transloadit oferece predefinições práticas, por exemplo para otimizar um vídeo para iPad, que são portadas com relativa facilidade, mas também oferecemos controle refinado sobre o comportamento do FFmpeg para usuários avançados. Especialmente essa última categoria de clientes ficaria, com razão, bastante irritada se suas instruções detalhadas deixassem de ser compatíveis de repente por causa de uma atualização.
Múltiplas versões
O desejo de evoluir sem quebrar as configurações existentes nos levou a projetar um sistema em que novas versões das nossas ferramentas de codificação podem coexistir e ser totalmente opcionais.
Até agora, lançamos as seguintes versões de stack:
v0.0.1em 13 de julho de 2009v1.0.0em 27 de abril de 2011v2.0.0em 7 de julho de 2013v2.1.0em 12 de novembro de 2013v2.2.3em 3 de junho de 2014
Sempre tivemos builds personalizados, e é por isso que geramos uma página dedicada que mostra todos os formatos e codecs compatíveis de cada stack.
Lançamentos graduais
Ao longo dos anos, acumulamos 9905 testes automatizados, muitos dos quais usam comparações visuais para garantir que nossa codificação funcione como esperado. Mesmo assim, sempre existe aquele cenário estranho em que um usuário final incomum produz um mp4 esquisito com um segundo stream de vídeo estranho que causa problemas para os quais ainda não tínhamos testes. Claro que, ao fim desse dia, nós teremos esses testes implementados. 😄
Por esse motivo, até agora sempre optamos por lançamentos graduais das nossas versões de stack. Normalmente trabalhamos com um punhado de clientes e, à medida que a confiança no novo build cresce, começamos a recomendá-lo para cada vez mais clientes.
Por fim, nossa documentação passa a recomendar a versão como o stack preferencial. Uma atualização orgânica.
Como nunca descontinuamos um stack, essa abordagem funcionou bem para nós e para nossos clientes. No entanto, isso pode mudar, e vamos explicar por quê.
Descontinuação
Até agora, nunca descontinuamos um stack. A verdade, porém, é que a cada stack que adicionamos, nossos deploys ficam um pouco mais lentos e nossa carga de suporte ao cliente aumenta um pouco. Além disso, a cada atualização de sistema operacional que aplicamos aos nossos clusters, stacks antigos ficam mais difíceis de compilar e menos capazes de rodar sem problemas. Embora estejamos migrando para contêineres, o que vai ajudar com esses problemas de compatibilidade, eles não vão ajudar a reduzir nossa carga de deploy, suporte e manutenção.
É por isso que agora estamos considerando descontinuar nosso stack FFmpeg v1.0.0, de 2009, no próximo ano.
Achamos melhor informar você sobre isso o quanto antes. Certamente não faremos nada de forma
imprudente. Estamos compartilhando isso com você agora apenas porque pensamos nisso hoje.
Stack do FFmpeg v2.2.3
Observação: nosso versionamento pode parecer SemVer, mas não é. É um versionamento interno da Transloadit, sem significado semântico público. Qualquer versão pode quebrar a compatibilidade com versões anteriores e deve ser tratada dessa forma durante a atualização.
Nossa versão de stack mais recente é a que mais nos orgulha. Claro, o v1.0.0 pode estar em produção há
mais tempo, e certamente estava à frente do seu tempo 😄, mas investimos mais esforço no v2.2.3 do
que em qualquer outra versão. Ele já está em produção há mais de um ano e já recebeu mais tráfego do
que qualquer um de seus antecessores. Raramente (nunca é uma palavra perigosa, da qual preferimos
manter distância) vemos problemas com ele que possam ser atribuídos ao fato de ele ser um build ruim.
Ter sido usado por alguns dos nossos maiores clientes corporativos, com os casos mais extremos, nos deu a confiança para recomendar este build de coração a todos os clientes, para todas as suas necessidades de codificação de áudio e vídeo.
Atualização
Considere estas instruções de exemplo, em que os uploads recebidos são convertidos para o formato do iPad, miniaturas de pré-visualização são extraídas e todos os resultados são então exportados para o seu servidor privado via 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 instruções foram aprimoradas para facilitar a leitura, mas devem ser codificadas como JSON válido quando você as enviar ao nosso serviço.
Para que essas instruções passem a usar nosso stack mais recente, adicione um parâmetro ffmpeg_stack
nos Steps de codificação:
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}"
É só isso! 😄
Você pode aplicar o parâmetro ffmpeg_stack aos seguintes Robots:
Além de a sua codificação ficar mais rápida, você também vai ter uma qualidade maior e poderá oferecer suporte a mais formatos de entrada do que com qualquer versão anterior.
Ressalvas
Bom demais para ser verdade? Bem, não, mas há alguns pontos aos quais você deve ficar atento: o mapeamento e os nomes de parâmetros alterados.
Mapeamento
Todas as predefinições v2.2.3 (como android ou iphone) foram ajustadas para descartar quaisquer
streams de dados e de legendas. Pouquíssimos clientes usavam esses streams, mas, como antes tentávamos
dar a eles um lugar nos arquivos de saída, e às vezes falhávamos nisso, acabamos causando sem querer
muita dor de cabeça para a maioria dos nossos clientes, que “só querem resultados”.
Se você depende de streams de dados ou de legendas, ainda pode usar as predefinições v2.2.3 e aproveitar as
outras melhorias desta versão, mas terá que sobrescrever o parâmetro map com 0. Assim,
todos os streams de entrada terão seu lugar no arquivo de saída, ao custo de alguns arquivos fazerem o
FFmpeg falhar, já que ele tentará interpretar streams de dados não suportados.
Um cliente relatou um problema com um arquivo de entrada que tinha dois streams de vídeo. Nossas
predefinições v2.2.3 tentarão dar a todos os streams de vídeo e áudio um lugar no novo arquivo. Se você
só tem interesse em um único stream de vídeo e de áudio, defina o mapeamento como:
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"
]
Embora isso ofereça o mapeamento mais resiliente, observe que um segundo stream do mesmo tipo de mídia seria descartado.
Para ser sincero, isso não parece ser um problema para os usuários finais em 99% dos casos que vemos, por isso estamos considerando tornar esse o padrão nas predefinições do nosso próximo stack voltadas a dispositivos portáteis.
Sempre recomendamos exportar arquivos :original junto com os resultados da codificação, para que, se você
não ficar satisfeito com suas configurações, possa reexecutar facilmente a Assembly com
novos parâmetros de codificação.
Nomes de parâmetros alterados
Antes, o FFmpeg trabalhava com um parâmetro -b para o bitrate de vídeo e -ab para o bitrate de
áudio, mas agora está migrando para uma sintaxe -b:v e -b:a. Isso também vale para muitos outros
parâmetros, como -codec:v versus -codec:a.
Além de ser mais consistente, isso também permite que você seja mais expressivo. Por exemplo, se você
quiser especificar apenas o codec do segundo stream de áudio, poderá escrever -codec:a:1 (o primeiro
stream tem o índice 0, então o segundo é 1).
Portanto, se você quiser sobrescrever o bitrate de áudio de uma predefinição ipad-high do v2.2.3, precisa
saber que ab agora virou b:a, ou corre o risco de seus modificadores de predefinição não
terem efeito:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
ffmpeg:
"b:a": 144000
Conclusão
Estamos vendo grandes melhorias com nosso stack FFmpeg mais recente. Ele é mais rápido, oferece qualidade superior, suporta streaming ao vivo adaptativo (HLS) e muito mais.
Recomendamos que todos os nossos clientes comecem a usá-lo, mesmo que inicialmente apenas em uma pequena porcentagem de suas Assemblies, e nos informem sobre quaisquer problemas que encontrarem além das ressalvas que mencionamos.
Ainda este ano, dependendo principalmente do seu feedback, planejamos descontinuar nosso stack
v1.0.0, que até lá terá 7 anos, ocasião em que certamente vamos brindar juntos! 😄






