Como comprimir vídeo com FFmpeg
Para reduzir o tamanho de um vídeo para a web, comece com vídeo H.264 e áudio AAC em um contêiner MP4.
Este comando cria output.mp4 a partir de um input.mp4 local, usando codificação baseada em qualidade:
if [ -e "./output.mp4" ] || [ -L "./output.mp4" ]; then
printf '%s\n' 'Choose a new filename: ./output.mp4 already exists.' >&2
false
else
ffmpeg -n -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -map '0:a:0?' \
-c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p \
-c:a aac -b:a 128k -ac 2 -movflags +faststart "./output.mp4"
fi
A compressão com perdas descarta detalhes. O resultado pode ficar menor, mas uma fonte que já é eficiente pode crescer ao ser recodificada. Guarde o original e compare a saída antes de escolher configurações para outros vídeos. O CRF controla a qualidade; ele não garante um tamanho de arquivo específico.
O comando seleciona o primeiro fluxo de vídeo que não seja arte de capa e a primeira faixa de áudio,
se houver. Ele gera AAC estéreo quando há áudio e, caso contrário, um vídeo sem som. As demais faixas
de áudio, os fluxos de legenda e os fluxos de dados são omitidos. O mapeamento opcional de áudio e a
recusa de sobrescrever com -n estão documentados na referência de comandos do FFmpeg.
-nostdin desativa a entrada interativa, e -xerror interrompe a execução nos erros que o FFmpeg detecta. Um erro
pode deixar uma saída incompleta; não a publique nem trate o tamanho reduzido dela como uma
compressão bem-sucedida.
Verifique os pré-requisitos
Use o Bash no Linux com ffmpeg e ffprobe no seu PATH. Estes exemplos foram testados com o FFmpeg
6.1.1 no Ubuntu 24.04 e com o FFmpeg 9.0.1 no Linux. Eles precisam do codificador de vídeo libx264, do
codificador de áudio nativo aac e do muxer MP4. Verifique a sua build:
ffmpeg -version &&
ffprobe -version &&
ffmpeg -hide_banner -h encoder=libx264 &&
ffmpeg -hide_banner -h encoder=aac
A saída da ajuda deve descrever os dois codificadores; uma mensagem “unknown” ou “not recognized” significa que a build não serve, mesmo que o comando de ajuda termine com status de sucesso. Se você precisar do FFmpeg, a página de download dele traz links para pacotes Linux e builds para macOS e Windows. Os exemplos de shell aqui são para Linux.
Use um clipe progressivo, com faixa dinâmica padrão (SDR), pixels quadrados e largura e altura pares.
Estes comandos não redimensionam o vídeo nem fazem mapeamento de tons HDR. yuv420p seleciona vídeo
8 bits 4:2:0; ele não transforma cores HDR em cores SDR corretas. Mantenha os nomes de arquivo entre
aspas, incluindo o prefixo ./ para nomes que começam com hífen. Cada codificação se recusa a
substituir um MP4 existente, então escolha um novo destino ao comparar configurações. A verificação do
shell também retorna um status de falha para um destino existente: a própria recusa de sobrescrever
do FFmpeg pode terminar com status de sucesso em algumas versões.
Escolha o CRF e a predefinição separadamente
Para libx264, comece com CRF 23. Experimente 20 se textos pequenos ou detalhes finos parecerem
danificados, ou 26 se reduzir bytes for mais importante. Valores de CRF mais baixos mantêm mais
detalhes e costumam gerar arquivos maiores; valores mais altos trocam mais detalhes por menos bytes.
Recodifique a partir do original em cada comparação.
A predefinição controla quanto trabalho de codificação o x264 realiza. medium é um ponto de partida
razoável; slow gasta mais tempo buscando formas eficientes de codificar o vídeo. Isso pode
melhorar a eficiência da compressão, mas não promete uma economia percentual fixa nem qualidade
idêntica com o mesmo CRF. Consulte as opções do codificador x264 para conhecer os
controles separados de qualidade e de predefinição.
Valores de CRF e nomes de predefinições pertencem a um codificador. CRF 23 no x264 não equivale em
qualidade ao mesmo valor no x265, VP9 ou AV1, e slow não é uma escala de qualidade compartilhada
entre codificadores. Se a resolução da fonte for maior do que a exibida, redimensionar pode ajudar mais
do que aumentar ainda mais o CRF, mas inspecione textos pequenos e outros detalhes no tamanho de
exibição pretendido antes de descartar pixels.
Comparação de qualidade e tamanho de arquivo
Inspecione a fonte e a saída com o ffprobe. Isto exibe as propriedades dos fluxos, a duração em segundos e o tamanho do arquivo em bytes:
ffprobe -v error -show_format -show_streams -of json "./input.mp4" &&
ffprobe -v error -show_format -show_streams -of json "./output.mp4"
Procure codec_name: "h264" e pix_fmt: "yuv420p" no fluxo de vídeo. Para uma fonte sem metadados de rotação,
a largura e a altura devem coincidir. Um fluxo de áudio deve informar aac com dois canais se a
entrada tinha áudio. Compare format.size e format.duration com a fonte. Pequenas diferenças de
preenchimento de áudio são normais; perder segundos de conteúdo não é.
Decodifique o resultado completo para detectar erros além dos metadados:
ffmpeg -v error -nostdin -xerror -i "./output.mp4" \
-map 0:V:0 -map '0:a:0?' -f null -
Uma decodificação bem-sucedida não produz nenhuma saída de erro aqui. Ela não mede a qualidade visual. Reproduza os dois arquivos no tamanho de exibição pretendido e inspecione movimento, gradientes, textos pequenos e a sincronia do áudio. Um arquivo menor só é útil se a imagem e o som continuarem aceitáveis para a sua página.
Use duas passagens para um limite de tamanho
Quando você tiver um limite de upload, escolha uma taxa de bits média em vez do CRF. Um cálculo
inicial é video bits/s = (target bytes × 8 ÷ duration seconds) − audio bits/s. Reserve parte do orçamento total para o contêiner e para a variação da
taxa de bits e, depois, meça o arquivo concluído. A codificação em duas passagens busca uma taxa de
bits média de vídeo; ela não é um limite exato de bytes.
Por exemplo, um clipe de 60 segundos abaixo de 10 MB (10.000.000 bytes) tem cerca de 1.333 kbit/s
disponíveis no total. Reservando 5% e destinando 128 kbit/s ao áudio, sobram cerca de 1.139 kbit/s
para o vídeo. Arredonde para baixo, para 1100k, em uma primeira tentativa. Use a duração real da sua
fonte informada pelo ffprobe e recalcule para um limite diferente. Sem áudio, este exemplo deixa a
reserva de áudio sem uso.
Execute este bloco completo no Bash. Ele cria target.mp4 independentemente da saída anterior com CRF:
(
if [ -e "./target.mp4" ] || [ -L "./target.mp4" ]; then
printf '%s\n' 'Choose a new filename: ./target.mp4 already exists.' >&2
exit 1
fi
pass_dir=$(mktemp -d) || exit 1
trap 'rm -rf -- "$pass_dir"' EXIT
ffmpeg -y -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -c:v libx264 -b:v 1100k -preset medium -pix_fmt yuv420p \
-pass 1 -passlogfile "$pass_dir/stats" -an -f null /dev/null &&
ffmpeg -n -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -map '0:a:0?' \
-c:v libx264 -b:v 1100k -preset medium -pix_fmt yuv420p \
-pass 2 -passlogfile "$pass_dir/stats" \
-c:a aac -b:a 128k -ac 2 -movflags +faststart "./target.mp4"
)
A primeira passagem coleta estatísticas; && impede que a segunda passagem seja executada se a
primeira falhar. O diretório temporário mantém os logs das passagens separados entre
execuções e é removido quando o bloco termina. O -y da primeira passagem se aplica apenas à saída
descartada em /dev/null; a segunda passagem usa -n para proteger target.mp4. Mantenha a
entrada, a taxa de bits, a predefinição e quaisquer filtros de vídeo iguais entre as passagens.
Repita os comandos de inspeção e decodificação com target.mp4 no lugar de output.mp4. Se ele
ultrapassar o seu limite, reduza a taxa de bits do vídeo e execute as duas passagens de novo com um
novo nome de arquivo de saída. Se a imagem ficar inaceitável antes de o arquivo caber no limite,
reconsidere a duração ou a resolução. Apenas trocar de codec não garante um resultado aceitável
dentro de qualquer orçamento.
Compatibilidade com navegadores
H.264 é o codec de vídeo; MP4 é o contêiner que armazena esse vídeo e o áudio AAC. Essa é uma combinação inicial prática para ampla reprodução na web, mas o suporte também depende do navegador, do sistema operacional, do perfil e do nível do codec, da resolução e do decodificador do dispositivo. Por exemplo, o Firefox pode depender dos codecs do sistema operacional para H.264. Consulte o guia de codecs de vídeo do MDN e teste o arquivo real nos navegadores e dispositivos que você atende. HEVC, VP9 e AV1 são alternativas a avaliar para esse público, não substitutos universalmente melhores ou universalmente suportados.
-movflags +faststart coloca o índice do MP4 antes dos dados de mídia, permitindo que um player compatível
comece a reprodução sem precisar baixar primeiro o final do arquivo. Isso não reduz o tamanho do
vídeo codificado nem cria versões para streaming adaptativo. A
documentação do muxer MP4 explica
essa etapa extra de indexação. Mesmo com uma decodificação local bem-sucedida, ainda é preciso testar
a reprodução no seu servidor web e no seu player reais antes do lançamento.
Reutilize as configurações com cuidado
Teste as configurações escolhidas em clipes representativos antes de codificar uma coleção. Uma gravação de tela com textos pequenos e um clipe de câmera na mão podem precisar de valores de CRF diferentes. Mantenha um destino separado para cada fonte e verifique o status de cada comando antes de inspecionar ou publicar a saída dele. Depois de uma codificação com falha, escolha um novo nome de saída ou remova apenas o arquivo incompleto que você acabou de criar; a recusa de sobrescrever também se aplica a arquivos parciais deixados por execuções anteriores.
