Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将utf8转换为cp1251以写入mp3文件的ID3_V1标记?_Python_Unicode_Encoding_Utf 8_Eyed3 - Fatal编程技术网

Python 如何将utf8转换为cp1251以写入mp3文件的ID3_V1标记?

Python 如何将utf8转换为cp1251以写入mp3文件的ID3_V1标记?,python,unicode,encoding,utf-8,eyed3,Python,Unicode,Encoding,Utf 8,Eyed3,ID3_V1仅支持拉丁1编码。为了使用俄语字符写入V1标记,使用cp1251编码。我想将数据从V2标记unicode复制到V1标记。我使用eyeD3获得具有以下代码的V2标记: tag.link(mp3path, v=eyeD3.ID3_V2) mp3album_v2 = tag.getAlbum() ... tag.link(mp3path, v=eyeD3.ID3_V1) tag.setTextEncoding(eyeD3.LATIN1_ENCODING) tag.setAlbum(mp3a

ID3_V1仅支持拉丁1编码。为了使用俄语字符写入V1标记,使用cp1251编码。我想将数据从V2标记unicode复制到V1标记。我使用eyeD3获得具有以下代码的V2标记:

tag.link(mp3path, v=eyeD3.ID3_V2)
mp3album_v2 = tag.getAlbum()
...
tag.link(mp3path, v=eyeD3.ID3_V1)
tag.setTextEncoding(eyeD3.LATIN1_ENCODING)
tag.setAlbum(mp3album_v2.encode('cp1251')) # ???
tag.update()
返回以下内容:

>>> print mp3album_v2
Жить в твоей голове

>>> print type(mp3album_v2)
<type 'unicode'>

>>> print repr(mp3album_v2)
u'\u0416\u0438\u0442\u044c \u0432 \u0442\u0432\u043e\u0435\u0439 \u0433\u043e\u043b\u043e\u0432\u0435'

但如果我尝试执行tag.setAlbumP3Album_v2.encode'cp1251'。encode'utf-8',那么我会得到一个错误UnicodeDecodeError:'utf8'编解码器无法解码位置0处的字节0xc6:无效的连续字节

ID3v1不能可靠地包含任何非ASCII字符。您可以将cp1251编码的字节写入ID3v1标记中,但它们仅在俄语语言环境操作系统安装时呈现为西里尔文,甚至不会在所有应用程序上呈现

EyeD3在内部处理Unicode字符串,并任意选择使用latin1(即ISO-8859-1)作为ID3v1标记的编码。这可能不是一个好的选择,因为latin1从来都不是西欧Windows框中默认的特定于语言环境的编码,它实际上是cp1252,类似但不相同

但是,这种编码选择的一个特性是,其中的每个字节都映射到具有相同代码点编号的Unicode字符。您可以利用这一点,制作一个Unicode字符串,该字符串包含的字符在编码为latin1时,最终将成为所选字符串的字节编码,而不是latin1编码


这是一个可怕的黑客攻击,其好处值得怀疑,也是您应该避免使用ID3v1的原因之一。

ID3v1不能可靠地包含任何非ASCII字符。您可以将cp1251编码的字节写入ID3v1标记中,但它们仅在俄语语言环境操作系统安装时呈现为西里尔文,甚至不会在所有应用程序上呈现

EyeD3在内部处理Unicode字符串,并任意选择使用latin1(即ISO-8859-1)作为ID3v1标记的编码。这可能不是一个好的选择,因为latin1从来都不是西欧Windows框中默认的特定于语言环境的编码,它实际上是cp1252,类似但不相同

但是,这种编码选择的一个特性是,其中的每个字节都映射到具有相同代码点编号的Unicode字符。您可以利用这一点,制作一个Unicode字符串,该字符串包含的字符在编码为latin1时,最终将成为所选字符串的字节编码,而不是latin1编码


这是一个可怕的黑客攻击,其好处值得怀疑,也是您应该避免ID3v1的原因之一。

使用@requireUnicode装饰器;这可能意味着编码是在其他地方处理的。将两个编码调用按顺序放置是没有意义的。编码从unicode转换为字节,而解码从字节转换为unicode。表达式x.encodey.encodez毫无意义,因为它再次从unicode到字节。在python3上,您会得到一个AttributeError,因为bytes不再具有encode方法;显然,库在整个过程中都需要Unicode,并且只有在保存时才进行编码。@MartijnPieters,我没有使用save方法和update保存数据,update没有encoding关键字。因此,主要的问题是如何将utf-8值转换为cp1251,然后转换为unicode?API需要unicode,这意味着不需要utf-8或其他编码。您必须找到一种方法来设置另一种编码,以便在再次保存标记时使用;这可能意味着编码是在其他地方处理的。将两个编码调用按顺序放置是没有意义的。编码从unicode转换为字节,而解码从字节转换为unicode。表达式x.encodey.encodez毫无意义,因为它再次从unicode到字节。在python3上,您会得到一个AttributeError,因为bytes不再具有encode方法;显然,库在整个过程中都需要Unicode,并且只有在保存时才进行编码。@MartijnPieters,我没有使用save方法和update保存数据,update没有encoding关键字。因此,主要的问题是如何将utf-8值转换为cp1251,然后转换为unicode?API需要unicode,这意味着不需要utf-8或其他编码。您必须找到一种方法来设置不同的编码,以便在再次保存标记时使用。非常感谢!是的,这是一个可怕的黑客,但这正是我要找的。非常感谢!是的,这是一个可怕的黑客,但这正是我要找的。
def setAlbum(self, a):
    self.setTextFrame(ALBUM_FID, self.strToUnicode(a));

def strToUnicode(self, s):
    t = type(s);
    if t != unicode and t == str:
        s = unicode(s, eyeD3.LOCAL_ENCODING);
    elif t != unicode and t != str:
        raise TagException("Wrong type passed to strToUnicode: %s" % str(t));
    return s;
album_name = u'Жить в твоей голове'
mangled_name = album_name.encode('cp1251').decode('latin1')
tag.setAlbum(mangled_name) # will encode as latin1, resulting in cp1251 bytes