- Aborda la estructura y el uso del framework FFmpeg, que permite codificar, decodificar, transcodificar y hacer streaming de audio y video
- Explica en detalle el papel de herramientas de línea de comandos como ffmpeg, ffplay, ffprobe y de bibliotecas clave como libavcodec, libavformat, libavfilter
- Implementa paso a paso el análisis de streams y el procedimiento de decodificación centrado en AVFormatContext, AVCodecContext, AVPacket, AVFrame
- Usa el sistema de compilación meson/ninja para descargar y compilar automáticamente el código de ejemplo, analizar archivos multimedia de muestra y mostrar los resultados
- Puede usarse como material introductorio práctico para entender el funcionamiento interno de FFmpeg y el pipeline de decodificación
Composición del paquete FFmpeg
- FFmpeg está compuesto por un conjunto de herramientas y bibliotecas capaz de codificar, decodificar, transcodificar distintos formatos de audio y video, y transmitirlos por red mediante streaming
-
Herramientas de FFmpeg
- ffmpeg: herramienta de conversión de formatos multimedia basada en línea de comandos
- ffplay: reproductor multimedia sencillo basado en SDL y las bibliotecas de FFmpeg
- ffprobe: herramienta para analizar streams multimedia
-
Bibliotecas de FFmpeg
- libavformat: proporciona funciones de entrada/salida y muxing/demuxing
- libavcodec: proporciona funciones de codificación/decodificación
- libavfilter: procesamiento de medios sin procesar mediante filtros basados en grafos
- libavdevice: soporte para dispositivos de entrada/salida
- libavutil: proporciona utilidades multimedia comunes
- libswresample: soporte para resampling de audio, conversión de formato de muestras y mezcla de audio
- libswscale: funciones de conversión de color y escalado de imagen
- libpostproc: funciones de posprocesamiento de video (deblocking, filtros de ruido, etc.)
Reproductor simple con FFmpeg
- La forma básica de uso de FFmpeg consiste en hacer demux del stream multimedia para separarlo en streams de audio y video, y luego decodificarlo a datos raw de audio/video
-
Estructuras principales
- AVFormatContext: estructura superior que gestiona la sincronización del stream, los metadatos y el muxing
- AVStream: stream continuo de audio o video
- AVCodec: define el método de codificación y decodificación de datos
- AVPacket: datos codificados dentro del stream
- AVFrame: frame de video sin procesar o muestra de audio decodificada
-
Proceso de análisis del stream y demux
- Asignar memoria para AVFormatContext con
avformat_alloc_context()
- Abrir el archivo multimedia con
avformat_open_input()
- Analizar la información de los streams del archivo con
avformat_find_stream_info()
- Mostrar la base de tiempo (time base), frame rate, tiempo de inicio, duración, tipo y código FourCC de cada stream
- Cerrar el archivo y liberar memoria con
avformat_close_input()
-
Búsqueda e inicialización del códec
- Buscar el decodificador correspondiente al ID de códec de AVStream con
avcodec_find_decoder()
- En el caso de un stream de video, mostrar la resolución (width, height); en el caso de audio, mostrar cantidad de canales y sample rate
- Crear AVCodecContext con
avcodec_alloc_context3()
- Aplicar al contexto del decodificador los parámetros de códec del stream con
avcodec_parameters_to_context()
- Abrir el decodificador con
avcodec_open2()
-
Lectura de paquetes y decodificación
- Asignar las estructuras
AVPacket y AVFrame para almacenar respectivamente paquetes codificados y frames decodificados
- Leer los paquetes secuencialmente desde el archivo de entrada con
av_read_frame()
- Identificar de qué stream provienen mediante el stream_index del paquete
- Enviar al decodificador solo los paquetes del stream de video seleccionado (
first_video_stream_index)
- Pasar el paquete al decodificador con
avcodec_send_packet()
- Recibir repetidamente los frames decodificados con
avcodec_receive_frame()
- Mostrar el número, tipo(I/P/B), formato, PTS y si es keyframe de cada frame
- Reutilizar la memoria del paquete con
av_packet_unref()
- Cuando todo termina, liberar memoria con
av_packet_free(), av_frame_free(), avcodec_free_context(), avformat_close_input()
-
Ejecución y ejemplo de resultados
- El código de ejemplo está disponible en el repositorio de GitHub
- Puede compilarse con meson y ninja (
pip3 install meson ninja)
- Al ejecutar
meson setup build, FFmpeg se descarga y configura automáticamente
- Compilar con
ninja -C build y ejecutar con ./build/ffmpeg-101 sample.mp4
- El resultado muestra el formato del archivo, la información de los streams (video/audio), el códec, la resolución, el sample rate, el PTS de cada paquete y la información de los frames decodificados
-
Resumen del ejemplo de salida
- Stream de video: H.264 (avc1), resolución 206x80, frame rate de 30fps
- Stream de audio: AAC (mp4a), 2 canales, 44.1kHz
- El PTS de cada paquete y el tipo de frame (I/P) se muestran en secuencia, y el proceso de decodificación se imprime en la consola
Entorno de compilación y ejecución
- Herramientas necesarias: Python, pip, meson, ninja
- Comando de instalación:
pip3 install meson ninja
-
Procedimiento de compilación
- Extraer el archivo comprimido de ejemplo en la carpeta
ffmpeg-101
- Ejecutar
meson setup build
- Compilar con
ninja -C build
- Ejecutar con
./build/ffmpeg-101 sample.mp4
- Si FFmpeg no está instalado en el sistema, se descarga y configura automáticamente
1 comentarios
Opiniones de Hacker News
Para quienes quieren entender a fondo cómo funcionan internamente FFmpeg y libav, recomienda mucho el tutorial de Leandro Moreira
Personalmente, es la explicación más completa y clara que ha visto hasta ahora
Enlace al tutorial de FFmpeg-libav
Sorprende que ya vayamos en ffmpeg 101. Se siente como si ffmpeg 8 hubiera salido ayer
Comparte otra guía
Enlace a la guía relacionada en HN
FFmpeg, una herramienta que realmente ama
Fue un excelente material introductorio de ffmpeg. Gracias
ffmpeg es un verdadero superpoder
Siempre lo usa cuando necesita ensamblar varios fragmentos de video en una sola forma reproducible