Заголовок кадра ID3

Я хочу попробовать читать теги ID3 самостоятельно без библиотеки в образовательных целях. Я должен сделать презентацию для школы о том, как это сделать.

Сначала я прочитал заголовок ID3 (первые 10 байт). Оно работает. Теперь я пытаюсь прочитать первый заголовок кадра, который почти во всех моих файлах следует сразу за заголовком ID3. Таким образом, нет расширенного заголовка. Заголовок кадра тоже должен быть 10 байт, верно? Ну тогда у меня проблема.

Заголовок кадра во всех файлах, которые я проверил, структурирован следующим образом:

+------------+   
-  Frame ID  -   
+------------+   
- Frame Size -   
+------------+   
- Frame Flags-   
+------------+   

После этого должно следовать значение, верно? Если идентификатор TALB (Album), это должно быть название альбома. И значение должно быть размером значения размера кадра. Однако все мои файлы имеют 0x03 перед названием альбома, фактически перед всеми кадрами, и размер кадра также на 1 больше. Пример:

ID кадра = TIT2
Размер кадра = 13(12+1 для 0x03)
Флаги ...
Значение = (0x03 символ)3 Doors Down

Что означает это значение? Я немного читал о кодировании текста, и это значение будет:

$03 Кодировка UTF-8 [UTF-8] Unicode [UNICODE]. Завершено с $00.

Но я не видел ни одной части, где находится это значение кодировки текста.

Это мой код (упрощенный), чтобы прочитать значение заголовка кадра:

//Method from a FrameHeader Class, takes 10 bytes as parameter
void setHeader( char* value ){

    int i = 0;
    for(; i < 4; i++ ){
        identifier += value[i];
    }

    for(; i < 8; i++ ){
        size = size << 8 | static_cast<unsigned char>(value[i]);
    }

    for(; i < 10; i++ ){
        flags += value[i];
    }
}

memblock = new char[10];
iStream.read( memblock, 10 );

FrameHeader frameHeader;
frameHeader.setHeader( memblock );

memblock = new char[ frameHeader.getSize() ];
iStream.read( memblock, frameHeader.getSize() );

cout << "Frame Indentifier : " << frameHeader.getIdentifier() << endl;
cout << "Frame Size : " << frameHeader.getSize() << endl;
cout << "Frame value : " << memblock << endl;*/

Я надеюсь, что моя проблема ясна. Я не могу загрузить файл, так как это песня, защищенная авторским правом, и у меня могут возникнуть проблемы с законом.

Я получил всю информацию из этого источника.


person Davlog    schedule 26.10.2014    source источник
comment
0x03 перед текстом является байтом кодирования. 0x03 указывает на UTF-8. en.wikipedia.org/wiki/ID3#ID3v2   -  person ooga    schedule 26.10.2014


Ответы (2)


Найденный вами байт является байтом кодирования. Из id3v2.4.0-structure.txt:

Фреймы, допускающие различные типы кодирования текста, содержат байт описания кодировки text
. Возможные кодировки:

 $00   ISO-8859-1 [ISO-8859-1]. Terminated with $00.
 $01   UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
       strings in the same frame SHALL have the same byteorder.
       Terminated with $00 00.
 $02   UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
       Terminated with $00 00.
 $03   UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.

А также:

Строки, зависящие от кодировки, представлены в описаниях фреймов
как текстовая строка в соответствии с кодировкой или полная текстовая строка
в соответствии с кодировкой
, если разрешены символы новой строки. Любые пустые строки
типа $01, заканчивающиеся NULL, могут иметь спецификацию Unicode, за которой
следует NULL Unicode ($FF FE 00 00 или $FE FF 00 00).

В дополнение к документу структуры вам необходимо обратиться к документу описания кадров, который расскажет вы, как кадр структурирован. TIT2 — это текстовый фрейм. Описание фрейма для TIT2 находится в разделе 4.2. Фреймы с текстовой информацией, и это показывает, что должен присутствовать байт Text Encoding:

Заголовок для «Фрейма текстовой информации», идентификатор: «T000» — «TZZZ», за исключением «TXXX», описанного в 4.2.6.

 Text encoding                $xx

 Information                  text string(s) according to encoding

По сути, вам нужно обращаться к этим двум документам вместе, так как некоторые кадры имеют этот байт, а некоторые нет, а некоторые кадры (если вы их реализуете) действительно требуют особой обработки. Взгляните, например, на рамку APIC, которая позволяет вставлять изображения в тег.

Возможно, стоит отметить, что написание полноценного и полнофункционального декодера ID3V2 является серьезной задачей (я занимался этим). Существует несколько версий стандарта — и теги, сделанные с каждой версией стандарта do< /em> существуют в дикой природе; не говоря уже о таких параметрах, как шифрование, сжатие и рассинхронизация, а также вопрос теги, сделанные неработающими кодировщиками. Для такого проекта, как ваш, я бы просто реализовал чтение нескольких наиболее распространенных фреймов. Если вы также записываете теги, просто позаботьтесь о том, чтобы дословно записать все кадры, чтение которых вы не реализовали.

В дополнение к цитируемым ресурсам также может быть полезна статья Википедии об ID3.

person Stephen Kennedy    schedule 26.10.2014

Со связанной страницы:

Фреймы, допускающие различные типы кодирования текста, содержат байт описания кодирования текста. Возможные кодировки:

$00 ИСО-8859-1 [ИСО-8859-1]. Завершено с $00.

$01 Кодировка UTF-16 [UTF-16] Unicode [UNICODE] с BOM. Все строки в одном кадре ДОЛЖНЫ иметь одинаковый порядок байтов. Завершено с $00 00.

$02 UTF-16BE [UTF-16] в кодировке Unicode [UNICODE] без спецификации. Завершено с $00 00.

$03 Кодировка UTF-8 [UTF-8] Unicode [UNICODE]. Завершено с $00.

Это означает, что первый байт строкового поля типа текстовая строка в соответствии с кодировкой всегда будет одним из этих байтов, и этот байт будет выбирать кодировку, используемую для текста. Но название кодировки вы не найдете буквально.

Обратите внимание, что существуют также поля типа текстовая строка, в которых отсутствует этот байт, и предполагается, что они соответствуют стандарту ISO-8859-1.

В вашем файле 0x03 означает, что следующий текст имеет кодировку UTF-8.

person rodrigo    schedule 26.10.2014
comment
Вы сказали первый байт строкового поля. Возможно ли, что нет строкового поля? - person Davlog; 26.10.2014
comment
@Davlog: Сразу после моей цитаты говорится, что это правильный способ создания полей типа текстовая строка в соответствии с кодировкой (ср. с простой текстовой строкой). Однако, поскольку ни один из этих байтов вряд ли будет отображаться как правильный символ, я бы на всякий случай запрограммировал запасной вариант на случай, если байта кодирования нет. Для таких неаккуратно созданных тегов я бы предположил ту же кодировку, что и для простых текстовых строк: ISO-8859-1. - person rodrigo; 26.10.2014