2004年08月01日

mt-daapdの文字化けを解消 ComputerScience

Local iTunes Music Server on FreeBSDの続き。

その昔、WindowsマシンでMP3ファイルをつくっていた頃は、ID3タグをShiftJISで入力していた。
今はもっぱらAACに変換してるから、iTunesで問題なく日本語タグが読めるのだけど、昔つくったファイルが文字化けしすぎ。

なので、日曜の午前的クイックハックをしてみた。
mt-daapd 0.2.0 に手を入れてみる。

戦略


mt-daapd は libid3tag を使って ID3タグを読んでいる。
なら、mt-daapdのソースから、libid3tagの関数をコールしているところを探してみる。

# pwd
mt-daapd-0.2.0/src
# grep id3_file_open *.c
mp3-scanner.c: pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);

mp3-scanner.cだとわかる。

scan_gettags() という、分かりやすい名前の関数内で、タグから情報を拾っている。拾ったタグはUCS-4だという仮定で、それをUTF-8にしてる様子。
実際のところは、UCS-4ではなくShiftJISなタグなので、ここにiconvをかまそう。

というわけで、次のようなコードを mp3-scanner.c:702 あたりに書いてみた。


// for sjis -> utf8
#define TAG_STR_SIZE 256 // XXX
{
iconv_t cd = iconv_open("UTF-8", "CP932");
id3_latin1_t* cp932_text = id3_ucs4_latin1duplicate(native_text);
char* in_ptr = (char*)cp932_text;
int cp932_size = id3_ucs4_latin1size(native_text);
char_t converted_text[TAG_STR_SIZE];
char* ot_ptr = (char*)converted_text;
size_t in_left = cp932_size, ot_left = TAG_STR_SIZE;
int rc = iconv(cd, ∈_ptr, ∈_left, &ot;_ptr, &ot;_left);
if(rc != 0) {
fprintf(stderr, "error in iconv");
exit(1);
}

utf8_text = (unsigned char*)malloc(cp932_size*sizeof(wchar_t));
if(utf8_text == NULL) {
fprintf(stderr, "error in allocating memory for utf8_text");
exit(1);
}
memcpy(utf8_text, converted_text, cp932_size*sizeof(wchar_t));
iconv_close(cd);
}

これでとりあえずはうまくいった。スクリーンショットをさらしてみる。
otosava
左ペインにある OTO-SAVA が、今回つくったmt-daapdの音源サーバで、その中のファイルの情報がちゃんと日本語で表示されているのが分かる。

問題点


  • まず、うまくいく場合と、そうでない場合がある。
    特定のファイルの読み込み中に、エラーが発生するのか、
    Rendezvous pipe closed... Exiting

    と出て、サーバが死ぬ。なんでだろう。

  • 適当ハックなので、文字列のサイズは256と決め打ちしちゃってるけど、これはまずかろう。
  • iconv descriptorを毎回つくってるのは無駄。
  • fprintf(stderr,"..."); exit(1) は、mt-daapdのエラー処理に適合しないだろう。
  • 全てをShiftJISだと決め打ちして処理してるのはいかがなものか

といったところでしょうか。一つ目のは致命的なので、そのうちちゃんと書くかな。
原因が分かる方がいたら、教えてください。

使い方


パッチをつくってみた。
cp932_utf8.diff
を、mt-daapd-0.2.0/src であてる。
# patch -p0 < cp932_utf8.diff

それから、mt-daapd-0.2.0/src/Makefile のLDFLAGSがある行に、-liconvを付け足す。
あとはmakeしたらできあがり。FreeBSD以外の環境でどうなのかは分かりませんが、Linuxとかでもそのままいけるでしょう。

ComputerScience: at 14:11 : トラックバック

コメント

コメントする










名前、アドレスを登録しますか?






ほげどり