MusicBeeのプラグイン開発
最近、MusicBeeというWindows向けのオーディオプレイヤーのプラグイン開発ばかりやってます。
本体がVer2.0辺りから.NET化したのもあって、プラグインも.NET(C#、VB.NET、C++/CLI)で非常に手軽に開発することができます。
コントロールはWinFormsです。
ビルドしたプラグインは主に2chのMusicBeeスレで公開していますが、
開発していくにあたっていろいろとノウハウも貯まってきたので、ここいらでいくつかご紹介します。
公式Wikiに書かれている内容もありますが、一応。
以下出てくるmbApiInterface
という謎の変数ですが、
これはMusicBeeのAPIにアクセスするためのインターフェースのインスタンスです。
公式Wikiで配布されているプラグインのソースコードをDLすると初めから宣言されています。
メインパネルで表示されている曲をすべて取得
public IEnumerable<string> GetDisplayedSongs() { return GetSongs("domain=DisplayedFiles"); } public IEnumerable<string> GetSongs(string query) { if (mbApiInterface.Library_QueryFiles(query)) { while (true) { string filepath = mbApiInterface.Library_QueryGetNextFile(); if (string.IsNullOrEmpty(filepath)) yield break; yield return filepath; } } }
ちなみに、ライブラリに存在する曲を丸ごとすべて、という場合には
public IEnumerable<string> GetAllSongs() { return GetSongs("domain=Library"); }
とすることで可能です。
設定画面のコントロール作成をべた書きしなければいけない問題
MusicBeePlugin.Plugin
クラスのConfigure
メソッドは、
内部変数about
のConfigurationPanelHeight
プロパティに0以外を代入することによって、設定画面のPanelコントロールのハンドルをIntPtr
構造体で受け取ります。
サンプルソースコードではこれに直接コーディングでコントロールを生やしていますが、
これをユーザーコントロールとして一まとめに作成したものを追加することで見通しがよくなります。
MusicBeeの設定画面で「保存」を押して閉じたときにMusicBeePlugin.Plugin
クラスのSaveSettings
メソッドが走るのですが、ここで編集した内容を反映させるため、私は設定を一まとめにプロパティで持ったConfig
クラスを作り、そのインスタンスを作成したユーザーコントロールに参照渡ししています。
public bool Configure(IntPtr panelHandle) { if (panelHandle != IntPtr.Zero) { Panel configPanel = (Panel)Control.FromHandle(panelHandle); var childUserControl = new MyUserControl(ref this.config); configPanel.Controls.Add(childUserControl); } return false; }
追記(02/13 0:27)
Configクラスのインスタンスを参照渡しするより、シングルトンパターン使った方がスッキリしますね。
public class Config { private Config() { } private static Config instance = new Config(); public static Config Instance { get { return Config.instance; } } }
ファイルへのタグ書き込みが上手くいかない問題の解決
公式のフォーラムをよく読むと分かるのですが、MusicBeePlugin.Plugin.MusicBeeApiInterface
クラスの中身を読んでいるだけでは気づけないんじゃないかと思います。
public void WriteTag(string filepath, MetaDataType type, string value) { mbApiInterface.Library_SetFileTag(filepath, type, value); mbApiInterface.Library_CommitTagsToFile(filepath); // ここ大事 }
実はLibrary_SetFileTag
メソッドはただバッファリングしているだけで、このメソッドを走らせているだけでは何重に実行しようとも実際に反映されることはありません。
反映させるためにはLibrary_CommitTagsToFile
メソッドを走らせる必要があります。
ここで割とハマりました。
こんなところですか。
本当はもっとある気がするんだけど、すぐには浮かんでこないのと、文章にとりとめがなくなりすぎてて意味不明になってしまうので。
蛇足
デザイナで編集してると気づかないうちに余計なプロパティまで変更してること、ありますよね。
DataGridViewのReadOnlyプロパティがいつの間にかtrueになっていたことに気づかず、新規行追加できねぇ!なんでだ!!って2日くらいハマってた。
— ところてん (@htsign) February 10, 2015