音楽ファイルに日本語のid3タグをつける


CDからリッピングする時は、コマンドラインで動作するripを使っているのですが、こいつが日本語のアルバム名とか曲名をうまく扱えなかったので調べて見ました。

リッピングの流れは、最初にCDDBと呼ばれるアーティスト名やアルバム名をWEBサービスで取得する仕組みを使います。 CDDBで取得したアーティスト名やアルバム名から、リッピングしたファイルを保存するディレクトリを決定します。 ripでは[アーティスト名]/[アルバム名]の形式で作成されたディレクトリの下に、ファイルを置きます。 各ファイルにはid3タグと呼ばれる形式で、音楽ファイルにアーティスト名やアルバム名、曲名等の情報を加えます。 このid3タグの情報を、ituneやAmarok等の音楽プレーヤーが読み取って、曲名を表示したりしているわけです。

文字化けの問題を調査するにあたり、まずCDDBで取得した情報が文字化けしていないかを調べました。 freedb.freedb.orgにクエリを投げると、CDの情報を取得するこの仕組みはCDDBと呼ばれ、ライブラリが提供されている言語もあります。 さてCDDB、プロトコルを指定することができ、プロトコルの値が6でないと日本語がうまく扱えないことがわかりました。 ripはperlで実装されており、CDDBへのアクセスはCDDB_get.pmを用いていました。CDDB_get.pmへプロトコルを指定する口があるので、簡単にプロトコルを変更することができました。

1
2
3
4
5
6
7
# CDDBに渡す設定を生成するときに、プロトコルを6で指定する。
my %config;                                       # Configuration passed to CDDB/CDDB_get
$config{PROTO_VERSION}      = 6;                  # CDDB protocol version
....

# CDDBに設定を渡す
%cd = get_cddb( %config );

プロトコルの変更を行うことで、rip実行時に日本語が文字化けしていたのが直りました。

これで解決かと思いきや、実際に音楽プレーヤーに表示されている情報は相変わらず文字化けしていました。 次に疑うべきは、id3タグを書き込んだ際の文字化けです。 id3にはバージョンがあり、バージョン1は日本語文字コードの問題が起こりやすいそうです。 という訳でUTF8がサポートされているバージョン2で書きこむように修正しました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BEGIN { $ENV{MP3TAG_USE_UTF_16LE} = 1; }
MP3::Tag->config(id3v23_unsync => 0);
my $mp3 = MP3::Tag->new($file) or die;
$mp3->get_tags() or die;

my $id3v2 = (exists $mp3->{ID3v2}) ? $mp3->{ID3v2} : $mp3->new_tag("ID3v2");

# TIT2 : Title/songname/content description
# TALB : Album/Movie/Show title
# APIC : Attached picture Keys: MIME type, Picture Type, Description, _Data

print STDERR "DEBUG: ID3V2 add framen" if $debug;
$id3v2->add_frame("TIT2", $song);
$id3v2->add_frame("TPE1", $artist);
$id3v2->add_frame("TALB", $title);
$id3v2->add_frame("TYER", $year);
$id3v2->add_frame("TRCK", $track);
$id3v2->add_frame("TCON", $genre);

print STDERR "DEBUG: write ID3V2 tagn" if $debug;
$id3v2->write_tag or die("E: tag write error, $filen");
print STDERR "DEBUG: close mp3n" if $debug;
$mp3->close();

これで無事に日本語の情報が音楽プレーヤーで表示されました。 確認したのはituneとAmarokです。 いやー、Perl久しぶりでしたよ。


Share