在分析 rhythmbox 显示中文 mp3 标记乱码的问题后,我们意识到这是一个 gstreamer 的问题。gstreamer 向 rhythmbox 提供了与乐曲格式无关的、Unicode 编码的标准化格式的标记信息。
gstreamer-plugins 中的一个插件,mad,负责 mp3 的解码工作。当发现该 mp3 中含有 id3v2 格式的标记信息时,它将调用一个名叫 libid3tag 的库去解析其中的内容。
在最初的 id3 标记信息规范中,没有对存储的字符串的编码作出规定。因此就像绝大多数情况那样,mp3 制作者使用各种形式的“地区编码”,比如 GB2312、Big-5 等,来存储该 mp3 的曲名、歌手等信息,并存储在 iso-8859 字段中。
当 id3v2 规范发布,并规定其中的字符串编码必须是 iso-8859 或者 unicode 时,已经太晚了,满世界的 mp3 都已经在 iso-8859 字段中填写了各类本地编码字符串。换句话说,所谓的 iso-8859 根本就不是它的字面意义,它只是表达说这是一个非 unicode 的字符串而已。
不幸的是 libid3tag 的作者显然并不生活在非西文地区。它忠实地执行了 id3v2 规范的内容:将 iso-8859 字段中的文字精确地按照 iso-8859->unicode 的方式进行转换,并向 gstreamer 提交 unicode 字符串。这样,存储在 iso-8859 字段中的一个中文字符就被编码成了2个 Unicode 字符。对其进行显示的结果,就是乱码。
在此似乎也无法苛责 libid3tag,毕竟它是根据规范而为。因此我选择了对 gstreamer-mad 打补丁,使其正确地按照当前系统所处的 locale,对存储在 iso-8859 字段中的字符串进行 unicode 转换。这样,当你的 locale 为中文时,就能通过 rhythmbox 正确看到中文 mp3 歌曲中的标记信息。
http://www.gnome-cn.org/Members/ ... s-native-tags.patch