SSブログ

MP3ストリーミングでUTF-16なTAGの文字化けをなおす その1 [linux]

私は、icecast-2.3.2+ices-0.4の環境で自宅用のMP3ストリーミングをしています。

最近、mp3ファイルのTAG管理にMp3tagを導入し、TAG形式を UTF-16で統一するようにしました

すると、配信されたMP3ストリーミングをwinampで受信すると、 アーティスト名やタイトルが文字化けするようになってしまいました。。。 orz..
(ま、当たり前と言えば当たり前ですが。。)

icecast-2.3.2はUTF-8なTAGは任意のキャラクタセットに変更できるようですが、UTF-16は当然ながらサポートされていません。

ならば、と思い無理やり対処してみたところ、見事に文字化けが直りました!!

本手法は環境によっては対応できないかもしれません。
試される方はあくまでも自己責任でお願いします。

まずは、情報集めから。。
UTF-16についてはこちら
ID2v2.3についてはこちら


続いて、Mp3tagのUTF-16がどういう形式なのか調べてみました。
というのも一口にUTF-16といっても実際には3種類あるからです

Mp3tagでTAGを入れたmp3ファイルをいくつかバイナリエディタで確認したところ、

のようになっていました。

先頭の10Byteがフレームヘッダです
さらにTPE1やTIT2は、TEXT情報フレームなので続く1byteがテキストエンコード情報です

テキストエンコード情報は
   Frames that allow different types of text encoding contains a text
   encoding description byte. Possible encodings:

     $00   ISO-8859-1 [ISO-8859-1]. Terminated with $00.
     $01   UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
           strings in the same frame SHALL have the same byteorder.
           Terminated with $00 00.
     $02   UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
           Terminated with $00 00.
     $03   UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.

   Strings dependent on encoding are represented in frame descriptions
   as , or  if newlines are allowed. Any empty strings of
   type $01 which are NULL-terminated may have the Unicode BOM followed
   by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00).

のように定義されており、この例では 01 なので BOMつきUTF-16であることがわかります。
続く2byteがBOMでFF FEになっていることからリトルエンディアンです

つまりMp3tagのUTF-16はBOM付きリトルエンディアンのUTF-16ということがわかりました
ちなみにiTunesのTAGも同じ形式のようです

続いて、ices0からicecast2に渡されるmetadataのフォーマットを調査してみました。
ices0のソースを眺めてみると、ID3v2タグがある場合は必ず、"song"として、[Artist]-[Title]が渡されます。
ここに先の例のUTF-16のArtistとTitleを当てはめると、

FF FE 4A 20 2D 20 FF FE 55 4F 4B 30 72 30 68 30 64 30 20

となり、これがicecast2に渡されることになります。

以上から、ices0での問題点を整理すると、
(1)TAGをchar型で扱うために、UTF-16のTAG中に現れる0x00がNULL文字として判断されるので実際のTAGと異なった情報になる
(2)"song"にはUTF16とUTF-16の間に普通の "スペース、マイナス、スペース(202D20)があるために、"song"全体をUTF-16からデコードできない
ということになります
そこで、上記の問題を以下のように修正することにしました。

(1)TAG中に現れる0x00を別の文字で置き換えることでchar型でもUTF-16を扱えるようにする
(2)icecast2に"song"として渡すのではなく、"artist","title"の別々のmetadataとして渡す

まずは上記方針に従って変更したices-0.4用のパッチを以下に掲載しておきます。



今回はUTF-16なmp3 TAGを解析してices0での問題点とその対策を考察してみました
次回はices0の変更に対応できるようにicecast2を修正します

いかがだったでしょうか


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

nice! 0

コメント 0

コメントを書く

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

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 1

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