我想做一个批量修改MP3标签的工具,实现的功能是把MP3文件名批量修改进MP3标签中去,不知道那位高手可否指导一下,好久没用Delphi了,最好能发源码,谢谢!重金求码!!!

解决方案 »

  1.   

    呵呵,还有钱?
    这里有个读取信息的,要写入改一下就可以了。
    http://community.csdn.net/Expert/topic/4732/4732750.xml?temp=1.647586E-02用FindFirst/FindNext遍历指定文件夹的mp3文件,获取文件名写入就可以了。
      

  2.   

    unit ID3Kernel;interfacetype
      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..$1c] of char; //61..7d
        Track:byte;                    //7e
        Genre:byte;                    //7f
      end;function ReadID3v1(strFile:string;var pid3v1:Tid3v1):integer;
    function WriteID3v1(strFile:string;var pid3v1:Tid3v1):integer;
    function DeleteID3v1(strFile:string):integer;implementationfunction ReadID3v1(strFile:string;var pid3v1:Tid3v1):integer;
    var
      f1:file of byte;
      bytAll: array [0..$7f] of byte;
      i: integer;
    begin
      result:=1;
      if strFile='' then exit;
      AssignFile(f1,strFile);
      FileMode:=0;
      Reset(f1);
      if FileSize(f1)<=$80 then exit;
      Seek(f1, FileSize(f1)-$80);
      for i:=0 to $7f do Read(f1,bytAll[i]);
      if (bytAll[0]<>ord('T')) and (bytAll[1]<>ord('A'))
        and (bytAll[2]<>ord('G')) then exit; // no 'TAG' found
      Move(bytAll,pid3v1,$80);
      CloseFile(f1);
      result:=0;
    end;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);
      FileMode:=2;
      Reset(f1);
      if FileSize(f1)<=$80 then exit;
      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));
      Move(pid3v1,bytAll,$80);
      for i:=0 to $7f do Write(f1,bytAll[i]);
      CloseFile(f1);
      result:=0;
    end;function DeleteID3v1(strFile:string):integer;
    var
      f1:file of byte;
      bytAll: array [0..$7f] of byte;
      i: integer;
    begin
      Result:=1;
      AssignFile(f1,strFile);
      FileMode:=2;
      Reset(f1);
      if FileSize(f1)<=$80 then exit;
      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;
      CloseFile(f1);
      Result:=0;
    end;end.
      

  3.   

    用xzhifei的 WriteID3v1(strFile:string;var pid3v1:Tid3v1):integer;遍历所有MP3文件写入即可
      

  4.   

    unit MPEGID3v1;interfaceuses
      Classes, SysUtils;const
      MAX_MUSIC_GENRES = 148;                       { Max. number of music genres }
      DEFAULT_GENRE = 255;                              { Index for default genre }  { Used with VersionID property }
      TAG_VERSION_1_0 = 1;                                { Index for ID3v1.0 tag }
      TAG_VERSION_1_1 = 2;                                { Index for ID3v1.1 tag }var
      MusicGenre: array [0..MAX_MUSIC_GENRES - 1] of string;        { Genre names }type
      { Used in TID3v1 class }
      String04 = string[4];                          { String with max. 4 symbols }
      String30 = string[30];                        { String with max. 30 symbols }  { Class TMPEGID3v1 }
      TMPEGID3v1 = class(TObject)
        private
          { Private declarations }
          FExists: Boolean;
          FVersionID: Byte;
          FTitle: String30;
          FArtist: String30;
          FAlbum: String30;
          FYear: String04;
          FComment: String30;
          FTrack: Byte;
          FGenreID: Byte;
          procedure FSetTitle(const NewTitle: String30);
          procedure FSetArtist(const NewArtist: String30);
          procedure FSetAlbum(const NewAlbum: String30);
          procedure FSetYear(const NewYear: String04);
          procedure FSetComment(const NewComment: String30);
          procedure FSetTrack(const NewTrack: Byte);
          procedure FSetGenreID(const NewGenreID: Byte);
          function FGetGenre: string;
        public
          { Public declarations }
          constructor Create;                                     { Create object }
          procedure ResetData;                                   { Reset all data }
          function ReadFromFile(const FileName: string): Boolean;      { Load tag }
          function RemoveFromFile(const FileName: string): Boolean;  { Delete tag }
          function SaveToFile(const FileName: string): Boolean;        { Save tag }
          property Exists: Boolean read FExists;              { True if tag found }
          property VersionID: Byte read FVersionID;                { Version code }
          property Title: String30 read FTitle write FSetTitle;      { Song title }
          property Artist: String30 read FArtist write FSetArtist;  { Artist name }
          property Album: String30 read FAlbum write FSetAlbum;      { Album name }
          property Year: String04 read FYear write FSetYear;               { Year }
          property Comment: String30 read FComment write FSetComment;   { Comment }
          property Track: Byte read FTrack write FSetTrack;        { Track number }
          property GenreID: Byte read FGenreID write FSetGenreID;    { Genre code }
          property Genre: string read FGetGenre;                     { Genre name }
      end;implementationtype
      { Real structure of ID3v1 tag }
      TagRecord = record
        Header: array [1..3]  of Char;                { Tag header - must be "TAG" }
        Title:  array [1..30] of Char;                                { Title data }
        Artist: array [1..30] of Char;                              { Artist data }
        Album:  array [1..30] of Char;                                { Album data }
        Year:   array [1..4]  of Char;                                   { Year data }
        Comment:array [1..30] of Char;                            { Comment data }
        Genre: Byte;                                                 { Genre data }
      end;{ ********************* Auxiliary functions & procedures ******************** }function ReadTag(const FileName: string; var TagData: TagRecord): Boolean;
    var
      SourceFile: file;
    begin
      try
        Result := true;
        { Set read-access and open file }
        AssignFile(SourceFile, FileName);
        FileMode := 0;
        Reset(SourceFile, 1);
        { Read tag }
        Seek(SourceFile, FileSize(SourceFile) - 128);
        BlockRead(SourceFile, TagData, 128);
        CloseFile(SourceFile);
      except
        { Error }
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function RemoveTag(const FileName: string): Boolean;
    var
      SourceFile: file;
    begin
      try
        Result := true;
        { Allow write-access and open file }
        FileSetAttr(FileName, 0);
        AssignFile(SourceFile, FileName);
        FileMode := 2;
        Reset(SourceFile, 1);
        { Delete tag }
        Seek(SourceFile, FileSize(SourceFile) - 128);
        Truncate(SourceFile);
        CloseFile(SourceFile);
      except
        { Error }
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function SaveTag(const FileName: string; TagData: TagRecord): Boolean;
    var
      SourceFile: file;
    begin
      try
        Result := true;
        { Allow write-access and open file }
        FileSetAttr(FileName, 0);
        AssignFile(SourceFile, FileName);
        FileMode := 2;
        Reset(SourceFile, 1);
        { Write tag }
        Seek(SourceFile, FileSize(SourceFile));
        BlockWrite(SourceFile, TagData, SizeOf(TagData));
        CloseFile(SourceFile);
      except
        { Error }
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function GetTagVersion(const TagData: TagRecord): Byte;
    begin
      Result := TAG_VERSION_1_0;
      { Terms for ID3v1.1 }
      if ((TagData.Comment[29] = #0) and (TagData.Comment[30] <> #0)) or
        ((TagData.Comment[29] = #32) and (TagData.Comment[30] <> #32)) then
        Result := TAG_VERSION_1_1;
    end;{ ********************** Private functions & procedures ********************* }procedure TMPEGID3v1.FSetTitle(const NewTitle: String30);
    begin
      FTitle := TrimRight(NewTitle);
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetArtist(const NewArtist: String30);
    begin
      FArtist := TrimRight(NewArtist);
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetAlbum(const NewAlbum: String30);
    begin
      FAlbum := TrimRight(NewAlbum);
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetYear(const NewYear: String04);
    begin
      FYear := TrimRight(NewYear);
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetComment(const NewComment: String30);
    begin
      FComment := TrimRight(NewComment);
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetTrack(const NewTrack: Byte);
    begin
      FTrack := NewTrack;
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.FSetGenreID(const NewGenreID: Byte);
    begin
      FGenreID := NewGenreID;
    end;{ --------------------------------------------------------------------------- }function TMPEGID3v1.FGetGenre: string;
    begin
      Result := '';
      { Return an empty string if the current GenreID is not valid }
      if FGenreID in [0..MAX_MUSIC_GENRES - 1] then Result := MusicGenre[FGenreID];
    end;
      

  5.   


    { ********************** Public functions & procedures ********************** }constructor TMPEGID3v1.Create;
    begin
      inherited;
      ResetData;
    end;{ --------------------------------------------------------------------------- }procedure TMPEGID3v1.ResetData;
    begin
      FExists := false;
      FVersionID := TAG_VERSION_1_0;
      FTitle := '';
      FArtist := '';
      FAlbum := '';
      FYear := '';
      FComment := '';
      FTrack := 0;
      FGenreID := DEFAULT_GENRE;
    end;{ --------------------------------------------------------------------------- }function TMPEGID3v1.ReadFromFile(const FileName: string): Boolean;
    var
      TagData: TagRecord;
    begin
      { Reset and load tag data from file to variable }
      ResetData;
      Result := ReadTag(FileName, TagData);
      { Process data if loaded and tag header OK }
      if (Result) and (TagData.Header = 'TAG') then
        begin
          FExists := true;
          FVersionID := GetTagVersion(TagData);
          { Fill properties with tag data }
          FTitle := TrimRight(TagData.Title);
          FArtist := TrimRight(TagData.Artist);
          FAlbum := TrimRight(TagData.Album);
          FYear := TrimRight(TagData.Year);
          if FVersionID = TAG_VERSION_1_0 then FComment := TrimRight(TagData.Comment)
          else
            begin
              FComment := TrimRight(Copy(TagData.Comment, 1, 28));
              FTrack := Ord(TagData.Comment[30]);
            end;
          FGenreID := TagData.Genre;
        end;
    end;{ --------------------------------------------------------------------------- }function TMPEGID3v1.RemoveFromFile(const FileName: string): Boolean;
    var
      TagData: TagRecord;
    begin
      { Find tag }
      Result := ReadTag(FileName, TagData);
      { Delete tag if loaded and tag header OK }
      if (Result) and (TagData.Header = 'TAG') then Result := RemoveTag(FileName);
    end;{ --------------------------------------------------------------------------- }function TMPEGID3v1.SaveToFile(const FileName: string): Boolean;
    var
      TagData: TagRecord;
    begin
      { Prepare tag record }
      FillChar(TagData, SizeOf(TagData), 0);
      TagData.Header := 'TAG';
      Move(FTitle[1], TagData.Title, Length(FTitle));
      Move(FArtist[1], TagData.Artist, Length(FArtist));
      Move(FAlbum[1], TagData.Album, Length(FAlbum));
      Move(FYear[1], TagData.Year, Length(FYear));
      Move(FComment[1], TagData.Comment, Length(FComment));
      if FTrack > 0 then
        begin
          TagData.Comment[29] := #0;
          TagData.Comment[30] := Chr(FTrack);
        end;
      TagData.Genre := FGenreID;
      { Delete old tag and write new tag }
      Result := (RemoveFromFile(FileName)) and (SaveTag(FileName, TagData));
    end;{ ************************** Initialize music genres ************************ }initialization
    begin
      { Standard genres }
      MusicGenre[0] := 'Blues';
      MusicGenre[1] := 'Classic Rock';
      MusicGenre[2] := 'Country';
      MusicGenre[3] := 'Dance';
      MusicGenre[4] := 'Disco';
      MusicGenre[5] := 'Funk';
      MusicGenre[6] := 'Grunge';
      MusicGenre[7] := 'Hip-Hop';
      MusicGenre[8] := 'Jazz';
      MusicGenre[9] := 'Metal';
      MusicGenre[10] := 'New Age';
      MusicGenre[11] := 'Oldies';
      MusicGenre[12] := 'Other';
      MusicGenre[13] := 'Pop';
      MusicGenre[14] := 'R&B';
      MusicGenre[15] := 'Rap';
      MusicGenre[16] := 'Reggae';
      MusicGenre[17] := 'Rock';
      MusicGenre[18] := 'Techno';
      MusicGenre[19] := 'Industrial';
      MusicGenre[20] := 'Alternative';
      MusicGenre[21] := 'Ska';
      MusicGenre[22] := 'Death Metal';
      MusicGenre[23] := 'Pranks';
      MusicGenre[24] := 'Soundtrack';
      MusicGenre[25] := 'Euro-Techno';
      MusicGenre[26] := 'Ambient';
      MusicGenre[27] := 'Trip-Hop';
      MusicGenre[28] := 'Vocal';
      MusicGenre[29] := 'Jazz+Funk';
      MusicGenre[30] := 'Fusion';
      MusicGenre[31] := 'Trance';
      MusicGenre[32] := 'Classical';
      MusicGenre[33] := 'Instrumental';
      MusicGenre[34] := 'Acid';
      MusicGenre[35] := 'House';
      MusicGenre[36] := 'Game';
      MusicGenre[37] := 'Sound Clip';
      MusicGenre[38] := 'Gospel';
      MusicGenre[39] := 'Noise';
      MusicGenre[40] := 'AlternRock';
      MusicGenre[41] := 'Bass';
      MusicGenre[42] := 'Soul';
      MusicGenre[43] := 'Punk';
      MusicGenre[44] := 'Space';
      MusicGenre[45] := 'Meditative';
      MusicGenre[46] := 'Instrumental Pop';
      MusicGenre[47] := 'Instrumental Rock';
      MusicGenre[48] := 'Ethnic';
      MusicGenre[49] := 'Gothic';
      MusicGenre[50] := 'Darkwave';
      MusicGenre[51] := 'Techno-Industrial';
      MusicGenre[52] := 'Electronic';
      MusicGenre[53] := 'Pop-Folk';
      MusicGenre[54] := 'Eurodance';
      MusicGenre[55] := 'Dream';
      MusicGenre[56] := 'Southern Rock';
      MusicGenre[57] := 'Comedy';
      MusicGenre[58] := 'Cult';
      MusicGenre[59] := 'Gangsta';
      MusicGenre[60] := 'Top 40';
      MusicGenre[61] := 'Christian Rap';
      MusicGenre[62] := 'Pop/Funk';
      MusicGenre[63] := 'Jungle';
      MusicGenre[64] := 'Native American';
      MusicGenre[65] := 'Cabaret';
      MusicGenre[66] := 'New Wave';
      MusicGenre[67] := 'Psychadelic';
      MusicGenre[68] := 'Rave';
      MusicGenre[69] := 'Showtunes';
      MusicGenre[70] := 'Trailer';
      MusicGenre[71] := 'Lo-Fi';
      MusicGenre[72] := 'Tribal';
      MusicGenre[73] := 'Acid Punk';
      MusicGenre[74] := 'Acid Jazz';
      MusicGenre[75] := 'Polka';
      MusicGenre[76] := 'Retro';
      MusicGenre[77] := 'Musical';
      MusicGenre[78] := 'Rock & Roll';
      MusicGenre[79] := 'Hard Rock';
      { Extended genres }
      MusicGenre[80] := 'Folk';
      MusicGenre[81] := 'Folk-Rock';
      MusicGenre[82] := 'National Folk';
      MusicGenre[83] := 'Swing';
      MusicGenre[84] := 'Fast Fusion';
      MusicGenre[85] := 'Bebob';
      MusicGenre[86] := 'Latin';
      MusicGenre[87] := 'Revival';
      MusicGenre[88] := 'Celtic';
      MusicGenre[89] := 'Bluegrass';
      MusicGenre[90] := 'Avantgarde';
      MusicGenre[91] := 'Gothic Rock';
      MusicGenre[92] := 'Progessive Rock';
      MusicGenre[93] := 'Psychedelic Rock';
      MusicGenre[94] := 'Symphonic Rock';
      MusicGenre[95] := 'Slow Rock';
      MusicGenre[96] := 'Big Band';
      MusicGenre[97] := 'Chorus';
      MusicGenre[98] := 'Easy Listening';
      MusicGenre[99] := 'Acoustic';
      MusicGenre[100]:= 'Humour';
      MusicGenre[101]:= 'Speech';
      MusicGenre[102]:= 'Chanson';
      MusicGenre[103]:= 'Opera';
      MusicGenre[104]:= 'Chamber Music';
      MusicGenre[105]:= 'Sonata';
      MusicGenre[106]:= 'Symphony';
      MusicGenre[107]:= 'Booty Bass';
      MusicGenre[108]:= 'Primus';
      MusicGenre[109]:= 'Porn Groove';
      MusicGenre[110]:= 'Satire';
      MusicGenre[111]:= 'Slow Jam';
      MusicGenre[112]:= 'Club';
      MusicGenre[113]:= 'Tango';
      MusicGenre[114]:= 'Samba';
      MusicGenre[115]:= 'Folklore';
      MusicGenre[116]:= 'Ballad';
      MusicGenre[117]:= 'Power Ballad';
      MusicGenre[118]:= 'Rhythmic Soul';
      MusicGenre[119]:= 'Freestyle';
      MusicGenre[120]:= 'Duet';
      MusicGenre[121]:= 'Punk Rock';
      MusicGenre[122]:= 'Drum Solo';
      MusicGenre[123]:= 'A capella';
      MusicGenre[124]:= 'Euro-House';
      MusicGenre[125]:= 'Dance Hall';
      MusicGenre[126]:= 'Goa';
      MusicGenre[127]:= 'Drum & Bass';
      MusicGenre[128]:= 'Club-House';
      MusicGenre[129]:= 'Hardcore';
      MusicGenre[130]:= 'Terror';
      MusicGenre[131]:= 'Indie';
      MusicGenre[132]:= 'BritPop';
      MusicGenre[133]:= 'Negerpunk';
      MusicGenre[134]:= 'Polsk Punk';
      MusicGenre[135]:= 'Beat';
      MusicGenre[136]:= 'Christian Gangsta Rap';
      MusicGenre[137]:= 'Heavy Metal';
      MusicGenre[138]:= 'Black Metal';
      MusicGenre[139]:= 'Crossover';
      MusicGenre[140]:= 'Contemporary Christian';
      MusicGenre[141]:= 'Christian Rock';
      MusicGenre[142]:= 'Merengue';
      MusicGenre[143]:= 'Salsa';
      MusicGenre[144]:= 'Trash Metal';
      MusicGenre[145]:= 'Anime';
      MusicGenre[146]:= 'JPop';
      MusicGenre[147]:= 'Synthpop';
    end;end.
      

  6.   

    unit MPEGID3v2;interfaceuses
      Classes, SysUtils;const
      TAG_VERSION_2_3 = 3;                               { Code for ID3v2.3.x tag }type
      { Class TMPEGID3v2 }
      TMPEGID3v2 = class(TObject)
        private
          { Private declarations }
          FExists: Boolean;
          FVersionID: Byte;
          FSize: Integer;
          FTitle: string;
          FArtist: string;
          FAlbum: string;
          FTrack: Byte;
          FYear: string;
          FGenre: string;
          FComment: string;
          procedure FSetTitle(const NewTitle: string);
          procedure FSetArtist(const NewArtist: string);
          procedure FSetAlbum(const NewAlbum: string);
          procedure FSetTrack(const NewTrack: Byte);
          procedure FSetYear(const NewYear: string);
          procedure FSetGenre(const NewGenre: string);
          procedure FSetComment(const NewComment: string);
        public
          { Public declarations }
          constructor Create;                                     { Create object }
          procedure ResetData;                                   { Reset all data }
          function ReadFromFile(const FileName: string): Boolean;      { Load tag }
          function RemoveFromFile(const FileName: string): Boolean;  { Delete tag }
          function SaveToFile(const FileName: string): Boolean;        { Save tag }
          property Exists: Boolean read FExists;              { True if tag found }
          property VersionID: Byte read FVersionID;                { Version code }
          property Size: Integer read FSize;                     { Total tag size }
          property Title: string read FTitle write FSetTitle;        { Song title }
          property Artist: string read FArtist write FSetArtist;    { Artist name }
          property Album: string read FAlbum write FSetAlbum;       { Album title }
          property Track: Byte read FTrack write FSetTrack;        { Track number }
          property Year: string read FYear write FSetYear;         { Release year }
          property Genre: string read FGenre write FSetGenre;        { Genre name }
          property Comment: string read FComment write FSetComment;     { Comment }
      end;implementationconst
      { ID3v2 tag ID }
      ID3V2_ID = 'ID3';  { Max. number of supported tag frames }
      ID3V2_FRAME_COUNT = 7;  { Names of supported tag frames }
      ID3V2_FRAME: array [1..ID3V2_FRAME_COUNT] of string =
        ('TIT2', 'TPE1', 'TALB', 'TRCK', 'TYER', 'TCON', 'COMM');type
      { ID3v2 frame header }
      FrameHeader = record
        ID: array [1..4] of Char;                                      { Frame ID }
        Size: Integer;                                    { Size excluding header }
        Flags: Word;                                                      { Flags }
      end;  { ID3v2 header data - for internal use }
      TagInfo = record
        { Real structure of ID3v2 header }
        ID: array [1..3] of Char;                                  { Always "ID3" }
        Version: Byte;                                           { Version number }
        Revision: Byte;                                         { Revision number }
        Flags: Byte;                                               { Flags of tag }
        Size: array [1..4] of Byte;                   { Tag size excluding header }
        { Extended data }
        FileSize: Integer;                                    { File size (bytes) }
        Frame: array [1..ID3V2_FRAME_COUNT] of string;  { Information from frames }
      end;{ ********************* Auxiliary functions & procedures ******************** }function ReadHeader(const FileName: string; var Tag: TagInfo): Boolean;
    var
      SourceFile: file;
      Transferred: Integer;
    begin
      try
        Result := true;
        { Set read-access and open file }
        AssignFile(SourceFile, FileName);
        FileMode := 0;
        Reset(SourceFile, 1);
        { Read header and get file size }
        BlockRead(SourceFile, Tag, 10, Transferred);
        Tag.FileSize := FileSize(SourceFile);
        CloseFile(SourceFile);
        { if transfer is not complete }
        if Transferred < 10 then Result := false;
      except
        { Error }
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function GetVersionID(const Tag: TagInfo): Byte;
    begin
      { Get tag version from header }
      Result := Tag.Version;
    end;{ --------------------------------------------------------------------------- }function GetTagSize(const Tag: TagInfo): Integer;
    begin
      { Get total tag size }
      Result :=
        Tag.Size[1] * $200000 +
        Tag.Size[2] * $4000 +
        Tag.Size[3] * $80 +
        Tag.Size[4] + 10;
      if Result > Tag.FileSize then Result := 0;
    end;{ --------------------------------------------------------------------------- }procedure SetTagItem(const ID, Data: string; var Tag: TagInfo);
    var
      Iterator: Byte;
    begin
      { Set tag item if supported frame found }
      for Iterator := 1 to ID3V2_FRAME_COUNT do
        if ID3V2_FRAME[Iterator] = ID then Tag.Frame[Iterator] := Data;
    end;{ --------------------------------------------------------------------------- }function Swap32(const Figure: Integer): Integer;
    var
      ByteArray: array [1..4] of Byte absolute Figure;
    begin
      { Swap 4 bytes }
      Result :=
        ByteArray[1] * $1000000 +
        ByteArray[2] * $10000 +
        ByteArray[3] * $100 +
        ByteArray[4];
    end;{ --------------------------------------------------------------------------- }procedure ReadFrames(const FileName: string; var Tag: TagInfo);
    var
      SourceFile: file;
      Frame: FrameHeader;
      Data: array [1..250] of Char;
      DataPosition: Integer;
    begin
      try
        { Set read-access, open file }
        AssignFile(SourceFile, FileName);
        FileMode := 0;
        Reset(SourceFile, 1);
        Seek(SourceFile, 10);
        while (FilePos(SourceFile) < GetTagSize(Tag)) and (not EOF(SourceFile)) do
        begin
          FillChar(Data, SizeOf(Data), 0);
          { Read frame header and check frame ID }
          BlockRead(SourceFile, Frame, 10);
          if not (Frame.ID[1] in ['A'..'Z']) then break;
          DataPosition := FilePos(SourceFile);
          { Read frame data and set tag item if frame supported }
          BlockRead(SourceFile, Data, Swap32(Frame.Size) mod SizeOf(Data));
          SetTagItem(Frame.ID, Data, Tag);
          Seek(SourceFile, DataPosition + Swap32(Frame.Size));
        end;
        CloseFile(SourceFile);
      except
      end;
    end;{ --------------------------------------------------------------------------- }function ExtractTrack(const TrackString: string): Byte;
    var
      Index, Value, Code: Integer;
    begin
      { Extract track from string }
      Index := Pos('/', Trim(TrackString));
      if Index = 0 then Val(Trim(TrackString), Value, Code)
      else Val(Copy(Trim(TrackString), 1, Index - 1), Value, Code);
      if Code = 0 then Result := Value
      else Result := 0;
    end;{ --------------------------------------------------------------------------- }function ExtractGenre(const GenreString: string): string;
    begin
      { Extract genre from string }
      Result := Trim(GenreString);
      if Pos(')', Result) > 0 then Delete(Result, 1, LastDelimiter(')', Result));
    end;
      

  7.   

    呵呵!其實上面的都不好用的!德國的一個論壇的有個單元叫做 mp3fileunit,那個才是真正的厲害!因為這裡貼出來的都是不能讀取象 千千靜聽 的播放器寫入的完整歌詞,但是, mp3fileunit就可以