Я пытаюсь прочитать mp3-файл на C++ и показать информацию о файле id3, содержащуюся в этом файле. Проблема в том, что когда я читаю заголовок фрейма, размер содержимого, который он держит, является неправильным. Вместо того, чтобы дать мне целое число в 10 байт, он дает мне 167772160 байт. http://id3.org/id3v2.3.0#ID3v2_frame_overviewБинарное чтение ID3-тега mp3-файла
struct Header {
char tag[3];
char ver;
char rev;
char flags;
uint8_t hSize[4];
};
struct ContentFrame
{
char id[4];
uint32_t contentSize;
char flags[2];
};
int ID3_sync_safe_to_int(uint8_t* sync_safe)
{
uint32_t byte0 = sync_safe[0];
uint32_t byte1 = sync_safe[1];
uint32_t byte2 = sync_safe[2];
uint32_t byte3 = sync_safe[3];
return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;
}
const int FRAMESIZE = 10;
Код выше, используется для того, чтобы перевести двоичные данные ASCCI. Внутри основной
Header header;
ContentFrame contentFrame;
ifstream file(argv[1], fstream::binary);
//Read header
file.read((char*)&header, FRAMESIZE);
//This will print out 699 which is the correct filesize
cout << "Size: " << ID3_sync_safe_to_int(header.hSize) << endl << endl;
//Read frame header
file.read((char*)&contentFrame, FRAMESIZE);
//This should print out the frame size.
cout << "Frame size: " << int(contentFrame.contentSize) << endl;
Я написал программу для решения этой задачи в Perl и она отлично работает, там распаковывать используется, например, как:
my($tag, $ver, $rev, $flags, $size) = unpack("Z3 C C C N"), "header");
my($frameID, $FrameContentSize, $frameFlags) = unpack("Z4 N C2", "content");
sync_safe_to_int также используется в чтобы получить размер заголовка правильно, но для размера контура он должен печатать без каких-либо преобразований N Незнакомый длинный (32-разрядный) в «сети» (big-endia n) порядок.
C Значение без знака (октет).
Z Строка с нулевым завершением (ASCIZ), будет заполняться нулями.
Выход из моей программы:
содержание заголовка
Тэг: ID3
Ver: 3
Rev: 0
Флаги: 0
Размер: 699
НЕПРАВИЛЬНО выход! содержание кадров
ID: TPE1
размер: 167772160
Флаги:
Правильный выход из Perl! содержание кадра
ID: TPE1
размер: 10
Флаги: 0
У меня возникли проблемы после вашего вопроса. Вы говорите * «он дает мне около 140000 байт» *, а затем позже вы говорите, что видите «размер: 1677772160». Это ошибка или я вас не понимаю? – Borodin
Это была ошибка с моей стороны, теперь она должна была быть исправлена. Правильный выход - 10, а неправильный вывод - 167772160. Прошу прощения за путаницу около 1400000, которую вы можете забыть, мой плохой. – Fredrik