SSブログ

mt-daapdの日本語化と韓国語対応 [ソフトウェア/PC関係]

フリーのiTunesサーバー・ソフトウェアであるmt-daapdは,海外製ではあるが,UNICODEに対応しているので,mp3ファイルのID3タグがUNICODEで書かれている限り,日本語であろうと正しくiTunesで表示できる。ところが,ID3タグがShift JISで書かれていると,当然のように対応できない。iTunes以外のID3タグを設定するソフトでは,Shift JISを使う場合が多いので,そういうファイルは曲名もアーティスト名も表示できないことになってしまう。

しかし有難いことに,日本語対応パッチが,「かずー」さんという方のサイトなどで配布されているので,私もこれを使わせて頂いている。mt-daapdの現時点での最新バージョンは0.2.4.1で,同サイトのパッチが0.2.4用のため,一箇所parser.cというファイルでパッチ当てに失敗するのだが,parser.c.rejというファイルを参考にすれば,手で修正するのは簡単だ。

このパッチでは,文字コード変換にlibiconvを使用しているので,あらかじめlibiconvをインストールしておく必要がある。単体のlibiconvがインストールされてなくても,glibcのlibiconv相当のインターフェースでビルドはできてしまい,正しく日本語の変換が行われない場合があるので注意が必要だ。libiconvはこちらのリンク先からdownload可能。私の環境では,configureしてmakeを実行するだけで,簡単にビルドできた。

mt-daapdのビルドにあたっては,インストールされたlibiconvを使用するようにするため,環境変数LDFLAGSに「-liconv」を設定しておく必要がある。また,libiconvのインストール先によっては,LD_LIBRARY_PATHも設定しないと,リンク時にエラーになってしまうので注意(すべてDebian Linuxの場合。ほかの環境は知らず)。ちなみに,システム・ワイドにLD_LIBRARY_PATHを設定する場合には,/etc/bash.bashrcに記述するのがよいらしい。最初,/etc/profileに書いていて,まったく反映されずにしばらく悩んだ。/etc/profileは,ログイン・シェルのbashでしか読み込まれないのだそうだ。

mt-daapdのソース・パッケージはDebianに対応しているので,ビルドしてDebianパッケージを作成することができる。これは,以前やったmediatombの場合と同様の手順になる。ソース・パッケージの展開からビルドまでの流れは次のようなものだ。

tar zxvf mt-daapd-0.2.4.1.tar.gz cd mt-daapd-0.2.4.1 patch -p1 < ../mt-daapd-0.2.4-cp932.patch # ここでsrc/parser.cに手でパッチを当てる export LDFLAGS=-liconv dpkg-buildpackage -uc -us -b -d cd ..

出来上がったパッケージを「dpkg -i」コマンドでインストールし,/etc/mt-daapd.confの中の,楽曲ファイルを置くディレクトリの設定を行って起動すれば,別のPCのiTunesで無事見えるようになる。日本語もちゃんと表示できる。

しかし残念なことに,今度は韓国語の曲名などが正しく表示できない。全部半角カタカナの「キ」になってしまうのだ。もちろん,ID3タグの文字コードは,EUC-KRなどではなく,UNICODEで設定されている。実際,パッチを当てなければ表示できるので,パッチの影響であることは間違いない。ということで,ちょっと調べてみた。

mt-daapdがID3タグの抽出に使用しているライブラリlibid3は,id3_ucs4_tという32ビット型の配列としてタグ情報を保持している。もしIDタグの文字列がUNICODEであれば,1文字が1要素に対応するようにこの配列にセットされるのだが,ASCIIや,Shift JISのようなマルチバイト文字の場合は,1バイトが1要素になるようにセットされてしまう。件のパッチでは,この配列のデータからバイト配列を生成し,それをiconvでUTF-8へ変換しているのだが,問題はこのバイト配列生成の部分にあった。libid3のid3_ucs4_latin1duplicate関数を使用しているのだが,これは元のデータが0xff以下ならそのまま,それより上は対応する文字がないとして,置き換え文字(replacment char)のに変えてしまうのである。ASCIIはUNICODEでも0xff以下だからよいのだが,ハングル等は0x100以上になってしまうので,すべて置き換え文字=0xb7に変換されてしまうという訳だ。パッチでは,この変換後のバイト配列をShift JISとみなしてiconvで変換し,エラーならEUC JPとみなしてリトライ,それでもエラーなら別の言語と認識するようになっている。しかし,ハングルが置き換えられた0xb7は,Shift JISでも有効な「半角のキ」なので,Shift JISとみなした変換が成功してしまう。その結果,「キ」だらけの曲名になってしまうのだ。

