こんにちわ。
「文字エンコード」と掛けまして、
「壊れた家電製品」と、ときます。
そのココロは・・・・
ヘンカン(変換と返還)するのがポイント。
最近、謎掛けにハマりつつある、ユゲタです。
前回まで、mp3のid3タグを解析するために、バイナリ操作をしてきましたが、データを取り出すことはできたんですが、どうしても日本語文字列が文字化けをしてしまって、
それをどういう風に対応するのかを考えて対応関数を作ってみました。
ソース
id3v1系
id3v1系の文字エンコードは、SJISでデコードすると、うまく変換できるようです。
var txt = new TextDecoder("SJIS");
value = txt.decode(datas);
id3v2.2
id3v2.2は、frameのヘッダ内のflg情報が"1"の場合は、"utf-16"でデコードするといいのですが、flg情報が"0"の場合は、デコードせずに
そのまま連結して文字コード変換してあげるとうまくいきます。
var flg = datas[6];
var size_arr = datas.slice(3, 3 + 3);
var size = lib.size_bit(size_arr , 8) + 6;
var data_arr = datas.slice(7 , size);
if(flg){
var utf16 = new TextDecoder("utf-16");
var value = utf16.decode(data_arr);
}
else{
var value = "";
for(var i in data_arr){
value += String.fromCharCode(data_arr[i]);
}
}
value = value.replace(/\u0000/g , "");
id3v2.3,id3v2.4
id3v2.3とid3v2.4は、リファレンスに文字列の1bit目を元に以下のように判断する仕様になっています。
function txtEncoding = function(bite){
switch(bite){
case 0x01 : return "utf-16";
case 0x02 : return "utf-16be";
case 0x03 : return "utf-8";
case 0x00 :
default : return "iso-8859-1";
}
};
function bin2txt = function(data){
var enc = txtEncoding(data[0]);
var dec = new TextDecoder(enc);
switch(enc){
case "utf-16":
case "utf-16be":
case "utf-8":
var txt = dec.decode(data.slice(1));
var esc = unescape(encodeURIComponent(txt));
return decodeURIComponent(escape(esc));
default:
return dec.decode(data);
}
};
var size_arr = datas.slice(4, 4 + 4);
var size = lib.size_bit(size_arr , 8) + 10;
var data_arr = datas.slice(10 , size);
var value = bin2txt(data_arr);
注意)上記のプログラムのdatasは、バイナリデータの該当箇所を入れてお使いください。
解説
id3タグで最も悩ましかった点が、文字化け対応でした。
それぞれバージョン毎に対応が違うという点は、分岐処理でなんとなったんですが、ver2.3の文字コード対応は非常に骨が折れました・・・
ちなみに、macのfinderでmp3ファイルを見た時に、id3v2.3の文字列で日本語で登録されているものが文字化けしていたので、文字化けしていることが通常なのかと思ってたんですが、
仕様書通りに変換してみると、文字化けが無くなったので、apple-osのバグと考えてもいいかもしれませんね。
ちなみに、id3v1系は、"SJIS"で、id3v2.2は"utf-16"、id3v2.3とv2.4は、"utf-8"と"utf-16le"と"utf-16be","iso-8859-1"の4パターンあり、1ビット目で判定して処理を変える必要があるところまではいいのですが、このままだと、まだ文字化けをしていたので、追加で、"encodeURIComponent"してから"decodeURIComponent"するという裏技チックな処理をすることで、javascriptで文字化けすることがなくなりました。
なかなかこの技を見つけるのに苦労したので、是非ブログに書いておこうと思って記事にしてみました。
とりあえず、mp3のid3タグを取得するツールが完成したので、githubにアップして公開しておこうと思います。
nodejs系のライブラリしか無かったので、nodeを使わないネイティブjsでのライブラリは貴重だと思いますよ。
お楽しみに!!!
0 件のコメント:
コメントを投稿