老问题,怎样实现像winamp一样取得媒体文件信息呢?如比特率,我头快爆啦! (50分)

  • 主题发起人 主题发起人 jog81
  • 开始时间 开始时间
J

jog81

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,想了好久也搞不定。主要是想取得文件的压缩频率等信息。如果谁有代码能完全实现这个功能,我将放出100分![?]
 
网上有完整的代码,估计有某个函数。
我曾经也有看到过类似音频处理的控件,更省事。
你搜索一下看看吧。
 
没有函数可以做到的.
你想提取什么格式的啊?MP3 WAV??还是MIDI啊?
去读文件头或文件尾一般都可以得到文件信息..
 
我想读Real文件的信息,哪位高手能帮忙?![?]
 
Real 也有几种的..ra rm rmvb rmj
不过大部头信息都在文件头..例如rmj就是这样的.
 
我也想知道 听课ing ....
 
{
----------------------------------------------------------
MAS-CompMaker was used to generate this code
MAS-CompMaker, 2000-2001?Mats Asplund
----------------------------------------------------------

Component Name: Tmp3Tag
Author: Slightly improved and redone from a class made by
Andrey V. Sorokin, into a component by Mats Asplund.
Creation: 2001-11-08
Version: 1.0
Description: A component for reading and writing mp3-tags.
Credit: Andrey V.Sorokin
Saint-Petersburg, Russia
anso@mail.ru
anso@usa.net
http://anso.da.ru
http://anso.virtualave.net
E-mail: masprod@telia.com
Site: http://go.to/masdp
Legal issues: Copyright(c) 1999,2000 by Andrey V.Sorokin.
All rights reserved 2001?by Mats Asplund.

Usage:
This software is provided 'as-is', without any express or
implied warranty. In no event will the author be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it
and redistribute it freely, subject to the following
restrictions:

1. The origin of this software must not be misrepresented,
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the productdo
cumentation would be appreciated but is
not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

4. If you decide to use this software in any of your applications.
Send me an EMail and tell me about it.

Quick Reference:

Tmp3Tag inherits from TComponent.

Key-Properties:

TagPresent: True if loaded tag seems to be OK.

TagModified: True if anything changed.

v1Tag: True if ID3v1, false if ID3v1.1

Title: Music title

Artist: Performer

Year: Year as 4-chars string.

Album: Album title

Track: Track number (only if not v1)

Comment: Comment

GenreID: Genre ID (see fID3Genres which contains genres list as
TStrings)

Genre: Genre as string


Key-Methods:

LoadTag: Load tag from ABuf (max ABufSz)

LoadTagFromStream: Find ID3tag in AStream (max AStreamSz bytes from current
position) and Load it. If success then
returns offset to
tag, else
-1.

LoadTagFromFile: Load ID3Tag from file AFileName

SaveTag: Write tag into ABuf (max ABufSz bytes), clear Modified.

SaveTagToStream: Write tag ito current position of AStream, clear Modified.

SaveTagToFile: Add/Update tag in file AFileName, clear Modified.

DeleteTagFromFile: Delete tag from file AFileName (if it exists).

--------------------------------------------------------------------------------
}
unit mp3Tag;

interface

uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls;

type

Tmp3Tag = class(TComponent)
private
fAbout: string;
fModified: Boolean;
fOk: Boolean;
fv1: Boolean;
fTrack: Integer;
fGenreID: Integer;
fArtist: string;
FTitle: string;
fAlbum: string;
fYear: string;
fComment: string;
fGenre: string;
fID3Genres: TStringList;
procedure SetCop(Value: string);
procedure SetGenreID(AGenreID: Integer);
procedure SetTrack(ATrack: Integer);
procedure Setv1(b: Boolean);
procedure SetField(AIdx: Integer;
S: string);
procedure Reset;
procedure SetGenre(const Value: string);
procedure SetID3Genres(const Value: TStringList);
public
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
procedure LoadTag(const ABuf;
ABufSz: Integer);
procedure LoadTagFromStream(AStream: TStream;
AStreamSz: Integer);
procedure LoadTagFromFile(const aFileName: string);
procedure SaveTag(var ABuf;
ABufSz: Integer);
procedure SaveTagToStream(AStream: TStream);
procedure SaveTagToFile(const aFileName: string);
procedure DeleteTagFromFile(const aFileName: string);
published
property TagPresent: Boolean read fOk write fOk;
property TagModified: Boolean read fModified;
property v1Tag: Boolean read fv1 write Setv1;
property Title: string index 1 read FTitle write SetField;
property Artist: string index 2 read fArtist write SetField;
property Year: string index 3 read fYear write SetField;
property Album: string index 4 read fAlbum write SetField;
property Track: Integer read fTrack write SetTrack;
// ID3v1.1 only
property Comment: string index 5 read fComment write SetField;
property GenreID: Integer read fGenreID write SetGenreID;
property Genre: string read fGenre write SetGenre;
property Genres: TStringList read fID3Genres write SetID3Genres;
property About: string read fAbout write SetCop;
end;


procedure Register;

implementation

