開発中の音楽再生履歴記録・検索システム(仮)、そこそこ使えているうえに、煮詰まっているというか、完成度が高くなってきたために(それでもまだ8割くらいか)、いくら作り・直してもキリがなくて(しかも、劇的にすごくはならない)疲れたので、ちょっと脇道に逸れて、先日書いたgmusicbrowser(以下GMB)との連携・統合の一部の、GMBの再生履歴を取って記録することを試してみた。

まあ、GMBで再生している曲情報を取ること自体は全く簡単で、Dbusインタフェースを使えば目をつぶってもできたくらいだが(実際には少し手こずった)w、その先が大変だ。

先日も書いたように、再生している曲・演奏・録音(以下「演奏」)が「何か」を特定(同定)することが難しい。なぜ同定が要るかというと、GMBでもSpotifyでも同じ演奏を再生したら、同じ演奏の履歴として記録したいのだ。片方で再生したらもう片方とは別扱いになるのでは全く無意味だ。

そして、上記のGMBから取れる曲情報は、曲名、アーティスト名、アルバム名などで、それだけあれば充分だと思われるだろうが、実際には不十分だ。例えば、以下のような問題がある。

  • 同じアーティストが同じ曲(だけど実体が異なる)を何度も演奏/録音/発売した場合(例: ライブ、再録、リミックス、シングル/アルバム版、リマスター)、それらの区別が付かない。: 例: John Lennon "Give peace a chance" (通常版と"Shaved fish"中の短縮版)
  • 同じ演奏だけど微妙に曲名などが異なる場合、同じ演奏と判定できない。: 例: "Somebody To Love"と"Somebody To Love - Remastered 2011"
    • 逆に、何度も演奏/録音/発売した場合に微妙に曲名を変えてくれると、1番目の問題が緩和できる。: 例: 「かもめが翔んだ日」と「かもめが翔んだ日(スタジアム・バージョン)」
    • 「ファジー判定」のような仕組みがあるといいのかも知れないが、今度は上のような微妙に曲名を変えてくれた別演奏が同じになってしまいそうだ。
    • CDをPCに取り込んだ時に使ったCDDBの曲情報と、Spotifyの情報が異なる場合もあるし、自分で記述を変更した場合もある。
    • 日本のアーティストでは、表記が日本語かローマ字かの違いも問題になる。

そこで、先日も書いたように、各演奏はISRCで区別し(ISRCのないものは別扱いにする)、ある演奏がどのISRCに対応するかを音響指紋で識別しようと考えた。音響指紋と演奏を照合するためのシステムは、AcoustIDとMusicBrainzを使うことにした(無料で使えるのはこれらしかないため)。

手順は以下である。

  1. GMBの演奏(ファイル)の音響指紋を計算する。: fpcalcコマンド
  2. その音響指紋をAcoustIDに送り、演奏に紐付けられたMusicBrainz ID(以下MBID)を得る。
  3. 得られたMBIDでMusicBrainzからISRCを得る。

全くシンプルで、すぐにでもできそうに見える。確かに、それほど時間が掛からずに作れた(でも疲れたw)。が、ちょっと試したらとんでもなかった。以下のような問題が噴出した。

  • ある音響指紋に対して、実際とは異なる演奏(候補)が出てくることが結構ある。: 確率的なものなので仕方ない。
  • AcoustIDに登録されていてもMBIDがない演奏が結構ある。: ボランティアベースだから仕方ない。。。
  • MBIDがあってもISRCがない演奏が結構ある。: ボランティアベースだから仕方ない。。。
  • 登録内容(例: 曲名)が誤っている演奏がある。: ボランティアベースだから仕方ない?? 気付いたら修正しろってこと?
  • MusicBrainzのアクセス制限(アクセス頻度)が厳しく(最大 平均1回/秒)、それを破らないように、間隔をおいて何度も検索すると時間が掛かる。: 無料だから仕方ない。。。
    • 素行の悪いアプリは公表されてアクセス制限されるようなので、なるべく規則を破らないようにしないといけない。
    • AcoustIDにも同様に制限があるが、まだ緩い(最大 平均3回/秒)。

