ffmpeg可使用filter实现各种复杂的操作,混音只是其中一小部分功能。代码实现因为参考已经说的较为详细,我这里补充一些我认为重要的。
1、命令实现
ffmpeg -i dragen.opus -i Monsters.opus -filter_complex "[0:a]aresample=8000[a0];
[1:a]adelay=delays=6400|6400,aresample=8000[a1];[a0][a1]amix=inputs=2" -b:a 20k
-y mixer.aac -v debug
实现功能:将输入的两个音频文件合成一路码率20kbit/s的aac文件,两个音频文件均重采样为8K HZ,其中第二个文件的两个通道都延迟6400ms混入输出。
命令参数解释
- [0:a],[1:a] : 分别代表输入的两个文件第一个及第二个,如果多个文件,以此类推;如[10:a]第11个输入文件;
- aresample : 重采样filter,重采样音频,具体可查看 ffmpeg官方的filter文档
- adelay: 音频延时多少在输出,这里是第二个文件的两个通道都延迟6400ms,delays的单位可以是采样帧数,用大写S标记,如adelay=dealys=500S|700S, 如果精度到秒级别的话可以用adelay=dealys=5s|5s,延时5秒。 详细见adelay文档
- amix: 混音filter,参数inputs的值为输入文件数量,此处是两个音频输入文件;
命令输出的一些关于filter的信息
2、重要概念
2.1、滤镜(filter)
功能实现的基本单元,每个滤镜有特定功能,如aresample,aformat,不同的滤镜之间用“,”隔开,如下
《1》、
adelay=delays=6400|6400,aresample=8000
同一个滤镜的参数直接用“:”隔开,如下:
《2》、
aformat=sample_fmts=fltp:channel_layouts=stereo:sample_rates=8000
2.2、滤镜链(filterchain)
由滤镜组成的链表,几个滤镜流水线协作完成一个复杂功能,如[1:a]adelay=delays=6400|6400,aresample=8000是由两个滤镜组成的滤镜链,不同的滤镜链之间用";"隔开。在命令行格式中每个滤镜链的输出可以用一个[name]的的形式代表,
ffmpeg -i dragen.aac -i Monsters.aac -filter_complex "[0:a]aresample=8000[a0];
[1:a]aresample=8000[a1];[a0][a1]amix=inputs=2:duration=first:dropout_transition=2"
-b:a 9600 -y mix_t.aac
上面这个命令中[0:a]的滤镜链的输出用[a0]代替,[1:a]的输出用[a1]代替然后amix的输入为[a0][a1]
2.3、滤镜图(filtergraph)
实现整个功能的所有滤镜链的集合,上述1的命令-filter_complex之后双引号里的组成一个图。
3、代码补充说明
代码实现主要是参考4.1博主和ffmpeg自带的filtering_audio.c,在参考4.1.的博客中已经给出很详细的demo实现,以下做些补充
3.1、打印构建的filter直观图
char *temp = avfilter_graph_dump(filter_graph, NULL);
printf("filter_graph: %s\n", temp);
输出类似于
仔细看会发现上面自动添加了aresample filter(所有输入都被重采样为8K,所以不同担心输入采样率不同的问题),我的filter描述如下是没有的
这个是ffmpeg根据你的输入输出自动加入的,默认开启,可以通下面这个函数进行关闭
avfilter_graph_set_auto_convert(filter_graph,AVFILTER_AUTO_CONVERT_NONE);
3.2 filter参数设置
代码中一个filter哪些参数需要设置可以参考官方文档,如下面设置的abuffer参数就可以由官方文档获得参考。
abuffer所有的参数如下
3.3、 不同采样率输入文件问题
如果输入的文件采样率不同使用参考4.1博客的代码会有问题,需要设置AVFilterLink input的min_samples,将其设置为你音频格式的帧率,如AAC的1024,也许还有其它方法,我目前是这么解决的。
3.4、flush操作
记得flush所有编解码器及buffersink,不然有些帧就丢了,文件稍有截短,可参考ffpmpge的transcoding.c文件的flush操作流程。
最终输出aac文件,有类似于执行命令的一些log
4、 参考
《1》、FFmpeg 混音学习【三】两路混流完整代码
《2》、ffmpeg官方filter