將影片擷取至 AVI 檔案
[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。
下圖顯示將視訊擷取至 AVI 檔案的最簡單圖形。
AVI Mux篩選器會從擷取釘選擷取影片串流,並將它封裝到 AVI 資料流程。 音訊串流也可以連線到 AVI Mux 篩選器,在此情況下,多工會交錯兩個數據流。 檔案寫入器篩選器會將 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::p ut_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 篩選器之間插入編碼器篩選,以編碼視訊串流。 使用 [系統裝置列舉值 ] 或 [篩選對應器 ] 來選取編碼器篩選準則。 (如需詳細資訊,請參閱 列舉裝置和 Filters.)
將編碼器篩選指定為 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 或其他介面來設定編碼參數。 如需可能介面的清單,請參閱 檔案編碼和解碼介面。
相關主題