文章目录
**流媒体过滤器 - AVFilter**
**函数说明** :
**函数名称** : **avfilter_graph_alloc**
**功能** : 相当于合拢所有过滤器的统一上下文
**avfilter_init_str参数选项**:
**abuffersink ( 媒体数据最终出口 ) **
**aformat ( 将媒体数据进行格式化 )**
**amix ( 混音处 )**:
**abuffer ( 媒体数据入口 )**
**volume ( 调节媒体数据音量等参数 )**
**音频功能流程** :
**混音流程** :
**AvFilterContext流程** :
**初始化AVFilter流程** :
**实例**:
**混音**:
流媒体过滤器 - AVFilter
函数说明 :
avfilter_init_str参数选项:
key | value type | value 选项 | 默认值 | 解释 |
---|---|---|---|---|
NULL | NULL | NULL | NULL | NULL |
-
aformat ( 将媒体数据进行格式化 )
-
key value type value 选项 默认值 解释 sample_fmts STRING 0 格式化后的采样格式 sample_rates STRING 0 格式化后的采样率 channel_layouts STRING 0 格式化后的声道布局 -
amix ( 混音处 ):
key | value type | value 选项 | 默认值 | 解释 |
---|---|---|---|---|
inputs | INT | INT16_T_MAX | 2 | 输入音频数 |
duration | INT | 0 ~ 2 | 0 | 0 ~ longest (以最长输入为准) 1 ~ shortest (以最短输入为准) 2 ~ first (以首个输入为准) |
dropout_transition | FLOAT | INT32_T_MAX | 2.0 | 当输入流结束时,用于音量重新正规化的转换时间(以秒为单位) |
weights | STRING | 0 | “1 1” | 为每个输入设置权重 |
normalize | BOOL | ture or false | true | 规模的输入 |
-
abuffer ( 媒体数据入口 )
key | value type | value 选项 | 默认值 | 解释 | |
---|---|---|---|---|---|
time_base | AV_OPT_TYPE_RATIONAL | INT32_T_MAX | 0 |
|
|
sample_rate | INT | INT32_T_MAX | 0 |
|
|
sample_fmt | AV_OPT_TYPE_SAMPLE_FMT | -1 ~ INT32_T_MAX | -1 |
|
|
channel_layout | STRING |
|
|||
channels | INT | INT32_T_MXA | 0 |
|
-
volume ( 调节媒体数据音量等参数 )
key | value type | value 选项 | 默认值 | 解释 |
---|---|---|---|---|
volume | STRING | 1.0 | 设置音量调节表达式 1.0 = 100% | |
precision | INT | 0 ~ 2 | 1 | 选择数学精度 0 ~ fixed (select 8-bit fixed-point) 1 ~ float (select 32-bit fixed-point) 2 ~ double (select 64-bit fixed-point) |
eval | INT | 0 ~ 1 | 0 | specify when to evaluate expressions 0 ~ once (eval volume expression once) 1 ~ frame (eval volume expression per-frame) |
replaygain | INT | 0 ~ 3 | 0 | Apply replaygain side data when present 0 ~ drop (replaygain side data is dropped) 1 ~ ignore (replaygain side data is ignored) 2 ~ track (track gain is preferred) 3 ~ album (album gain is preferred) |
replaygain_preamp | DOUBLE | -15.0 ~ 15.0 | 0.0 | Apply replaygain pre-amplification |
replaygain_noclip | BOOL | true or false | true | Apply replaygain clipping prevention |
音频功能流程 :
-
初始化AVFilter流程 :
-
实例:
-
混音:
-
//本实例不做任何异常判断 //核心 使用过滤器必备 AVFilterGraph * pFilterGraph = avfilter_graph_alloc(); /***************** 查找获取相应的过滤器 *****************/ //abuffersink - 音频出口 const AVFilter* pFilterABuffsink = avfilter_get_by_name("abuffersink"); //aformat - 对音频进行重新格式化 const AVFilter* pFilterAFormat = avfilter_get_by_name("aformat"); //amix - 将音频数据混音汇总 const AVFilter* pFilterAMix = avfilter_get_by_name("amix"); //abuffer - 音频入口 const AVFilter* pFilterABuffer = avfilter_get_by_name("abuffer"); //volume - 音频音量调整 const AVFilter* pFilterVolume = avfilter_get_by_name("volume"); /************ 根据相应过滤器创建过滤器实例 ************/ //abuffersink实例 AVFilterContext* pFilterCtxABuffSink = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffsink, "sink"); //aformat实例 AVFilterContext* pFilterCtxAFormat = avfilter_graph_alloc_filter(pFilterGraph, pFilterAFormat, "format"); //amix实例 AVFilterContext* pFilterCtxAMix = avfilter_graph_alloc_filter(pFilterGraph, pFilterAMix, "mix"); //abuffer - 入口0 实例 AVFilterContext* pFilterCtxABuffer_0 = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffer, "buffer0"); //abuffer - 入口1 实例 AVFilterContext* pFilterCtxABuffer_1 = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffer, "buffer1"); //volume - 控制入口0的音量 实例 AVFilterContext* pFilterCtxVolume_0 = avfilter_graph_alloc_filter(pFilterGraph, pFilterVolume, "volume0"); /****************** 参数选项设置 ********************/ //abuffersink - 参数设置 avfilter_init_str(pFilterCtxABuffSink, nullptr); //aformat - 参数设置 - 采样率:44100 | 采样格式:f32 | 声道布局:双声道 avfilter_init_str(pFilterCtxAFormat, "sample_rates=44100:sample_fmts=flt:channel_layouts=0x3"); //amix - 参数设置 - 输入音频流数:2 | 持续时长:最长的音频为准 | dropout_transition:输入流结束时,容量重整时间 avfilter_init_str(pFilterCtxAMix, "inputs=2:duration=longest:dropout_transition=0"); //abuffer入口0 - 参数设置 - 采样率:44100 | 采样格式:s16 | 声道布局:双声道 avfilter_init_str(pFilterCtxABuffer_0, "sample_rate=44100:sample_fmt=s16:channel_layout=0x3"); //abuffer入口1 - 参数设置 - 采样率:48000 | 采样格式:flt | 声道布局:双声道 avfilter_init_str(pFilterCtxABuffer_1, "sample_rate=48000:sample_fmt=flt:channel_layout=0x3"); //volume 0 - 参数设置 - 音量 10% avfilter_init_str(pFilterCtxVolume_0, "volume=0.1"); /************ 对目前个不相关的过滤器做连接 *************/ //abuffer入口0 -> volume0 avfilter_link(pFilterCtxABuffer_0, 0, pFilterCtxVolume_0, 0); //volume0 -> amix 混音 avfilter_link(pFilterCtxVolume_0, 0, pFilterCtxAMix, 0); //abuffer入口1 -> amix avfilter_link(pFilterCtxABuffer_1, 0, pFilterCtxAMix, 1); //amix -> aformat avfilter_link(pFilterCtxAMix, 0, pFilterCtxAFormat, 0); //aformat -> abuffersink avfilter_link(pFilterCtxAFormat, 0, pFilterCtxABuffSink, 0); //graph整合 avfilter_graph_config(pFilterGraph, nullptr); bool bReadFileEnd_0 = false; bool bReadFileEnd_1 = false; AVFrame* pFrame_0 = av_frame_alloc(); AVFrame* pFrame_1 = av_frame_alloc(); AVFrame* pFrameOut = av_frame_alloc(); /****** * * 打开文件、初始化avframe操作 * ******/ while(!bReadFileEnd_0 || !bReadFileEnd_1 ) { /******* 输入其一 *******/ if(!bReadFileEnd_0) { /*** * 读取 pcm 一帧数据 ***/ if(/* Read File End */) bReadFileEnd_0 = ture; } /******* 输入其二 *******/ if(!bReadFileEnd_1) { /*** * 读取 pcm 一帧数据 ***/ if(/* Read File End */) bReadFileEnd_1 = ture; } /******* 只要其中一路还有数据就必须得传入数据 *******/ //传入的数据流其一 - 通过abuffer0传入 av_buffersrc_add_frame(pFilterCtxABuffer_0, bReadFileEnd_0 ? nullptr : pFrame_0); //传入的数据流其二 - 通过abuffer1传入 av_buffersrc_add_frame(pFilterCtxABuffer_1, bReadFileEnd_1 ? nullptr : pFrame_1; /****** 读取混音后的数据 ******/ while(true) { //从abuffersink中获取一帧数据 if(av_buffersink_get_frame(pFilterCtxABuffSink, pFrameOut) < 0) { //读取失败则表示过滤器中已经不存在数据了,需要重新往里添加帧 break; } /*** * 将数据写入输出文件 ***/ } }