Я пытаюсь прочитать теги ID3v1 из mp3-файлов, используя «BASS.dll» (через bass.lib и bass.h).
Работает нормально, пока файл .mp3 не имеет заголовка (или исполнителя), содержащего 30 символов.
Вместо
Happy Times (Feat. Margaux Bos
я получил Happy Times (Feat. Margaux BosEmigrate
с Emigrate
добавлено (это тег исполнителя).
Как сделать так, чтобы он работал правильно, без добавления тега Artist?
Вот мой исходный код:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"#include "bass.h"//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
BASS_Init(-1, 44000, 0, 0, 0);
if(OpenDialog1->Execute())
{
HSTREAM stream = BASS_StreamCreateFile(false, OpenDialog1->FileName.c_str(), 0, 0, 0);
TAG_ID3 *tags = (TAG_ID3*)BASS_ChannelGetTags(stream, BASS_TAG_ID3);
Edit1->Text = tags->title;
}
}
Текстовые поля TAG_ID3
Не гарантируется, что struct завершается нулем, но ваш код обрабатывает их так, как если бы они были, поэтому он завершает чтение следующего поля, когда отсутствует нулевой терминатор. Чтобы это исправить, вы должны принять во внимание их максимальную длину, например:
Edit1->Text = AnsiString().sprintf("%.*s", sizeof(tags->title), tags->title);
Или же:
Edit1->Text = AnsiString(tags->title, sizeof(tags->title)).TrimRight();
То же самое со всеми другими текстовыми полями:
id
: 3 символаtitle
: 30 символовartist
: 30 символовalbum
: 30 символовyear
: 4 символаcomment
: 30 символовВы можете использовать простую обертку шаблона, чтобы помочь вам:
template<size_t N>
String toString(char (&arr)[N])
{
return AnsiString().sprintf("%.*s", N, arr);
/* or:
return AnsiString(arr, N).TrimRight();
*/
}
Edit1->Text = toString(tags->title);
Обратите внимание, что comment
поле имеет дополнительное предостережение:
Если 30-й символ является ненулевым, а 29-й — нулевым, то 30-й символ является номером дорожки, и комментарий ограничен первыми 28 символами.
Других решений пока нет …