请问各位大虾,
    怎样才能获取各种音乐文件的信息,如 歌曲名 作者 专辑 等等。
例如: mp3 wma ogg 等等。
谢谢大家!

解决方案 »

  1.   

    每一个MP3文件包含有一个ID3-Tag头, 它用来提供艺术家、标题、专辑、出版年和歌曲流派等信息。这个头总是128字节长并位于MP3文件末尾。ID3-Tag 结构是这样的: type 
    TID3Tag = packed record // 128 字节
       TAGID: array[0..2] of char; // 3 字节: 必须是TAG
       Title: array[0..29] of char; // 30 字节: 歌曲标题
       Artist: array[0..29] of char; // 30 字节: 歌曲的艺术家
       Album: array[0..29] of char; // 30 字节: 歌曲专辑
       Year: array[0..3] of char; // 4 字节: 出版年
       Comment: array[0..29] of char; // 30 字节: 评论
       Genre: byte; // 1 字节: 种类标识
    end; 为读取ID3-Tag信息并在一个对话框中显示,试试这个函数: procedure TForm1.Button1Click(Sender: TObject); 
    const
      _mp3file='G:\Mp3\Miscellaneous\ATC - Around The World.mp3'; 
    var
      id3tag: Tid3tag;
      mp3file: Tfilestream; 
    begin
      mp3file:=Tfilestream.create(_mp3file,fmOpenRead);
      try
        mp3file.position:=mp3file.size-128; // 跳到id3-tag
        mp3file.Read(id3tag,SizeOf(id3tag));
        showmessage(' Title: '+id3tag.title+#13+
                    ' Artist: '+id3tag.artist+#13+
                    ' Album: '+id3tag.album+#13+
                    ' Year: '+id3tag.year+#13+
                    ' Comment: '+id3tag.comment+#13+
                    ' Genre-ID: '+inttostr(id3tag.genre)
                    );
      finally
        mp3file.free;
      end; 
    end; 这个函数读取_mp3file描述的文件,跳到倒数第128个字节,读取并在对话框中显示信息。
      

  2.   

    mp3file:=Tfilestream.create(_mp3file,fmOpenRead);
      
    这句出错?没道理啊?
      

  3.   

    现在好了,可能是文件被占用可是我写进去的东西,用MEDIAPLAYER读不出来啊,播放倒是没有问题
      

  4.   

    使用这个类,被我修改了的:当不存在ID3标签的时候,将抛出异常。
    unit untMP3Tags;interface
    uses Classes,SysUtils;
     Const
      erCancel = 0;
      erSave   = 1;
      erRemove = 2;  MAXGENRES = 114;
      GENRES: 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'
      );
      type
      String03 = String[3];
      String04 = String[4];
      String30 = String[30];  TFileName    = Type String;  TTag = packed record
        Tag       : String03;
        Title     : String30;
        Artist    : String30;
        Album     : String30;
        Year      : String04;
        Comment   : String30;
        GenreID   : Byte;
      end;
      Type
     TReadWriteTag = packed record
        TAG    : Array[1..3] of char;
        Title  : Array[1..30] of char;
        Artist : Array[1..30] of char;
        Album  : Array[1..30] of char;
        Year   : Array[1..4] of char;
        Comment: Array[1..30] of char;
        Genre  : Byte;
      end;
      TErrorEvent = procedure(Sender: TObject; Error : String) of Object;  TMP3Tag = class(TComponent)
      private
        FFileName  : TFileName;
        FValid     : Boolean;
        FTag       : TTag;
        FGenre     : String;
        FError     : String;    FAutoSave  : Boolean;
        //If you press "Save" in the edit box it saves automatically    FOnFileChange : TNotifyEvent;
        FOnChange     : TNotifyEvent;
        FOnError      : TErrorEvent;    procedure SetFileName(Value: TFileName);
        procedure SetTitle(Value: String30);
        procedure SetArtist(Value: String30);
        procedure SetAlbum(Value: String30);
        procedure SetYear(Value: String04);
        procedure SetComment(Value: String30);
        procedure SetGenreID(Value: Byte);
        procedure SetTag(Value: TTag);  protected  public
        procedure Open;
        procedure Remove;
        procedure Save;
        function GenreToByte(const strGenre:string):BYTE;
        function ByteToGenre(const ID:BYTE):string;
    //    Function  Edit:Byte;
      published
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;    property Filename  :TFilename read FFilename    write SetFilename;
        property MP3Tag    : TTag     read FTag         write SetTag;    property Title     : String30 read FTag.Title   write SetTitle;
        property Artist    : String30 read FTag.Artist  write SetArtist;
        property Album     : String30 read FTag.Album   write SetAlbum;
        property Year      : String04 read FTag.Year    write SetYear;
        property Comment   : String30 read FTag.Comment write SetComment;
        property GenreID   : Byte     read FTag.GenreID write SetGenreID;
        property Genre     : String   read FGenre;    property EditAutoSave : Boolean read FAutoSave  write FAutoSave;    property Valid: Boolean read FValid;
        property Error: String read FError;    property onFileNameChange  : TNotifyEvent read FOnFileChange write FOnFileChange;
        property onChange : TNotifyEvent read FOnChange write FOnChange;
        property onError  : TErrorEvent  read FOnError  write FOnError;
      end;implementation
     procedure TMP3Tag.SetFileName(Value: TFileName);
    begin
       FFileName:=Value;   Open;
       if Assigned(onFileNameChange) then onFileNameChange(Self);end;
    procedure TMP3Tag.SetTitle(Value: String30);
    begin
       FTag.Title:=Value;
       if Assigned(onChange) then onChange(Self);
    end;procedure TMP3Tag.SetArtist(Value: String30);
    begin
       FTag.Artist:=Value;
       if Assigned(onChange) then onChange(Self);
    end;procedure TMP3Tag.SetAlbum(Value: String30);
    begin
       FTag.Album:=Value;
       if Assigned(onChange) then onChange(Self);
    end;procedure TMP3Tag.SetYear(Value: String04);
    begin
       FTag.Year:=Value;
       if Assigned(onChange) then onChange(Self);
    end;procedure TMP3Tag.SetComment(Value: String30);
    begin
       FTag.Comment:=Value;
       if Assigned(onChange) then onChange(Self);
    end;procedure TMP3Tag.SetGenreID(Value: Byte);
    begin
       FTag.GenreID:=Value;
       if Assigned(onChange) then onChange(Self);
    end;{------------------------------------}procedure TMP3Tag.SetTag(Value: TTag);
    begin
       FTag:=Value;
       if Assigned(onChange) then onChange(Self);
    end;{-------------------------------------}procedure ClearTag(Var ATag : TTag);
    Begin
     With aTag do
      Begin
       Tag:='';
       Title:='';
       Artist:='';
       Album:='';
       Year:='';
       Comment:='';
       GenreID:=12;
      end;
    End;
      

  5.   


    procedure TMP3Tag.Open;Function RemoveSpaces(St : String):String;
    Var
     T : Byte;
    Begin
     T:=Length(ST);
     While (T>0) and (St[T]=' ') do
      Dec(T);
     Result:=Copy(St,1,T);
    End;
    procedure FillTag(STag : TReadWriteTag; Var DTag : TTag);
    Var
     T : Byte;
    Begin ClearTag(DTag); For T:=1 to 3 do
       DTag.Tag:=DTag.Tag+STag.Tag[T]; For T:=1 to 4 do
       DTag.Year:=DTag.Year+STag.Year[T]; For T:=1 to 30 do
      Begin
       DTag.Artist:=DTag.Artist+STag.Artist[T];
       DTag.Title:=DTag.Title+STag.Title[T];
       DTag.Album:=DTag.Album+STag.Album[T];
       DTag.Comment:=DTag.Comment+STag.Comment[T];
      end; DTag.GenreID:=STag.Genre; DTag.Artist:=RemoveSpaces(DTag.Artist);
     DTag.Title:=RemoveSpaces(DTag.Title);
     DTag.Album:=RemoveSpaces(DTag.Album);
     DTag.Comment:=RemoveSpaces(DTag.Comment);
     DTag.Year:=RemoveSpaces(DTag.Year);
    end;Var
     aStream : TFileStream;
     ATag    : TReadWriteTag;
    begin
     FValid:=False;
     ClearTag(FTag);
     //asm int 3;end;
     IF FileExists(FFileName) then
      Begin
       aStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite);
       IF AStream.Size>128 then
        Begin
          aStream.Seek(-128,soFromEnd);
          aStream.ReadBuffer(aTag, 128);
          FillTag(aTag,FTag);
          IF FTag.Tag = 'TAG' then
           Begin
             FValid:=True;
           end Else
            Begin
             FError:='MP3 does not contain a mp3 tag or wrong file format!';
             ClearTag(FTag);
             FTag.Tag:='TAG';
             FTag.Title:=Copy(ExtractFileName(FFileName),1,30);
            end;    end else FError:='File too small to be a MP3 file!';
       aStream.Free;
      end else FError:='File does not exist!';
     IF Not FValid then
      IF Assigned(OnError) then raise Exception.Create(FError);
    end;procedure TMP3Tag.Remove;
    var
      aFile  : file;
      aTag   : TReadWriteTag;begin
      If FileExists (FFileName) then begin
        AssignFile (aFile, FFileName);
        {$I-}
        Reset (aFile,1);
        {$I+}
        if (IOResult=0) and (FileSize(aFile) > 128) then begin
           Seek(AFile,FileSize(aFile)-128);
           BlockRead(aFile, ATag, 128);
           if aTag.TAG='TAG' then begin
             Seek (aFile,FileSize(aFile)-128);
             Truncate(aFile);
           end;
           Close(aFile);
        end;    ClearTag(FTag);
        Open;
      end;
    end;procedure TMP3Tag.Save;procedure FillReadWriteTag(STag : TTag; Var DTag : TReadWriteTag);
    Begin FillChar (DTag, SizeOf(DTag), 0); DTag.Tag:='TAG'; Move (STag.Year[1],DTag.Year, Length(STag.Year));
     Move (STag.Artist[1],DTag.Artist, Length(STag.Artist));
     Move (STag.Title[1],DTag.Title, Length(STag.Title));
     Move (STag.Album[1],DTag.Album, Length(STag.Album));
     Move (STag.Comment[1],DTag.Comment, Length(STag.Comment));
     DTag.Genre:=STag.GenreID;
    end;
    Var
     aStream : TFileStream;
     aTag    : TReadWriteTag;
    begin
     FError:='';
     IF FileExists(FFileName) then
      Begin
       aStream := TFileStream.Create(FFileName, fmOpenReadWrite or fmShareDenyWrite);
       IF AStream.Size>128 then
        Begin
          aStream.Seek(-128,soFromEnd);
          aStream.ReadBuffer(aTag, 128);
          IF aTag.Tag = 'TAG' then aStream.Seek(-128,soFromEnd)
          Else aStream.Seek(0,soFromEnd);
        end else aStream.Seek(0,soFromEnd);
        FillReadWriteTag(FTag,ATag);
        aStream.WriteBuffer(aTag, 128);
        aStream.Free;
      end else FError:='File does not exist!';  IF FError<>'' then
      IF Assigned(OnError) then OnError(Self,FError);
    end; function TMP3Tag.GenreToByte(const strGenre:string):byte;
     var i:integer;
     begin
     GenreToByte:=$ff;
     for i:=0 to MAXGENRES do
            if strGenre= GENRES[i] then GenreToByte:=i;
     end;
     function TMP3Tag.ByteToGenre(const ID:BYTE):string;
     begin
     if ((ID>= 0) and (ID<=MAXGENRES)) then ByteToGenre:=GENRES[ID] else ByteToGenre:='';
     end;{-------------------------------------}constructor TMP3Tag.Create(AOwner: TComponent);
    begin
       inherited Create(AOwner);
       FError:='';
       FAutoSave:=True;    FFileName:='';
        FValid:=false;    FGenre:='';
        FError:='';    FAutoSave  :=false;
    end;destructor TMP3Tag.Destroy;
    begin
       inherited Destroy;
    end;{---------------------------}
    end.
      

  6.   

    在Open方法中,把最后一句改为:
    IF Not FValid then
      IF Assigned(OnError) then
        OnError(FError)
      else
        raise Exception.Create(FError);
      

  7.   

    谢谢大家!但是,怎样读出 WMA 等文件的信息呢?
      

  8.   

    这个方法我试过,有时候会读出一些乱码,不知怎么办?(——用winamp读取时很正常)