共用方式為


將影片擷取至 AVI 檔案

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

下圖顯示將影片擷取至 AVI 檔案的最簡單圖形。

avi 影片擷取圖表

AVI Mux 濾鏡會從擷取端取得視訊串流,並將其封裝到 AVI 視訊流。 音訊串流也可以連接到 AVI 多工器,在此情況下,多工器會交織這兩個數據流。 檔案寫入器 篩選器會將 AVI 數據流寫入磁碟。

若要建置圖形,請從呼叫 ICaptureGraphBuilder2::SetOutputFileName 方法開始,如下所示:

IBaseFilter *pMux;
hr = pBuild->SetOutputFileName(
    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
    L"C:\\Example.avi", // File name.
    &pMux,              // Receives a pointer to the mux.
    NULL);              // (Optional) Receives a pointer to the file sink.

第一個參數會指定檔案類型, 在此案例中為 AVI。 第二個參數會提供檔名。 若為 AVI,SetOutputFileName 方法會共同建立 AVI Mux 篩選和檔案寫入器篩選,並將其新增至圖形。 它還通過呼叫 IFileSinkFilter::SetFileName 方法,在檔案寫入器濾鏡上設定檔名,並連接這兩個濾鏡。 方法會在第三個參數中傳回指向 AVI Mux 的指標。 可選擇性地,它會在第四個參數中傳回指向 IFileSinkFilter 介面的指標。 如果您不需要這個介面,您可以將此參數設定為 NULL,如上一個範例所示。

接下來,呼叫 ICaptureGraphBuilder2::RenderStream 方法,將擷取篩選連接到 AVI Mux,如下所示:

hr = pBuild->RenderStream(
    &PIN_CATEGORY_CAPTURE, // Pin category.
    &MEDIATYPE_Video,      // Media type.
    pCap,                  // Capture filter.
    NULL,                  // Intermediate filter (optional).
    pMux);                 // Mux or file sink filter.

// Release the mux filter.
pMux->Release();

第一個參數提供了引腳類別,其中用於擷取的類別是 PIN_CATEGORY_CAPTURE。 第二個參數會提供媒體類型。 第三個參數是指向擷取過濾器的 IBaseFilter 介面的指標。 第四個參數是可選的;它允許您先將視訊串流通過中間過濾器,如編碼器,然後再傳送至多工器篩選器。 否則,請將此參數設定為 NULL,如上一個範例所示。 第五個參數是多工篩選器的指標。 呼叫 SetOutputFileName 方法可取得此指標。

若要擷取音訊,請使用媒體類型呼叫 RenderStream MEDIATYPE_Audio。 如果您要從兩個不同的裝置擷取音訊和視訊,最好讓音訊串流成為主數據流。 這有助於防止兩個數據流之間的漂移,因為 AVI Mux 篩選器會調整視訊串流上的播放速率以符合音訊數據流。 若要設定主要數據流,請在 AVI Mux 篩選器上呼叫 IConfigAviMux::SetMasterStream 方法:

IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
    pConfigMux->SetMasterStream(1);
    pConfigMux->Release();
}

SetMasterStream 的參數是數據流號碼,由您呼叫 RenderStream 的順序決定。 例如,如果您先針對視訊呼叫 RenderStream,然後再呼叫音訊,則視訊是數據流 0,而音訊則是數據流 1。

您也可以呼叫 IConfigInterleaving::put_Mode 方法來設定 AVI Mux 濾鏡如何交錯音訊和視訊串流。

IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
    pInterleave->put_Mode(INTERLEAVE_CAPTURE);
    pInterleave->Release();
}

使用INTERLEAVE_CAPTURE旗標,AVI Mux 會以適合視訊擷取的速率執行交錯。 您也可以使用INTERLEAVE_NONE,這表示不會交錯 — AVI Mux 只會按照數據到達的順序來寫入數據。 INTERLEAVE_FULL 旗標表示 AVI Mux 執行完整交錯,不過,此模式不太適合視訊擷取,因為它需要更高的系統資源。

編碼視訊串流

您可以在擷取篩選與 AVI Mux 篩選之間插入編碼器篩選,以編碼視訊串流。 使用 系統裝置枚舉器篩選映射器 以選擇編碼器篩選器。 (如需詳細資訊,請參閱 列舉裝置和篩選

將編碼器篩選指定為 RenderStream 的第四個參數,如下列範例所示:

IBaseFilter *pEncoder;
/* Create the encoder filter (not shown). */
// Add it to the filter graph.
pGraph->AddFilter(pEncoder, L"Encoder");

/* Call SetOutputFileName as shown previously. */

// Render the stream.
hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
    pCap, 
pEncoder, pMux);
pEncoder->Release();

編碼器篩選器可能支援 IAMVideoCompression 或其他介面來設定編碼參數。 如需可能介面的清單,請參閱 檔案編碼和譯碼介面

將影片錄製至檔案