CDDBの日本語文字列取得実験成功。
先日から、CDDBからCDの情報を取得する実験をしていました。
とりあえず、解決しそうなので、中間報告です。
Pythonで実現する一般的な方法は、CDDBとDiscIDをつかって
日本語に対応しているCDDBサーバの情報を取ってくるという方法だと
思います。。。が。。
私の試した結果、アルバムタイトルとアーティスト名は文字化けせずに取得
できるのですが、各トラックの曲名は文字化けしてしまって。。。
エンコードを変換すればいいのかな。。。と思っていろいろやっても
結局だめでした。
頭をかかえながら、ネットで調べてみると、freedb2.org というものが
できているらしいことがわかりました。(TrackType.orgが正式名称かも)
TrackType.orgでは、CDのdisk_idを指定して曲名などを検索する機能があります。
そのページでは日本語が全く化けずに表示されていました。
ためしに、TrackType.orgをCDDBのサーバに指定して、情報をとってきてみました。
でも、症状は変わらず。。。
トラックの曲名は、ASCIIコードのようなデータしか取得できません。。
「ちくしょ。。」
と思いながら、さらにTrackType.orgのnewsというページを呼んでみると、
http経由でテキスト、XML形式のページに直接アクセスできると書かれていました。
たとえば、カテゴリがsoundtrack, disk_idが123456だったとしたら、
(カテゴリ、disk_idはCDDB.query()で取得したもの)
そのCDの情報を取得するには
http://www.freedb2.org/xml/soundtrack/123456
とすればCDの情報を取得できます。
これをPythonでやらせてみよう!!
ということでさっそく作ってみました。
Pythonのスクリプトを実行させると、現在挿入されているCDの
情報が画面に表示されます。
# python pyTrackType.py
=============================
artist = オリガ
album = 永遠。
year = 1998
genre = Vocal
track count = 12
1 : Name = 雨
2 : Name = 私の太陽
3 : Name = 遠い日
4 : Name = 忘れな草
5 : Name = 二人の絆
6 : Name = スター
7 : Name = 花の散るとき
8 : Name = 永遠とは
9 : Name = Tam
10 : Name = ピリグリム
11 : Name = こわれた夢
12 : Name = ポーリュシカ・ポーレ
といった感じです。
これを使えば、Exaileの曲名を文字化けなしで取り込む
こともできそうです。
ソースコードはそれほど長くないので、ここにコピペします。
(あとでポケット倉庫@wikiにも置いておきます)
ちなみに、以下のソースはCDが挿入されてなかったり、
ネットワークにつながってない場合のチェックはしていません。ご了承くださいませ。。
import CDDB import DiscID import httplib import xml.sax from xml.sax.handler import ContentHandler # # class Freedb2XMLHandler(ContentHandler): ## def __init__(self): ContentHandler.__init__(self) self.album = '' self.artist = '' self.year = '' self.genre = '' self.trackNames = {} self.tmpStr = '' self.inTrack = False self.trackNo = '' self.tagDict = {'artist': 0, 'title': 1, 'year': 2, 'genre': 3, 'track': 4, 'number': 5 } ## def startElement(self, name, attrs): self.tmpStr = '' if name in self.tagDict: if self.tagDict[name] == self.tagDict['track']: self.inTrack = True self.trackNo = '' ## def endElement(self, name): if not name in self.tagDict: return tagType = self.tagDict[name] if tagType == self.tagDict['artist']: self.artist += self.tmpStr elif tagType == self.tagDict['title']: if self.inTrack: self.trackNames[int(self.trackNo)] = self.tmpStr else: self.album += self.tmpStr elif tagType == self.tagDict['number']: self.trackNo += self.tmpStr elif tagType == self.tagDict['year']: self.year += self.tmpStr elif tagType == self.tagDict['genre']: self.genre += self.tmpStr if tagType == self.tagDict['track']: self.inTrack = False ## def characters(self, content): self.tmpStr += content ## def get_track_name(self, trackNo): if trackNo in self.trackNames: return self.trackNames[trackNo] return '' def get_cd_category_and_discid(cdDevice, serverURL): category = '' discID = '' disc = DiscID.open(cdDevice) #print disc disc_info = DiscID.disc_id(disc) #print disc_info (status, info) = CDDB.query(disc_info, serverURL) # status # 200 : success # 210 : multiple inexact maches ware found # 211 : multiple exact maches ware found # other: error if status in [210, 211]: info = info[0] status = 200 if status == 200: category = info['category'] discID = info['disc_id'] return (category, discID) # # if __name__ == '__main__': (category, discID) = get_cd_category_and_discid('/dev/cdrom', 'http://tracktype.org:80/~cddb/cddb.cgi') con = httplib.HTTPConnection('www.freedb2.org') con.request('GET','/xml/%s/%s' % (category, discID), body='', headers={'User-Agent': 'Python/2.5'}) response = con.getresponse() xmldata = response.read() #print xmldata parser = xml.sax.make_parser() handler = Freedb2XMLHandler() parser.setContentHandler(handler) parser.feed(xmldata) print '=============================' print 'artist = %s' % handler.artist print 'album = %s' % handler.album print 'year = %s' % handler.year print 'genre = %s' % handler.genre cnt = len(handler.trackNames) print 'track count = %d' % cnt for i in range(cnt): print '%d : Name = %s' % (i+1, handler.get_track_name(i+1))