トップページ > 記事閲覧
動画再生について
名前:hadounoyuusya 日時: 2015/08/08 00:13

初めまして、DXライブラリを今日から使い始めた者です C#で利用しております windowsフォームアプリケーションでアルファチャンネルの透過動画を再生させたく、 この記事(ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=3212) を見つけ使ってみたのですがムービーグラフィックハンドルから-1を返され実行できません char*の代わりにstringを代用しています ファイル形式はaviです。 using DxLibDLL; (中略) [DllImport("DxLib.dll")] public static extern int LoadGraph(string FileName); (中略) private void Form1_Load(object sender, EventArgs e) { SetMovieColorA8R8G8B8Flag(TRUE); int MovieGraphHandle = LoadGraph("sample.avi"); PlayMovieToGraph(MovieGraphHandle); while (ProcessMessage() == 0) { DrawGraph(0, 0, MovieGraphHandle, FALSE); WaitTimer(10); } } DXライブラリをあまりよく分かっていなくて申し訳ございません。
メンテ

Page: 1 |

Re: 動画再生について ( No.1 )
名前:管理人 日時:2015/08/08 14:39

MovieGraphHandle には -1 が入っていない( LoadGraph("sample.avi") は成功している )のでしょうか? もし MovieGraphHandle に -1 が入っている場合は sample.avi の読み込みに失敗しています 仮にそうだとしますと、原因は「指定したファイルが見つからなかった」か「対応していない動画形式だった」のどちらかになります avi のファイルの読み込みにはPCにインストールされているコーデックを使用しているので、 DXライブラリの動画機能に対応している「PCにインストールされているコーデック」の中に 指定の avi ファイルに対応しているものがない場合、読み込みは失敗します なので、もし指定しているファイルのパスが正しいのに読み込めない、という場合はDXライブラリが 確実に読み込むことができる Ogg Theora という動画形式に変換して使用することを検討してみてください <ffmpeg2theora>( aviファイルを ogvファイル( Ogg Theora形式 )に変換するソフト ) http://v2v.cc/~j/ffmpeg2theora/ どうしても avi 形式ではないと駄目、という場合はDXライブラリが対応しているデータ形式に変更( 拡張子は avi のままで、内部のデータ形式を変更 )するという方法がありますが、もしデータ形式の変更も駄目、となりますと 残念ですが現在のDXライブラリでは対応できないということになります・・・
メンテ
Re: 動画再生について ( No.2 )
名前:hadounoyuusya 日時:2015/08/08 20:27

ステップイン実行で確認してみたところ、-1を返されるのでLoadGraphが原因のようです aviファイルにはアルファチャンネルが設定されてあり、それを利用したいので変換はできません それでいろいろ調べてみましたが、DxLibの「使用必須関数」という関数の宣言をしていなかったのでそれが原因かと思います 早速実装しようと思ったのですがForm1_Loadではreturnは使えないなどのビルドエラーが出てきてしまいました
メンテ
Re: 動画再生について ( No.3 )
名前:hadounoyuusya 日時:2015/08/09 02:27

returnがよくわからなかったのでとりあえず if (DxLib_Init() == -1) { Application.Exit(); } DxLib_End() ; Application.Exit(); で対処してみました すると動画はうまく再生されたのですが、フォームという概念がなくなり、全画面表示で動画が再生されました alt+tabで画面解除できたの全画面表示で間違いないと思います これはなにが原因なのでしょうか…
メンテ
Re: 動画再生について ( No.4 )
名前:管理人 日時:2015/08/09 09:31

フォームのウインドウハンドルを取得する方法は分かりますでしょうか? DxLib_Init を呼び出す前の箇所で SetUserWindow( フォームのウインドウハンドル ) ; という感じで、SetUserWindow という関数にフォームのウインドウハンドルを渡しておけば 全画面表示にはならなくなるのですが・・・
メンテ
Re: 動画再生について ( No.5 )
名前:hadounoyuusya 日時:2015/08/09 13:20

返信ありがとうございます [DllImport("DxLib.dll")] public static extern int SetUserWindow(IntPtr WindowHandle); public IntPtr DXHandle; (中略) private void Form1_Load(object sender, EventArgs e) { DXHandle = this.Handle; SetUserWindow(DXHandle); if (DX.DxLib_Init() == -1) { Application.Exit(); } (中略) } 言われた通りに記述しました 実行してみると全画面ではなくなりましたが、また動画が再生されなくなってしました…
メンテ
Re: 動画再生について ( No.6 )
名前:管理人 日時:2015/08/09 14:56

> 実行してみると全画面ではなくなりましたが、また動画が再生されなくなってしました… 再び LoadGraph が -1 を返すようになったということでしょうか?
メンテ
Re: 動画再生について ( No.7 )
名前:hadounoyuusya 日時:2015/08/09 17:56

調べてみるとMovieGraphHandleが0でも-1ではなく67239937を返していました
メンテ
Re: 動画再生について ( No.8 )
名前:管理人 日時:2015/08/09 23:39

