Кодиране на текст в 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 Byte Order Mark, който се използва за разграничаване между 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 без BOM (има малка причина това да съществува и никога не съм срещал това в природата), а кодирането 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 кодиран Unicode с BOM), в ID3v2.2 и ID3v2.3.

02 – UTF-16BE кодиран Unicode без BOM, в ID3v2.4.

03 – UTF-8 кодиран Unicode, в 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) без BOM. Беше кодиран като UTF-16BE. Не съм сигурен дали има някаква неофициална настройка по подразбиране, но изглежда, че Windows и инструмент на трета страна го декодират правилно. - person Dustin; 09.05.2015

Страхотно, получих код за правилно четене на Unicode & ASCII (по-долу)!

Един въпрос обаче - очаквах Encoding.UNICODE.GetString() да се справи с BOM, но изглежда не е така. Предполагам, че трябва сам да прочетеш тези байтове и да се справиш с данните? Току-що премахнах 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