怎样获得wma文件信息。比特率,传输率,声道等等。请专家指点

解决方案 »

  1.   

    {
    示例代码:
    var
      WMA:TWMAfile;
    begin
    WMA:= TWMAfile.Create;
    WMA.ReadFromFile(Edit1.Text );
    Memo1.Lines.Clear ;
    Memo1.Lines.Add('ChannelMode:'+WMA.ChannelMode  );
    Memo1.Lines.Add('Title:'+WMA.Title  );
    Memo1.Lines.Add('Artist:'+WMA.Artist  );
    Memo1.Lines.Add('Album:'+WMA.Album  );
    Memo1.Lines.Add('Year:'+WMA.Year  );
    Memo1.Lines.Add('Genre:'+WMA.Genre  );
    Memo1.Lines.Add('Comment:'+WMA.Comment  );
    WMA.Free ;
    end;
    }WMA:------------------------------
    unit WMAfile;interfaceuses
      Classes, SysUtils;const
      { Channel modes }
      WMA_CM_UNKNOWN = 0;                                               { Unknown }
      WMA_CM_MONO = 1;                                                     { Mono }
      WMA_CM_STEREO = 2;                                                 { Stereo }  { Channel mode names }
      WMA_MODE: array [0..2] of string = ('Unknown', 'Mono', 'Stereo');type
      { Class TWMAfile }
      TWMAfile = class(TObject)
        private
          { Private declarations }
          FValid: Boolean;
          FFileSize: Integer;
          FChannelModeID: Byte;
          FSampleRate: Integer;
          FDuration: Double;
          FBitRate: Integer;
          FTitle: WideString;
          FArtist: WideString;
          FAlbum: WideString;
          FTrack: Integer;
          FYear: WideString;
          FGenre: WideString;
          FComment: WideString;
          procedure FResetData;
          function FGetChannelMode: string;
        public
          { Public declarations }
          constructor Create;                                     { Create object }
          function ReadFromFile(const FileName: string): Boolean;     { Load data }
          property Valid: Boolean read FValid;               { True if valid data }
          property FileSize: Integer read FFileSize;          { File size (bytes) }
          property ChannelModeID: Byte read FChannelModeID;   { Channel mode code }
          property ChannelMode: string read FGetChannelMode;  { Channel mode name }
          property SampleRate: Integer read FSampleRate;       { Sample rate (hz) }
          property Duration: Double read FDuration;          { Duration (seconds) }
          property BitRate: Integer read FBitRate;              { Bit rate (kbit) }
          property Title: WideString read FTitle;                    { Song title }
          property Artist: WideString read FArtist;                 { Artist name }
          property Album: WideString read FAlbum;                    { Album name }
          property Track: Integer read FTrack;                     { Track number }
          property Year: WideString read FYear;                            { Year }
          property Genre: WideString read FGenre;                    { Genre name }
          property Comment: WideString read FComment;                   { Comment }
      end;implementationconst
      { Object IDs }
      WMA_HEADER_ID =
        #48#38#178#117#142#102#207#17#166#217#0#170#0#98#206#108;
      WMA_FILE_PROPERTIES_ID =
        #161#220#171#140#71#169#207#17#142#228#0#192#12#32#83#101;
      WMA_STREAM_PROPERTIES_ID =
        #145#7#220#183#183#169#207#17#142#230#0#192#12#32#83#101;
      WMA_CONTENT_DESCRIPTION_ID =
        #51#38#178#117#142#102#207#17#166#217#0#170#0#98#206#108;
      WMA_EXTENDED_CONTENT_DESCRIPTION_ID =
        #64#164#208#210#7#227#210#17#151#240#0#160#201#94#168#80;  { Max. number of supported comment fields }
      WMA_FIELD_COUNT = 7;  { Names of supported comment fields }
      WMA_FIELD_NAME: array [1..WMA_FIELD_COUNT] of WideString =
        ('WM/TITLE', 'WM/AUTHOR', 'WM/ALBUMTITLE', 'WM/TRACK', 'WM/YEAR',
         'WM/GENRE', 'WM/DESCRIPTION');  { Max. number of characters in tag field }
      WMA_MAX_STRING_SIZE = 250;type
      { Object ID }
      ObjectID = array [1..16] of Char;  { Tag data }
      TagData = array [1..WMA_FIELD_COUNT] of WideString;  { File data - for internal use }
      FileData = record
        FileSize: Integer;                                    { File size (bytes) }
        MaxBitRate: Integer;                                { Max. bit rate (bps) }
        Channels: Word;                                      { Number of channels }
        SampleRate: Integer;                                   { Sample rate (hz) }
        ByteRate: Integer;                                            { Byte rate }
        Tag: TagData;                                       { WMA tag information }
      end;{ ********************* Auxiliary functions & procedures ******************** }function ReadFieldString(const Source: TStream; DataSize: Word): WideString;
    var
      Iterator, StringSize: Integer;
      FieldData: array [1..WMA_MAX_STRING_SIZE * 2] of Byte;
    begin
      { Read field data and convert to Unicode string }
      Result := '';
      StringSize := DataSize div 2;
      if StringSize > WMA_MAX_STRING_SIZE then StringSize := WMA_MAX_STRING_SIZE;
      Source.ReadBuffer(FieldData, StringSize * 2);
      Source.Seek(DataSize - StringSize * 2, soFromCurrent);
      for Iterator := 1 to StringSize do
        Result := Result +
          WideChar(FieldData[Iterator * 2 - 1] + (FieldData[Iterator * 2] shl 8));
    end;{ --------------------------------------------------------------------------- }procedure ReadTagStandard(const Source: TStream; var Tag: TagData);
    var
      Iterator: Integer;
      FieldSize: array [1..5] of Word;
      FieldValue: WideString;
    begin
      { Read standard tag data }
      Source.ReadBuffer(FieldSize, SizeOf(FieldSize));
      for Iterator := 1 to 5 do
        if FieldSize[Iterator] > 0 then
        begin
          { Read field value }
          FieldValue := ReadFieldString(Source, FieldSize[Iterator]);
          { Set corresponding tag field if supported }
          case Iterator of
            1: Tag[1] := FieldValue;
            2: Tag[2] := FieldValue;
            4: Tag[7] := FieldValue;
          end;
        end;
    end;{ --------------------------------------------------------------------------- }procedure ReadTagExtended(const Source: TStream; var Tag: TagData);
    var
      Iterator1, Iterator2, FieldCount, DataSize, DataType: Word;
      FieldName, FieldValue: WideString;
    begin
      { Read extended tag data }
      Source.ReadBuffer(FieldCount, SizeOf(FieldCount));
      for Iterator1 := 1 to FieldCount do
      begin
      

  2.   

    { Read field name }
        Source.ReadBuffer(DataSize, SizeOf(DataSize));
        FieldName := ReadFieldString(Source, DataSize);
        { Read value data type }
        Source.ReadBuffer(DataType, SizeOf(DataType));
        { Read field value only if string }
        if DataType = 0 then
        begin
          Source.ReadBuffer(DataSize, SizeOf(DataSize));
          FieldValue := ReadFieldString(Source, DataSize);
        end
        else
          Source.Seek(DataSize, soFromCurrent);
        { Set corresponding tag field if supported }
        for Iterator2 := 1 to WMA_FIELD_COUNT do
          if UpperCase(Trim(FieldName)) = WMA_FIELD_NAME[Iterator2] then
            Tag[Iterator2] := FieldValue;
      end;
    end;{ --------------------------------------------------------------------------- }procedure ReadObject(const ID: ObjectID; Source: TStream; var Data: FileData);
    begin
      { Read data from header object if supported }
      if ID = WMA_FILE_PROPERTIES_ID then
      begin
        { Read file properties }
        Source.Seek(80, soFromCurrent);
        Source.ReadBuffer(Data.MaxBitRate, SizeOf(Data.MaxBitRate));
      end;
      if ID = WMA_STREAM_PROPERTIES_ID then
      begin
        { Read stream properties }
        Source.Seek(60, soFromCurrent);
        Source.ReadBuffer(Data.Channels, SizeOf(Data.Channels));
        Source.ReadBuffer(Data.SampleRate, SizeOf(Data.SampleRate));
        Source.ReadBuffer(Data.ByteRate, SizeOf(Data.ByteRate));
      end;
      if ID = WMA_CONTENT_DESCRIPTION_ID then
      begin
        { Read standard tag data }
        Source.Seek(4, soFromCurrent);
        ReadTagStandard(Source, Data.Tag);
      end;
      if ID = WMA_EXTENDED_CONTENT_DESCRIPTION_ID then
      begin
        { Read extended tag data }
        Source.Seek(4, soFromCurrent);
        ReadTagExtended(Source, Data.Tag);
      end;
    end;{ --------------------------------------------------------------------------- }function ReadData(const FileName: string; var Data: FileData): Boolean;
    var
      Source: TFileStream;
      ID: ObjectID;
      Iterator, ObjectCount, ObjectSize, Position: Integer;
    begin
      { Read file data }
      try
        Source := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
        Data.FileSize := Source.Size;
        { Check for existing header }
        Source.ReadBuffer(ID, SizeOf(ID));
        if ID = WMA_HEADER_ID then
        begin
          Source.Seek(8, soFromCurrent);
          Source.ReadBuffer(ObjectCount, SizeOf(ObjectCount));
          Source.Seek(2, soFromCurrent);
          { Read all objects in header and get needed data }
          for Iterator := 1 to ObjectCount do
          begin
            Position := Source.Position;
            Source.ReadBuffer(ID, SizeOf(ID));
            Source.ReadBuffer(ObjectSize, SizeOf(ObjectSize));
            ReadObject(ID, Source, Data);
            Source.Seek(Position + ObjectSize, soFromBeginning);
          end;
        end;
        Source.Free;
        Result := true;
      except
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function IsValid(const Data: FileData): Boolean;
    begin
      { Check for data validity }
      Result :=
        (Data.MaxBitRate > 0) and (Data.MaxBitRate < 320000) and
        ((Data.Channels = WMA_CM_MONO) or (Data.Channels = WMA_CM_STEREO)) and
        (Data.SampleRate >= 8000) and (Data.SampleRate <= 96000) and
        (Data.ByteRate > 0) and (Data.ByteRate < 40000);
    end;{ --------------------------------------------------------------------------- }function ExtractTrack(const TrackString: WideString): Integer;
    var
      Value, Code: Integer;
    begin
      { Extract track from string }
      Result := 0;
      Val(TrackString, Value, Code);
      if Code = 0 then Result := Value;
    end;{ ********************** Private functions & procedures ********************* }procedure TWMAfile.FResetData;
    begin
      { Reset variables }
      FValid := false;
      FFileSize := 0;
      FChannelModeID := WMA_CM_UNKNOWN;
      FSampleRate := 0;
      FDuration := 0;
      FBitRate := 0;
      FTitle := '';
      FArtist := '';
      FAlbum := '';
      FTrack := 0;
      FYear := '';
      FGenre := '';
      FComment := '';
    end;{ --------------------------------------------------------------------------- }function TWMAfile.FGetChannelMode: string;
    begin
      { Get channel mode name }
      Result := WMA_MODE[FChannelModeID];
    end;{ ********************** Public functions & procedures ********************** }constructor TWMAfile.Create;
    begin
      { Create object }
      inherited;
      FResetData;
    end;{ --------------------------------------------------------------------------- }function TWMAfile.ReadFromFile(const FileName: string): Boolean;
    var
      Data: FileData;
    begin
      { Reset variables and load file data }
      FResetData;
      FillChar(Data, SizeOf(Data), 0);
      Result := ReadData(FileName, Data);
      { Process data if loaded and valid }
      if Result and IsValid(Data) then
      begin
        FValid := true;
        { Fill properties with loaded data }
        FFileSize := Data.FileSize;
        FChannelModeID := Data.Channels;
        FSampleRate := Data.SampleRate;
        FDuration := Data.FileSize * 8 / Data.MaxBitRate;
        FBitRate := Data.ByteRate * 8 div 1000;
        FTitle := Trim(Data.Tag[1]);
        FArtist := Trim(Data.Tag[2]);
        FAlbum := Trim(Data.Tag[3]);
        FTrack := ExtractTrack(Trim(Data.Tag[4]));
        FYear := Trim(Data.Tag[5]);
        FGenre := Trim(Data.Tag[6]);
        FComment := Trim(Data.Tag[7]);
      end;
    end;end.
      

  3.   

    { Read field name }
        Source.ReadBuffer(DataSize, SizeOf(DataSize));
        FieldName := ReadFieldString(Source, DataSize);
        { Read value data type }
        Source.ReadBuffer(DataType, SizeOf(DataType));
        { Read field value only if string }
        if DataType = 0 then
        begin
          Source.ReadBuffer(DataSize, SizeOf(DataSize));
          FieldValue := ReadFieldString(Source, DataSize);
        end
        else
          Source.Seek(DataSize, soFromCurrent);
        { Set corresponding tag field if supported }
        for Iterator2 := 1 to WMA_FIELD_COUNT do
          if UpperCase(Trim(FieldName)) = WMA_FIELD_NAME[Iterator2] then
            Tag[Iterator2] := FieldValue;
      end;
    end;{ --------------------------------------------------------------------------- }procedure ReadObject(const ID: ObjectID; Source: TStream; var Data: FileData);
    begin
      { Read data from header object if supported }
      if ID = WMA_FILE_PROPERTIES_ID then
      begin
        { Read file properties }
        Source.Seek(80, soFromCurrent);
        Source.ReadBuffer(Data.MaxBitRate, SizeOf(Data.MaxBitRate));
      end;
      if ID = WMA_STREAM_PROPERTIES_ID then
      begin
        { Read stream properties }
        Source.Seek(60, soFromCurrent);
        Source.ReadBuffer(Data.Channels, SizeOf(Data.Channels));
        Source.ReadBuffer(Data.SampleRate, SizeOf(Data.SampleRate));
        Source.ReadBuffer(Data.ByteRate, SizeOf(Data.ByteRate));
      end;
      if ID = WMA_CONTENT_DESCRIPTION_ID then
      begin
        { Read standard tag data }
        Source.Seek(4, soFromCurrent);
        ReadTagStandard(Source, Data.Tag);
      end;
      if ID = WMA_EXTENDED_CONTENT_DESCRIPTION_ID then
      begin
        { Read extended tag data }
        Source.Seek(4, soFromCurrent);
        ReadTagExtended(Source, Data.Tag);
      end;
    end;{ --------------------------------------------------------------------------- }function ReadData(const FileName: string; var Data: FileData): Boolean;
    var
      Source: TFileStream;
      ID: ObjectID;
      Iterator, ObjectCount, ObjectSize, Position: Integer;
    begin
      { Read file data }
      try
        Source := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
        Data.FileSize := Source.Size;
        { Check for existing header }
        Source.ReadBuffer(ID, SizeOf(ID));
        if ID = WMA_HEADER_ID then
        begin
          Source.Seek(8, soFromCurrent);
          Source.ReadBuffer(ObjectCount, SizeOf(ObjectCount));
          Source.Seek(2, soFromCurrent);
          { Read all objects in header and get needed data }
          for Iterator := 1 to ObjectCount do
          begin
            Position := Source.Position;
            Source.ReadBuffer(ID, SizeOf(ID));
            Source.ReadBuffer(ObjectSize, SizeOf(ObjectSize));
            ReadObject(ID, Source, Data);
            Source.Seek(Position + ObjectSize, soFromBeginning);
          end;
        end;
        Source.Free;
        Result := true;
      except
        Result := false;
      end;
    end;{ --------------------------------------------------------------------------- }function IsValid(const Data: FileData): Boolean;
    begin
      { Check for data validity }
      Result :=
        (Data.MaxBitRate > 0) and (Data.MaxBitRate < 320000) and
        ((Data.Channels = WMA_CM_MONO) or (Data.Channels = WMA_CM_STEREO)) and
        (Data.SampleRate >= 8000) and (Data.SampleRate <= 96000) and
        (Data.ByteRate > 0) and (Data.ByteRate < 40000);
    end;{ --------------------------------------------------------------------------- }function ExtractTrack(const TrackString: WideString): Integer;
    var
      Value, Code: Integer;
    begin
      { Extract track from string }
      Result := 0;
      Val(TrackString, Value, Code);
      if Code = 0 then Result := Value;
    end;{ ********************** Private functions & procedures ********************* }procedure TWMAfile.FResetData;
    begin
      { Reset variables }
      FValid := false;
      FFileSize := 0;
      FChannelModeID := WMA_CM_UNKNOWN;
      FSampleRate := 0;
      FDuration := 0;
      FBitRate := 0;
      FTitle := '';
      FArtist := '';
      FAlbum := '';
      FTrack := 0;
      FYear := '';
      FGenre := '';
      FComment := '';
    end;{ --------------------------------------------------------------------------- }function TWMAfile.FGetChannelMode: string;
    begin
      { Get channel mode name }
      Result := WMA_MODE[FChannelModeID];
    end;{ ********************** Public functions & procedures ********************** }constructor TWMAfile.Create;
    begin
      { Create object }
      inherited;
      FResetData;
    end;{ --------------------------------------------------------------------------- }function TWMAfile.ReadFromFile(const FileName: string): Boolean;
    var
      Data: FileData;
    begin
      { Reset variables and load file data }
      FResetData;
      FillChar(Data, SizeOf(Data), 0);
      Result := ReadData(FileName, Data);
      { Process data if loaded and valid }
      if Result and IsValid(Data) then
      begin
        FValid := true;
        { Fill properties with loaded data }
        FFileSize := Data.FileSize;
        FChannelModeID := Data.Channels;
        FSampleRate := Data.SampleRate;
        FDuration := Data.FileSize * 8 / Data.MaxBitRate;
        FBitRate := Data.ByteRate * 8 div 1000;
        FTitle := Trim(Data.Tag[1]);
        FArtist := Trim(Data.Tag[2]);
        FAlbum := Trim(Data.Tag[3]);
        FTrack := ExtractTrack(Trim(Data.Tag[4]));
        FYear := Trim(Data.Tag[5]);
        FGenre := Trim(Data.Tag[6]);
        FComment := Trim(Data.Tag[7]);
      end;
    end;end.
      

  4.   

    这么麻烦?DOWM这个http://swiss.torry.net/vcl/mmedia/audio/wmafile.zip
    就是了http://lysoft.7u7.net
      

  5.   

    fei19790920(饭桶的马甲(抵制日货)谢谢,我都感谢你