次の方法で共有


AVI ファイルへのビデオのキャプチャ

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

次の図は、ビデオを AVI ファイルにキャプチャするための最も簡単なグラフを示しています。

avi ビデオ キャプチャ グラフ

AVI Mux フィルターは、キャプチャ ピンからビデオ ストリームを取得し、AVI ストリームにパッケージ化します。 オーディオ ストリームを AVI Mux フィルターに接続することもできます。その場合、mux は 2 つのストリームをインターリーブします。 ファイル ライター フィルターは、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) を指定します。 2 番目のパラメーターは、ファイル名を指定します。 AVI の場合、SetOutputFileName メソッドは AVI Mux フィルターとファイル ライター フィルターを作成し、グラフに追加します。 また、 IFileSinkFilter::SetFileName メソッドを呼び出してファイル ライター フィルターにファイル名を設定し、2 つのフィルターを接続します。 メソッドは、3 番目のパラメーターで AVI Mux へのポインターを返します。 必要に応じて、4 番目のパラメーターで 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されるピン カテゴリを示します。 2 番目のパラメーターは、メディアの種類を示します。 3 番目のパラメーターは、キャプチャ フィルターの IBaseFilter インターフェイスへのポインターです。 4 番目のパラメーターは省略可能です。これにより、ビデオ ストリームを mux フィルターに渡す前に、エンコーダーなどの中間フィルターを介してルーティングできます。 それ以外の場合は、前の例に示すように、このパラメーターを NULL に設定します。 5 番目のパラメーターは、mux フィルターへのポインターです。 このポインターは、SetOutputFileName メソッドを呼び出すことによって取得されます。

オーディオをキャプチャするには、メディアの種類が MEDIATYPE_Audio の RenderStream を呼び出します。 2 つの個別のデバイスからオーディオとビデオをキャプチャする場合は、オーディオ ストリームをマスター ストリームにすることをお勧めします。 AVI Mux フィルターはオーディオ ストリームに合わせてビデオ ストリームの再生速度を調整するため、これは 2 つのストリーム間のドリフトを防ぐのに役立ちます。 マスター ストリームを設定するには、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 を呼び出し、次にオーディオに対して 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 フィルターの間にエンコーダー フィルターを挿入します。 システム デバイス列挙子またはフィルター マッパーを使用してエンコーダー フィルターを選択します。 (詳細については、「 デバイスとフィルターの列挙」を参照してください)。

次の例では、エンコーダー フィルターを RenderStream の 4 番目のパラメーターとして指定します。太字で示します。

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 またはその他のインターフェイスがサポートされている場合があります。 使用可能なインターフェイスの一覧については、「 ファイル エンコードとデコード インターフェイス」を参照してください。

ビデオをファイルにキャプチャする