建立音訊擷取圖形

[與此頁面相關聯的功能, DirectShow 是舊版功能。 它已被媒體播放程式、IMFMediaEngine媒體基金會的音訊/視訊擷取所取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能使用 MediaPlayer、IMFMediaEngineMedia Foundation 中的音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

音訊擷取應用程式的第一個步驟是建置篩選圖形。 圖形的組態取決於您想要建立的文件類型。

WavDest 篩選器會以 SDK 範例的形式提供。 若要使用它,您必須建置並註冊篩選條件。

若要使用 ASF 寫入器篩選器,您必須安裝 Windows 媒體 SDK 並取得軟體金鑰來解除鎖定篩選條件。 如需詳細資訊,請參閱 在 DirectShow 中使用 Windows Media。

您可以使用 Capture Graph Builder 物件來建置篩選圖形,也可以「手動」建置圖形;也就是說,讓應用程式以程序設計方式新增並連接每個篩選。 本文說明手動方法。 如需使用擷取圖形產生器的詳細資訊,請參閱 影片擷取。 該文章的大部分資訊都適用於僅限音訊的圖表。

新增音訊擷取裝置

由於音訊擷取篩選器會與特定硬體裝置通訊,因此您不只能呼叫 CoCreateInstance 來建立篩選。 請改用 系統裝置列舉值 來列舉「音訊擷取來源」類別中的所有裝置,而該類別標識符CLSID_AudioInputDeviceCategory識別。

系統裝置列舉值會傳回裝置的Moniker清單;每個Moniker的易記名稱都會對應至裝置的名稱。 選擇其中一個傳回的Moniker,並用它來建立該裝置的音訊擷取篩選器實例。 將篩選新增至篩選圖形。 使用者慣用的音訊錄製裝置會先出現在Moniker清單中。 (使用者按兩下 控制台中的 [音效] 和 [多媒體],以選取慣用的裝置。

如需詳細資訊,請參閱 使用系統裝置列舉值

若要指定要從哪個輸入擷取,請從音訊擷取篩選條件取得 IAMAudioInputMixer 介面,並呼叫 put_Enable 方法來指定輸入。 不過,此方法的其中一個限制是,不同的硬體裝置可能會使用不同的字串來識別其輸入。 例如,一張卡片可能會使用「麥克風」來識別麥克風輸入,而另一張卡片可能會使用 “Mic”。 若要判斷指定輸入的字元串標識符,請使用 Windows 多媒體函式 waveOutOpenmixerOpenmixerGetLineInfo。 如需詳細資訊,請參閱 混合器裝置查詢

新增 Multiplexer 和檔案寫入器

音訊擷取圖形必須包含多任務器和檔案寫入器。

多任務器是一種篩選條件,可將一或多個數據流結合成具有特定格式的單一數據流。 例如,AVI Mux 篩選器會將音訊和視訊串流結合成交錯的 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.

此範例會使用AddFilterByCLSID依CLSID新增篩選中所述的函式,以及 ConnectFilters Connect Two Filters 中所述的函式。 這兩者都不是 DirectShow API。

音訊擷