WindowsFormで動画再生といえばWMPやDirectShowだが、WMPはURLやパス指定なのでStreamは使えない。
DirectShowはできるけど難しいみたいなのでほかの方法で。UWPはSetSource関数使えばできるがそもそもWin10のみ。
調べたところ、VLCを使えば簡単にできるっぽいのでこれでいく。
環境
- Windows 7
- VisualStudio 2017
- WindowsFormアプリケーション
- C#
- VLC
VLC準備
DLLダウンロード
まずVLCのDLLデータの準備をする。
公式サイトからVer3以上のzipを入手。
zipがあるのは32bitだけなので、64bitがほしい方は一度インストールしてください。DLLを別途保存したらアンインストールして大丈夫。
解凍後、以下のものを別フォルダに移動。インストールした方はC:\Program Files\VideoLAN\VLCにあります。
- libvlc.dll
- libvlccore.dll
- pluginsフォルダ
プロジェクト作成
WindowsFormアプリケーションのプロジェクトを作成します。
NuGetで「vlc.dotnet」と検索すると「Vlc.DotNet.Forms」があると思うので、それをインストール。一緒にCoreとInteropsもインストールされる。
無い方はパッケージソースを「nuget.org」にしたら多分出ます。
次に「プロジェクト」->「プロジェクトのプロパティ」->「ビルド」を選択。
32bitを取った方はプラットフォームターゲットをx86に、64bitを取った方は「x64」に変更する。
DLL設定
ツールボックスに「VlcControl」があると思うので、それをデザインに貼り付け。無い方は再起動か、右クリック->アイテム選択で追加する。
追加した「VlcControl」のプロパティから「VlcLibDirectoryNeeded」を追加して、以下を追記。
先ほどとったDLLとpluginsフォルダが入っているフォルダパスを指定する。
private void vlc_VlcLibDirectoryNeeded(object sender, VlcLibDirectoryNeededEventArgs e) {
e.VlcLibDirectory = new DirectoryInfo("ここにDLLのフォルダパスを指定");
}
これで準備完了。
ソースコード
MemoryStream ms = new MemoryStream();
FileStream fs = new FileStream(@"動画ファイルパス",FileMode.Open,FileAccess.Read);
//MemoryStreamに格納
while (true) {
var buffer = new byte[1024];
var len = fs.Read(buffer, 0, buffer.Length);
if (len > 0) {
ms.Write(buffer, 0, len);
} else {
break;
}
}
vlcControl1.Play(ms); //再生
これだけ。
エラー
System.InvalidOperationException: 'You need VLC version 3.0 or higher to be able to use CreateNewMediaFromStream'
VLCのバージョンが3以上じゃないよ。
System.ComponentModel.Win32Exception: '%1 は有効な Win32 アプリケーションではありません。'
32bitのDLLを取ったのにプラットフォームターゲットがx64、またはその逆になってるかも。
System.AccessViolationException: '保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。'
おそらくpluginsフォルダの中のDLLのどれかがない。
System.Exception: ''VlcLibDirectory' must be set.'
「vlc_VlcLibDirectoryNeeded」イベントが設定されてない。