теги mutagen и id3 - путаница в кодировке символов

1

У меня возникла проблема при чтении некоторых тегов id3 с исландскими буквами.
Быстрый пример из оболочки.

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

Прежде всего, я не совсем уверен, как проверить, какой символ кодирует теги. Из того, что я собрал, это способ сделать это с помощью мутагена:

>>> 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

Это выводит "0" для каждого элемента.

И я где-то видел, что для id3-тегов число 0 означает, что строка кодируется iso-8859-1, но я не знаю, куда идти оттуда. Думаю, это неправильно?

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

Как вы можете с уверенностью сказать, я серьезно смущаюсь, когда речь идет о проблемах с кодировкой символов.
Все, что я хочу, это захватить теги как правильные строки utf-8, чтобы я мог поместить их в свою базу данных. Это всего лишь один пример, хотя, наверное, я, вероятно, столкнусь с некоторыми другими файлами с совершенно разными кодировками, поэтому я ищу хорошее решение. Просто исправление этого действительно поможет мне попасть на трассу.

Заранее спасибо.

Теги:
character-encoding
id3
mutagen

2 ответа

1
Лучший ответ

Добро пожаловать в забавный мир кодирования.

На этом этапе:

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

... вы закончите с байтовой строкой unicode. Во второй строке Python печатает ASCII-репрезентацию этой байтовой строки, поэтому вы видите шестнадцатеричные значения. Вам нужно, чтобы Python взял эту строку байта и закодировал ее, используя один из доступных кодировок символов. Для меня это тоже путаница. Просто помните, что вы декодируете символы в шестнадцатеричные значения и кодируете шестнадцатеричные значения в символы.

Итак, если вы это сделаете:

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'

Ну, это раздражает. Вы сказали ему кодировать в UTF-8, но у вас все еще есть ASCII. Хитрость заключается в том, что выполнение такого вызова в Python просто выводит ASCII-представление того, что было на вход. Если вы измените его на:

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

... вы видите правильный результат. Итак, как только вы на самом деле что-то делаете с новым кодированным текстом, вы увидите, что он представлен так, как вы хотите. Печатать его на консоли, записывать в файл или отображать его в виджетах графического интерфейса.

  • 0
    Спасибо. Это проясняет некоторые вещи. Так что мне просто нужно закодировать строку с помощью utf8, прежде чем представлять ее? Будет ли это работать независимо от того, что является исходной кодировкой (до тех пор, пока python может ее декодировать)?
  • 0
    Я думаю, что путь наименьшего сопротивления будет предполагать, что все в UTF-8, если вы в Linux. Вы можете попробовать модуль chardet для автоматического определения кодировки, если вы не уверены на 100%, что это будет (обратите внимание, что я никогда не использовал этот модуль): chardet.feedparser.org
Показать ещё 1 комментарий
0
if len(Genre)>0:
    MyGenre = u' '
    MyGenre = Genre
    audio.add(TCON(encoding=3, text=MyGenre))
audio.save()

Это работает для меня

  • 2
    Добавьте некоторые объяснения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню