项目中需要对音频数据进行增益处理,了解到FFmpeg中有volume filter可实现此功能,基于volume filter开发,并记录.
- FFmpeg命令行使用volume filter
//将1.wav音量增大2倍并保存为2.wav,如果想降低2倍,参数为volume=0.5
ffmpeg.exe -i 1.wav -af volume=2 2.wav
- FFmpeg代码实现
//===初始化部分
//代码中用到的变量
AVFilterGraph* m_pGraph;
AVFilterContext* m_pABufferSrcCtx;
AVFilterContext* m_pABufferSinkCtx;
AVFilterContext* m_pVolumeCtx;
AVFilterContext* m_pAformatCtx;
//1.注册avfilter
avfiter_register_all()
//创建一个filter graph
m_pGraph = avfilter_graph_alloc();
//2. 创建filter source
const AVFilter* abuffersrc = avfilter_get_by_name("abuffer");
m_pABufferSrcCtx = avfilter_graph_alloc_filter(m_pGraph, abuffersrc, "src");
//构造参数配置(输入音频格式、输入采样率、输入声道配置)
_snprintf(options_str, sizeof(options_str),
"sample_fmt=%s:sample_rate=%d:channel_layout=%0x",
av_get_sample_fmt_name(m_SampleFmt),
m_nSampleRate,
m_nChannelLayout);
//传入参数开始初始化
ret = avfilter_init_str(m_pABufferSrcCtx, options_str);
// 3. 创建 volume filter
const AVFilter* volume = avfilter_get_by_name("volume");
//获取该filter的上下文环境
m_pVolumeCtx = avfilter_graph_alloc_filter(m_pGraph, volume, "volume");
//构造参数配置 调节音量的大小,例如0.5为原来的一半
_snprintf(options_str, sizeof(options_str),
"volume=%g", m_dVolumn);
//传入参数开始初始化
ret = avfilter_init_str(m_pVolumeCtx, options_str);
// 4. 创建 buffer sink
const AVFilter* abuffersink = avfilter_get_by_name("abuffersink");
m_pABufferSinkCtx = avfilter_graph_alloc_filter(m_pGraph, abuffersink, "sink");
//传入参数开始初始化,我们不做重采样,所以这里不指定参数了,或者指定跟buffer source 相同的参数
ret = avfilter_init_str(m_pABufferSinkCtx, NULL);
// 5. 链接filter
ret = avfilter_link(m_pABufferSrcCtx, 0, m_pVolumeCtx, 0);
ret = avfilter_link(m_pVolumeCtx, 0, m_pAformatCtx, 0);
ret = avfilter_link(m_pAformatCtx, 0, m_pABufferSinkCtx, 0);
//6. 初始化整个filter链
ret = avfilter_graph_config(m_pGraph, NULL);
//===调用部分
//7. 解码一帧AVFrame数据
avcodec_send_packet(avcodeccontext, packet);
avcodec_receive_frame(avcodeccontext, frame);
//8. 送到source filter中, 从sink中取出来
if(0 == av_buffersrc_add_frame(m_pABufferSrcCtx, pFrame))
{
while(0 == av_buffersink_get_frame(m_pABufferSinkCtx, pFrame))
{
//doSomeThing
}
}
//9. 使用结束记得释放资源
avfilter_free(m_pABufferSrcCtx);
avfilter_free(m_pABufferSinkCtx);
avfilter_free(m_pVolumeCtx);
avfilter_free(m_pAformatCtx);
avfilter_graph_free(&m_pGraph);
=