我懷疑微軟原始的 wma tag 是純綷 utf-16le 編碼,而 perl 的 Audio::WMA 模塊在提取之後處理成了混合編碼。所以
看了看 /usr/share/perl5/Audio/WMA.pm ,果然,寫這個模塊的人沒有考慮到混合字符的情況。他把西歐字符轉換為
latin1 編碼,而其他字符轉換為 utf16 編碼,然後混合在一起。一個害死人的 bug。修改這個 pm 文件之後,問題解決。
On 3月21日, 上午10时40分, purl lamp <lamp.p...@gmail.com> wrote:
> 41 4C 42 55 4D 54 49 54 - 4C 45 3AALBUMTITLE:Encode::XS=SCALAR(0x8441198)5F
> 66 5B CB 53_f[.SEncode::XS=SCALAR(0x847f6a8)34 69 6E 314in1
> Encode::XS=SCALAR(0x8441198)CD 73 CF 85 C6 96.s....* Encodings too
> ambiguous: cp936 or UTF-16LE*2D-Encode::XS=SCALAR(0x8441198)39 31 66 2E 6E
> 65 7491f.netEncode::XS=SCALAR(0x8441198)
> 以上是按照空格切割的结果,两种编码混在一起之后问题多多,尤其是 4in1 和 - 之间的串。
>
> 2009/3/21 PIG <addm...@gmail.com>
>
> > win的utf-16和unix的utf-16 00的位置不一样。
>
> > 2009/3/20 Calvin <calvin.n...@gmail.com>:
> > > 见本讨论组"文件"里面的 tags 文件。
> > > 我是直接 print 到这个文件里面的,ubuntu 下面 file 了一下,结果为 data,应该保持了原始获取的编码。
>
> > > On 3月20日, 下午6时14分, cnhack TNT <cnhack...@gmail.com> wrote:
> > >> 忘了说了,发附件,不要直接贴内容:-)
>
> > >> 2009/3/20 cnhack TNT <cnhack...@gmail.com>
>
> > >> > 能否将你取得的一个 tag 样例信息导出到文本文件,然后发上来
> > >> > 另外,你可以 hexdump
>
> > 一下这个文件,因为UTF-16LE是双字节编码,如果是混合编码,有可能看到的字节数为奇数(多看几个出问题的文件,因为非utf-16le编码的字符其字节个数可能刚好凑够偶数个)
>
> > >> > 2009/3/20 Calvin <calvin.n...@gmail.com>
>
> > >> > 最近在处理一些 wma 文件的 tag,遇到这样的问题,非常棘手。
>
> > >> >> 从网上搜索到的资料说,默认微软 wma 格式音频文件的 tag 是用 utf-16le 编码的。
>
> > >> >> 我用 Audio::WMA 取得 tag 信息,用 utf-16le
> > decode后,汉字解码正常,凡是遇到夹杂在中文字串中的英文字母或者短横
> > >> >> 之类的符号就乱码(显示成不正确的汉字或奇怪的符号)。如果用 latin1 或 gbk 来
> > decode,则所有汉字显示乱码,而夹杂在汉字里面的
> > >> >> 英文字母和符号显示正常。
>
> > >> >> 怀疑这些字符串是混合编码的,汉字使用 utf-16le 编码,而英文字母和符号使用 latin1
> > 编码,然后凑成一个完整的字符串。究竟是不是这
> > >> >> 样呢?还是 perl 对 utf-16le 解码本身有 bug?
>
> > >> >> 这样的字符串怎样才能正确解码呢?
>
> > >> >> 如果是混合编码的话,作为模拟,一下脚本是一个实验:
>
> > >> >> #!/usr/bin/perl
> > >> >> use Encode;
>
> > >> >> $s1="出征进行曲";
> > >> >> $s1=decode_utf8($s1);
> > >> >> $s1=encode('utf-16le',$s1); #直接这样编码成 utf-16le是完全没问题的
> > >> >> $s2="-AFtest-第4曲";
> > >> >> $s2=decode_utf8($s2);
> > >> >> $s2=encode('gbk',$s2); #直接这样编码成 gbk 也是完全没问题的
> > >> >> $string=$s1.$s2; #这里,为了模拟,制作了一个混合编码字串
>
> > >> >> $aa=decode('utf-16le',$string); # 这里,用 utf-16le 解码
> > >> >> $aa=encode('utf8', $aa); #这里,让 perl 去掉标签,不会打印Wide character的警告
> > >> >> print "$aa\n"; #这里,原 $s1 部分解码正常,原 $s2 部分乱码
>
> > >> >> $aa=decode('gbk',$string); # 这里,用 gbk 解码
> > >> >> $aa=encode('utf8', $aa); #这里,让 perl 去掉标签,不会打印Wide character的警告
> > >> >> print "$aa\n"; #这里,原 $s1 部分乱码,原 $s2 部分显示正常
>
> > >> >> 如何让整个 $string 都正确解码呢?
--~--~---------~--~----~------------~-------~--~----~
您收到此信息是由于您订阅了 Google 论坛"PerlChina Mongers 讨论组"论坛。
要在此论坛发帖,请发电子邮件到 perlchina@googlegroups.com
要退订此论坛,请发邮件至 perlchina+unsubscribe@googlegroups.com
更多选项,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问该论坛
-~----------~----~----~----~------~----~------~--~---
没有评论:
发表评论