Media Foundation を使う(下準備と音声ファイルの再生)

Windows のマルチメディア API 、Media Foundation の使い方メモです。日本語のドキュメントが、DirectShow に比べて少ないため、調べたことを書き残しておこうと思います。もう、ネイティブのプログラムを書こうなんて人はほとんどいないのかもしれませんね…


Media Foundation は、Windows Vista 以降から採用された API で、DirectShow を置き換える新しいマルチメディア API です。新しいと言っても、Windows 10 時代の今では古いのかもしれません。とはいえ、標準で MP4 コンテナや、AAC ・ H.264 まわりを扱えるようですので十分でしょう。

Media Foundation が標準でサポートしている形式一覧

ドキュメントは?

Microsoft のページに Media Foundation Programming Guide というドキュメントがあり、日本語の記事を探すよりも、こちらをポチポチ読んでいくのが早そうです。

下準備

Media Foundation の API を使うには、最初と最後に初期化と終了の命令を呼ぶ必要があります。どうやら、CoInitialize よりも後が良いようです。ヘッダーファイルは、使うものによって色々あるので追々。

コード1: 初期化
コード2: 終了処理

音声ファイルを再生してみる

Media Session Playback Example に従って音声ファイルを再生してみようと思います。こちらのサンプルでは、しっかりとクラス化されてきれいに書かれていますが、今回は試しにべた書きで進めてみようと思います。

Media Session は、メディアファイルの再生に便利なパイプラインをまとめたもののようです。単に再生するだけなら、これを使うのが良さそうです(サンプルに SimplePlay Sample というのがあるのですが、こちらの API は将来的に削除予定らしいです)。説明を読んでみると、保護されたファイルの再生などもこちらでできるようです。

さて、Media Session を使った再生は以下の感じらしいです。

  1. Create a new media session.
  2. Create the media source.
  3. Create the topology.
  4. Queue the topology (asynchronous)
  5. Start playback (asynchronous)

順に行きます。

Media Session の生成

まずは、再生の本体、Media Session を生成します。ここは普通に MFCreateMediaSession を呼びます。

Media Source の生成

次に、Media Source を生成します。手順としては、

  1. MFCreateSourceResolver で SourceResolver を作る
  2. SourceResolver の CreateObjectFromURL メソッドで Media Source を生成(ポインターを取得)
  3. QueryInterface で IMFMediaSource のインタフェースを取得
  4. IMFMediaSource の CreatePresentationDescriptor メソッドで、MediaSource の PresentationDescriptor を取得(トポロジー生成に使う)

という感じのようです。

トポロジーの生成

長いので、詳細は省略…くわしくは、こちらに。

手順としては、

  1. MFCreateTopology で空のトポロジーを生成
  2. PresentationDescriptor の GetStreamDescriptorCount で、ストリームの数を取得
  3. 各ストリームについて、SourceNode -> OutputNode というブランチを生成して、トポロジーに追加(サンプルの AddBranchToPartialTopology 関数)

といった感じのようです(サンプルの CreatePlaybackTopology)。詳細な実装は、先に紹介したサンプルのメソッドそのままで。

トポロジーの設定

トポロジーを生成し、ブランチを設定したら、Media Session に設定します。

再生

Media Session の生成と設定が完了したら、Start メソッドで再生できます。第二引数の varStart には、開始位置が設定できるようです。

終了処理

以下の処理が必要なようです。

  1. MediaSession を Close
  2. MediaSource を Shutdown
  3. MediaSession を Shutdown

MediaSession を Close は、非同期処理のようで、しっかりと処理をするには、終了イベントが呼ばれるまで待つ必要があるようです。このあたりの処理は、またの機会に。

まとめ

Media Foundation (Media Session)を使った、音声ファイル(ウィンドウハンドルを渡せば、動画も)の再生方法を紹介しました。正直、面倒です。ただ、DirectShow と比べると、まぁ、こんなものかなとも思います。

次は、音声や動画のデコードをやってみたいと思います。