トップページ > 記事閲覧
複数のムービーを連続再生
名前:jenga12 日時: 2015/04/05 03:24

今回質問させていただきたいのは、 タイトルの通り連続再生(非同期)についてです。 OpenMovieToGraph() または、 LoadGraph()で 一気に使用動画のグラフィックハンドルを取得してから、 再生を開始させ、GetMovieStateToGraph() にて再生が終わったか判断し 次の動画の再生を開始する。 という一連の流れのプログラムを書いていましたが、 動画切り替わりのタイミングで、黒背景が1〜4フレームほど出てしまいます。 約1秒ごとに、約500KB〜700KB程度の動画へ再生を切り替える処理になっているので、 読み込みが追いついていないのかと考え、 動画をなるべく軽くしたり、切り替え判別に TellMovieToGraph()なども使用してみましたが一向に改善せず... 何か解決策、または代替案などはないものでしょうか? 以下に、症状発生時のコードを載せます。 【ソースコード】 #include "DxLib.h" #include <stdlib.h> #include <time.h> int Init(void); // 初期化関数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ int MovieGraphHandle[3] = {-1, -1, -1}; // グラフィックハンドル int rnd = 0; // 乱数 /*** 初期化処理 ***/ if(Init()){ return -1; } /*** グラフィックハンドルロード ***/ MovieGraphHandle[0] = OpenMovieToGraph("./data/030.avi"); MovieGraphHandle[1] = OpenMovieToGraph("./data/030_1.avi"); MovieGraphHandle[2] = OpenMovieToGraph("./data/030_2.avi"); /*** 全て再生位置を先頭へ ***/ SeekMovieToGraph(MovieGraphHandle[0], 0); SeekMovieToGraph(MovieGraphHandle[1], 0); SeekMovieToGraph(MovieGraphHandle[2], 0); /*** 1つめの動画の再生 ***/ PlayMovieToGraph(MovieGraphHandle[rnd]); /*** メインループ ***/ while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){ DrawExtendGraph(0, 0, 640, 480, MovieGraphHandle[rnd], FALSE); // イメージの描画 /*** 再生が終わった(?) ***/ if((GetMovieStateToGraph(MovieGraphHandle[rnd])) == 0){ // TellMovieToGraph() もうまくいかない(?) /*** ランダムに次の動画を選択し、再生開始 ***/ rnd = rand() % 3; SeekMovieToGraph(MovieGraphHandle[rnd], 0); PlayMovieToGraph(MovieGraphHandle[rnd]); } } /*** DXライブラリ終了処理 ***/ DxLib_End(); return 0; } int Init(void){ /*** ウィンドウモードに設定 ***/ ChangeWindowMode(TRUE); /*** ログ出力を行わない ***/ SetOutApplicationLogValidFlag(FALSE); /*** DXライブラリ初期化 ***/ if(DxLib_Init() == -1){ return -1; } /*** 非アクティブ状態でも動作するように設定 ***/ SetAlwaysRunFlag(TRUE); /*** ウィンドウサイズとカラービット数の設定 ***/ SetGraphMode(640, 480, 32); /*** ダブルバッファ & バイリニア補間方式へ ***/ SetDrawScreen(DX_SCREEN_BACK); SetDrawMode(DX_DRAWMODE_BILINEAR); /*** ウィンドウタイトルの設定 ***/ SetMainWindowText("mod"); /*** 乱数初期化 ***/ srand((unsigned int)time(NULL)); return 0; }
メンテ

Page: 1 |

Re: 複数のムービーを連続再生 ( No.1 )
名前:S.S. 日時:2015/04/05 12:01

本当ですね 初めて知りました... if文の条件文を GetMovieStateToGraph(MovieGraphHandle[rnd] == 0 から TellMovieToGraphToFrame(MovieGraphHandle[rnd]) == GetMovieTotalFrameToGraph(MovieGraphHandle[rnd]) みたいにすれば 一応滑らかに切り替わりましたが... いかがでしょうか 当方GetMovieStateToGraphの細かい仕様がわからないので わかる人の対応を待つのが吉でしょう
メンテ
Re: 複数のムービーを連続再生 ( No.2 )
名前:管理人 日時:2015/04/05 15:58

動画再生機能の動画再生処理は全般的にメインスレッドとは別のスレッドを使用して 非同期で行われているので、PlayMovieToGraph を呼んだ直後に1フレーム目が 表示されることや動画の最終フレームが表示された直後に GetMovieStateToGraph の 戻り値が 0 になることなどは保証できず、本件のように数フレームの誤差も 許されないような処理には向いていません 解決策としては S.S.さんがご提案の方法のように少し前後の動画を被せて 再生するなどの妥協策となります あと、aviファイルは各PCにインストールされているコーデックを使用していて 再生の挙動がより不安定になってしまうので、よろしければDXライブラリの中に再生用の プログラムを含めてしまっている ogv 形式を avi形式の代わりに使用してみてください ( avi から ogv への変換は ffmpeg2theora というソフトがお勧めです http://v2v.cc/~j/ffmpeg2theora/download.html ) 妥協策を採用する場合も、挙動が不安定な aviファイルよりは ogvファイルを使用したほうが まだ安定すると思います
メンテ
Re: 複数のムービーを連続再生 ( No.3 )
名前:jenga12 (解決) 日時:2015/04/05 16:52

やはりそういう仕様となっていましたか。 ogv形式のみならず mpeg1, mepg2, DivX, Xvid, H264 など、 さまざまなコーデックを試しましたがやはり挙動が不安定でしたので、 連番画像を用いることで対策することといたしました。 ムービーの処理はなかなか手ごわいですね...
メンテ
Re: 複数のムービーを連続再生 ( No.4 )
名前:管理人(解決) 日時:2015/04/05 17:04

動画のデコード処理は重いので他スレッドを使用した非同期処理が基本である上に フレームレートもゲームのフレームレートと一致していないことも当たり前のようにあるので 昔からゲームとは相性の悪いメディアです・・・
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存