Кодировка текста в тегах ID3v2.3

Благодаря этому и нескольким другим сайтам я создал простой код для чтения тегов ID3v2.3 из файлов MP3. Это было отличным опытом обучения, поскольку раньше я ничего не знал о шестнадцатеричном/байтовом/двоичном коде и т. д.

Я могу успешно читать данные, но столкнулся с проблемой, которая, как мне кажется, связана с используемой кодировкой. Я понял, что текстовые фреймы имеют байт в начале «текста», который описывает используемую кодировку, и, возможно, дополнительную информацию в следующих 2 байтах...

Пример: Данные из фрейма TIT2 начинаются с байта $03 (шестнадцатеричный) перед фактическим текстом. Этот текст отображается правильно, хотя и с дополнительным символом в начале, с использованием Encoding.ASCII.GetString

В другом MP3 данные из TIT2 начинаются с $01, а за ними следует $FF $FE, что, как я полагаю, связано с Unicode? Однако сам текст разбит, между каждым текстовым символом есть $00, и это останавливает отображение данных в формах Windows (как только встречается 00, текст просто останавливается, поэтому я получаю первый символ и все ). Я пытался использовать Encoding.UNICODE.GetString, но это, похоже, возвращает тарабарщину.

Печать этих данных на консоли, кажется, работает с пробелами между каждым символом, поэтому чтение данных работает правильно.

Я читал официальную документацию для ID3v2.3, но, думаю, я просто недостаточно осведомлен, чтобы понять раздел кодирования текста.

Любые ответы или ссылки на статьи, которые могут помочь, будут высоко оценены!

С уважением Росс


person phanteh    schedule 25.03.2012    source источник


Ответы (3)


Данные из кадра TIT2 начинаются с байта $03 (шестнадцатеричный) перед фактическим текстом. Этот текст отображается правильно, хотя и с дополнительным символом в начале, с использованием Encoding.ASCII.GetString

Кодировка 0x03 — это UTF-8, поэтому вы должны использовать Encoding.UTF8.GetString. Символ в начале может быть знаком порядка байтов U + FEFF, который используется для различения UTF-16LE и UTF-16BE ... для UTF-8 это бесполезно, но инструменты Windows все равно любят помещать его туда.

UTF-8 — это функция ID3v2.4, отсутствующая в версии 2.3, возможно, поэтому вы не можете найти ее в спецификации. В реальном мире вы найдете всякую ерунду в тегах ID3 независимо от версии.

данные из TIT2 начинаются с $01, а за ними следует $FF $FE, что, как я полагаю, связано с Unicode? Однако сам текст разбит, между каждым текстовым символом есть $00,

Это UTF-16LE, кодировка преобразования текста в байты, которую Windows ошибочно называет «Unicode». Он состоит из двухбайтовых кодовых единиц, поэтому символы в диапазоне от U+0000 до U+00FF выводятся как младший байт того же числа, за которым следует нулевой старший байт. Префикс 0xFF-0xFE является правильно используемой меткой порядка байтов. Encoding.Unicode.GetString должен вернуть из этого правильную строку — опубликовать какой-нибудь код?

Печать этих данных на консоли, кажется, работает

Получение символов, отличных от ASCII, для печати на консоли Windows может быть пробным, поэтому, если у вас возникнут проблемы, имейте в виду, что они могут быть вызваны самой операцией печати.

Для полноты, кодировка 0x02 - это UTF-16BE без спецификации (для этого мало причин, и я вообще никогда не встречал такого в дикой природе), а кодировка 0x00 должна быть ISO-8859-1, но на самом деле может быть практически любой кодировкой ASCII-superset, скорее кодовой страницей Windows 'ANSI', такой как Encoding.GetEncoding(1252), чем стандартом, таким как 8859-1.

person bobince    schedule 25.03.2012

Просто добавьте еще один комментарий для кода кодировки текста:

00 – ISO-8859-1 (ASCII).

01 — UCS-2 (Юникод в кодировке UTF-16 со спецификацией), в ID3v2.2 и ID3v2.3.

02 — Юникод в кодировке UTF-16BE без спецификации, в ID3v2.4.

03 — Юникод в кодировке UTF-8, в ID3v2.4.

из: http://en.wikipedia.org/wiki/ID3

person houqp    schedule 14.11.2012
comment
Просто для полноты, ISO-8859-1 — это Latin-1 (ASCII от 0..127 + западноевропейские акцентированные символы от 128..255) en.wikipedia.org/wiki/ISO/IEC_8859-1 - person Ad N; 11.07.2013
comment
Хотя это не спецификация, я видел теги ID3v2.3 UTF (01) без спецификации. Он был закодирован как UTF-16BE. Я не уверен, есть ли какое-то неофициальное значение по умолчанию, но Windows и сторонний инструмент, похоже, правильно его декодировали. - person Dustin; 09.05.2015

Отлично, я получил код для правильного чтения Unicode и ASCII (ниже)!

Однако есть один вопрос: я ожидал, что Encoding.UNICODE.GetString() будет обрабатывать спецификацию, но, похоже, это не так. Я так понимаю, вы должны читать эти байты и обрабатывать данные самостоятельно? Я только что удалил 2 байта, если это UNICODE ниже.

public class Frame
{
    FrameHeader _header;
    public string data;
    public string name;


    public Frame(FrameHeader frm, byte[] bytes)
    {
        _header = frm;
        name = _header._name;
        if (!name.Equals("APIC"))
        {
            byte[] actualdata;
            int y;
            int x;
            int encoding = bytes[0];

            if (encoding.Equals(1))
            {
                y = 3;
                actualdata = new byte[bytes.Length - 3];
                for (x = 0; x < (bytes.Length - 3); x++, y++)
                    actualdata[x] = bytes[y];
                data = Encoding.Unicode.GetString(actualdata);
            }
            else
            {
                y = 1;
                actualdata = new byte[bytes.Length - 1];
                for (x = 0; x < (bytes.Length - 1); x++, y++)
                    actualdata[x] = bytes[y];
                data = Encoding.ASCII.GetString(actualdata);
            }
        }
    }
}
person phanteh    schedule 25.03.2012