gstreamer 读取 mp3 标记时中文乱码的研究结果
在分析 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/LoneStar/gst-plugins-native-tags.patch 实际上,libid3tag本身有必要向这种现实妥协。应该添加一个可选参数,表明待取信息的字符集。 从 libid3tag 中确实可以读出这个字符集信息,只是方法比较 ugly。读出之后再自行做转换,也比较 ugly。这2个就是我的补丁用到的方法。 fedora下对应的gst-plugins文件是哪个?我没找到。 gst-plugins 中的 mad 插件
其他的都在同一目录中 此问题已经报告至 bugzilla.gnome.org,可惜至今无下文。大家支持一把啊:
http://bugzilla.gnome.org/show_bug.cgi?id=149274 http://sourceforge.net/tracker/index.php?func=detail&aid=663888&group_id=12349&atid=112349
个人认为这个方法比较好一点。 这个人只提到了 id3v1...然而目前的状况是 v1 恰恰没有问题,问题出在 v2。v2 确实有编码标记,恰恰是这个标记是错的,才导致了目前的问题。
如果 libid3tag 愿意在此问题上向标准妥协,那么一切便迎刃而解了 问题应该就是在v1上吧。本来id3v1本身都是iso-8859-1的编码,就不应该在里面存放中文,但大家还是不管。id3v2中的中文部分是放在Unicode中。 你看见过哪款 mp3 使用了中文 unicode 标记么?我还没见到过。
用 Winamp 打开一个 v1 的 mp3, 在 id3v2 的框下点一下 Copy from ID3v1,就得到一个 ID3v2 的 mp3。你猜它是怎么编码的?你去网上搜搜,看哪个有 v2 的中文 mp3 使用过了Unicode。
再使用任何一款 windows 下的 mp3 播放软件,从 Realone 到 WMP,甚至随身 mp3 播放器,看有哪款不支持这种形式的 id3v2 标记。
这个问题对我们华人来说不难理解吧?
gstreamer 的 v1 处理代码没问题了,已经做了 locale-to-utf8 转换。现在就是 v2 部分,使用了“错误”的转换方法。 这是fedora的gstid3tag.c文件,请教如何补丁? 楼上的,下次还是用附件的好不好?看着累
这个文件处理了 id3v1。在其中函数 gst_tag_extract() 处我们可以看见已经调用了 g_locale_to_utf8() 进行转换,所以这段代码是没问题的,无须补丁。 gstreamer 的 v1 处理代码没问题了,已经做了 locale-to-utf8 转换。现在就是 v2 部分,使用了“错误”的转换方法。
我觉得现在的MP3似乎还是id3v1的比较多,设置了v2还是少数的。现在的情况是,连v1的都识别不了。看来不管是v1还是v2,只要是ISO-8859-1的部分,其实都是ANSI的了。
细究起来,强制从当前locale转到utf-8也不一定那么可行,最好是可选的locale,默认就是当前locale。 楼上的,下次还是用附件的好不好?看着累
这个文件处理了 id3v1。在其中函数 gst_tag_extract() 处我们可以看见已经调用了 g_locale_to_utf8() 进行转换,所以这段代码是没问题的,无须补丁。
那id3v2呢?我的无法正常显示中文曲目。 id3v2 的问题这里有个补丁,补的是 gst-plugin-mad。当然如前述,问题的根源出在 libid3tag。不过要改这个恐怕比较难
gst-plugin mad 的 id3v2 补丁
页:
[1]