foobar2000コンポーネント動いた!

iTunesからの再生履歴をSQLiteデータベースにエクスポートしてfoobar2000の自作コンポーネントで使うことにチャレンジしてきたのだが、今日、ようやく動かすことができた。限定的ではあるが。

固定項目の表示のさせ方は前回までにブログに書いておいたので続きをまとめておく。

SQLite3については、ソースをダウンロードして静的リンクすると配布するときなどは便利になるのであるが、今回は後回し、ということで、DLLを使うことで作業を始めた。デバッグまでなら違いはでない。コンポーネントディレクトリにsqlite3.dllを置いておけば使うことができる。

今動かしている状態では、一レコードに対して一度しかSQLを発行しないようにしている。STLのmapで結果をキャッシュしておいてメモリにおいてしまった。SQLエラーが出たのでパフォーマンスの問題かな?と思ってそうしたのであるが、必要無いようであれば意味無いので、削除して、常に最新状態をSQLで取得したほうがデータ管理上よさそうである。レートの更新をデータベースに対して実行した場合のキャッシュの扱いなど、考えたくもない問題だからだ。

そして、SQLでヒットするはずなのにヒットしないレコードがあることに気づいた。SQLiteでエラーコードを見るとSELECT文の実行後にレコードが返ってきていないのがわかったので調べられた。その時の検索に使ったキーもデバッグ文で出力してデータを調べた。問題は日本語のようだった。iTunesからのRubyでのデータベース作成がまずいようだった。

~(波ダッシュ)-(全角ハイフン)♥(ハート、「R♥35」なるコンピレーションアルバムのタイトルで使用)などがほぼ化けている。

調べたところ、RubyのスクリプトをUTF-8で書いていたが、OLE32のインタフェースで、取得文字列のコードがShift-JISになってしまっているようで、そこからUTF-8にNKFで変換してデータベースを作っているから化けているようだった。foobar2000では内部がUTF-8で動いているからUTF-8で化けていないデータベースを作れれば問題ないはずだ。調べたところ、COM処理を始める前に、

WIN32OLE.codepage = WIN32OLE::CP_UTF8

と指定しておくと、COMで入ってくる文字列がUTF-8になるようだった(UTF-16は指定できなかった)。最初にUTF-8で取得できるのであればデータベースに登録する前にNKFを通す必要がないはずなのでそのまま登録したところ、SQLでヒットしないデータは激減した。が、ゼロにはならなかった。

デバッグ文を調べると数件(20曲前後)あった。全部iTunesの仕様というか、バグと言うか、そんな感じのもの。壊れるのはMP3ファイルが主なのであるが、iTunesライブラリのメタデータが正常でMP3ファイルのタグだけ壊れることがある。多分、私がネットワーク越しに複数回ファイルコピーをしていて、ベリファイがうまくできていなかったのだと思われるが、そんなファイルがいくつかある。そのファイルはiTunesでプロパティを見るとトラック番号やディスク番号が正しくセットされている(これらをデータベースのキーに使っている)。だけど、foobar2000やその他のタグエディタで見るとタグが正しくセットされていない。直してもiTunesでアートワークを設定しなおすとまた壊れることもある。CDを持ってきてエンコードしなおすといいのだが、レンタルもので店頭から消えたものだとそうもいかない。

もう一点は、全角・半角問題。「-」が、iTunesライブラリでは全角で、タグには半角で入っている曲があった。COMで取ってくるデータはiTunesライブラリのデータなので、データベースには全角が入っている。タグを読むfoobar2000は半角をキーにして検索する。一致しない、ということである。

件数が少ないのと、当面配布する予定がないコンポーネントなので、データベースを手修正して使い始めてしまう予定ではあるが、自動化できないとなると少し困った問題ではある。

最後に、今日一番はまった問題が、データ取得後にfoobar2000が「応答なし」になってしまってどうにもならなくなってしまった問題である。最初はSQLのパフォーマンスかと思い、それでSTLのmapを使うなど、いろいろなことをしたのであるが、原因は、スマートプレイリスト(iTunes流に言うところの)であった。元々、foo_playcountが返す%last_played%を使ったスマートプレイリストをいくつか作ってあり、それを残しておいたのであるが、COLUMN UIの設定を変えるのが面倒だったので自作コンポーネントが変えるTitle Formatingの名前を%last_played%にしている。するとスマートプレイリストへの対応は別途必要なのか、その方法はこれから調べるのであるが、そこで固まっていたようである。

スマートプレイリストを削除したらfoobar2000本体は固まらなくなった。確かに、消す前もスマートプレイリストは更新されていなかったのであるが。スマートプレイリストで、最後に更新した日付で期間を指定したり、ソート順を指定したりするので、そのためにはどのように値を持って、返さなければいけないか、また調べなければならない。

コメント