2016年7月10日日曜日

VLC media playerをLAN経由で操作する


VLC media playerというメディア再生ソフトがあります。クロスプラットフォームでオープンソース、そして数多くのコーデックを内蔵しているため、ほとんどのメディアファイルを再生できます。私も、動画ファイルの再生にはとても重宝しています。

さて、このVLC media playerですが、LAN経由で操作する機能を持っています。
例えば動画を再生中、パソコンから離れて見ていても、手元のスマホなどがLANにつながっていれば、再生を止めたり、シークしたり、プレイリストの次のファイルへ行ったりと、様々な操作ができるとても便利な機能です。

有効にするのも簡単です。詳細は他のページに譲りますが、VLCの設定画面でWebインターフェースを有効にし、
C:\Program Files\VideoLAN\VLC\lua\http\.hosts
でアクセスを受け入れるIPアドレスのマスクを設定してやれば良いだけです。



そして適当なウェブブラウザでhttp://localhost:8080を開くとウェブからVLCを操作する画面が出てきます。もちろんLAN他のPCからIPアドレスを指定してアクセスすればリモートで操作できるわけですし、これを使いやすいようにしたAndroid/iPhoneアプリなども出回っています。

というわけは、当然C#でVLCリモートコントロールライブラリが作れるのでは?という発想になるわけです。
まあ、パソコンの場合ウェブブラウザからアクセスできるのでそんなに必要性は無いわけですが…。いやいや、自分でアプリ作りたいでしょ…作りたくない?

いろいろ調べてみましたが、意外と操作するのは簡単みたいです。
VLC HTTP requests
ここに詳しく書かれていました。HTTPのGETリクエストでコマンドを送る仕様になっているようで、非常にシンプルです。ブラウザで試してみることすらできてしましますが、例えば
http://localhost:8080/requests/status.xml?command=pl_play
にアクセスするだけでVLCで一時停止/停止していたファイルを再生することができてしまいます。
また、一方でそのstatus.xmlの本文にXMLで現在再生中のファイルのファイル名やメタ情報や再生長、再生位置やボリュームから現在フルスクリーンで表示しているかどうかまで非常に多種多様な情報が入っています。これをパースすることでシークバーなどを作れそうですね。


というわけで、ライブラリを作ってみました。

VLC Controller - nuget

やっていることはstatus.xmlとplaylist.xmlのパースと、コマンドの送信機能です。

VLCを操作する

まずは、上記のNugetからライブラリをインストールし、インスタンスを作ります。
VlcController vlc = new VlcController() {
    HostUrl = @"http://localhost:8080/",
    Password = "****",
};
VLCが動いているマシンのURLとBasic認証用のパスワードを指定し、インスタンスを形成します。
public async void PlayButtonClicked()
{
    await vlc.Play();
}
あとは超簡単で、このように必要に応じてメソッドを呼び出せば良いです。どのようなメソッドがあるかはVisualStudio等で確認してください。引数も特に困ることは無いかと思います。

あ、再生メソッドやプレイリスト編集系メソッド等に「id」っていう引数が出てくるものがあると思いますが、それに関しては、下記のプレイリストについてのところでidが説明されますので、それを入れてください。

VLCの状態を取得する

再生中のファイルの情報や、再生位置、ボリューム、ランダム再生のON/OFFなどといった、再生状態にかかわる情報はStatusプロパティ、プレイリストについてはPlaylistプロパティに保持されています。このデータは一定間隔でポーリングして取得しており、デフォルトではポーリングはON、 ポーリング間隔は1秒にしてあります。これもVlcControllerクラスのプロパティから変更可能です。
もしもVLCが起動されていないなどで接続できていない場合はIsConnectedプロパティがfalseになります。また、それと同時にStatusプロパティとPlaylistプロパティがnullになります。注意してください。

Status

Statusクラスには、上記の通り再生状態にかかわる情報が入っています。プロパティ一覧を見れば、どのような情報が返ってくるのかがわかるでしょう。

Playlist

Playlistクラスはツリー構造が取られています。VLCのプレイリストはツリー構造になっており、通常のプレイリストの他、マイビデオなどにあるメディアもプレイリストから参照できるようになっています。


左上に「マイビデオ」等が書かれていますね。 これを1度クリックすると読み込まれ、Webインターフェースを介して触ることができるようになります。

PlaylistクラスにはRootNodeプロパティがあり、ここにはNodeクラスのインスタンスが入っています。このルートノードの下に、プレイリスト、メディアライブラリ、マイビデオなどといった各項目のノードが入っております。
各階層の中に入っている再生項目はLeafクラスのインスタンスになっており、これには長さ、URI、現在再生中の項目かどうかを示すフラグなどといった情報が入っています。LeafとNodeはともにElementBase抽象クラスを親クラスとして持っており、NodeクラスのChildrenプロパティはElementBaseの配列になっていることに注意してください。

ElementBaseクラスにはIdプロパティがあり、各ノード、LeafにユニークなIdが振られています。これを一部のコントロール系メソッドの引数に渡してやることによって、任意の項目を再生したり、プレイリストから削除したりすることができるようになります。


このライブラリを使って、ガジェットのようなものを作ったり、ツールバーに常駐するようなツールを作ることで、単なるWebインターフェースよりも使い勝手のいいリモコンツールを作ることができるかもしれませんね。
もしくは、このライブラリが使えるかどうかはわかりませんが、Wi-Fi経由でVLCを操作するリモコンなどを最近流行りのラズベリーパイみたいなコンピューターで作ってみるのも手かもしれません。

夢は広がりますね!