動画再生機能¶
吉里吉里Z がサポートする動画再生機能について記載します。
目次¶
諸元¶
| モード | オーバーレイモード (vomOverlay) | ビデオオーバーレイを使用し、画面の最前面 (全画面) に動画を表示するモード |
| モード | レイヤーモード (vomLayer) | 指定したレイヤーへ動画をデコードして再生するモード |
| モード | ミキサーモード (vomMixer) | 動画に追加のレイヤー画像を合成して表示するモード (ソフトウェア合成固定) |
| 特殊再生機能 | セグメントループ | 指定されたフレーム間をループする機能 |
| 特殊再生機能 | ピリオドイベント | 指定されたフレームでイベントを発生させる機能 |
| 特殊再生機能 | 再生速度指定 | 動画の再生速度を指定する機能 |
| 特殊再生機能 | マルチオーディオ | 多重化された音声のうち、1つを選択して再生する機能 |
| 音声バランス (パニング) |
-100000 ~ 0 ~ 100000 |
-100000 が 完全に左、0 が中央、100000 が完全に右。 ステレオのソースを再生する場合は、パンは、 左右どちらかのチャンネルを減衰させることで実現される。 |
| 音声ボリューム | 0 ~ 100000 | 0 が完全ミュート、100000 が 100% の音量 |
| 音声ストリーム | コンテンツに依存 | 再生する音声ストリームを選択 |
| 再生速度 | >0 | 1.0が等倍速。音声ありの場合の上限は概ね 2.0≧速度>0。 |
| 取得可能値 | フレームレート | 1秒当りのフレーム数 |
| 取得可能値 | 現在のフレーム | 現在表示しているフレーム。 表示しているフレーム番号と完全に一致する保証はない。 |
| 取得可能値 | 現在の再生時間 | 動画の最初からの動画内での経過時間。 |
| 取得可能値 | 画像サイズ | 幅と高さ |
| 取得可能値 | 音声ストリーム数 | 多重化されている音声ストリームの数 |
| 取得可能値 | 全フレーム数 | 動画が保持しているフレームの数 |
| 取得可能値 | 合計時間 | 動画の合計時間 |
| イベント | フレーム更新 | ビデオフレームが更新された後に発生 |
| イベント | Periodイベント | 通常ループ終端、セグメントループ終端、 設定したピリオドイベント、再生準備完了時に発生。 |
| イベント | ステータス変更 | 再生状態が変更された時に発生 |
VideoOverlay.visible は動画の表示可否のみを制御するプロパティで、既定値は false です。デコードと音声再生は visible の値に関係なく進行します (吉里吉里2/Z 由来の挙動)。表示を伴わない準備・先読みや、音声のみを進めたい場合にこの性質を利用できます。
モード¶
| 種類 | 説明 |
|---|---|
| オーバーレイモード (vomOverlay) | 動画を画面の最前面 (全画面) に表示する既定モードです。他のどのレイヤーよりも手前に表示されます。 WINVER では映像は描画デバイス (BasicDrawDevice) の Direct3D 11 バックバッファへ合成されます。 単純に動画を再生して停止する用途に最も適し、負荷も軽くなります。追加画像の合成は行いません (必要な場合はミキサーモードを使用)。 互換のため定数 vomMFEVR が vomOverlay の別名として残されています。 |
| レイヤーモード (vomLayer) | 指定のレイヤーへ動画をデコードして再生するモードです。 環境依存性が低く、指定フレーム間でのループ(セグメントループ)や指定フレームでの処理(ピリオドイベント)などの機能が使用可能です。 ただし、他のモードよりも CPU 負荷が高くなるという難点があります。 |
| ミキサーモード (vomMixer) | オーバーレイに加え、setMixingLayer で指定したレイヤー画像を動画の上へ合成できるモードです。追加画像を確実に合成するため、この用途ではハードウェアデコードを使わず必ずソフトウェア合成経路になります。 |
対応形式とデコーダ¶
WINVER では、拡張子・コンテナに応じて次のデコーダが用いられます。
| 形式 | デコーダ | 備考 |
|---|---|---|
| webm (VP8 / VP9) | movie-player | アルファチャンネル付き webm に対応します。 |
| mpg / mpeg (MPEG-1) | pl_mpeg | 複数音声ストリームの多重化に対応します (マルチオーディオ)。 |
| wmv / asf / mp4 / mov / avi 等 | Media Foundation SourceReader | CPU 側で BGRA へデコードします (CPU パス)。 |
| mp4 / wmv 等 (MF ネイティブ) | IMFMediaEngine (HW デコード) | 既定でハードウェアデコードされます。-mediaengine=no を指定すると無効化され、CPU の SourceReader へフォールバックします。 |
IMFMediaEngine による HW デコードパスは、BasicDrawDevice の Direct3D 11 デバイスを共有します。音声再生および AV 同期は MediaEngine が内部で処理します。
オーバーレイ合成の仕組み¶
オーバーレイ (およびミキサー) の映像は、pull 型の VideoPresenter を通じて描画デバイスへ渡されます。BasicDrawDevice の Show からフレーム毎に presenter へフレームが要求され、バックバッファへ合成されます。
presenter を受け入れる host を持たない描画デバイスへ切り替わっている場合は、子ウィンドウを用いた Direct3D 11 present へフォールバックします。
System.captureScreen はバックバッファの読み戻しによって画面を取得するため、オーバーレイ映像を含んだ状態でキャプチャされます。
SDL(GENERIC) での動画再生¶
SDL(GENERIC) 系統では、webm を movie-player、MPEG-1 を pl_mpeg でデコードします。
映像の提示 (presenter) には SDL_Renderer 版と OpenGL 版があり、OpenGL 版では BT.601 の YUV→RGB 変換をシェーダで行います。Emscripten(web) ではブラウザの <video> を用います。
動画の音声は miniaudio 経由で再生されます (MovieAudioSink)。再生済みサンプル数を AV 同期のマスタクロックとして用い、映像側をこれに追従させます。
特殊再生機能¶
| 種類 | 説明 |
|---|---|
| セグメントループ | 指定されたフレーム間をループする機能です。 この機能を使用するためには、動画ファイル自体にループで戻る先のフレームにキーフレームを設定しておく必要があります。 キーフレームがない場合、期待したようにループされません。 |
| ピリオドイベント | 指定されたフレームでイベントを発生させ、何らかの処理ができる機能です。 イベント発生時に、離れたフレームにシークすることで、間のフレームを飛ばして、あたかも動画がつながっているように見せることが可能です。 また、動画にあわせて字幕を出したい時なども、字幕の開始フレームにピリオドイベントを設定し、イベントを待って文字を表示することで実現可能です。 他に、この機能を使えば、動画自体には音を入れず、指定フレームで SE を使って音を鳴らすことも可能です。 |
| 再生速度コントロール | 動画の再生速度が指定可能です。 1.0 を指定すると通常の再生速度、0.5 では半分の再生速度、2 では2倍の再生速度になります。 設定可能な範囲はデコーダ/コーデックに依存します。 |
| マルチオーディオ | MPEG-1 では、複数のオーディオストリームを多重化可能なため、それを利用する機能です。 この機能では、任意のオーディオストリームを再生することが可能です。 たとえば、BGM のみ、BGM+声などのストリームを準備しておき、ユーザーがどのモードで再生するか指定可能にすることなどが出来ます。 ただ、オーディオストリームの切り替えには 2 秒程度のタイムラグがあるため、あまりインタラクティブな用途には向いていません。 上記のユーザーによる選択やシーンによって動画音声が変わるような用途に使えます。 |
動画再生準備について ( preparevideo )¶
preparevideo は、動画の 1 フレーム目を指定されたレイヤーに描画します。
これは、意図しない画像(メモリ上のごみや前回の画像など)が画面上に表示されるのを防ぐ目的で利用されます。
つまり、再生対象としたレイヤーを非表示にして、動画を openvideo で開いた後、preparevideo をコールし、準備完了を待ち、準備できた後に再生対象レイヤーを表示状態にするような処理を記述することで、表示した時に動画の 1 フレーム目を表示することが出来ます。
なお、この機能はレイヤーモードの時のみ意味を持ちます。
レイヤーモードでのレイヤー指定について¶
レイヤーモードで動画を再生する場合、videolayer を使用して、描画対象レイヤーを指定します。
videolayer では、slot と channel, page, layer が指定できます。
slot は、異なるビデオを同時に再生する時に、どのビデオに対する操作かを特定するためにあります。
複数の動画を同時に再生することはほとんどないと思いますので、通常は記述を省略し、0 が指定されるようにしておけば問題ありません。
channel は、出力するレイヤーを指定するためにあります。
1 つの動画に付き 2 つまで出力するレイヤーを指定できるので、そのどちらに対する指定かを特定するために利用します。
2 つ指定可能になっているのは、トランジションを利用するためです。
動画再生中にトランジションを実行すると、表と裏のレイヤーが入れ替わるため、片方にしか出力していないと、動画が非表示になってしまいます。
これを避けるため、動画再生中にトランジションを行う場合は、チャンネルの 1 と 2 に表と裏のレイヤーを設定しておきます。トランジションを行わないのであれば、表面だけ指定しておけば問題ありません。
動画終端での振る舞い¶
ループを指定せずに動画を再生すると、最後まで再生したら動画は停止します。
動画の最後のフレームを表示したままゲームを進行したい場合、この動作は好ましくありません。
これを回避する最も簡単な方法はレイヤーモードを使用することです。
レイヤーモードでは、レイヤーに対して動画が描画されるため、最後のフレームの画像がそのままレイヤーに残ります。
そのため、特に意識することなく、最後のフレームを表示したままゲームを進行出来ます。
オーバーレイやミキサーの場合は、停止すると表示が消えてしまうため、最終フレームに達する前に一時停止しなければなりません。
これは、ピリオドイベントで実現できますが、本当に最終フレームにしてしまうと、停止してしまう可能性があるため、動画の末尾に数フレームダミーフレームを入れておき、少し通り越しても大丈夫なようにしておいた方が良いです。
レイヤーモードで動画が表示されない現象について¶
動画の再生対象としたレイヤーの表示タイプがアルファなどになっていると、動画が表示されないという事態が発生します。
これは、動画がアルファチャンネルを持っていない場合、アルファチャンネルの位置に不定データが書き込まれるためです。
レイヤー表示タイプがアルファになっている場合、この不定データがアルファ値として扱われるため、完全に透明になってしまったりします。
これを回避するためには、再生対象レイヤーの表示タイプを opaque にしてやります。
そうすると動画が表示されるようになります。
ミキシング再生¶
ミキサーモードはその名の通り、他のレイヤーと動画をミキシングして再生することを実現できます。
ミキサーモードでミキシングに関係して指定できるのは、背景色、ブレンド率、ミキシング対象レイヤーです。
ミキシング対象レイヤーは、設定した瞬間の画像と動画がミキシングされます。
そのため、ミキシング対象レイヤーが更新されても、再度設定しない限り内容は更新されません。
ただ、毎フレームの更新時に設定をコールすると、かなり CPU 負荷が高くなります。
CPU 負荷を抑えるために、設定する場合は、更新された時のみに限定した方が良いです。
背景色は、ブレンド率を 1.0 未満にした場合にブレンドされる色です。
背景色を黒などに設定し、ブレンド率を変化させることで、フェードイン/アウトが実現できます。
当然、ミキシング対象レイヤーとのフェードイン/アウトも可能です。
ミキシング対象レイヤーとのブレンド率やレイヤー位置はレイヤーの情報が使われます。
つまり、表示位置はレイヤーの位置に、ブレンド率はレイヤーの不透明度に依存します。
ただ、レイヤーとのブレンドは毎回指定する必要があるという仕様から、レイヤーとフェードイン/アウトをすると CPU 負荷が高くなってしまいます。
キーフレームとシーク¶
吉里吉里Z ではシークを高速に行うため、シーク可能位置をキーフレームに限定しています。
キーフレーム以外のフレームを指定した場合、指定フレームに最も近いキーフレームへシーク処理が行われます。
ただし、この動作は Codec 依存のため、しばしば意図しない動作が行われます。
そのため、シークを行うフレームへは必ずキーフレームを設定するようにした方が良いです。