创建音频捕获图

[与本页关联的功能 DirectShow 是一项旧版功能。 它已被 MediaPlayerIMFMediaEngine媒体基础中的音频/视频捕获所取代。 这些功能已针对 Windows 10 和 Windows 11 进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngine媒体基础中的音频/视频捕获,而不是 DirectShow。 如果可能,Microsoft 建议应重写使用旧 API 的现有代码,以尽可能地使用新的 API。]

音频捕获应用程序的第一步是生成筛选器图。 图表的配置取决于想要创建的文件类型。

WavDest 筛选器作为 SDK 示例提供。 要使用它,则必须生成并注册筛选器。

要使用 ASF 编写器筛选器,则必须安装 Windows Media SDK 并获取软件密钥来解锁筛选器。 有关详细信息,请参阅在 DirectShow 中使用 Windows Media

可以使用 Capture Graph Builder 对象来生成筛选器图形,也可以“手动”生成图形;也就是说,让应用程序以编程方式添加和连接每个筛选器。 本文介绍手动方法。 有关使用捕获图形生成器的详细信息,请参阅视频捕获。 本文中的大部分信息都适用于仅音频图表。

添加音频捕获设备

由于音频捕获筛选器与特定的硬件设备通信,因此不能简单地调用 CoCreateInstance 来创建筛选器。 相反,使用系统设备枚举器来枚举“音频捕获源”类别中的所有设备,该类别由类标识符 CLSID_AudioInputDeviceCategory 标识。

系统设备枚举器返回设备的名字列表;每个名字的友好名称对应于设备的名称。 选择返回的名称之一并使用它来为该设备创建音频捕获筛选器的实例。 将筛选器添加到筛选器图中。 用户的首选音频录制设备会首先出现在名字对象列表中。 (用户通过单击“控制面板”中的“声音和多媒体”来选择首选设备。)

有关详细信息,请参阅使用系统设备枚举器

要指定从哪个输入进行捕获,请从音频捕获筛选器中获取 IAMAudioInputMixer 接口,并调用 put_Enable 方法来指定输入。 然而,这种方法的一个限制是不同的硬件设备可能使用不同的字符串来识别它们的输入。 例如,一张卡可以使用“Microphone”来标识麦克风输入,而另一张卡可以使用“Mic”。 要确定给定输入的字符串标识符,请使用 Windows 多媒体函数 waveOutOpenmixerOpenmixerGetLineInfo。 有关详细信息,请参阅混音器设备查询

添加多路复用器和文件编写器

音频捕获图必须包含一个多路复用器和一个文件编写器。

多路复用器一种筛选器,可将一个或多个数据流合并为具有特定格式的单一数据流。 例如,AVI 多路转换器筛选器将音频和视频流合并为交错的 AVI 流。 对于音频捕获,通常只有一个音频流,但音频数据仍必须打包成可保存到磁盘的格式,这就需要一个多路复用器。 多路复用器的选择取决于目标格式:

  • AVI:AVI 多路复用器
  • WAV:WavDest
  • WMA:ASF 编写器

文件编写器是一个筛选器,用于将接收到的数据写入文件。 对于 AVI 或 WAV 文件,请使用文件编写器筛选器。 对于 WMA 文件,ASF 编写器既是多路复用器,又是文件编写器。

创建筛选器并将其添加到图表后,将音频捕获筛选器的输出引脚连接到多路复用器的输入引脚,并将多路复用器的输出引脚连接到筛选器编写器的输入引脚(假设这些是独立的筛选器)。 要指定文件名,请查询文件编写器的 IFileSinkFilter 接口,并调用 IFileSinkFilter::SetFileName 方法。

示例代码

以下示例演示了如何使用 WavDest 筛选器生成音频捕获图。 同样的原则也适用于其他文件类型。

IBaseFilter *pSrc = NULL, *pWaveDest = NULL, *pWriter = NULL;
IFileSinkFilter *pSink= NULL;
IGraphBuilder *pGraph;

// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
    IID_IGraphBuilder, (void**)&pGraph);

// This example omits error handling.

// Not shown: Use the System Device Enumerator to create the 
// audio capture filter.

// Add the audio capture filter to the filter graph. 
hr = pGraph->AddFilter(pSrc, L"Capture");

// Add the WavDest and the File Writer.
hr = AddFilterByCLSID(pGraph, CLSID_WavDest, L"WavDest", &pWaveDest);
hr = AddFilterByCLSID(pGraph, CLSID_FileWriter, L"File Writer", &pWriter);

// Set the file name.
hr = pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pSink);
hr = pSink->SetFileName(L"C:\\MyWavFile.wav", NULL);

// Connect the filters.
hr = ConnectFilters(pGraph, pSrc, pWaveDest);
hr = ConnectFilters(pGraph, pWaveDest, pWriter);

// Not shown: Release interface pointers.

本例使用了使用 CLSID 添加筛选器中描述的 AddFilterByCLSID 函数和连接两个筛选器中描述的 ConnectFilters 函数。 这两者都不是 DirectShow API。

音频捕获