const
ID3v1TagLen = 128;

procedure Register;
begin

RegisterComponents('MAs Prod.', [Tmp3Tag]);
end;


constructor Tmp3Tag.Create(AOwner: TComponent);
begin

inherited Create(AOwner);
fID3Genres:= TStringList.Create;
fID3Genres.Duplicates:= dupAccept;
fID3Genres.Sorted:= false;
fID3Genres.CommaText:=
'"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","Psychedelic","Rave","Showtunes","Trailer","Lo-Fi",'
+ '"Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical",'
+ '"Rock &
Roll","Hard Rock",' // 79 standard genres
+ '"Folk","Folk/Rock","National Folk","Swing","Fast Fusion",'
+ '"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",'
+ '"Ballad","Power Ballad","Rhythmic Soul","Freestyle",'
+ '"Duet","Punk Rock","Drum Solo","Acapella","Euro-House",'
+ '"Dance Hall", "Goa", "Drum &
Bass", "Club-House", "Hardcore",'
+ '"Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat",'
+ '"Christian Gangs", "Heavy Metal", "Black Metal", "Crossover",'
+ '"Contemporary Ch?", "Cristian Rock", "Merengue", "Salsa",'
+ '"Thrash Metal", "Anime", "JPop", "Synthpop", ""';
// 0 .. 93h

fGenreId:= 0;
fGenre:= 'Blues';
fAbout:= 'Version 1.0, 2001?Andrey V.Sorokin &
Mats Asplund';
end;


procedure Tmp3Tag.DeleteTagFromFile(const aFileName: string);
var
F: TStream;
S: string;
begin

F:= TFileStream.Create(aFileName, fmOpenReadWrite or fmShareExclusive);
try
if F.Size >= ID3v1TagLen then

begin

F.Position:= F.Size - ID3v1TagLen;
SetString(S, nil, 3);
F.ReadBuffer(S[1], 3);
if S = 'TAG' then

begin

F.Size:= F.Size - ID3v1TagLen;
end;

end;

finally F.Free;
end;

end;

{ of procedure TID3v1Tag.DeleteFromFile }

destructor Tmp3Tag.Destroy;
begin

inherited Destroy;
end;


procedure Tmp3Tag.LoadTag(const ABuf;
ABufSz: Integer);
var
b: array[0..ID3v1TagLen - 1] of Byte absolute ABuf;
GenreIdx, i: Integer;
function BufStr(APos, ALen: Integer): string;
begin