MovieGraphHandle に 67239937 が代入されているということでしたら読み込みに成功しています ( LoadGrpah は成功時に 0 を返すのではなくグラフィックハンドルを返すので ) 現状のプログラムはどのようになっているのでしょうか? もし最初に貼り付けていただいた int MovieGraphHandle = LoadGraph("sample.avi"); PlayMovieToGraph(MovieGraphHandle); while (ProcessMessage() == 0) { DrawGraph(0, 0, MovieGraphHandle, FALSE); WaitTimer(10); } こちらのようになっているのでしたら、以下のように SetDrawScreen と ScreenFlip を使用する 方式にしてみていただけないでしょうか? int MovieGraphHandle = LoadGraph("sample.avi"); PlayMovieToGraph(MovieGraphHandle); SetDrawScreen( DX_SCREEN_BACK ); while (ProcessMessage() == 0) { DrawGraph(0, 0, MovieGraphHandle, FALSE); ScreenFlip(); }
メンテ
Re: 動画再生について ( No.9 )
名前:hadounoyuusya 日時:2015/08/09 23:56

再生されませんね… ウインドウハンドルの一連の流れをコメントにして全画面で表示すると相変わらず再生されるのですが… private void Form1_Load(object sender, EventArgs e) { DXHandle = this.Handle; SetUserWindow(DXHandle); if (DxLib_Init() == -1) { Application.Exit(); } SetMovieColorA8R8G8B8Flag(TRUE); int MovieGraphHandle = LoadGraph("sample.avi""); PlayMovieToGraph(MovieGraphHandle); SetDrawScreen(DX_SCREEN_BACK); while (DX.ProcessMessage() == 0) { DrawGraph(0, 0, MovieGraphHandle, FALSE); ScreenFlip(); } DxLib_End(); Application.Exit(); }
メンテ
Re: 動画再生について ( No.10 )
名前:管理人 日時:2015/08/10 00:03

うーんそうですか・・・ よろしければ現在試されているWindowsフォームアプリのプロジェクトのフォルダを丸ごと zip等で圧縮してメールでこちら BQE00322(あっとまーく)nifty.com ( (あっとまーく)を@に置き換えてください ) に送っていただけないでしょうか? 直接手元で実行して現状を拝見できれば原因も調べられると思いますので・・・
メンテ
Re: 動画再生について ( No.11 )
名前:hadounoyuusya 日時:2015/08/10 00:31

送らせていたただきました
メンテ
Re: 動画再生について ( No.12 )
名前:管理人 日時:2015/08/10 02:12

すみません、メールが届いていないようです、容量オーバーかもしれません ビルドで作成される拡張子が pdb や exe のファイルはこちらでビルドしても作成されますので除いた上で zipファイルにしてみてください m(_ _;m ( あと、DxLib.dll もこちらで用意できるので無くても大丈夫です )
メンテ
Re: 動画再生について ( No.13 )
名前:hadounoyuusya 日時:2015/08/10 09:46

おそらくaviファイルのせいかもしれません お手数ですがこちらにアップしましたので、パスワードに私の名前をコピーペーストしてダウンロードするという形でお願いします ttp://fast-uploader.com/file/6994722980429/
メンテ
Re: 動画再生について ( No.14 )
名前:管理人 日時:2015/08/11 00:21

ありがとうございます、手元でも現象を確認できました Windowsフォームアプリケーションについて詳しくないのですが、どうやら Form1_Load の中で ループ処理などをしてはいけないようです 少し検索してみたところ、hart_edsf様の「C#でDxLibを使う」の投稿にWindowsフォームアプリケーションで DXライブラリを使う方法が記載されていました 「C#でDxLibを使う」 http://qiita.com/hart_edsf/items/0301f17e2d9acd890c5e こちらの内容に沿ってアップしていただいたプロジェクトのソースを書き換えてみたところ、動画が再生されました 変更後のプログラムは以下の通りですので、よろしければお試しください // Form1.cs ---------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; // DLL Import using DxLibDLL; using QuartzTypeLib; namespace デスクトップ常駐 { public partial class Form1 : Form { public IntPtr DXHandle; public int MovieGraphHandle; public Form1() { InitializeComponent(); DXHandle = this.Handle; DX.SetUserWindow(DXHandle); DX.DxLib_Init(); DX.SetMovieColorA8R8G8B8Flag(DX.TRUE); MovieGraphHandle = DX.LoadGraph("../../data/BNKRG_ジャンプ_正面.avi"); DX.PlayMovieToGraph(MovieGraphHandle); DX.SetDrawScreen(DX.DX_SCREEN_BACK); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { DX.DxLib_End(); } private void Form1_Load(object sender, EventArgs e) { } public void MainLoop() { DX.DrawGraph(0, 0, MovieGraphHandle, DX.FALSE); DX.ScreenFlip(); } } } // ------------------------------------- // Program.cs -------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace デスクトップ常駐 { static class Program { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Form1 Form1Obj = new Form1(); Form1Obj.Show(); while( Form1Obj.Created ) { Form1Obj.MainLoop(); Application.DoEvents(); } } } } // ------------------------------------- あと、アップしていただいたプロジェクトには DxLib_x64.dll が含まれていませんでしたが、 64bit版の Windows を使用している環境では必要になりますので、DxLib.dll と同じフォルダに置くようにしてください
メンテ
Re: 動画再生について ( No.15 )
名前:hadounoyuusya 日時:2015/08/11 09:21

ちゃんとウィンドウで再生されました! ありがとうございます あとは透過できれば完璧なのですが透過させるにはどうすればよいのでしょうか TRUEにしているはずなんですが反映されません…
メンテ
Re: 動画再生について ( No.16 )
名前:管理人 日時:2015/08/11 23:52

私の手元では DX.DrawGraph(0, 0, MovieGraphHandle, DX.FALSE); を DX.DrawGraph(0, 0, MovieGraphHandle, DX.TRUE); にしたところ透過されました Form1.cs の public void MainLoop() { DX.DrawGraph(0, 0, MovieGraphHandle, DX.FALSE); DX.ScreenFlip(); } こちらの部分を public void MainLoop() { DX.DrawBox(0, 0, 2048, 2048, DX.GetColor(255, 255, 0), DX.TRUE); DX.DrawGraph(0, 0, MovieGraphHandle, DX.TRUE); DX.ScreenFlip(); } このように変更すると動画中のキャラクター以外の部分が透過しているのが分かると思います ( DX.DrawGraph(0, 0, MovieGraphHandle, DX.FALSE); にすると動画のキャラクター以外の部分も透過されず黒くなるので )
メンテ
Re: 動画再生について ( No.17 )
名前:hadounoyuusya 日時:2015/08/12 00:49

MainLoopのDrawBoxで透過されていることを確認しました ですがその行を抜くと透過されてなく、Form1のbackcolorが見えません…
メンテ
Re: 動画再生について ( No.18 )
名前:管理人 日時:2015/08/14 01:15

DrawGraph の引数 TransFlag を TRUE にすることで行える透過は 「DXライブラリの画面に既に描かれている物に上書きしない」ためのもので、 ウインドウ自身を透過するための機能ではありません ウインドウを透過する場合は SetUseBackBufferTransColorFlag という関数と UpdateLayerdWindowForSoftImage という関数を 使用するのですが、こちらは SetUserWindow で指定したウインドウに対して描画する場合は効果がありません・・・ とりあえず SetUserWindow を使用しない形式のウインドウを透過させるプログラムを組んでみましたので、 よろしければご覧ください // Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using DxLibDLL; namespace デスクトップ常駐 { static class Program { public static int MovieGraphHandle; public static int Screen; public static int ScreenSizeX, ScreenSizeY; public static int SoftImage; /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { // ウインドウモードで起動 DX.ChangeWindowMode(DX.TRUE); // 透過ウインドウ設定 DX.SetUseBackBufferTransColorFlag(DX.TRUE); // ウインドウサイズを動画のサイズに設定 DX.SetGraphMode(854, 480, 32); // DXライブラリを初期化 if (DX.DxLib_Init() < 0) { return; } // 画面サイズを取得 DX.GetDrawScreenSize(out ScreenSizeX, out ScreenSizeY); // 描画対象にできるアルファチャンネル付き画面を作成 Screen = DX.MakeScreen(ScreenSizeX, ScreenSizeY, DX.TRUE); // 画面取り込み用のソフトウエア用画像を作成 SoftImage = DX.MakeARGB8ColorSoftImage(ScreenSizeX, ScreenSizeY); // アルファチャンネルつき動画の読み込み DX.SetMovieColorA8R8G8B8Flag(DX.TRUE); MovieGraphHandle = DX.LoadGraph("../../data/BNKRG_ジャンプ_正面.avi"); DX.PlayMovieToGraph(MovieGraphHandle); // 描画先を描画対象にできるアルファチャンネル付き画面にする DX.SetDrawScreen(Screen); // メインループ while (DX.ProcessMessage() == 0) { // 描画可能画像をクリアする DX.ClearDrawScreen(); // 動画を描画する DX.DrawGraph(0, 0, MovieGraphHandle, DX.TRUE); // 描画先の画像をソフトイメージに取得する DX.GetDrawScreenSoftImage(0, 0, ScreenSizeX, ScreenSizeY, SoftImage); // 取り込んだソフトイメージを使用して透過ウインドウの状態を更新する DX.UpdateLayerdWindowForSoftImage(SoftImage); // 少し待つ DX.WaitTimer(12); } // DXライブラリの後始末 DX.DxLib_End(); } } }
メンテ
Re: 動画再生について ( No.19 )
名前:hadounoyuusya(解決) 日時:2015/08/15 16:40

ありがとうございます! 希望どおりのプログラムになってくれました!
メンテ

Page: 1 |

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

   クッキー保存