mp3tag 4: 读写mp3tag id3v1的代码
(yanlb2000, 2005.04.16)
上篇文章,我说道,为了满足自己管理大量mp3文件及其tag标记信息的需要,我决定自己编个软件。
编这样一个软件,首先解决的就是mp3tag的结构规范。我懒得网上去查这些资料了,反正id3v1也不太复杂,我就来点"蛮干"的,启动UltraEdit和Winamp,试着打开一些mp3歌曲文件,并对id3v1信息做些修改,前后对比尝试。很快,id3v1的结构我就自己琢磨出来了。具体过程我就不写了,反正最后的结果,就是完成了一个读写id3v1的通用代码。
这些代码,用Delphi的Object Pascal语言编写。完整地实现了对一个mp3文件读、写(添加或修改)、删除id3v1标记的功能。
如果你喜欢,可以保存为一个id3v1.pas文件,直接使用在Delphi中。或者,编译为一个DLL,被其他语言调用。
unit id3v1;
// copyright yanlb, 2005.04.16
interface
uses
SysUtils;
(*
If an mp3 file has a tag of id3v1, the tag will be appended to the end of the file,
, with type defined as bellow. The length of this type is 128 bytes.
*)
type
Tid3v1= record
Tag: array[0..2] of char; //00..02 , ='TAG'
Title:array[0..$1d] of char; //03..20
Artist:array[0..$1d] of char; //21..3e
Album:array[0..$1d] of char; //3f..5c
Year:array[0..3] of char; //5d..60
Comment:array[0..$1b] of char; //61..7c
NULL:byte; //7d , =0
Track:byte; //7e
Genre:byte; //7f , Index to Genre
end;
function ReadID3v1(strFile:string;var pid3v1:Tid3v1):integer;
function WriteID3v1(strFile:string;var pid3v1:Tid3v1):integer;
function DeleteID3v1(strFile:string):integer;
procedure ClearID3v1(var pid3v1:Tid3v1);
function StrPCopyLen(Dest: PChar; const Source: string; Len:integer): PChar;
implementation
{ Read id3v1 tags from .MP3 file }
function ReadID3v1(strFile:string;var pid3v1:Tid3v1):integer;
var
f1:file of byte;
i: integer;
begin
result:=1;
if strFile='' then exit;
AssignFile(f1,strFile);
try
FileMode:=0;
Reset(f1);
if FileSize(f1)>$80 then begin
Seek(f1, FileSize(f1)-$80);
BlockRead(f1,pid3v1,sizeof(Tid3v1),i);
if (i<Sizeof(Tid3v1)) or (pid3v1.Tag'TAG') then
ClearID3v1(pid3v1);
end // filesize > $80
finally
CloseFile(f1);
end; // try
result:=0;
end;
{ Write id3v1 tags to .MP3 file }
function WriteID3v1(strFile:string;var pid3v1:Tid3v1):integer;
var
f1:file of byte;
bytAll: array [0..$7f] of byte;
i: integer;
begin
result:=1;
AssignFile(f1,strFile);
try
FileMode:=2;
Reset(f1);
if FileSize(f1)>$80 then begin
Seek(f1, FileSize(f1)-$80);
for i:=0 to $2 do Read(f1,bytAll[i]); // test if 'TAG' exists
if (bytAll[0]=ord('T')) and (bytAll[1]=ord('A'))
and (bytAll[2]=ord('G'))
then Seek(f1,FileSize(f1)-$80)
else Seek(f1,FileSize(f1));
BlockWrite(f1,pid3v1,Sizeof(Tid3v1),i);
end // if filesize>$80
finally
CloseFile(f1);
end; // try
result:=0;
end;
{ Delete id3v1 tags from a .MP3 file }
function DeleteID3v1(strFile:string):integer;
var
f1:file of byte;
bytAll: array [0..$7f] of byte;
i: integer;
begin
Result:=1;
AssignFile(f1,strFile);
try
FileMode:=2;
Reset(f1);
if FileSize(f1)>$80 then begin
Seek(f1, FileSize(f1)-$80);
for i:=0 to $2 do Read(f1,bytAll[i]); // test if 'TAG' exists
if (bytAll[0]=ord('T')) and (bytAll[1]=ord('A'))
and (bytAll[2]=ord('G'))
then begin
Seek(f1,FileSize(f1)-$80);
Truncate(f1)
end
end // if filesize > $80
finally
CloseFile(f1);
end; // try
Result:=0;
end;
procedure ClearID3v1(var pid3v1:Tid3v1);
begin
FillChar(pid3v1,sizeof(Tid3v1),0);
end;
{fill a string to a Tid3v1's field with length specified.}
function StrPCopyLen(Dest: PChar; const Source: string; Len:integer): PChar;
var
str1: string;
begin
str1:=Source;
if Length(str1)>Len then SetLength(str1,Len);
result:=strpCopy(Dest,str1);
end;
end.
----------------------------------------------------------------
查看我博客上关于MP3tag专题的其他文章,请看
专题:MP3tag http://www.blogcn.com/User13/yanlb2000/blog/56196103.html