共用方式為


預覽電視音訊

[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。

若要預覽電視音訊,請將交叉欄篩選上的音訊解碼器釘選路由傳送至音訊微調器釘選。 若要將音訊靜音,請將音訊解碼器釘選路由傳送至 -1,如下圖所示。 (使用 Crossbars.)

路由音訊解碼器針腳

基本方法如下:

  1. 使用 ICaptureGraphBuilder2::FindInterface 方法來尋找交叉欄篩選。
  2. 使用 IAMCrossbar::get_CrossbarPinInfo 方法來列舉交叉列篩選的輸入和輸出針腳。 搜尋音訊解碼器輸出釘選和音訊微調器輸入針腳。
  3. 如果您找到正確的針腳,請呼叫 IAMCrossbar::Route 來路由釘選。 如果沒有,請尋找上游以尋找另一個交叉列,並重複此程式。
  4. 若要將音訊靜音,請將音訊解碼器釘選路由傳送至 -1。

大部分的電視微調器都會使用單一交叉橫條篩選準則,但有些則使用兩個交叉橫條篩選。 因此,如果第一個交叉欄失敗,您可能必須搜尋第二個交叉列。

注意

與您可能預期的相反,不需要音訊擷取篩選或音訊轉譯器來預覽音訊,因為微調器卡片與聲音卡之間有實體連線。

 

下列程式碼會更詳細地顯示這些步驟。 首先,以下是協助程式函式,可搜尋指定針腳類型的交叉欄篩選:

HRESULT FindCrossbarPin(
    IAMCrossbar *pXBar,                 // Pointer to the crossbar.
    PhysicalConnectorType PhysicalType, // Pin type to match.
    PIN_DIRECTION Dir,                  // Pin direction.
    long *pIndex)       // Receives the index of the pin, if found.
{
    BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);

    // Find out how many pins the crossbar has.
    long cOut, cIn;
    HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
    if (FAILED(hr)) return hr;
    // Enumerate pins and look for a matching pin.
    long count = (bInput ? cIn : cOut);
    for (long i = 0; i < count; i++)
    {
        long iRelated = 0;
        long ThisPhysicalType = 0;
        hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
            &ThisPhysicalType);
        if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
        {
            // Found a match, return the index.
            *pIndex = i;
            return S_OK;
        }
    }
    // Did not find a matching pin.
    return E_FAIL;
}

下一個函式會根據 bActivate 參數的值,嘗試啟動或靜音音訊。 它會搜尋指定的交叉欄篩選,以取得所需的針腳。 如果找不到它們,則會傳回錯誤碼。

HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
    // Look for the Audio Decoder output pin.
    long i = 0;
    HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
        PINDIR_OUTPUT, &i);
    if (SUCCEEDED(hr))
    {
        if (bActivate)  // Activate the audio. 
        {
            // Look for the Audio Tuner input pin.
            long j = 0;
            hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, 
                PINDIR_INPUT, &j);
            if (SUCCEEDED(hr))
            {
                return pXBar->Route(i, j);
            }
        }
        else  // Mute the audio
        {
            return pXBar->Route(i, -1);
        }
    }
    return E_FAIL;
}

下一個函式會搜尋篩選圖表中的交叉欄位篩選。 如果找到音訊,它會嘗試使用先前的函式來啟動或靜音音訊 () 。 如果作業失敗,方法會搜尋上游中的第二個交叉欄,然後再試一次。 如需在圖表中管理多個交叉列篩選的更一般化方法,請參閱 AmCap 範例應用程式中的 CCrossbar 類別。

HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
  BOOL bActivate)
{
    // Search upstream for a crossbar.
    IAMCrossbar *pXBar1 = NULL;
    HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
        IID_IAMCrossbar, (void**)&pXBar1);
    if (SUCCEEDED(hr)) 
    {
        hr = ConnectAudio(pXBar1, bActivate);
        if (FAILED(hr))
        {
            // Look for another crossbar.
            IBaseFilter *pF = NULL;
            hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
            if (SUCCEEDED(hr)) 
            {
                // Search upstream for another one.
                IAMCrossbar *pXBar2 = NULL;
                hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
                    IID_IAMCrossbar, (void**)&pXBar2);
                pF->Release();
                if (SUCCEEDED(hr))
                {
                    hr = ConnectAudio(pXBar2, bActivate);
                    pXBar2->Release();
                }
            }
        }
        pXBar1->Release();
    }
    return hr;
}

下列程式碼示範如何呼叫這些函式:

// Build the analog TV graph (not shown).
// Activate the audio.
hr = ActivateAudio(pBuild, pCap, TRUE);
// Later, mute the audio.
hr = ActivateAudio(pBuild, pCap, FALSE);

請注意,這些範例函式會重複許多相同的函式呼叫。 例如,它們會每次列舉交叉條針腳。 在實際的應用程式中,您可能會快取其中一些資訊。

類比電視音訊

使用交叉欄