XNAで動画を再生する
About
XNAでは動画を扱うための機能も用意されています。動画を標準対応形式にエンコードする面倒くささはありますが、再生自体はそれほど難しくありません。ここでは動画を取り込んで単純に再生する所までを扱います。
WindowsGame1_PlayMovieInXNA.zip
- VS2010
- XNA4.0
音声付でロイヤリティ(著作権)フリー、かつ動画サイズがそこそこ小さいものをWeb上で発見することができなかったので、ここではXJINEが携帯電話で適当に撮影した動画を利用します。色々と面倒なのでこのサンプル動画に対する著作権を主張する以外の一切の利用方法を許可するという条件で公開することにします。実際に撮影した動画であるとか、自ら製作した動画を利用することの方が実際のシチュエーションには近いでしょうから、結果的に良かったのかもしれません。
以下の画像が実際にXNA4.0上で再生した動画です。元々はmp4ファイルであったものをエンコードしてwmvにしています。動画サイズはエンコード前後とも変わらず1280x720です。
対応形式に動画をエンコードする
XNAで動画を再生する上で一番問題なのが、XNAの標準的な機能によって読み込める動画形式に、用意した動画を対応させることです。XNAで再生される動画は次の条件を満たす必要があります。
- デジタル著作権管理(DRM)で保護されているビデオは使用できない
- VC-1標準を使用して、WindowsMediaVideo9メインプロフィールにエンコードされている
- 固定ビットレート(CBR)によってエンコードされている
- オーディオトラックが含まれている
- オーディオは単一パスCBRフォーマット、WindowsMediaAudio(wma)によってエンコードされている
- 次の表に対応する最大ビットレート以下である
レベル 最大ビットレート フレームレートによる代表的な解像度 低 2 Mbps 320 x 240 @24Hz(QVGA) 中 10 Mbps 720 x 480 @30Hz
720 x 576 @25Hz高 20 Mbps 1280 x 720 @30Hz
エンコードの話をし始めるとキリがないので最低限の説明のみ次のページに用意しました。基本的には「WindowsMediaEncoder9」を利用してエンコード(変換)していけば良いのだと思います。もちろん、手持ちの動画編集用ソフトなどが上記の条件を満たす出力が可能であるなら、それを利用するのが良いのでしょうが、フリーでフルに対応しているセットは、ちょっと探した限りでは見当たりませんでした。
2012年7月現在では上記の条件を満たす動画しか再生することができませんが、次期XBOXや対応ハードが現れればこれらの制限は緩和される可能性があると思います。いつまでWindowsMediaVideo9を使うのか、と思ってしまいます。
XNAに取り込んで再生する
動画さえ用意できればプログラミング自体は対して難しいことはありません。まずテクスチャやモデルと同じようにゲームリソースとして動画を読み込みます。XNAには「Videoクラス」が用意されていて、そこに対応形式にエンコードした動画を読み込みます。さらに、その動画を再生するための「VideoPlayerクラス」も用意しておきましょう。こちらは実際に再生したり、一時停止、ループなどを管理するために利用されます。
GraphicsDeviceManager graphics; SpriteBatch spriteBatch; //再生するビデオ Video video; //ビデオを再生するためのプレイヤ VideoPlayer vPlayer;
用意した動画をリソースとして読み込む方法も他のリソースの方法と同様です。ここでは読み込み時にプレイヤも初期化、設定して、ついでに再生もしてしまいます。
「VideoPlayer.IsLoopedプロパティ」はMSDNの他、実際に記述されているSummary・サマリも「プレイヤーがループでビデオを再生しているかどうかを示す値を取得します。」となっていますが、実際にはsetもでき、ループするかしないかを確かに設定することができます。リファレンステキスト面での不備だと思われます。
protected override void LoadContent() { // 新規の SpriteBatch を作成します。これはテクスチャーの描画に使用できます。 spriteBatch = new SpriteBatch(GraphicsDevice); //対応形式のビデオを読み込み video = Content.Load<Video>("TargetVideo"); //プレイヤを作って vPlayer = new VideoPlayer(); //ループを設定する vPlayer.IsLooped = true; //ビデオを再生 vPlayer.Play(video); }
動画の映像は実際にはテクスチャとして扱われます。再生中の動画からその時点での画像(テクスチャ)を取得するには「VideoPlayer.GetTextureメソッド」を利用します。返り値はTexture2Dとなっていて、そのまま表示してやることで連続してテクスチャが切り替わり動画として見ることができます。この他にも現在の再生位置を確認するプロパティなどが用意されているのでMSDNなどリファレンスを確認してみてください。
spriteBatch.Begin(); //ビデオから抽出した現在のフレーム(Texture2D)を描画 spriteBatch.Draw(vPlayer.GetTexture(), Vector2.Zero, Color.White); spriteBatch.End();