📄 ump3tag.pas
字号:
unit uMP3TAG;
interface
uses SysUtils, Classes;
const
{ 流派索引表 }
MAXGENRES = 114;
GENRESTable: array [0..MAXGENRES] of String = (
'Blues','Classic Rock','Country','Dance','Disco','Funk','Grunge',
'Hip-Hop','Jazz','Metal','New Age','Oldies','Other','Pop','R&B',
'Rap','Reggae','Rock','Techno','Industrial','Alternative','Ska',
'Death Metal','Pranks','Soundtrack','Euro-Techno','Ambient',
'Trip-Hop','Vocal','Jazz+Funk','Fusion','Trance','Classical',
'Instrumental','Acid','House','Game','Sound Clip','Gospel',
'Noise','AlternRock','Bass','Soul','Punk','Space','Meditative',
'Instrumental Pop','Instrumental Rock','Ethnic','Gothic',
'Darkwave', 'Techno-Industrial','Electronic','Pop-Folk',
'Eurodance','Dream', 'Southern Rock','Comedy','Cult',
'Gangsta','Top 40','Christian Rap', 'Pop/Funk','Jungle',
'Native American','Cabaret','New Wave', 'Psychadelic','Rave',
'Showtunes','Trailer','Lo-Fi','Tribal','Acid Punk','Acid Jazz',
'Polka','Retro','Musical','Rock & Roll','Hard Rock','Folk',
'Folk/Rock','National Folk','Swing','Bebob','Latin','Revival',
'Celtic','Bluegrass','Avantgarde','Gothic Rock',
'Progressive Rock','Psychedelic Rock','Symphonic Rock',
'Slow Rock','Big Band','Chorus','Easy Listening','Acoustic',
'Humour','Speech','Chanson','Opera','Chamber Music','Sonata',
'Symphony','Booty Bass','Primus','Porn Groove','Satire',
'Slow Jam','Club','Tango','Samba','Folklore');
{ 128字节的ID3v1结构 }
type
ID3Struct = packed record
FID: array [0..2 ] of Char;
FTitle: array [0..29] of Char;
FArtist: array [0..29] of Char;
FAlbum: array [0..29] of Char;
FYear: array [0..3 ] of Char;
FComment: array [0..29] of Char;
FGenre: Byte;
end;
TID3Tag = class
private
FStream: TFileStream;
Tag, Tag2: ID3Struct;
public
Title, Artist, Album, Year, Comment: string;
Genre: Byte;
GenreStr: string;// 流派对应字符串
FileName: string;// 文件名
function ReadTag: Boolean; // 读取Tag
function WriteTag: Boolean; // 写Tag
function RemoveTag: Boolean; // 除去Tag
end;
implementation
function TID3Tag.ReadTag: Boolean;
begin
Result := False;
try
FStream := TFileStream.Create(FileName, fmOpenRead);
FStream.Seek(-128, soFromEnd);
FStream.ReadBuffer(Tag, 128); // 读取TAG
if StrLComp(Tag.FID, 'TAG', 3) = 0 then
with Tag do
begin
Title := Trim(Copy(FTitle, 1, SizeOf(FTitle)));
Artist := Trim(Copy(FArtist, 1, SizeOf(FArtist)));
Album := Trim(Copy(FAlbum, 1, SizeOf(FAlbum)));
Year := Trim(Copy(FYear, 1, SizeOf(FAlbum)));
Comment := Trim(Copy(FComment, 1, SizeOf(FComment)));
Genre := FGenre;
if FGenre <= MAXGENRES then
GenreStr := GENRESTable[FGenre] else GenreStr := 'Unknown';
Result := True;
end;
finally
Fstream.Free;
end;
end;
function TID3Tag.WriteTag: Boolean;
procedure MoveStr(Sour: string; Dest: PChar);
begin
if Length(Sour) > 0 then
Move(Sour[1], Dest^, Length(Sour));
end;
begin
Result := False;
FillChar(Tag, SizeOf(Tag), 32);// 先填充空格
with Tag do
begin
FID := 'TAG';
FGenre := Genre;
MoveStr(Title, Ftitle);
MoveStr(Artist, FArtist);
MoveStr(Album, FAlbum);
MoveStr(Year, FYear);
MoveStr(Comment, FComment);
end;
try
FStream := TFileStream.Create(FileName, fmOpenReadWrite);
FStream.Seek(-128, soFromEnd);
FStream.ReadBuffer(Tag2,sizeof(Tag2));
if StrLComp(Tag.FID, 'TAG', 3) <> 0 then // 判断原来是否有Tag
FStream.Seek(0, soFromEnd); // 没有-追加到文件尾 有-覆盖原来的
FStream.WriteBuffer(Tag, SizeOf(Tag));
Result := True;
finally
FStream.Free;
end;
end;
function TID3Tag.RemoveTag: Boolean;
begin
Result := False;
try
FStream := TFileStream.Create(FileName, fmOpenReadWrite
or fmShareExclusive);
FStream.Seek(-128, soFromEnd);
FStream.ReadBuffer(Tag,sizeof(Tag));
if StrLComp(Tag.FID, 'TAG', 3) = 0 then //若有Tag,除去
FStream.Size := FStream.Size - 128;
Result := True;
finally
FStream.Free;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -