ファイルを再生する方法
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
この記事は、DirectShow プログラミングのフレーバーを提供することを目的としています。 これは、オーディオまたはビデオファイルを再生するシンプルなコンソールアプリケーションを提示します。 このプログラムは数行しか長くはありませんが、DirectShow プログラミングの機能の一部を示しています。
DirectShow アプリケーション プログラミングの概要に関する記事で説明されているように、DirectShow アプリケーションは常に同じ基本的な手順を実行します。
- フィルター グラフ マネージャーのインスタンスを作成します。
- フィルター グラフ マネージャーを使用してフィルター グラフを作成します。
- グラフを実行すると、データがフィルター内を移動します。
このトピックのコードをコンパイルしてリンクするには、ヘッダー ファイル Dshow.h と静的ライブラリ ファイル strmiids.lib へのリンクを含めます。 詳細については、「 DirectShow アプリケーションのビルド」を参照してください。
まず 、CoInitialize または CoInitializeEx を呼び出して COM ライブラリを初期化します。
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
// Add error-handling code here. (Omitted for clarity.)
}
簡単にするために、この例では戻り値は無視されますが、常に任意のメソッド呼び出しから HRESULT 値をチェックする必要があります。
次に、 CoCreateInstance を呼び出してフィルター グラフ マネージャーを作成します。
IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
次に示すように、クラス識別子 (CLSID) がCLSID_FilterGraph。 Filter Graph Manager はインプロセス DLL によって提供されるため、実行コンテキストは CLSCTX_INPROC_SERVER。 DirectShow ではフリー スレッド モデルがサポートされているため、COINIT_MULTITHREADED フラグを指定して CoInitializeEx を呼び出すこともできます。
CoCreateInstance の呼び出しは IGraphBuilder インターフェイスを返します。このインターフェイスには、主にフィルター グラフを構築するためのメソッドが含まれています。 この例には、他の 2 つのインターフェイスが必要です。
- IMediaControl は ストリーミングを制御します。 グラフを停止および開始するためのメソッドが含まれています。
- IMediaEvent には、フィルター グラフ マネージャーからイベントを取得するためのメソッドがあります。 この例では、インターフェイスを使用して再生が完了するまで待機します。
これらのインターフェイスはどちらも、フィルター グラフ マネージャーによって公開されます。 返された IGraphBuilder ポインターを使用してクエリを実行します。
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
フィルター グラフを作成できるようになりました。 ファイルの再生では、これは 1 つのメソッド呼び出しによって行われます。
hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
IGraphBuilder::RenderFile メソッドは、指定したファイルを再生できるフィルター グラフを作成します。 最初のパラメーターは、ワイド文字 (2 バイト) 文字列として表されるファイル名です。 2 番目のパラメーターは予約済みであり、 NULL と等しい必要があります。
指定したファイルが存在しない場合、またはファイル形式が認識されない場合、このメソッドは失敗する可能性があります。 ただし、メソッドが成功したと仮定すると、フィルター グラフは再生の準備ができました。 グラフを実行するには、 IMediaControl::Run メソッドを呼び出します。
hr = pControl->Run();
フィルター グラフが実行されると、データはフィルター内を移動し、ビデオとオーディオとしてレンダリングされます。 再生は別のスレッドで行われます。 再生が完了するまで待機するには、 IMediaEvent::WaitForCompletion メソッドを呼び出します。
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
このメソッドは、ファイルの再生が完了するか、指定されたタイムアウト間隔が経過するまでブロックします。 値 INFINITE は、ファイルの再生が完了するまでアプリケーションが無期限にブロックを意味します。 イベント処理のより現実的な例については、「イベント への応答」を参照してください。
アプリケーションが完了したら、インターフェイス ポインターを解放し、COM ライブラリを閉じます。
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
コード例
この記事で説明する例の完全なコードを次に示します。
#include <dshow.h>
void main(void)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// Build the graph. IMPORTANT: Change this string to a file on your system.
hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
if (SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it
// can block indefinitely.
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
関連トピック