从主机麦克中取出音频,经过Filter变换处理,编码为TS文件。
1、首先要取得主机麦克设备的名称:
用ffmpeg 命令取ymt
ffmpeg -list_devices true -f dshow -i dummy
如下图所示:
2、麦克设备的名称转化为UTF-8
由于函数需要,要把设备名称转为UTF-8格式:
WideCharToMultiByte(CP_UTF8, 0, wchar_devicename, -1, utf_8_devicename, buffer_len, 0, 0);
3、Filter主要源码:
(1)创建filter:
int InitAudioFilter(AVCodecContext * codecContext)
{
char args[512];
int ret;
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
g_outputs = avfilter_inout_alloc();
g_inputs = avfilter_inout_alloc();
auto audioDecoderContext = g_inputAudioFormatContext->streams[0]->codec;
if (!audioDecoderContext->channel_layout)
audioDecoderContext->channel_layout = av_get_default_channel_layout(audioDecoderContext->channels);
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE };
static const int64_t out_channel_layouts[] = { audioDecoderContext->channel_layout, -1 };
static const int out_sample_rates[] = { audioDecoderContext->sample_rate , -1 };
AVRational time_base = g_inputAudioFormatContext->streams[0]->time_base;
g_filter_graph = avfilter_graph_alloc();
g_filter_graph->nb_threads = 1;
sprintf_s(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64x",
time_base.num, time_base.den, audioDecoderContext->sample_rate,
av_get_sample_fmt_name(audioDecoderContext->sample_fmt), audioDecoderContext->channel_layout);
ret = avfilter_graph_create_filter(&g_buffersrcAudioContext, abuffersrc, "in",
args, NULL, g_filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
return ret;
}
/* buffer audio sink: to terminate the filter chain. */
ret = avfilter_graph_create_filter(&g_buffersinkContext, abuffersink, "out",
NULL, NULL, g_filter_graph);
if (ret < 0) {
return ret;
}
ret = av_opt_set_int_list(g_buffersinkContext, "sample_fmts", out_sample_fmts, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
return ret;
}
ret = av_opt_set_int_list(g_buffersinkContext, "channel_layouts", out_channel_layouts, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
return ret;
}
ret = av_opt_set_int_list(g_buffersinkContext, "sample_rates", out_sample_rates, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
return ret;
}
/* Endpoints for the filter graph. */
g_outputs->name = av_strdup("in");
g_outputs->filter_ctx = g_buffersrcAudioContext;;
g_outputs->pad_idx = 0;
g_outputs->next = NULL;
g_inputs->name = av_strdup("out");
g_inputs->filter_ctx = g_buffersinkContext;
g_inputs->pad_idx = 0;
g_inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(g_filter_graph, "anull",
&g_inputs, &g_outputs, nullptr)) < 0)
return ret;
if ((ret = avfilter_graph_config(g_filter_graph, NULL)) < 0)
return ret;
av_buffersink_set_frame_size(g_buffersinkContext, 1024);
return 0;
}
(2)使用filter:
if (av_buffersrc_add_frame_flags(g_buffersrcAudioContext, pSrcAudioFrame, AV_BUFFERSRC_FLAG_PUSH) >= 0)
{
ret = av_buffersink_get_frame_flags(g_buffersinkContext, filterFrame, AV_BUFFERSINK_FLAG_NO_REQUEST);
if (ret >= 0)
{
....
}
}
4、工程项目源代码下载:
在本工程在Debug – x86编译通过。
记得调用命令ffmpeg 取得设备名称