- Aborda a estrutura e o uso do framework FFmpeg, capaz de codificar, decodificar, transcodificar e fazer streaming de áudio e vídeo
- Explica de forma concreta o papel de ferramentas de linha de comando como ffmpeg, ffplay, ffprobe e de bibliotecas centrais como libavcodec, libavformat, libavfilter
- Implementa passo a passo o processo de análise de streams e decodificação com foco em AVFormatContext, AVCodecContext, AVPacket, AVFrame
- Usa o sistema de build meson/ninja para baixar e compilar automaticamente o código de exemplo, analisar arquivos de mídia de amostra e exibir os resultados
- Pode ser usado como material introdutório prático para entender o funcionamento interno do FFmpeg e o pipeline de decodificação
Composição do pacote FFmpeg
- FFmpeg é composto por um conjunto de ferramentas e bibliotecas capaz de codificar, decodificar, transcodificar vários formatos de áudio e vídeo e fazer streaming pela rede
-
Ferramentas do FFmpeg
- ffmpeg: ferramenta de conversão de formatos multimídia via linha de comando
- ffplay: player de mídia simples baseado em SDL e nas bibliotecas do FFmpeg
- ffprobe: ferramenta para analisar streams multimídia
-
Bibliotecas do FFmpeg
- libavformat: fornece funções de entrada/saída e muxing/demuxing
- libavcodec: fornece funções de codificação/decodificação
- libavfilter: processamento de mídia bruta por meio de filtros baseados em grafo
- libavdevice: suporte a dispositivos de entrada/saída
- libavutil: fornece utilitários multimídia comuns
- libswresample: suporta reamostragem de áudio, conversão de formato de amostra e mixagem de áudio
- libswscale: funções de conversão de cor e redimensionamento de imagem
- libpostproc: funções de pós-processamento de vídeo (deblocking, filtros de ruído etc.)
Player simples com FFmpeg
- A forma básica de uso do FFmpeg é fazer demux de um stream multimídia para separá-lo em streams de áudio e vídeo e então decodificá-los em dados brutos de áudio/vídeo
-
Principais estruturas
- AVFormatContext: estrutura de nível superior que gerencia sincronização do stream, metadados e muxing
- AVStream: stream contínuo de áudio ou vídeo
- AVCodec: define o método de codificação e decodificação dos dados
- AVPacket: dados codificados dentro do stream
- AVFrame: frame de vídeo bruto decodificado ou amostras de áudio
-
Processo de análise de stream e demux
- Aloca memória para AVFormatContext com
avformat_alloc_context()
- Abre o arquivo multimídia com
avformat_open_input()
- Analisa as informações dos streams no arquivo com
avformat_find_stream_info()
- Exibe time base, frame rate, tempo inicial, duração, tipo e código FourCC de cada stream
- Fecha o arquivo e libera a memória com
avformat_close_input()
-
Busca e inicialização de codec
- Busca o decodificador correspondente ao ID de codec do AVStream com
avcodec_find_decoder()
- No caso de stream de vídeo, exibe a resolução (width, height); no caso de áudio, o número de canais e sample rate
- Cria o AVCodecContext com
avcodec_alloc_context3()
- Aplica os parâmetros de codec do stream ao contexto do decodificador com
avcodec_parameters_to_context()
- Abre o decodificador com
avcodec_open2()
-
Leitura e decodificação de pacotes
- Aloca as estruturas
AVPacket e AVFrame para armazenar respectivamente pacotes codificados e frames decodificados
- Lê os pacotes sequencialmente do arquivo de entrada com
av_read_frame()
- Identifica de qual stream o pacote veio por meio do stream_index do pacote
- Envia ao decodificador apenas os pacotes do stream de vídeo selecionado (
first_video_stream_index)
- Entrega o pacote ao decodificador com
avcodec_send_packet()
- Recebe repetidamente os frames decodificados com
avcodec_receive_frame()
- Exibe o número de cada frame, tipo (I/P/B), formato, PTS e se é keyframe
- Reaproveita a memória do pacote com
av_packet_unref()
- Ao final do processamento, libera a memória com
av_packet_free(), av_frame_free(), avcodec_free_context(), avformat_close_input()
-
Exemplo de execução e resultado
- O código de exemplo é fornecido no repositório do GitHub
- Pode ser compilado com meson e ninja (
pip3 install meson ninja)
- Ao executar
meson setup build, o FFmpeg é baixado e configurado automaticamente
- Após compilar com
ninja -C build, execute com ./build/ffmpeg-101 sample.mp4
- O resultado mostra o formato do arquivo, informações dos streams (vídeo/áudio), codec, resolução, sample rate, o PTS de cada pacote e as informações dos frames decodificados
-
Resumo do exemplo de saída
- Stream de vídeo: H.264 (avc1), resolução 206x80, frame rate de 30fps
- Stream de áudio: AAC (mp4a), 2 canais, 44.1kHz
- O PTS de cada pacote e o tipo de frame (I/P) são exibidos em sequência, e o processo de decodificação é mostrado no console
Ambiente de build e execução
- Ferramentas necessárias: Python, pip, meson, ninja
- Comando de instalação:
pip3 install meson ninja
-
Procedimento de build
- Extraia o arquivo compactado de exemplo para a pasta
ffmpeg-101
- Execute
meson setup build
- Compile com
ninja -C build
- Execute com
./build/ffmpeg-101 sample.mp4
- Se o FFmpeg não estiver instalado no sistema, ele será baixado e configurado automaticamente
1 comentários
Comentários do Hacker News
Para quem quer entender profundamente como o FFmpeg e o libav funcionam por dentro, recomendo fortemente o tutorial de Leandro Moreira
Pessoalmente, é a explicação mais completa e clara que já vi até hoje
Link para o tutorial FFmpeg-libav
Surpreende que já estejamos no ffmpeg 101. Parece que o ffmpeg 8 saiu ontem
Compartilha outro guia
Link para o guia relacionado no HN
FFmpeg, uma ferramenta que eu realmente adoro
Foi um ótimo material introdutório sobre ffmpeg. Obrigado
O ffmpeg é um verdadeiro superpoder
Eu sempre uso quando preciso montar vários trechos de vídeo em um único formato reproduzível