Etiquetas mutagénicas e id3: confusión en la codificación de caracteres

Me he encontrado con un problema al leer algunas etiquetas id3 con letras islandesas.
Un ejemplo rápido del caparazón.

>>> audio = mutagen.easyid3.EasyID3('./Björk/Albums/1990 - Gling-Gló [mp3-231]/01 - Gling-Gló.mp3')
>>> audio['title']
5: [u'Gling-Gl\xf3']

En primer lugar, no estoy muy seguro de cómo verificar en qué carácter se codifican las etiquetas. Por lo que he reunido, esta es la forma de hacerlo con mutágeno:

>>> audio = mutagen.id3.ID3('./Björk/Albums/1990 - Gling-Gló [mp3-231]/01 - Gling-Gló.mp3')
>>> for key, value in audio.items():
...     print value.encoding

Esto genera '0' para cada elemento.

Y vi en alguna parte que para las etiquetas id3, el número 0 significaba que la cadena está codificada en iso-8859-1, pero no sé a dónde ir desde allí. ¿Supongo que esto no es correcto?

>>> audio.get('artist')[0].decode('iso-8859-1')
14: u'Bj\xc3\xb6rk'

Como puede ver probablemente, estoy seriamente confundido cuando se trata de problemas de codificación de caracteres.
Todo lo que quiero es capturar las etiquetas como cadenas utf-8 adecuadas para poder ponerlas en mi base de datos. Sin embargo, este es solo un ejemplo, supongo que probablemente me encuentre con otros archivos con codificaciones completamente diferentes, así que estoy buscando una buena solución completa. Sin embargo, arreglar esto realmente me ayudaría a ponerme en la pista.

Gracias de antemano.

preguntado el 28 de agosto de 11 a las 00:08

2 Respuestas

Bienvenido al divertido mundo de la codificación.

En este paso:

>>> audio = mutagen.easyid3.EasyID3('./Björk/Albums/1990 - Gling-Gló [mp3-231]/01 - Gling-Gló.mp3')
>>> audio['title']
[u'Gling-Gl\xf3']

... terminas con una cadena de bytes Unicode. En la segunda línea, Python está imprimiendo una representación ASCII de esta cadena de bytes, por lo que ve los valores hexadecimales. Lo que necesita es que Python tome esa cadena de bytes y codificar utilizando una de las codificaciones de caracteres disponibles. Esto también fue una fuente de confusión para mí. Solo recuerde, decodifica de los caracteres a los valores hexadecimales y codifica los valores hexadecimales en caracteres.

Entonces, si haces esto:

In [1]: s = u'./Björk/Albums/1990 - Gling-Gló [mp3-231]/01 - Gling-Gló.mp3'

In [2]: s
Out[2]: u'./Bj\xf6rk/Albums/1990 - Gling-Gl\xf3 [mp3-231]/01 - Gling-Gl\xf3.mp3'

In [3]: s.encode('UTF-8')
Out[3]: './Bj\xc3\xb6rk/Albums/1990 - Gling-Gl\xc3\xb3 [mp3-231]/01 - Gling-Gl\xc3\xb3.mp3'

Bueno, eso es molesto. Le dijiste que codificara en UTF-8 pero aún tienes ASCII. El truco es que hacer una llamada de este tipo en Python solo genera la representación ASCII de lo que sea la entrada. Si lo cambia a:

In [4]: print s.encode('UTF-8')
./Björk/Albums/1990 - Gling-Gló [mp3-231]/01 - Gling-Gló.mp3

... ves el resultado correcto. Entonces, una vez que haga algo con el texto recién codificado, lo verá representado de la manera que desee. Imprimirlo en la consola, escribirlo en un archivo o mostrarlo en un widget GUI debería verse bien.

Respondido 28 ago 11, 14:08

Gracias. Eso aclara algunas cosas. Entonces, ¿simplemente tendría que codificar la cadena con utf8 antes de representarla? ¿Funcionará sin importar cuál sea la codificación de origen (siempre que Python pueda decodificarla)? - Steinthor.palsson

Creo que el camino de menor resistencia será asumir que todo está en UTF-8 si estás en Linux. Puede probar el módulo chardet para detectar automáticamente la codificación si no está 100% seguro de cuál será (tenga en cuenta que nunca he usado este módulo): chardet.feedparser.org - usuario626998

(Reconozco que asumir que todo está en UTF-8 es bastante descuidado) - user626998

if len(Genre)>0:
    MyGenre = u' '
    MyGenre = Genre
    audio.add(TCON(encoding=3, text=MyGenre))
audio.save()

Esto es trabajo para mí

Respondido 06 Abr '16, 11:04

Agrega alguna explicación. - Ketan

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.