Saturday, November 11, 2006

audacious写入id3tag乱码问题


我的audacious和audacious-plugins的版本及USE flag如下:
[I] media-sound/audacious Installed: 1.2.1(chardet -gnome nls)
[I] media-plugins/audacious-plugins Installed: 1.2.2-r1(aac alsa arts chardet -esd flac -jack -lirc -modplug mp3 -musepack nls -oss -pulseaudio -sid -sndfile timidity vorbis wma)
值得注意的一点是,我都加上了chardet USE flag,这样在UTF-8环境下就不必为本来encoding为GB码的mp3文件里的id3tag转码了。
只需要稍微设置一下:
Preference->Playlit->Metadata:
auto character encoding detector for: Chinese
fallback character encoding: gbk
还有一点是,如果主窗口显示不出汉字。看看你是否选择了这个选项:
Preference->Appearance->Fonts->Use bitmap fonts if available
请不要选中这一项试试。如果使用微软雅黑,同时选中这个选项,主窗口的歌曲名如果是汉字就会乱码。而不选则不乱码。
这两个地方设置过后,audacious已经几近完美了。不过还有一个问题,就是修改id3tag保存后,再打开该文件会发现id3tag乱码。
经过我的分析,原因大概是这样:
1. id3v2.4.0标准里定义了tag可以有4种encoding,可以在tag里标明,占用一个字节,其中UTF8的值为3。
2. 如果指定encoding为utf8,taglib在写入时会遵循标准的约定,在tag里用一个字节表示encoding,就是3。
TextIdentificationFrame::renderFields()
3. 但是在读取tag的时候,我发现似乎taglib根本没有考虑这里还有个字节表示encoding。而是把3看作字符串的一部分。
StringList::toString()仅仅是把list里的String相加。
这样当然就会乱码了。
这恐怕应该算是taglib的一个flaw吧,暂时的解决办法,我想可以不指定以utf8为encoding写入。那样的话,就是Latin1,而它的值是0,这样有也就相当于没有。

此外,在保存id3v1 tag的时候,还有另外一个问题。就是如果指定了encoding为utf8,保存时就已经乱码了。
TagPrivate::stringHandler->render(d->title)
d->title这个时候已经是以utf16(这是taglib内部保存字符串的形式,参见prepare())保存的了。我们看StringHandler::render的实现
ByteVector ID3v1::StringHandler::render(const String &s) const
{
return s.data(String::Latin1);
}
实际上这个时候只有以String::UTF8调用data才能把utf16转回utf8,可惜的是这里居然是不分青红皂白的就用了String::Latin1。

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home