というわけで,以上の処理の前段に,i3d_ucs4_t配列が0x100以上のデータを含むかどうかをチェックして,含む場合には単にUTF-8変換して戻る,というコードを追加したらハングルもちゃんと表示されるようになった。差分は次の通りである。

diff -cr mt-daapd-0.2.4.1-orig/src/mp3-scanner.c mt-daapd-0.2.4.1/src/mp3-scanner.c *** mt-daapd-0.2.4.1-orig/src/mp3-scanner.c 2008-02-17 18:26:40.597079106 +0900 --- mt-daapd-0.2.4.1/src/mp3-scanner.c 2008-02-17 18:34:00.695910113 +0900 *************** *** 797,810 **** char * in, * in8, * iconv_buf; iconv_result rc; ! in = (char*)id3_ucs4_latin1duplicate(native_text); ! if (!in) { goto out; } ! in8 = (char*)id3_ucs4_utf8duplicate(native_text); ! if (!in8) { ! free(in); goto out; } --- 797,820 ---- char * in, * in8, * iconv_buf; iconv_result rc; ! in8 = (char*)id3_ucs4_utf8duplicate(native_text); ! if (!in8) { goto out; } ! { ! int ucs4_len = id3_ucs4_length(native_text); ! int i; ! for(i = 0 ; i < ucs4_len ; i++){ ! if( native_text[i] > 0xff){ ! return in8; ! } ! } ! } ! ! in = (char*)id3_ucs4_latin1duplicate(native_text); ! if (!in) { ! free(in8); goto out; } diff -cr mt-daapd-0.2.4.1-orig/src/parser.c mt-daapd-0.2.4.1/src/parser.c *** mt-daapd-0.2.4.1-orig/src/parser.c 2008-02-17 18:26:40.617076735 +0900 --- mt-daapd-0.2.4.1/src/parser.c 2008-02-11 04:14:31.000000000 +0900 *************** *** 132,138 **** --- 132,145 ---- #define AGO 287 #define INTERVAL 288 + #define USE_CP932 + #ifdef USE_CP932 + #define UNKNOWN_STR "UNKNOWN" + #ifndef FILESYSTEM_CES + #define FILESYSTEM_CES "CP932" + #endif + #endif /* Copy the first part of user declarations. */

まぁ,ふつうの日本人なら,英語と日本語が使えれば十分なのだろうし,そもそも自分で使うために作ったパッチを好意で公開してくれているわけだから文句をいうつもりはないが,敢えてSWエンジニアの視点から一言いわせてもらうと,UNICODEを無差別に一旦ASCIIへ変換してしまうという発想は,ちょっと乱暴過ぎますなぁ。

こういう傾向は,特に欧米の人に顕著なようで,UNICODE(UCS-2)対応を謳っていても,上位バイトに0が入っていることしか考慮していないプログラムを書く人が時々いる。mediatombが使ってる,libid3tag(バージョン3.8.3)もそうで,内部のロジックに,一旦ASCII変換して何らかの処理をして,また元の文字コードに変換しなおす,というのが入っていたりする。日本語の文字などは,ASCII変換したときにデータが落ちてしまうので,後で戻すといっても元には戻らない。

UNICODEが普及してきているといっても,所詮こんなもんだ。いっそのこと,ASCII文字も,上位バイトが0じゃないエリアにマップしてしまえばよかったんじゃないかな。まぁ,文字種が少ないから結局あんまり意味ないかもしれないけど。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。