次の方法で共有


ファイルを再生する方法

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

この記事は、DirectShow プログラミングのフレーバーを提供することを目的としています。 これは、オーディオまたはビデオファイルを再生するシンプルなコンソールアプリケーションを提示します。 このプログラムは数行しか長くはありませんが、DirectShow プログラミングの機能の一部を示しています。

DirectShow アプリケーション プログラミングの概要に関する記事で説明されているように、DirectShow アプリケーションは常に同じ基本的な手順を実行します。

  1. フィルター グラフ マネージャーのインスタンスを作成します。
  2. フィルター グラフ マネージャーを使用してフィルター グラフを作成します。
  3. グラフを実行すると、データがフィルター内を移動します。

このトピックのコードをコンパイルしてリンクするには、ヘッダー ファイル 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();
}

DirectShow の基本的なタスク