まさに、「聞いてないよー!」の世界だw

それでいろいろな工夫をしたが、現時点では、完全な自動処理(演奏の同定)をするのは難しい感じだ。以下に、したことと起こった問題を書く。

  • (MusicBrainzに情報がない場合に、)曲情報(曲名、アーティスト名など)でSpotifyを検索する。演奏時間やリリース年などでフィルタリングを厳しくする。
    • 最初の問題(同名曲の区別ができない/微妙に違う名前の曲が同じと判定できない)が起こる。
    • ライブ版がアルバム版と認識されることがある(曲名などが同じで、たまたま演奏時間が近い場合)。
    • "Various Artists"が幅広くマッチしてしまう。 → 無視するようにした。
  • (MusicBrainzの誤情報に備えて、)MusicBrainzで得られたISRCでSpotifyを検索して正当性を確認する。
    • Spotifyにない演奏が結構ある。SpotifyにあってもISRCがない演奏もあるうえに、MusicBrainzでもSpotifyでも複数のISRCがある演奏もある。そもそも、曲情報の表記が異なることがあるので、判定すら難しい。

ちょっと見た感じでは、多くの(2/3以上?)普通の演奏では問題なく動いている(→ 出力の例)のだが、たまに間違うのはやっぱり気に入らない。

他の問題として、MusicBrainzではリマスターやレコードの演奏などが全部通常版(例: CD)と同じに区分されている(Spotifyは、基本的に最新の1種類しかない。リマスターがあればそれだけになるし、当然ながらレコード版はない)。これは、技術だけでなくポリシーの問題も絡むので、すぐにはどうすればいいかが決められない。リマスターやレコードを通常版と別扱いにしたいこともあるし、そうでない場合もあるのだ。

AcoustIDとMusicBrainzはイマイチなので使わなくてもいいのかと思ったが、そうではない。それ以外に有効な手段がないので、やっぱり音響指紋での識別をした方がいい。その点で、Spotifyが音響指紋を提供してくれると一番ありがたいが、そうも行かない。今のところは、(リアルタイムでの)完璧な同定は諦め、バッチ処理でGMBとISRCの対応表を作って、その結果を「見て」修正するのがいい感じだ。ただ、GMBには1.5万曲くらい入っているので何とも大変そうだし、時代遅れな気がする。

次善の策として、SpotifyにはなくてGMBでしか再生できない演奏についてだけ対応表を作って、その内容を確認することが考えられる。それなら2500曲以下と大分減るが、そういう演奏はISRCがないものも多いので、別の問題(ISRC以外の何で演奏を区別するか)がある・・・

できそうでできないのは、SpotifyのAPIの音楽分析アルゴリズム(演奏の「活発さ」や拍などが分析されて公開されている)でGMBの演奏を分析して音響指紋の代わりに照合に使うことだ。でも、SpotifyのAPIではローカルファイルの分析はできないと思うし、Spotifyのアルゴリズムは公開されていないので、自分で実装することもできない。

もう一つ、最後の手段としてあるのは、仕舞い込んだCDを引っ張りだして、その中に記録されているであろうISRCを取り込むことだ。これが一番確実ではあるが(こうなると分かっていたら、最初からやっていただろう)、ISRCが入ってないものもあるだろうし、レンタルのものはできないし、そもそも、面倒だからやりたくないw

てな訳で、またしても(普通の人には全くどうでもいい)泥沼にはまり込んだ今日この頃・・・

(6/9 7:15追記) 昨夜、寝る直前に思い付いたのだが、IDとして各演奏に固有の識別記号を割り当てたいので、曲ファイルのダイジェスト(ハッシュ)値(例: MD5)をIDに使ってみたい。ただし、普通にファイルのダイジェスト値を使うと、それはタグ(例: 曲名)を変更しただけでも変わってしまって不便(タグを変えるとファイルとIDが合わなくなってしまう)なので、音響指紋のダイジェスト値を使うことを考えた。

