Gre's Blog(跡地)

※更新していません。中の人の詳細→ gr3.ie

WMPから読み込んだmp3ファイルのID3タグの文字化けが治らない理由

自宅サーバに音楽ファイルを入れて家の中からPCやiPadでアクセスして音楽を聴いているが、どうも昔Windows Media Playerでインポートしたmp3ファイルのメタ情報の文字化けが残ったままだった。

色々ググってみたところ文字化けをするのはmp3ファイルのメタ情報(ID3タグ)がShift-JIS(以下、SJIS)で保存されているのが原因らしい。併せてEasyTAGなるソフトウェアで治せるとの情報があり、試してみたが、結局直すことができなかった。
なぜ治せないのだろうか?と思い、mp3ファイルのメタ情報を16進数で出力してみたら、ちょっと気になった点があった。音楽のメタ情報についての知識は疎いので、これから話すことの理由についてよくご存じの方が居たら詳しく教えていただきたい。


私の音楽フォルダにある「葉加瀬太郎 - 情熱大陸.mp3」というファイルのタグ情報をmid3v2コマンドで表示するとこのようになる。ターミナルソフト上ではUTF-8以外のマルチバイト文字は文字化けするようになっているため、やはりID3タグ情報は文字化けしている。

f:id:greymd:20140924233548p:plain

例えばTALBの部分はおそらくアルバム名であろう。ここは本来は「情熱大陸」となっているはずである。

ここで下の画像のようにアルバム名の文字化け部分だけをシェルで切り出す。
確かになんとなく4文字ということはわかる。

f:id:greymd:20140924233716p:plain


od -xにより16進数表示をする。


f:id:greymd:20140924233831p:plain

8f c2 ae c3 94 c2 c2 4d c3 91 c2 a5 c2 97 0a a4

するとなぜか16バイト分の文字列が出現する。はて、SJISは2バイト文字ではなかっただろうか?なぜ8バイトではないのだろうか。

そこで試しに純粋なSJISの「情熱大陸」という文字列は、16進数で表すとどのようになるのかを、下記のコマンドで調べてみる。

f:id:greymd:20140924233900p:plain

ee 8f 4d 94 e5 91 a4 97 00 0a

すると、見事に8バイトである。つまりID3タグに含まれていた情報はSJISではなかったのか……?
ここで、ID3タグの文字列と、正規のSJISの文字列の16進数版を比較してみよう。

  • ID3タグ内の「情熱大陸」という文字列の16進数表記

8f c2 ae c3 94 c2 c2 4d c3 91 c2 a5 c2 97 0a a4

ee 8f 4d 94 e5 91 a4 97 00 0a


すると、どうも法則性があるような気がする。
ID3タグ情報は、本来ならば2バイト文字であるSJISの文字を、1バイトずつに分割し、c2、あるいはc3という1バイトを付与しているような気がする。しかし具体的な法則性を考察するのは面倒なのでやめる。


つまり、愚直に純粋なSJISからUnicodeへ変換しようとしていたEasyTAGでは、この文字化けは治せなかったということなのかもしれない。
このようなファイルに関してはMp3tagやID3Uniなどのソフトを使って文字化けを直すことができた(参考)が、果たしてこれらのソフトウェアはどのようにして文字エンコードを変換しているのだろうか?

試しにID3UniのREADMEを読んでみたが、やはりSJISからUnicodeへ変換するソフトであるという旨が書いてあった。正確にはコイツが変換している文字列はSJISとは似て非なるものなのだが……。

これは仮説だが、もしかしたら、.NET Frameworkなどを使用すると、フレームワークがメタ情報の扱い方を隠蔽化してしまっているのかもしれない。ゆえに、開発者はファイルからメタ情報を取り出したり、更新したりすることはできるが、実際に書き込まれているバイト列までは意識しなくて良い開発環境が整っているのかもしれない。

だがそもそもの話、なぜこのような似非SJISバイト列になっているのだろうか?SJISには2バイト目が5C等になりうることによる問題がある。それを防ぐための方策だろうか?
いずれにしても、Windows Media Playerで音楽を取り込むのは今後控えておこう……。