SetString(Result, nil, ALen);
Move(b[APos], Result[1], ALen);
if Pos(#0, Result) > 0 then

Result:= Copy(Result, 1, Pos(#0, Result) - 1);
Result:= TrimRight(Result);
end;

begin

// save genres IDs for genres list resorting ability
Reset;
for i:= 0 to fID3Genres.Count - 1
do
fID3Genres.Objects:= TObject(i);

fOk:= false;
fModified:= false;
if ABufSz < ID3v1TagLen then
Exit;
if BufStr(0, 3) = 'TAG' then

begin

fOk:= true;
FTitle:= BufStr(3, 30);
fArtist:= BufStr(33, 30);
fAlbum:= BufStr(63, 30);
fYear:= BufStr(93, 4);
fComment:= BufStr(97, 30);
if (b[97 + 28] = 0) and (b[97 + 29] <> 0) then

begin

fv1:= false;
fTrack:= b[97 + 29];
end
else

begin

fv1:= true;
fTrack:= 0;
end;

fGenreID:= b[127];
GenreIdx:= fID3Genres.IndexOfObject(TObject(fGenreID));
if GenreIdx >= 0 then
fGenre:= fID3Genres[GenreIdx]
else
fGenre:= '';
end;

end;

{ of procedure TID3v1Tag.Load }

procedure Tmp3Tag.LoadTagFromFile(const aFileName: string);
var
F: TStream;
begin

F:= TFileStream.Create(aFileName, fmOpenRead or fmShareDenyNone);
try
LoadTagFromStream(F, F.Size);
finally F.Free;
end;

end;

{ of procedure TID3v1Tag.LoadFromFile }

procedure Tmp3Tag.LoadTagFromStream(AStream: TStream;
AStreamSz: Integer);
var
Buf: array[0..ID3v1TagLen - 1] of Byte;
begin

Reset;
if AStreamSz >= ID3v1TagLen then

begin

AStream.Position:= AStream.Position + AStreamSz - ID3v1TagLen;
AStream.ReadBuffer(Buf, ID3v1TagLen);
LoadTag(Buf, ID3v1TagLen);
end
else
fOk:= false;
end;

{ of procedure TID3v1Tag.LoadFromStream }

procedure Tmp3Tag.Reset;
begin

fGenreID:= 94;
{empty string}
fArtist:= '';
FTitle:= '';
fAlbum:= '';
fYear:= '';
fComment:= '';
fGenre:= '';
end;


procedure Tmp3Tag.SaveTag(var ABuf;
ABufSz: Integer);
var
b: array[0..ID3v1TagLen - 1] of Byte absolute ABuf;
procedure StrBuf(APos, ALen: Integer;
const AStr: string);
var
Len: Integer;
begin

Len:= Length(AStr);
if Len > ALen then

Len:= ALen;
Move(AStr[1], b[APos], Len);
if Len < ALen then

FillChar(b[APos + Len], ALen - Len, $20);
end;

begin

if ABufSz < ID3v1TagLen then

raise Exception.Create('TID3v1Tag.Save: Buffer too small');
// fOk ?!!
StrBuf(0, 3, 'TAG');
StrBuf(3, 30, FTitle);
StrBuf(33, 30, fArtist);
StrBuf(63, 30, fAlbum);
StrBuf(93, 4, fYear);
StrBuf(97, 30, fComment);
if not fv1 then

begin

b[97 + 28]:= 0;
b[97 + 29]:= fTrack;
end;

b[127]:= fGenreID;
fModified:= false;
end;

{ of procedure TID3v1Tag.Save }

procedure Tmp3Tag.SaveTagToFile(const aFileName: string);
var
F: TStream;
S: string;
begin

F:= TFileStream.Create(aFileName, fmOpenReadWrite or fmShareDenyNone);
try
if F.Size >= ID3v1TagLen then

begin

F.Position:= F.Size - ID3v1TagLen;
SetString(S, nil, 3);
F.ReadBuffer(S[1], 3);
end
else
S:= 'NON';
if S = 'TAG' then

F.Position:= F.Size - ID3v1TagLen
else
F.Position:= F.Size;
SaveTagToStream(F);
finally F.Free;
end;

end;

{ of procedure TID3v1Tag.SaveToFile }

procedure Tmp3Tag.SaveTagToStream(AStream: TStream);
var
Buf: array[0..ID3v1TagLen - 1] of Byte;
begin

SaveTag(Buf, ID3v1TagLen);
AStream.WriteBuffer(Buf, ID3v1TagLen);
end;

{ of procedure TID3v1Tag.SaveToStream }

procedure Tmp3Tag.SetCop(Value: string);
begin

Exit;
end;


procedure Tmp3Tag.SetField(AIdx: Integer;
S: string);
procedure SetIt(const ANewValue: string;
AMaxLen: Integer;
var AField: string);
begin

if Copy(ANewValue, 1, AMaxLen) <> AField then

begin

AField:= Copy(ANewValue, 1, AMaxLen);
fModified:= true;
end;

end;

begin

case AIdx of
1: SetIt(S, 30, FTitle);
2: SetIt(S, 30, fArtist);
3: SetIt(S, 4, fYear);
4: SetIt(S, 30, fAlbum);
5:
if fv1 then

SetIt(S, 30, fComment)
else

SetIt(S, 28, fComment);
end;

end;

{ of procedure TID3v1Tag.SetTitle }

procedure Tmp3Tag.SetGenre(const Value: string);
begin

if Value <> fGenre then

begin

fGenre:= Value;
fGenreID:= Genres.IndexOf(fGenre);
fModified:= true;
end;

end;


procedure Tmp3Tag.SetGenreID(AGenreID: Integer);
begin

if fGenreID <> AGenreID then

begin

fGenreID:= AGenreID;
fGenre:= Genres[fGenreID];
fModified:= true;
end;

end;

{ of procedure TID3v1Tag.SetGenreID}

procedure Tmp3Tag.SetID3Genres(const Value: TStringList);
begin

Exit;
// List should be read-only
end;


procedure Tmp3Tag.SetTrack(ATrack: Integer);
begin

if fTrack <> ATrack then

begin

fTrack:= ATrack;
fv1:= fTrack = 0;
fModified:= true;
end;

end;

{ of procedure TID3v1Tag.SetTrack }

procedure Tmp3Tag.Setv1(b: Boolean);
begin

if fv1 <> b then

begin

fv1:= b;
fModified:= true;
end;

end;

{ procedure TID3v1Tag.Setv1 }

end.



{ *************************************************************************** }
{ }
{ Audio Tools Library (Freeware) }
{ Class TWMAfile - for extracting information from WMA file header }
{ }
{ Copyright (c) 2001,2002 by Jurgen Faul }
{ E-mail: jfaul@gmx.de }
{ http://jfaul.de/atl }
{ }
{ Version 1.0 (29 April 2002) }
{ - File info: file size, channel mode, sample rate, duration, bit rate }
{ - WMA tag info: title, artist, album, track, year, genre, comment }
{ }
{ *************************************************************************** }

unit WMAfile;

interface

uses
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:do
uble;
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:do
uble 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;


implementation

const
{ 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 &amp;
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 StringSizedo

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 5do

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 FieldCountdo

begin

{ 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_COUNTdo

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 ObjectCountdo

begin

Position := Source.Position;
Source.ReadBuffer(ID, SizeOf(ID));
Source.ReadBuffer(ObjectSize, SizeOf(ObjectSize));
ReadObject(ID, Source, Data);
Source.Seek(Position + ObjectSize, soFrombegin
ning);
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 &amp;
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 &amp;
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.

 
每一个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);
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部