foobar2000用コンポーネント作成開始

foobar2000用のコンポーネントを作り始めた。

iTunesからのメタデータの移行、Last.fm関連、iPod関連までは既に公開されているもので移行できてしまう。その後の運用についてもだいたい調べた範囲で行けそうだし、見た目のカスタマイズにこだわるだけだろう。

問題が、自宅サーバへの再生履歴送信部分だ。ここだけは自分で作るか、やめるかしかない。ので、作ることにした。SDKはダウンロードしておいたので、今日、中身を見た。ドキュメントがあるのかと思ったのに、ほとんどなかった。唖然とした。ライセンス文書と簡単なサンプルくらいしかない。正直、ビルド手順もわからなかった。

ラッキーなことに、カスタムDBのコンポーネントの作者の方がブログでコンポーネント作成の基礎(環境構築から何もしないコンポーネントの作成、メタデータの取得程度まで)を書いてくれていたのでそれを参考に作業を開始した。

ビルド手順もこの人のブログが無かったらお手上げだっただろう。

きたへいの悠々自適 foobar2000関連の記事
ここからの、「コンポーネント開発入門」をそれぞれ読むと手順がわかる。ただ、私はVisual Studio 2010 Expressな環境なので(製品版を買うお金はなく、公開しないから問題はない)デバッグが非常にやりづらかった(詳細は後述)。

この手順でビルド環境を整備、Expressでもビルド環境は普通に作れたが、バージョンが2010だと使うプロジェクトファイルがこのブログとは変わってくる点だけ注意が必要であった。

骨格はこのブログの、「foobar2000 曲情報を表示しよう」をベースに作業を始めた。自宅サーバへは、曲名、アーティスト、アルバム、再生完了日時を送信しているのでここから始めるのが近いと考えた。

iTunesではポーリングして、「最近再生した項目」という標準で存在するスマートプレイリストを利用して更新された分だけをサーバへ送っていた。これなら、iPodで複数回聴いた曲に対応できないのを除けばiPodで聴いたものとiTunesで聴いたものを区別する必要がなかったし作りが単純にできたからだ。

foobar2000ではないわけではないが、きちんと定義しないとスマートプレイリストが使えない。iTunesでやっていた方法を取るのであれば、コンポーネントの設定時にスマートプレイリスト相当のプレイリストの作成・設定を行えるようにしなければならない。

ということで、Last.fmの標準クライアントに近い方法を取ることにした。リアルタイムで再生したものを送信、iPodはiPod用のコンポーネントにSDKがあるのでそれを調べて連携する作りにすればいいだろう、という設計方針を立てた。

今日やったのは、再生中の曲名、アーティスト、アルバムをまず表示するところから。これはサンプルの拡張ですぐできたが、日本語が化けた。調べたところ、fb2kではUTF-8が使われていて(音楽ファイルのタグはUTF-16で書きこむのが標準のはずだから変換していることになる)、Visual StudioのデバッグコンソールにはUTF-16で出力しなければいけない、ということがわかった。サーバへはUTF-8で送信したいので、fb2kから取得した生データがそのまま使える。しかし、デバッグプリントや、もしGUIで画面に送信履歴を出すのならUTF-16でそれらの文字列をもっていなければいけない。とりあえずデバッグ用に変換関数をWebから拾ってきて作った。

デバッグついでにExpressならではの悩みを。製品版だと、「コンソール」というのが使えるらしい。Visual Studioのビューの一つでデバッグ時にだけ表示できてプログラムから専用に出力できる。オーバーヘッドは残るもののリリース版では無視されるらしい。それがExpressではないので、「出力」Windowにメッセージを出すしかない。それはブレークポイントの設定で「トレースポイント」というのを設定しておくと、デバッガはその行では止まらずに「出力」ウインドウに関数名や変数の内容を出力できる。文字列はユニコード環境(標準)ではUTF-16でなければならない。ただ、何もしないでfb2kを実行すると本体や他のコンポーネントが大量に例外を発生させていてこのウインドウがいっぱいになってしまいデバッグ文は確認できない。スクロールバーで戻しても次が出ると戻ってしまうので読めない。終了後に全体をコピーペーストしてメモ帳でいらない行を消して確認したほうが速い。

今日作ったのは、曲の開始時にコールバックを設定して曲名、アーティスト、アルバム名、曲長(秒単位、整数)を取得し、on_playback_time()というコールバックを利用してポーリングした。このコールバックは再生中に1秒間隔で今何秒再生したか?をパラメータにして呼ばれるので、それが曲長と一致すれば再生終了と判断することにした。実際、その直後に次の曲の再生開始コールバックが呼ばれていた。スキップ、途中で止めた場合の動作確認は不完全なままだ。

ここまでできているので、あとは取得したデータをサーバに送る処理を書けばfb2kで再生した分はエラーがなければ大丈夫だろう。ただ、通信エラー時のリトライ、fb2k終了(異常終了時含む)までに送信できなかったデータをどうするか?(バッファリングをメモリにするかファイルにするかということになる)などなどエラー処理は根が深そうである。

通信処理はiPodからのデータを送信する時と共用化したほうがメンテが楽になるので、先にiPodコンポーネントとの連携を調べてみようと考えているところである。そっちもSDKがあり、ダウンロードはしてあるが解答すらしていない。

コメント