ファイル名などをテーブルに記録して、そこでの通し番号などでIDを割り当てることもできる(GMBの方式)が、ファイルを移動したり名前を変えたらテーブルを更新しなくてはならないから不便だ。それを解消するために、曲のファイル自体にIDを持たせたい。そのためには、ファイル内(例: タグ)にIDを記録するか、ファイル名にIDを付加するか、上記のようなファイルの特徴をIDにするのがいいだろう。

IDをファイル内に記録する場合、既存のファイルすべてに記録する必要があって面倒なうえに、内容が変わらないのにファイルが更新されるのは嫌だし、今後、ファイルを追加するたびに忘れずにIDを記録しなくてはならないので煩雑だ。

ファイル名にIDを付加する(デジカメ画像の管理で実施している)のは簡便だが、既存の多くのファイル名を変えるのは好ましくない。例えば、GMBへの曲の登録をし直す必要があって、現実的でない。また、ファイルを追加するたびにIDを追加しなくてはならない煩雑さもある。

ファイルの特徴をIDにするのであれば、ファイル自体には何もしなくていいうえに、ファイルの中身を変更しない限り、あらかじめ決めた手順(計算)によっていつでも同じIDが得られるから便利だ。

音響指紋は、その名のとおり、(ファイルに格納された)音の特徴(だけ)に基づいているので、タグは無関係なはずだ。実際に試してみたら、本当に、タグを変えても音響指紋とそのダイジェスト値は変わらなかった(当たり前のことだが、結構うれしかった)。なお、当然ながら、異なる演奏は別の(音響指紋・)ダイジェスト値になった。ただし、同じ演奏でも、通常(CD)版とリマスター版やレコード版の音響指紋は異なったので、結構敏感なようだ。

この方式なら、IDはファイル(の中身の音)に固有だし、生成にも再現性がある(同じ音のファイルに対してはいつでも同じ値が生成できる)。ただ、音質や雑音などの条件が異なると「同じ演奏」でも同じIDにはならないが、そこは諦める(そもそも、GMBの中では重複した演奏(ファイル)は極力排除しているから、大きな問題ではないと思う。あるとすれば、リマスター版やレコードをオリジナル(CD)と同じと扱うかどうかの類だ)。

逆に、ダイジェスト値に衝突(偶然の一致、重複)が生じて、別の演奏に同じIDが割り当たる可能性はある。ただ、広く使われている方式でも(ハッキングを除いて)そういう問題が起こったという話は聞かないので、確率は低そうだ(また、音響指紋のデータは短いので、指紋の小さな変化でもダイジェスト値に反映されるから衝突は起こりにくそうだと想像するが、確証はない)。万が一衝突した場合は、(どうにかしてそれが検出できたとすれば、)IDに子番号を追加すればいいのではないかと思っている(と書いたものの、IDをテーブルなどで一元管理しないので、IDを生成した時点では衝突は分からなそうだ・・・ が、下に書いた変換テーブルで対応できるかも知れない)。

また、ISRCへの変換は変換テーブルで行う。その時に、重複した同じ演奏のIDに一つのISRCを割り当てることで集約できそうだ。

再生履歴DBでは、当初は、同じ演奏であっても、GMBのもの(音響指紋からIDを生成)とSpotifyのもの(ISRCからIDを生成)とは別のものとして記録するが、上記ISRCへの変換テーブルができたら、履歴などの情報を自動的にマージ(統合)したい(実際には、記録されたデータ自体は変更せず、DBの機能を使って統合されているように見せたい)。

と、またしても夢は膨らむのであったw (そして、例によって落とし穴が待ち構えている?)

(21:06 わずかに加筆・修正; 21:19 題の誤りを修正; 6/9 7:15 追記)

  •   1
  •   0

コメントを書く

名前    

メール 

URL