近期尝试 Listen 和 Banshee 才发现,Rhythmbox 上出现的 mp3乱码问题依然,并且更加严重,想要彻底弄清和解决必须搞清两点,第一, mp3 标签类型和编码,第二,各种播放器对 mp3标签读取情况,相信它们应该都有相关的开发文档来说明,但我还是用了一个最笨的方法,就是一个一个的測试来得出结论,真理不是来自于实践吗?
1、了解 mp3 标签类型和使用的编码 首先说 mp3 标签类型和编码,大家应该知道眼下主要存在这几种标准,ID3v1, ID3v2 2.3, ID3v2 2.4,APEv2,ID3v1 仅仅支持 ISO-8859-1 编码 (编码集參考),严格的说它是不支持中文的 (并不代表它不能储存中文信息,眼下中文mp3 的 ID3v1 标签都使用这个字段来储存 GBK/GB18030 编码的中文信息),而第二版 (ID3v2) 支持的格式添加了utf-16,直到 2.4 版才開始支持 uft-8,但 ID3v2 标准没有统一标签内容的编码,比如 2.4 版的 ID3v2 你能够使用ISO-8859-1 编码,也能够使用 utf-16/uft-8 这样的 Unicode 编码格式。做得最好的是APEv2,它不但有非常好的扩展性,并且还把编码格式统一为 utf-8,这样一来仅仅要支持 APEv2 读取的播放器播放带有 APEv2 标签的mp3 就不会存在乱码问题。 2、了解各种播放器对 mp3 标签读取情况 接下来研究的就是各种播放器对这几种标准的标签支持程度,測试的播放器有:gnome 自带的 Rhythmbox 0.10.0,Listen 0.5, Banshee 0.12.1+dfsg-3, Quod Libet 0.24, Exaile! 0.2.8, GMPC0.13.0, Audacious 1.2.2。 測试的方法非常easy,用一个 mp3 文件,分别写入不同类型的标签 (排列组合下来共 20 多种),在 ID3v1 和 ID3v22.3/2.4 中分别使用不同的编码写入中文信息 (如 GBK编码),然后用这些播放器去读取,得到其结果。从这次的測试结果来看,Rhythmbox 对各种 mp3 的标签支持最好,这主要归功于它支持APEv2 标签的读取。而 Banshee 和剩下的播放器全然一样,都不支持 APEv2 的读取,这个就能非常好的解释为什么一些 mp3 在Rhythmbox 上正常,在其它播放器上就会乱码。原因是如今非常多 mp3 为了兼容,都同一时候使用了 ID3v1 和 APEv2标签,Rhythmbox 读取 ID3v1 一样会乱码,但它优先读取了 APEv2 标签,而 Banshee 这些播放器不支持 APEv2就仅仅能读取 ID3v1,当然会乱码了。 他们的共同特点就是,所依赖的 libid3tag 库全然依照 ID3 标准来读取标签内容。无论使用何种标准的标签,仅仅要是读取以Unicode 编码的中文内容,肯定没有问题,遇到 GBK/GB18030 编码的中文内容时,还是把它当成 ISO-8859-1编码来读取,不乱才怪。 ps: Vista 上的 WMP 不支持 ID3v2 2.4 和 APEv2标签的读取,但它非常聪明不能读取就用文件名称取代,千千静听支持全系列标签的读取,但不支持以 ID3v2 2.4 标准的写入,不知道即将公布的5.0 有变化没有。foobar2000 v0.9.4.3 支持全系列标签的读取,默认使用 ID3v2 2.4 ( utf-8 )写入,不愧被誉为经典。 3、解决的方法 既然明确了乱码的原因,就得找解决的方法,一种办法就像 Win上的播放器一样,能够依据本地的编码方式来解码,或使用一些其它转码机制,要不还能够选择优先读取顺序。以上測试的播放器中除了 Audacious外其它都不支自己定义编码读取功能。另外一个解决的方法就是把 mp3 标签转换为 Unicode编码,这样的方式既简单又支持标准,推荐大家使用。假设像 Banshee 一样支持显示文件路径也能够解决乱码问题,但这不是根本之道。 眼下发现有 2 个工具能够把标签转换为 Unicode 编码,并且都支持批量转换。 1) 一个是周枫用 java 编写的 ID3iconv 0.2.1,最后更新时间为 2004/2/20。 用法: java -jar ~/id3iconv-0.2.1.jar -e gbk *.mp3 假设想转换当前文件夹下的全部 mp3 (包含子文件夹): find . -iname "*.mp3" -execdir java -jar ~/id3iconv-0.2.1.jar -e gbk {} /; * 注意以上 ~/id3iconv-0.2.1.jar 位置依据自己情况而定 * 相信如今大陆绝大多数能找到的 mp3 标签都是以 GBK/GB18030 编码,使用 -e gbk 来处理就够了,当然你也能够使用 -e gb18030 来处理。 * -e gbk 參数是代表把 GBK 编码的标签转换为 Unicode 编码,本身是 Unicode 编码的就不转换。假设须要转换其它编码的文件能够自行改动,如改为 Big5。 * 经測试,转换后为 2.3 版的 ID3v2,编码格式为 uft-16 2) 另外一个是用 Python 写的 “Mutagen”,眼下最新版本号 1.11,Ubuntu 7.04 源里也带有 1.10 版本号的 Mutagen,能够用这个命令来安装: sudo apt-get install python-mutagen ps:安装 Quod Libet 和 Listen 都必须这个 用法: mid3iconv -e gbk *.mp3 假设想转换当前文件夹下的全部 mp3 (包含子文件夹): find . -iname "*.mp3" -execdir mid3iconv -e gbk {} /; * 相信如今大陆绝大多数能找到的 mp3 标签都是以 GBK/GB18030 编码,使用 -e gbk 来处理就够了,当然你也能够使用 -e gb18030 来处理。 * -e gbk 參数是代表把 GBK 编码的标签转换为 Unicode 编码,本身是 Unicode 编码的就不转换。假设须要转换其它编码的文件能够自行改动,如改为 Big5。 * 经測试,转换后为 2.4 版的 ID3v2,编码格式为 uft-16 * 只是它会同一时候用 Unicode 编码填满 D3v1, ID3v2, APEv2 标签,可是 ID3v1 又不支持中文的Unicode 编码,所以转换后的 ID3v1 标签全是问号。所以最好加上 –remove-v1 參数,转换后删除 ID3v1 标签。 mid3iconv -e gbk --remove-v1 *.mp