Чтение ID3 тегов
Люди, может кто нибудь знает, как можно прочитать ID3 тег из MP3'шного файла? Буду очень благодарен за любую полезную инфу или линк...
Цитата:
Originally posted by PASS
Люди, может кто нибудь знает, как можно прочитать ID3 тег из MP3'шного файла? Буду очень благодарен за любую полезную инфу или линк...
Люди, может кто нибудь знает, как можно прочитать ID3 тег из MP3'шного файла? Буду очень благодарен за любую полезную инфу или линк...
http://www.codenet.ru/progr/formt/mp3tag.php
http://www.codenet.ru/progr/formt/mp3tag1.php
Код:
struct TAG // объявляем структуру ID3 тега ver. 1.1
{
unsigned char tag [ 03 ]; // сигнатура 'TAG' 3 байта
unsigned char title [ 30 ]; // название 30 байт
unsigned char artist [ 30 ]; // исполнитель 30 байт
unsigned char album [ 30 ]; // альбом 30 байт
unsigned char year [ 04 ]; // год 4 байта
unsigned char comment [ 28 ]; // комментарий 28 байт
unsigned char sep [ 01 ]; // нулевой байт
unsigned char track [ 01 ]; // номер трека 1 байт
unsigned char genre [ 01 ]; // код стиля 1 байт
};
// Функция для чтения ID3 тегов ( параметр - имя файла )
void GetMp3Tag ( AnsiString fName )
{
HANDLE hFile;
DWORD dwFileSize;
DWORD dwBytesRead;
DWORD dwTagSize;
DWORD dwStartPos;
TAG tMp3;
// Отткрываем файл для чтения
hFile = CreateFile ( fName.c_str (), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
// Если файл успешно открыт...
if ( hFile != INVALID_HANDLE_VALUE )
{
// вычисляем его размер
dwFileSize = GetFileSize ( hFile, NULL );
// вычисляем размер тега
dwTagSize = sizeof ( TAG );
// вычисляем позицию, с которой надо читать
dwStartPos = dwFileSize - dwTagSize;
// устанавливаем указатель на нужную позицию
SetFilePointer ( hFile, dwStartPos, NULL, FILE_BEGIN );
// читаем файл и записываем все в структуру
ReadFile ( hFile, &tMp3, dwTagSize, &dwBytesRead, NULL );
}
// закрываем файл
CloseHandle ( hFile );
// выводим 5 сообщений:
MessageBox( NULL, tMp3.title, "Title", NULL );
MessageBox( NULL, tMp3.artist, "Artist", NULL );
MessageBox( NULL, tMp3.album, "Album", NULL );
MessageBox( NULL, tMp3.year, "Year", NULL );
MessageBox( NULL, tMp3.comment, "Comment", NULL );
}
{
unsigned char tag [ 03 ]; // сигнатура 'TAG' 3 байта
unsigned char title [ 30 ]; // название 30 байт
unsigned char artist [ 30 ]; // исполнитель 30 байт
unsigned char album [ 30 ]; // альбом 30 байт
unsigned char year [ 04 ]; // год 4 байта
unsigned char comment [ 28 ]; // комментарий 28 байт
unsigned char sep [ 01 ]; // нулевой байт
unsigned char track [ 01 ]; // номер трека 1 байт
unsigned char genre [ 01 ]; // код стиля 1 байт
};
// Функция для чтения ID3 тегов ( параметр - имя файла )
void GetMp3Tag ( AnsiString fName )
{
HANDLE hFile;
DWORD dwFileSize;
DWORD dwBytesRead;
DWORD dwTagSize;
DWORD dwStartPos;
TAG tMp3;
// Отткрываем файл для чтения
hFile = CreateFile ( fName.c_str (), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
// Если файл успешно открыт...
if ( hFile != INVALID_HANDLE_VALUE )
{
// вычисляем его размер
dwFileSize = GetFileSize ( hFile, NULL );
// вычисляем размер тега
dwTagSize = sizeof ( TAG );
// вычисляем позицию, с которой надо читать
dwStartPos = dwFileSize - dwTagSize;
// устанавливаем указатель на нужную позицию
SetFilePointer ( hFile, dwStartPos, NULL, FILE_BEGIN );
// читаем файл и записываем все в структуру
ReadFile ( hFile, &tMp3, dwTagSize, &dwBytesRead, NULL );
}
// закрываем файл
CloseHandle ( hFile );
// выводим 5 сообщений:
MessageBox( NULL, tMp3.title, "Title", NULL );
MessageBox( NULL, tMp3.artist, "Artist", NULL );
MessageBox( NULL, tMp3.album, "Album", NULL );
MessageBox( NULL, tMp3.year, "Year", NULL );
MessageBox( NULL, tMp3.comment, "Comment", NULL );
}
Поблема в том, что если, например, тег содержит комметарий, то год "сливается" с комментарием, т.е. выводится слитно с ним... Также, если все поля заполнены "под завязку", то они тоже все сливаются ( в каждом MessageBox'е выводится ВСЕ содержание ID3 тега ). Может кто подскажет, где ошибку искать?
[QUOTE]
Судя по коду, в тегах для экономии памяти нет доп. символа для хранения конца строки '\0'.
Следовательно надо самому его добавлять, например так:
...
unsigned char c[31];
// после 3-его символа добавляем \0
memmove( c, tTag.tag, 3); c[4] = '\0';
// после 30-его символа добавляем \0
memmove( c, tTag.title, 30); c[31] = '\0';
// далее выводим, например так:
ShowMessage( AnsiString((char*) c ) );
// или как в твоем случае
MessageBox( NULL, с, "Comment", NULL );
Спасибо за внимание :)
[QUOTE]
Судя по коду, в тегах для экономии памяти нет доп. символа для хранения конца строки '\0'.
Следовательно надо самому его добавлять, например так:
...
unsigned char c[31];
// после 3-его символа добавляем \0
memmove( c, tTag.tag, 3); c[4] = '\0';
// после 30-его символа добавляем \0
memmove( c, tTag.title, 30); c[31] = '\0';
// далее выводим, например так:
ShowMessage( AnsiString((char*) c ) );
// или как в твоем случае
MessageBox( NULL, с, "Comment", NULL );
Спасибо за внимание :)
Попробовал добавлять нулевой ограничитель к каждой строке, но проблема осталась: когда тег заполнен полностью, при попытки вывести на экран отдельный элемент (заголовок, исполнитель и т.д.) выводится все содержимое тега. Кто-нибудь знает, в чем тут дело?
Цитата:
Originally posted by PASS
Попробовал добавлять нулевой ограничитель к каждой строке, но проблема осталась: когда тег заполнен полностью, при попытки вывести на экран отдельный элемент (заголовок, исполнитель и т.д.) выводится все содержимое тега. Кто-нибудь знает, в чем тут дело?
Попробовал добавлять нулевой ограничитель к каждой строке, но проблема осталась: когда тег заполнен полностью, при попытки вывести на экран отдельный элемент (заголовок, исполнитель и т.д.) выводится все содержимое тега. Кто-нибудь знает, в чем тут дело?
;-) Ну что, попробуй еще раз я проверил все работает, правда ошибся насчет индекса нулевого символа:
memmove( c, tMp3.title, 30 ); c[30] = 0;
Я даже проверил сам, написав прогу в Builder 5.0
C уважением :)