最简单的基于 FFmpeg 的视音频复用器
最简单的基于 FFmpeg 的视音频复用器
参考雷霄骅博士的文章,链接:最简单的基于FFmpeg的封装格式处理:视音频复用器(muxer)
正文
本文介绍一个视音频复用器(Muxer)。
视音频复用器(Muxer)即是将视频压缩数据(例如 H.264)和音频压缩数据(例如 AAC)合并到一个封装格式数据(例如MKV)中去。如下图所示。
在这个过程中并不涉及到编码和解码。
本文记录的程序将一个 H.264 编码的视频码流文件和一个 MP3 编码的音频码流文件,合成为一个 MP4 封装格式的文件。
程序的流程如下图所示:
从流程图中可以看出,一共初始化了 3 个 AVFormatContext,其中 2 个用于输入,1 个用于输出。3 个 AVFormatContext 初始化之后,通过 avcodec_copy_context() 函数可以将输入视频/音频的参数拷贝至输出视频/音频的 AVCodecContext 结构体。然后分别分别调用视频输入流和音频输入流的 av_read_frame(),从视频输入流中取出视频的 AVPacket,音频输入流中取出音频的 AVPacket,分别将取出的 AVPacket 写入到输出文件中即可。其间用到了一个不太常见的函数 av_compare_ts(),是比较时间戳用的。通过该函数可以决定该写入视频还是音频。
本文介绍的视音频复用器,输入的视频不一定是 H.264 裸流文件,音频也不一定是纯音频文件。可以选择两个封装过的视音频文件作为输入。程序会从视频输入文件中“挑”出视频流,音频输入文件中“挑”出音频流,再将“挑选”出来的视音频流复用起来。
对于某些封装格式(例如 MP4/FLV/MKV 等)中的 H.264,需要用到名称为“h264_mp4toannexb”的 bitstream filter。这一点在前一篇文章《最简单的基于 FFmpeg 的视音频分离器 - 简化版》中,已经有过详细叙述,这里不再重复。
对于某些封装格式(例如 MP4/FLV/MKV 等)中的 AAC,需要用到名称为“aac_adtstoasc”的 bitstream filter。
简单介绍一下流程中各个重要函数的意义:
- avformat_open_input():打开输入文件。
- avcodec_copy_context():赋值 AVCodecContext 的参数。
- avformat_alloc_output_context2():初始化输出文件。
- avio_open():打开输出文件。
- avformat_write_header():写入文件头。
- av_compare_ts():比较时间戳,决定写入视频还是写入音频。这个函数相对要少见一些。
- av_read_frame():从输入文件读取一个 AVPacket。
- av_interleaved_write_frame():写入一个 AVPacket 到输出文件。
- av_write_trailer():写入文件尾。
源程序:
结果
运行程序,输出如下:
输入文件为:
视频:cuc_ieschool.ts
音频:huoyuanjia.mp3
输出文件为:cuc_ieschool.mp4
输出的文件视频为“cuc_ieschool”,配合“霍元甲”的音频。
工程文件下载
GitHub:UestcXiye / Simplest-FFmpeg-Muxer
CSDN:Simplest FFmpeg Muxer.zip