Wenn ich deinen Code richtig vestanden habe, dann sind die ID3 Tag felder alle mit fester Länge codiert ?
Dann müsste die hier funktionieren:
Delphi-Quellcode:
type
PID3Tag = ^TID3Tag;
TID3Tag = record
ID: String;
Title: String;
Artist: String;
Album: String;
Year: String;
Comment: String;
Genre: Byte;
end;
function ReadID3Tag(const FileName: String): TID3Tag;
function StrLPas(Value: PChar; Len: Integer): String;
function Min(A,B: Integer): Integer;
begin
if A <= B then Result := A
else Result := B;
end;
begin
SetString(Result, Value, Min(Len, StrLen(Value)));
Result := Trim(Result);
end;
type
TID3Struct = packed record
ID: array[0..2] of Char; // 3
Title: array[0..29] of Char; // 33
Artist: array[0..29] of Char; // 63
Album: array[0..29] of Char; // 93
Year: array[0..3] of Char; // 97
Comment: array[0..29] of Char; // 127
Genre: Byte; // 128
end;
var
Tag: TID3Struct;
begin
with TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone) do
try
Position := Size - SizeOf(Tag);
Read(Tag, SizeOf(Tag));
finally
Free;
end;
with Tag do
begin
Result.ID := StrLPas(ID, SizeOf(ID));
Result.Title := StrLPas(Title, SizeOf(Title));
Result.Artist := StrLPas(Artist, SizeOf(Artist));
Result.Album := StrLPas(Album, SizeOf(Album));
Result.Year := StrLPas(Year, SizeOf(Year));
Result.Comment := StrLPas(Comment, SizeOf(Comment));
Result.Genre := Genre;
end;
end;
Leider ist der MP3 ID3 Tag so ziemlich die schlechteste Struktur die ein Programmierer sich einfallen lassen kann. Sie benutzt keine Variable Length Felder, keine Null Terminierten Chars oder eben keine PASCAL typischen Längenbasierten Strings. D.h. egal ob man in C/C++ oder PASCAL oder sonstwas programmiert, man muß IMMER eine Konvertierung der gelesenen Daten vorsehen. Dabei ist es zusätzlich noch wichtig Leerzeichen oder eventuelle Nullterminatoren zu berücksichtigen. Der ID3 ist eben eine ziemlich unprofessionelle Sache, dies merkt man auch daran das am ID3 "Standard" so viele Änderungen vorgenommen wurden.
Hier eine Version die eher C Typisch ist:
Delphi-Quellcode:
type
TID3Tag = record
// diese Struktur erweitert die Char arrays um ein Zeichen für Nullterminator,
// somit muß sie Feld für Feld gelesen und geschrieben werden, da ID3 eben diese Terminatoren NICHT speichert.
ID: array[0..3] of Char;
Title: array[0..30] of Char;
Artist: array[0..30] of Char;
Album: array[0..30] of Char;
Year: array[0..4] of Char;
Comment: array[0..30] of Char;
Genre: Byte;
end;
function ReadID3Tag(const FileName: String): TID3Tag;
begin
FillChar(Result, SizeOf(Result), 0);
with TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone) do
try
Position := Size - 128;
Read(Result.ID, 3);
Read(Result.Title, 30);
Read(Result.Artist, 30);
Read(Result.Album, 30);
Read(Result.Year, 4);
Read(Result.Comment, 30);
Read(Result.Genre, 1);
finally
Free;
end;
end;
Gruß Hagen