線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1381
推到 Plurk!
推到 Facebook!

mp3文件的时间?

尚未結案
coldcoffee
一般會員


發表:60
回覆:22
積分:16
註冊:2003-05-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-01-09 14:25:33 IP:61.51.xxx.xxx 未訂閱
我知道MP3文件的大小,怎么能转换成播放时间的长短?
jackalan168
一般會員


發表:6
回覆:12
積分:8
註冊:2004-01-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-01-09 17:20:24 IP:218.2.xxx.xxx 未訂閱
MP3大小不是根据大小算的,请看下面范例:    这是个很好的单元,可以读取MP3文件的ID3 V1,V2的信息,文件长度,采样、时间等。    如果需要知道其他用法MAIL找我。    =======================READ TIME========================== Var Strtime : string;    if not MusicInfo.ReadFromFile(filename) then    strTime :='00:00' else    strTime := FillAboutZero(inttostr(round(MusicInfo.Duration) div 60),2) +':'+FillAboutZero(inttostr(round(MusicInfo.Duration) mod 60),2);    =============单元==============    unit MPEGaudio;    interface    uses   Classes, SysUtils, ID3v1, ID3v2;    const   { Table for bit rates }   MPEG_BIT_RATE: array [0..3, 0..3, 0..15] of Word =     (     { For MPEG 2.5 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0)),     { Reserved }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)),     { For MPEG 2 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0)),     { For MPEG 1 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0),     (0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0))     );      { Sample rate codes }   MPEG_SAMPLE_RATE_LEVEL_3 = 0;                                     { Level 3 }   MPEG_SAMPLE_RATE_LEVEL_2 = 1;                                     { Level 2 }   MPEG_SAMPLE_RATE_LEVEL_1 = 2;                                     { Level 1 }   MPEG_SAMPLE_RATE_UNKNOWN = 3;                               { Unknown value }      { Table for sample rates }   MPEG_SAMPLE_RATE: array [0..3, 0..3] of Word =     (     (11025, 12000, 8000, 0),                                   { For MPEG 2.5 }     (0, 0, 0, 0),                                                  { Reserved }     (22050, 24000, 16000, 0),                                    { For MPEG 2 }     (44100, 48000, 32000, 0)                                     { For MPEG 1 }     );      { VBR header ID for Xing/FhG }   VBR_ID_XING = 'Xing';                                         { Xing VBR ID }   VBR_ID_FHG = 'VBRI';                                           { FhG VBR ID }      { MPEG version codes }   MPEG_VERSION_2_5 = 0;                                            { MPEG 2.5 }   MPEG_VERSION_UNKNOWN = 1;                                 { Unknown version }   MPEG_VERSION_2 = 2;                                                { MPEG 2 }   MPEG_VERSION_1 = 3;                                                { MPEG 1 }      { MPEG version names }   MPEG_VERSION: array [0..3] of string =     ('MPEG 2.5', 'MPEG ?', 'MPEG 2', 'MPEG 1');      { MPEG layer codes }   MPEG_LAYER_UNKNOWN = 0;                                     { Unknown layer }   MPEG_LAYER_III = 1;                                             { Layer III }   MPEG_LAYER_II = 2;                                               { Layer II }   MPEG_LAYER_I = 3;                                                 { Layer I }      { MPEG layer names }   MPEG_LAYER: array [0..3] of string =     ('Layer ?', 'Layer III', 'Layer II', 'Layer I');      { Channel mode codes }   MPEG_CM_STEREO = 0;                                                { Stereo }   MPEG_CM_JOINT_STEREO = 1;                                    { Joint Stereo }   MPEG_CM_DUAL_CHANNEL = 2;                                    { Dual Channel }   MPEG_CM_MONO = 3;                                                    { Mono }   MPEG_CM_UNKNOWN = 4;                                         { Unknown mode }      { Channel mode names }   MPEG_CM_MODE: array [0..4] of string =     ('Stereo', 'Joint Stereo', 'Dual Channel', 'Mono', 'Unknown');      { Extension mode codes (for Joint Stereo) }   MPEG_CM_EXTENSION_OFF = 0;                        { IS and MS modes set off }   MPEG_CM_EXTENSION_IS = 1;                             { Only IS mode set on }   MPEG_CM_EXTENSION_MS = 2;                             { Only MS mode set on }   MPEG_CM_EXTENSION_ON = 3;                          { IS and MS modes set on }   MPEG_CM_EXTENSION_UNKNOWN = 4;                     { Unknown extension mode }      { Emphasis mode codes }   MPEG_EMPHASIS_NONE = 0;                                              { None }   MPEG_EMPHASIS_5015 = 1;                                          { 50/15 ms }   MPEG_EMPHASIS_UNKNOWN = 2;                               { Unknown emphasis }   MPEG_EMPHASIS_CCIT = 3;                                         { CCIT J.17 }      { Emphasis names }   MPEG_EMPHASIS: array [0..3] of string =     ('None', '50/15 ms', 'Unknown', 'CCIT J.17');      { Encoder codes }   MPEG_ENCODER_UNKNOWN = 0;                                 { Unknown encoder }   MPEG_ENCODER_XING = 1;                                               { Xing }   MPEG_ENCODER_FHG = 2;                                                 { FhG }   MPEG_ENCODER_LAME = 3;                                               { LAME }   MPEG_ENCODER_BLADE = 4;                                             { Blade }   MPEG_ENCODER_GOGO = 5;                                               { GoGo }   MPEG_ENCODER_SHINE = 6;                                             { Shine }   MPEG_ENCODER_QDESIGN = 7;                                         { QDesign }      { Encoder names }   MPEG_ENCODER: array [0..7] of string =     ('Unknown', 'Xing', 'FhG', 'LAME', 'Blade', 'GoGo', 'Shine', 'QDesign');    type   { Xing/FhG VBR header data }   VBRData = record     Found: Boolean;                                { True if VBR header found }     ID: array [1..4] of Char;                   { Header ID: "Xing" or "VBRI" }     Frames: Integer;                                 { Total number of frames }     Bytes: Integer;                                   { Total number of bytes }     Scale: Byte;                                         { VBR scale (1..100) }     VendorID: string;                                { Vendor ID (if present) }   end;      { MPEG frame header data}   FrameData = record     Found: Boolean;                                     { True if frame found }     Position: Integer;                           { Frame position in the file }     Size: Word;                                          { Frame size (bytes) }     Xing: Boolean;                                     { True if Xing encoder }     Data: array [1..4] of Byte;                 { The whole frame header data }     VersionID: Byte;                                        { MPEG version ID }     LayerID: Byte;                                            { MPEG layer ID }     ProtectionBit: Boolean;                        { True if protected by CRC }     BitRateID: Word;                                            { Bit rate ID }     SampleRateID: Word;                                      { Sample rate ID }     PaddingBit: Boolean;                               { True if frame padded }     PrivateBit: Boolean;                                  { Extra information }     ModeID: Byte;                                           { Channel mode ID }     ModeExtensionID: Byte;             { Mode extension ID (for Joint Stereo) }     CopyrightBit: Boolean;                        { True if audio copyrighted }     OriginalBit: Boolean;                            { True if original media }     EmphasisID: Byte;                                           { Emphasis ID }   end;      { Class TMPEGaudio }   TMPEGaudio = class(TObject)     private       { Private declarations }       FFileLength: Integer;       FVendorID: string;       FVBR: VBRData;       FFrame: FrameData;       FID3v1: TID3v1;       FID3v2: TID3v2;       procedure FResetData;       function FGetVersion: string;       function FGetLayer: string;       function FGetBitRate: Word;       function FGetSampleRate: Word;       function FGetChannelMode: string;       function FGetEmphasis: string;       function FGetFrames: Integer;       function FGetDuration: Double;       function FGetVBREncoderID: Byte;       function FGetCBREncoderID: Byte;       function FGetEncoderID: Byte;       function FGetEncoder: string;       function FGetValid: Boolean;     public       { Public declarations }       constructor Create;                                     { Create object }       destructor Destroy; override;                          { Destroy object }       function ReadFromFile(const FileName: string): Boolean;     { Load data }       property FileLength: Integer read FFileLength;    { File length (bytes) }       property VBR: VBRData read FVBR;                      { VBR header data }       property Frame: FrameData read FFrame;              { Frame header data }       property ID3v1: TID3v1 read FID3v1;                    { ID3v1 tag data }       property ID3v2: TID3v2 read FID3v2;                    { ID3v2 tag data }       property Version: string read FGetVersion;          { MPEG version name }       property Layer: string read FGetLayer;                { MPEG layer name }       property BitRate: Word read FGetBitRate;            { Bit rate (kbit/s) }       property SampleRate: Word read FGetSampleRate;       { Sample rate (hz) }       property ChannelMode: string read FGetChannelMode;  { Channel mode name }       property Emphasis: string read FGetEmphasis;            { Emphasis name }       property Frames: Integer read FGetFrames;      { Total number of frames }       property Duration: Double read FGetDuration;      { Song duration (sec) }       property EncoderID: Byte read FGetEncoderID;       { Guessed encoder ID }       property Encoder: string read FGetEncoder;       { Guessed encoder name }       property Valid: Boolean read FGetValid;       { True if MPEG file valid }   end;    implementation    const   { Limitation constants }   MAX_MPEG_FRAME_LENGTH = 1729;                      { Max. MPEG frame length }   MIN_MPEG_BIT_RATE = 8;                                { Min. bit rate value }   MAX_MPEG_BIT_RATE = 448;                              { Max. bit rate value }   MIN_ALLOWED_DURATION = 0.1;                      { Min. song duration value }      { VBR Vendor ID strings }   VENDOR_ID_LAME = 'LAME';                                         { For LAME }   VENDOR_ID_GOGO_NEW = 'GOGO';                               { For GoGo (New) }   VENDOR_ID_GOGO_OLD = 'MPGE';                               { For GoGo (Old) }    { ********************* Auxiliary functions & procedures ******************** }    function IsFrameHeader(const HeaderData: array of Byte): Boolean; begin   { Check for valid frame header }   if ((HeaderData[0] and $FF) <> $FF) or     ((HeaderData[1] and $E0) <> $E0) or     (((HeaderData[1] shr 3) and 3) = 1) or     (((HeaderData[1] shr 1) and 3) = 0) or     ((HeaderData[2] and $F0) = $F0) or     ((HeaderData[2] and $F0) = 0) or     (((HeaderData[2] shr 2) and 3) = 3) or     ((HeaderData[3] and 3) = 2) then     Result := false   else     Result := true; end;    { --------------------------------------------------------------------------- }    procedure DecodeHeader(const HeaderData: array of Byte; var Frame: FrameData); begin   { Decode frame header data }   Move(HeaderData, Frame.Data, SizeOf(Frame.Data));   Frame.VersionID := (HeaderData[1] shr 3) and 3;   Frame.LayerID := (HeaderData[1] shr 1) and 3;   Frame.ProtectionBit := (HeaderData[1] and 1) <> 1;   Frame.BitRateID := HeaderData[2] shr 4;   Frame.SampleRateID := (HeaderData[2] shr 2) and 3;   Frame.PaddingBit := ((HeaderData[2] shr 1) and 1) = 1;   Frame.PrivateBit := (HeaderData[2] and 1) = 1;   Frame.ModeID := (HeaderData[3] shr 6) and 3;   Frame.ModeExtensionID := (HeaderData[3] shr 4) and 3;   Frame.CopyrightBit := ((HeaderData[3] shr 3) and 1) = 1;   Frame.OriginalBit := ((HeaderData[3] shr 2) and 1) = 1;   Frame.EmphasisID := HeaderData[3] and 3; end;    { --------------------------------------------------------------------------- }    function ValidFrameAt(const Index: Word; Data: array of Byte): Boolean; var   HeaderData: array [1..4] of Byte; begin   { Check for frame at given position }   HeaderData[1] := Data[Index];   HeaderData[2] := Data[Index + 1];   HeaderData[3] := Data[Index + 2];   HeaderData[4] := Data[Index + 3];   if IsFrameHeader(HeaderData) then Result := true   else Result := false; end;    { --------------------------------------------------------------------------- }    function GetCoefficient(const Frame: FrameData): Byte; begin   { Get frame size coefficient }   if Frame.VersionID = MPEG_VERSION_1 then     if Frame.LayerID = MPEG_LAYER_I then Result := 48     else Result := 144   else     if Frame.LayerID = MPEG_LAYER_I then Result := 24     else if Frame.LayerID = MPEG_LAYER_II then Result := 144     else Result := 72; end;    { --------------------------------------------------------------------------- }    function GetBitRate(const Frame: FrameData): Word; begin   { Get bit rate }   Result := MPEG_BIT_RATE[Frame.VersionID, Frame.LayerID, Frame.BitRateID]; end;    { --------------------------------------------------------------------------- }    function GetSampleRate(const Frame: FrameData): Word; begin   { Get sample rate }   Result := MPEG_SAMPLE_RATE[Frame.VersionID, Frame.SampleRateID]; end;    { --------------------------------------------------------------------------- }    function GetPadding(const Frame: FrameData): Byte; begin   { Get frame padding }   if Frame.PaddingBit then     if Frame.LayerID = MPEG_LAYER_I then Result := 4     else Result := 1   else Result := 0; end;    { --------------------------------------------------------------------------- }    function GetFrameLength(const Frame: FrameData): Word; var   Coefficient, BitRate, SampleRate, Padding: Word; begin   { Calculate MPEG frame length }   Coefficient := GetCoefficient(Frame);   BitRate := GetBitRate(Frame);   SampleRate := GetSampleRate(Frame);   Padding := GetPadding(Frame);   Result := Trunc(Coefficient * BitRate * 1000 / SampleRate) + Padding; end;    { --------------------------------------------------------------------------- }    function IsXing(const Index: Word; Data: array of Byte): Boolean; begin   { Get true if Xing encoder }   Result :=     (Data[Index] = 0) and     (Data[Index + 1] = 0) and     (Data[Index + 2] = 0) and     (Data[Index + 3] = 0) and     (Data[Index + 4] = 0) and     (Data[Index + 5] = 0); end;    { --------------------------------------------------------------------------- }    function GetXingInfo(const Index: Word; Data: array of Byte): VBRData; begin   { Extract Xing VBR info at given position }   FillChar(Result, SizeOf(Result), 0);   Result.Found := true;   Result.ID := VBR_ID_XING;   Result.Frames :=     Data[Index + 8] * $1000000 +     Data[Index + 9] * $10000 +     Data[Index + 10] * $100 +     Data[Index + 11];   Result.Bytes :=     Data[Index + 12] * $1000000 +     Data[Index + 13] * $10000 +     Data[Index + 14] * $100 +     Data[Index + 15];   Result.Scale := Data[Index + 119];   { Vendor ID can be not present }   Result.VendorID :=     Chr(Data[Index + 120]) +     Chr(Data[Index + 121]) +     Chr(Data[Index + 122]) +     Chr(Data[Index + 123]) +     Chr(Data[Index + 124]) +     Chr(Data[Index + 125]) +     Chr(Data[Index + 126]) +     Chr(Data[Index + 127]); end;    { --------------------------------------------------------------------------- }    function GetFhGInfo(const Index: Word; Data: array of Byte): VBRData; begin   { Extract FhG VBR info at given position }   FillChar(Result, SizeOf(Result), 0);   Result.Found := true;   Result.ID := VBR_ID_FHG;   Result.Scale := Data[Index + 9];   Result.Bytes :=     Data[Index + 10] * $1000000 +     Data[Index + 11] * $10000 +     Data[Index + 12] * $100 +     Data[Index + 13];   Result.Frames :=     Data[Index + 14] * $1000000 +     Data[Index + 15] * $10000 +     Data[Index + 16] * $100 +     Data[Index + 17]; end;    { --------------------------------------------------------------------------- }    function FindVBR(const Index: Word; Data: array of Byte): VBRData; begin   { Check for VBR header at given position }   FillChar(Result, SizeOf(Result), 0);   if Chr(Data[Index]) +     Chr(Data[Index + 1]) +     Chr(Data[Index + 2]) +     Chr(Data[Index + 3]) = VBR_ID_XING then Result := GetXingInfo(Index, Data);   if Chr(Data[Index]) +     Chr(Data[Index + 1]) +     Chr(Data[Index + 2]) +     Chr(Data[Index + 3]) = VBR_ID_FHG then Result := GetFhGInfo(Index, Data); end;    { --------------------------------------------------------------------------- }    function GetVBRDeviation(const Frame: FrameData): Byte; begin   { Calculate VBR deviation }   if Frame.VersionID = MPEG_VERSION_1 then     if Frame.ModeID <> MPEG_CM_MONO then Result := 36     else Result := 21   else     if Frame.ModeID <> MPEG_CM_MONO then Result := 21     else Result := 13; end;    { --------------------------------------------------------------------------- }    function FindFrame(const Data: array of Byte; var VBR: VBRData): FrameData; var   HeaderData: array [1..4] of Byte;   Iterator: Integer; begin   { Search for valid frame }   FillChar(Result, SizeOf(Result), 0);   Move(Data, HeaderData, SizeOf(HeaderData));   for Iterator := 0 to SizeOf(Data) - MAX_MPEG_FRAME_LENGTH do   begin     { Decode data if frame header found }     if IsFrameHeader(HeaderData) then     begin       DecodeHeader(HeaderData, Result);       { Check for next frame and try to find VBR header }       if ValidFrameAt(Iterator + GetFrameLength(Result), Data) then       begin         Result.Found := true;         Result.Position := Iterator;         Result.Size := GetFrameLength(Result);         Result.Xing := IsXing(Iterator + SizeOf(HeaderData), Data);         VBR := FindVBR(Iterator + GetVBRDeviation(Result), Data);         break;       end;     end;     { Prepare next data block }     HeaderData[1] := HeaderData[2];     HeaderData[2] := HeaderData[3];     HeaderData[3] := HeaderData[4];     HeaderData[4] := Data[Iterator + SizeOf(HeaderData)];   end; end;    { --------------------------------------------------------------------------- }    function FindVendorID(const Data: array of Byte; Size: Word): string; var   Iterator: Integer;   VendorID: string; begin   { Search for vendor ID }   Result := '';   if (SizeOf(Data) - Size - 8) < 0 then Size := SizeOf(Data) - 8;   for Iterator := 0 to Size do   begin     VendorID :=       Chr(Data[SizeOf(Data) - Iterator - 8]) +       Chr(Data[SizeOf(Data) - Iterator - 7]) +       Chr(Data[SizeOf(Data) - Iterator - 6]) +       Chr(Data[SizeOf(Data) - Iterator - 5]);     if VendorID = VENDOR_ID_LAME then     begin       Result := VendorID +         Chr(Data[SizeOf(Data) - Iterator - 4]) +         Chr(Data[SizeOf(Data) - Iterator - 3]) +         Chr(Data[SizeOf(Data) - Iterator - 2]) +         Chr(Data[SizeOf(Data) - Iterator - 1]);       break;     end;     if VendorID = VENDOR_ID_GOGO_NEW then     begin       Result := VendorID;       break;     end;   end; end;    { ********************** Private functions & procedures ********************* }    procedure TMPEGaudio.FResetData; begin   { Reset all variables } try   FFileLength := 0;   FVendorID := '';   FillChar(FVBR, SizeOf(FVBR), 0);   FillChar(FFrame, SizeOf(FFrame), 0);   FFrame.VersionID := MPEG_VERSION_UNKNOWN;   FFrame.SampleRateID := MPEG_SAMPLE_RATE_UNKNOWN;   FFrame.ModeID := MPEG_CM_UNKNOWN;   FFrame.ModeExtensionID := MPEG_CM_EXTENSION_UNKNOWN;   FFrame.EmphasisID := MPEG_EMPHASIS_UNKNOWN;   FID3v1.ResetData;   FID3v2.ResetData; except   //not end; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetVersion: string; begin   { Get MPEG version name }   Result := MPEG_VERSION[FFrame.VersionID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetLayer: string; begin   { Get MPEG layer name }   Result := MPEG_LAYER[FFrame.LayerID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetBitRate: Word; begin   { Get bit rate, calculate average bit rate if VBR header found }   if (FVBR.Found) and (FVBR.Frames > 0) then     Result := Round((FVBR.Bytes / FVBR.Frames - GetPadding(FFrame)) *       GetSampleRate(FFrame) / GetCoefficient(FFrame) / 1000)   else     Result := GetBitRate(FFrame); end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetSampleRate: Word; begin   { Get sample rate }   Result := GetSampleRate(FFrame); end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetChannelMode: string; begin   { Get channel mode name }   Result := MPEG_CM_MODE[FFrame.ModeID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEmphasis: string; begin   { Get emphasis name }   Result := MPEG_EMPHASIS[FFrame.EmphasisID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetFrames: Integer; var   MPEGSize: Integer; begin   { Get total number of frames, calculate if VBR header not found }   if FVBR.Found then     Result := FVBR.Frames   else   begin     if FID3v1.Exists then MPEGSize := FFileLength - FID3v2.Size - 128     else MPEGSize := FFileLength - FID3v2.Size;     Result := (MPEGSize - FFrame.Position) div GetFrameLength(FFrame);   end; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetDuration: Double; var   MPEGSize: Integer; begin   { Calculate song duration }   if FFrame.Found then     if (FVBR.Found) and (FVBR.Frames > 0) then       Result := FVBR.Frames * GetCoefficient(FFrame) * 8 /         GetSampleRate(FFrame)     else     begin       if FID3v1.Exists then MPEGSize := FFileLength - FID3v2.Size - 128       else MPEGSize := FFileLength - FID3v2.Size;       Result := (MPEGSize - FFrame.Position) / GetBitRate(FFrame) / 1000 * 8;     end   else     Result := 0; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetVBREncoderID: Byte; begin   { Guess VBR encoder and get ID }   Result := 0;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_LAME then     Result := MPEG_ENCODER_LAME;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_GOGO_NEW then     Result := MPEG_ENCODER_GOGO;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_GOGO_OLD then     Result := MPEG_ENCODER_GOGO;   if (FVBR.ID = VBR_ID_XING) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_LAME) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_GOGO_NEW) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_GOGO_OLD) then     Result := MPEG_ENCODER_XING;   if FVBR.ID = VBR_ID_FHG then     Result := MPEG_ENCODER_FHG; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetCBREncoderID: Byte; begin   { Guess CBR encoder and get ID }   Result := MPEG_ENCODER_FHG;   if (FFrame.OriginalBit) and     (FFrame.ProtectionBit) then     Result := MPEG_ENCODER_LAME;   if (GetBitRate(FFrame) <= 160) and     (FFrame.ModeID = MPEG_CM_STEREO) then     Result := MPEG_ENCODER_BLADE;   if (FFrame.CopyrightBit) and     (FFrame.OriginalBit) and     (not FFrame.ProtectionBit) then     Result := MPEG_ENCODER_XING;   if (FFrame.Xing) and     (FFrame.OriginalBit) then     Result := MPEG_ENCODER_XING;   if FFrame.LayerID = MPEG_LAYER_II then     Result := MPEG_ENCODER_QDESIGN;   if (FFrame.ModeID = MPEG_CM_DUAL_CHANNEL) and     (FFrame.ProtectionBit) then     Result := MPEG_ENCODER_SHINE;   if Copy(FVendorID, 1, 4) = VENDOR_ID_LAME then     Result := MPEG_ENCODER_LAME;   if Copy(FVendorID, 1, 4) = VENDOR_ID_GOGO_NEW then     Result := MPEG_ENCODER_GOGO; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEncoderID: Byte; begin   { Get guessed encoder ID }   if FFrame.Found then     if FVBR.Found then Result := FGetVBREncoderID     else Result := FGetCBREncoderID   else     Result := 0; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEncoder: string; var   VendorID: string; begin   { Get guessed encoder name and encoder version for LAME }   Result := MPEG_ENCODER[FGetEncoderID];   if FVBR.VendorID <> '' then VendorID := FVBR.VendorID;   if FVendorID <> '' then VendorID := FVendorID;   if (FGetEncoderID = MPEG_ENCODER_LAME) and     (Length(VendorID) >= 8) and     (VendorID[5] in ['0'..'9']) and     (VendorID[6] = '.') and     (VendorID[7] in ['0'..'9']) and     (VendorID[8] in ['0'..'9']) then     Result :=       Result + #32 +       VendorID[5] +       VendorID[6] +       VendorID[7] +       VendorID[8]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetValid: Boolean; begin   { Check for right MPEG file data }   Result :=     (FFrame.Found) and     (FGetBitRate >= MIN_MPEG_BIT_RATE) and     (FGetBitRate <= MAX_MPEG_BIT_RATE) and     (FGetDuration >= MIN_ALLOWED_DURATION); end;    { ********************** Public functions & procedures ********************** }    constructor TMPEGaudio.Create; begin   { Object constructor }   inherited;   FID3v1 := TID3v1.Create;   FID3v2 := TID3v2.Create;   FResetData; end;    { --------------------------------------------------------------------------- }    destructor TMPEGaudio.Destroy; begin   { Object destructor }   FID3v1.Free;   FID3v2.Free;   inherited; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.ReadFromFile(const FileName: string): Boolean; var   SourceFile: file;   Data: array [1..MAX_MPEG_FRAME_LENGTH * 2] of Byte;   Transferred, AttrByte, kk: Integer; begin   Result := false;   FResetData;   { At first search for tags, then search for a MPEG frame and VBR data }   if (FID3v2.ReadFromFile(FileName)) and (FID3v1.ReadFromFile(FileName)) then     try       { Open file, read first block of data and search for a frame }       kk := 0;       AttrByte := FileGetAttr(FileName);       if AttrByte And faReadOnly = faReadOnly then       begin         FileSetAttr(FileName,0);         kk := 1;       end;       AssignFile(SourceFile, FileName);       FileMode := 2;       Reset(SourceFile, 1);       FFileLength := FileSize(SourceFile);       Seek(SourceFile, FID3v2.Size);       BlockRead(SourceFile, Data, SizeOf(Data), Transferred);       FFrame := FindFrame(Data, FVBR);       { Try to search in the middle if no frame at the beginning found }       if (not FFrame.Found) and (Transferred = SizeOf(Data)) then       begin         Seek(SourceFile, (FFileLength - FID3v2.Size) div 2);         BlockRead(SourceFile, Data, SizeOf(Data), Transferred);         FFrame := FindFrame(Data, FVBR);       end;       { Search for vendor ID at the end if CBR encoded }       if (FFrame.Found) and (not FVBR.Found) then       begin         if not FID3v1.Exists then Seek(SourceFile, FFileLength - SizeOf(Data))         else Seek(SourceFile, FFileLength - SizeOf(Data) - 128);         BlockRead(SourceFile, Data, SizeOf(Data), Transferred);         FVendorID := FindVendorID(Data, FFrame.Size * 5);       end;       CloseFile(SourceFile);       if kk = 1 then         FileSetAttr(FileName,0 Or faReadOnly);       Result := true;     except       if kk = 1 then         FileSetAttr(FileName,0 Or faReadOnly);     end;   if not FFrame.Found then FResetData; end;    end.
jackalan168
一般會員


發表:6
回覆:12
積分:8
註冊:2004-01-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-01-09 17:21:46 IP:218.2.xxx.xxx 未訂閱
MP3大小不是根据大小算的,请看下面范例:    这是个很好的单元,可以读取MP3文件的ID3 V1,V2的信息,文件长度,采样、时间等。    如果需要知道其他用法MAIL找我。    =======================READ TIME========================== Var Strtime : string;    if not MusicInfo.ReadFromFile(filename) then    strTime :='00:00' else    strTime := FillAboutZero(inttostr(round(MusicInfo.Duration) div 60),2) +':'+FillAboutZero(inttostr(round(MusicInfo.Duration) mod 60),2);    =============单元==============    unit MPEGaudio;    interface    uses   Classes, SysUtils, ID3v1, ID3v2;    const   { Table for bit rates }   MPEG_BIT_RATE: array [0..3, 0..3, 0..15] of Word =     (     { For MPEG 2.5 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0)),     { Reserved }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)),     { For MPEG 2 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0)),     { For MPEG 1 }     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),     (0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0),     (0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0),     (0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0))     );      { Sample rate codes }   MPEG_SAMPLE_RATE_LEVEL_3 = 0;                                     { Level 3 }   MPEG_SAMPLE_RATE_LEVEL_2 = 1;                                     { Level 2 }   MPEG_SAMPLE_RATE_LEVEL_1 = 2;                                     { Level 1 }   MPEG_SAMPLE_RATE_UNKNOWN = 3;                               { Unknown value }      { Table for sample rates }   MPEG_SAMPLE_RATE: array [0..3, 0..3] of Word =     (     (11025, 12000, 8000, 0),                                   { For MPEG 2.5 }     (0, 0, 0, 0),                                                  { Reserved }     (22050, 24000, 16000, 0),                                    { For MPEG 2 }     (44100, 48000, 32000, 0)                                     { For MPEG 1 }     );      { VBR header ID for Xing/FhG }   VBR_ID_XING = 'Xing';                                         { Xing VBR ID }   VBR_ID_FHG = 'VBRI';                                           { FhG VBR ID }      { MPEG version codes }   MPEG_VERSION_2_5 = 0;                                            { MPEG 2.5 }   MPEG_VERSION_UNKNOWN = 1;                                 { Unknown version }   MPEG_VERSION_2 = 2;                                                { MPEG 2 }   MPEG_VERSION_1 = 3;                                                { MPEG 1 }      { MPEG version names }   MPEG_VERSION: array [0..3] of string =     ('MPEG 2.5', 'MPEG ?', 'MPEG 2', 'MPEG 1');      { MPEG layer codes }   MPEG_LAYER_UNKNOWN = 0;                                     { Unknown layer }   MPEG_LAYER_III = 1;                                             { Layer III }   MPEG_LAYER_II = 2;                                               { Layer II }   MPEG_LAYER_I = 3;                                                 { Layer I }      { MPEG layer names }   MPEG_LAYER: array [0..3] of string =     ('Layer ?', 'Layer III', 'Layer II', 'Layer I');      { Channel mode codes }   MPEG_CM_STEREO = 0;                                                { Stereo }   MPEG_CM_JOINT_STEREO = 1;                                    { Joint Stereo }   MPEG_CM_DUAL_CHANNEL = 2;                                    { Dual Channel }   MPEG_CM_MONO = 3;                                                    { Mono }   MPEG_CM_UNKNOWN = 4;                                         { Unknown mode }      { Channel mode names }   MPEG_CM_MODE: array [0..4] of string =     ('Stereo', 'Joint Stereo', 'Dual Channel', 'Mono', 'Unknown');      { Extension mode codes (for Joint Stereo) }   MPEG_CM_EXTENSION_OFF = 0;                        { IS and MS modes set off }   MPEG_CM_EXTENSION_IS = 1;                             { Only IS mode set on }   MPEG_CM_EXTENSION_MS = 2;                             { Only MS mode set on }   MPEG_CM_EXTENSION_ON = 3;                          { IS and MS modes set on }   MPEG_CM_EXTENSION_UNKNOWN = 4;                     { Unknown extension mode }      { Emphasis mode codes }   MPEG_EMPHASIS_NONE = 0;                                              { None }   MPEG_EMPHASIS_5015 = 1;                                          { 50/15 ms }   MPEG_EMPHASIS_UNKNOWN = 2;                               { Unknown emphasis }   MPEG_EMPHASIS_CCIT = 3;                                         { CCIT J.17 }      { Emphasis names }   MPEG_EMPHASIS: array [0..3] of string =     ('None', '50/15 ms', 'Unknown', 'CCIT J.17');      { Encoder codes }   MPEG_ENCODER_UNKNOWN = 0;                                 { Unknown encoder }   MPEG_ENCODER_XING = 1;                                               { Xing }   MPEG_ENCODER_FHG = 2;                                                 { FhG }   MPEG_ENCODER_LAME = 3;                                               { LAME }   MPEG_ENCODER_BLADE = 4;                                             { Blade }   MPEG_ENCODER_GOGO = 5;                                               { GoGo }   MPEG_ENCODER_SHINE = 6;                                             { Shine }   MPEG_ENCODER_QDESIGN = 7;                                         { QDesign }      { Encoder names }   MPEG_ENCODER: array [0..7] of string =     ('Unknown', 'Xing', 'FhG', 'LAME', 'Blade', 'GoGo', 'Shine', 'QDesign');    type   { Xing/FhG VBR header data }   VBRData = record     Found: Boolean;                                { True if VBR header found }     ID: array [1..4] of Char;                   { Header ID: "Xing" or "VBRI" }     Frames: Integer;                                 { Total number of frames }     Bytes: Integer;                                   { Total number of bytes }     Scale: Byte;                                         { VBR scale (1..100) }     VendorID: string;                                { Vendor ID (if present) }   end;      { MPEG frame header data}   FrameData = record     Found: Boolean;                                     { True if frame found }     Position: Integer;                           { Frame position in the file }     Size: Word;                                          { Frame size (bytes) }     Xing: Boolean;                                     { True if Xing encoder }     Data: array [1..4] of Byte;                 { The whole frame header data }     VersionID: Byte;                                        { MPEG version ID }     LayerID: Byte;                                            { MPEG layer ID }     ProtectionBit: Boolean;                        { True if protected by CRC }     BitRateID: Word;                                            { Bit rate ID }     SampleRateID: Word;                                      { Sample rate ID }     PaddingBit: Boolean;                               { True if frame padded }     PrivateBit: Boolean;                                  { Extra information }     ModeID: Byte;                                           { Channel mode ID }     ModeExtensionID: Byte;             { Mode extension ID (for Joint Stereo) }     CopyrightBit: Boolean;                        { True if audio copyrighted }     OriginalBit: Boolean;                            { True if original media }     EmphasisID: Byte;                                           { Emphasis ID }   end;      { Class TMPEGaudio }   TMPEGaudio = class(TObject)     private       { Private declarations }       FFileLength: Integer;       FVendorID: string;       FVBR: VBRData;       FFrame: FrameData;       FID3v1: TID3v1;       FID3v2: TID3v2;       procedure FResetData;       function FGetVersion: string;       function FGetLayer: string;       function FGetBitRate: Word;       function FGetSampleRate: Word;       function FGetChannelMode: string;       function FGetEmphasis: string;       function FGetFrames: Integer;       function FGetDuration: Double;       function FGetVBREncoderID: Byte;       function FGetCBREncoderID: Byte;       function FGetEncoderID: Byte;       function FGetEncoder: string;       function FGetValid: Boolean;     public       { Public declarations }       constructor Create;                                     { Create object }       destructor Destroy; override;                          { Destroy object }       function ReadFromFile(const FileName: string): Boolean;     { Load data }       property FileLength: Integer read FFileLength;    { File length (bytes) }       property VBR: VBRData read FVBR;                      { VBR header data }       property Frame: FrameData read FFrame;              { Frame header data }       property ID3v1: TID3v1 read FID3v1;                    { ID3v1 tag data }       property ID3v2: TID3v2 read FID3v2;                    { ID3v2 tag data }       property Version: string read FGetVersion;          { MPEG version name }       property Layer: string read FGetLayer;                { MPEG layer name }       property BitRate: Word read FGetBitRate;            { Bit rate (kbit/s) }       property SampleRate: Word read FGetSampleRate;       { Sample rate (hz) }       property ChannelMode: string read FGetChannelMode;  { Channel mode name }       property Emphasis: string read FGetEmphasis;            { Emphasis name }       property Frames: Integer read FGetFrames;      { Total number of frames }       property Duration: Double read FGetDuration;      { Song duration (sec) }       property EncoderID: Byte read FGetEncoderID;       { Guessed encoder ID }       property Encoder: string read FGetEncoder;       { Guessed encoder name }       property Valid: Boolean read FGetValid;       { True if MPEG file valid }   end;    implementation    const   { Limitation constants }   MAX_MPEG_FRAME_LENGTH = 1729;                      { Max. MPEG frame length }   MIN_MPEG_BIT_RATE = 8;                                { Min. bit rate value }   MAX_MPEG_BIT_RATE = 448;                              { Max. bit rate value }   MIN_ALLOWED_DURATION = 0.1;                      { Min. song duration value }      { VBR Vendor ID strings }   VENDOR_ID_LAME = 'LAME';                                         { For LAME }   VENDOR_ID_GOGO_NEW = 'GOGO';                               { For GoGo (New) }   VENDOR_ID_GOGO_OLD = 'MPGE';                               { For GoGo (Old) }    { ********************* Auxiliary functions & procedures ******************** }    function IsFrameHeader(const HeaderData: array of Byte): Boolean; begin   { Check for valid frame header }   if ((HeaderData[0] and $FF) <> $FF) or     ((HeaderData[1] and $E0) <> $E0) or     (((HeaderData[1] shr 3) and 3) = 1) or     (((HeaderData[1] shr 1) and 3) = 0) or     ((HeaderData[2] and $F0) = $F0) or     ((HeaderData[2] and $F0) = 0) or     (((HeaderData[2] shr 2) and 3) = 3) or     ((HeaderData[3] and 3) = 2) then     Result := false   else     Result := true; end;    { --------------------------------------------------------------------------- }    procedure DecodeHeader(const HeaderData: array of Byte; var Frame: FrameData); begin   { Decode frame header data }   Move(HeaderData, Frame.Data, SizeOf(Frame.Data));   Frame.VersionID := (HeaderData[1] shr 3) and 3;   Frame.LayerID := (HeaderData[1] shr 1) and 3;   Frame.ProtectionBit := (HeaderData[1] and 1) <> 1;   Frame.BitRateID := HeaderData[2] shr 4;   Frame.SampleRateID := (HeaderData[2] shr 2) and 3;   Frame.PaddingBit := ((HeaderData[2] shr 1) and 1) = 1;   Frame.PrivateBit := (HeaderData[2] and 1) = 1;   Frame.ModeID := (HeaderData[3] shr 6) and 3;   Frame.ModeExtensionID := (HeaderData[3] shr 4) and 3;   Frame.CopyrightBit := ((HeaderData[3] shr 3) and 1) = 1;   Frame.OriginalBit := ((HeaderData[3] shr 2) and 1) = 1;   Frame.EmphasisID := HeaderData[3] and 3; end;    { --------------------------------------------------------------------------- }    function ValidFrameAt(const Index: Word; Data: array of Byte): Boolean; var   HeaderData: array [1..4] of Byte; begin   { Check for frame at given position }   HeaderData[1] := Data[Index];   HeaderData[2] := Data[Index + 1];   HeaderData[3] := Data[Index + 2];   HeaderData[4] := Data[Index + 3];   if IsFrameHeader(HeaderData) then Result := true   else Result := false; end;    { --------------------------------------------------------------------------- }    function GetCoefficient(const Frame: FrameData): Byte; begin   { Get frame size coefficient }   if Frame.VersionID = MPEG_VERSION_1 then     if Frame.LayerID = MPEG_LAYER_I then Result := 48     else Result := 144   else     if Frame.LayerID = MPEG_LAYER_I then Result := 24     else if Frame.LayerID = MPEG_LAYER_II then Result := 144     else Result := 72; end;    { --------------------------------------------------------------------------- }    function GetBitRate(const Frame: FrameData): Word; begin   { Get bit rate }   Result := MPEG_BIT_RATE[Frame.VersionID, Frame.LayerID, Frame.BitRateID]; end;    { --------------------------------------------------------------------------- }    function GetSampleRate(const Frame: FrameData): Word; begin   { Get sample rate }   Result := MPEG_SAMPLE_RATE[Frame.VersionID, Frame.SampleRateID]; end;    { --------------------------------------------------------------------------- }    function GetPadding(const Frame: FrameData): Byte; begin   { Get frame padding }   if Frame.PaddingBit then     if Frame.LayerID = MPEG_LAYER_I then Result := 4     else Result := 1   else Result := 0; end;    { --------------------------------------------------------------------------- }    function GetFrameLength(const Frame: FrameData): Word; var   Coefficient, BitRate, SampleRate, Padding: Word; begin   { Calculate MPEG frame length }   Coefficient := GetCoefficient(Frame);   BitRate := GetBitRate(Frame);   SampleRate := GetSampleRate(Frame);   Padding := GetPadding(Frame);   Result := Trunc(Coefficient * BitRate * 1000 / SampleRate) + Padding; end;    { --------------------------------------------------------------------------- }    function IsXing(const Index: Word; Data: array of Byte): Boolean; begin   { Get true if Xing encoder }   Result :=     (Data[Index] = 0) and     (Data[Index + 1] = 0) and     (Data[Index + 2] = 0) and     (Data[Index + 3] = 0) and     (Data[Index + 4] = 0) and     (Data[Index + 5] = 0); end;    { --------------------------------------------------------------------------- }    function GetXingInfo(const Index: Word; Data: array of Byte): VBRData; begin   { Extract Xing VBR info at given position }   FillChar(Result, SizeOf(Result), 0);   Result.Found := true;   Result.ID := VBR_ID_XING;   Result.Frames :=     Data[Index + 8] * $1000000 +     Data[Index + 9] * $10000 +     Data[Index + 10] * $100 +     Data[Index + 11];   Result.Bytes :=     Data[Index + 12] * $1000000 +     Data[Index + 13] * $10000 +     Data[Index + 14] * $100 +     Data[Index + 15];   Result.Scale := Data[Index + 119];   { Vendor ID can be not present }   Result.VendorID :=     Chr(Data[Index + 120]) +     Chr(Data[Index + 121]) +     Chr(Data[Index + 122]) +     Chr(Data[Index + 123]) +     Chr(Data[Index + 124]) +     Chr(Data[Index + 125]) +     Chr(Data[Index + 126]) +     Chr(Data[Index + 127]); end;    { --------------------------------------------------------------------------- }    function GetFhGInfo(const Index: Word; Data: array of Byte): VBRData; begin   { Extract FhG VBR info at given position }   FillChar(Result, SizeOf(Result), 0);   Result.Found := true;   Result.ID := VBR_ID_FHG;   Result.Scale := Data[Index + 9];   Result.Bytes :=     Data[Index + 10] * $1000000 +     Data[Index + 11] * $10000 +     Data[Index + 12] * $100 +     Data[Index + 13];   Result.Frames :=     Data[Index + 14] * $1000000 +     Data[Index + 15] * $10000 +     Data[Index + 16] * $100 +     Data[Index + 17]; end;    { --------------------------------------------------------------------------- }    function FindVBR(const Index: Word; Data: array of Byte): VBRData; begin   { Check for VBR header at given position }   FillChar(Result, SizeOf(Result), 0);   if Chr(Data[Index]) +     Chr(Data[Index + 1]) +     Chr(Data[Index + 2]) +     Chr(Data[Index + 3]) = VBR_ID_XING then Result := GetXingInfo(Index, Data);   if Chr(Data[Index]) +     Chr(Data[Index + 1]) +     Chr(Data[Index + 2]) +     Chr(Data[Index + 3]) = VBR_ID_FHG then Result := GetFhGInfo(Index, Data); end;    { --------------------------------------------------------------------------- }    function GetVBRDeviation(const Frame: FrameData): Byte; begin   { Calculate VBR deviation }   if Frame.VersionID = MPEG_VERSION_1 then     if Frame.ModeID <> MPEG_CM_MONO then Result := 36     else Result := 21   else     if Frame.ModeID <> MPEG_CM_MONO then Result := 21     else Result := 13; end;    { --------------------------------------------------------------------------- }    function FindFrame(const Data: array of Byte; var VBR: VBRData): FrameData; var   HeaderData: array [1..4] of Byte;   Iterator: Integer; begin   { Search for valid frame }   FillChar(Result, SizeOf(Result), 0);   Move(Data, HeaderData, SizeOf(HeaderData));   for Iterator := 0 to SizeOf(Data) - MAX_MPEG_FRAME_LENGTH do   begin     { Decode data if frame header found }     if IsFrameHeader(HeaderData) then     begin       DecodeHeader(HeaderData, Result);       { Check for next frame and try to find VBR header }       if ValidFrameAt(Iterator + GetFrameLength(Result), Data) then       begin         Result.Found := true;         Result.Position := Iterator;         Result.Size := GetFrameLength(Result);         Result.Xing := IsXing(Iterator + SizeOf(HeaderData), Data);         VBR := FindVBR(Iterator + GetVBRDeviation(Result), Data);         break;       end;     end;     { Prepare next data block }     HeaderData[1] := HeaderData[2];     HeaderData[2] := HeaderData[3];     HeaderData[3] := HeaderData[4];     HeaderData[4] := Data[Iterator + SizeOf(HeaderData)];   end; end;    { --------------------------------------------------------------------------- }    function FindVendorID(const Data: array of Byte; Size: Word): string; var   Iterator: Integer;   VendorID: string; begin   { Search for vendor ID }   Result := '';   if (SizeOf(Data) - Size - 8) < 0 then Size := SizeOf(Data) - 8;   for Iterator := 0 to Size do   begin     VendorID :=       Chr(Data[SizeOf(Data) - Iterator - 8]) +       Chr(Data[SizeOf(Data) - Iterator - 7]) +       Chr(Data[SizeOf(Data) - Iterator - 6]) +       Chr(Data[SizeOf(Data) - Iterator - 5]);     if VendorID = VENDOR_ID_LAME then     begin       Result := VendorID +         Chr(Data[SizeOf(Data) - Iterator - 4]) +         Chr(Data[SizeOf(Data) - Iterator - 3]) +         Chr(Data[SizeOf(Data) - Iterator - 2]) +         Chr(Data[SizeOf(Data) - Iterator - 1]);       break;     end;     if VendorID = VENDOR_ID_GOGO_NEW then     begin       Result := VendorID;       break;     end;   end; end;    { ********************** Private functions & procedures ********************* }    procedure TMPEGaudio.FResetData; begin   { Reset all variables } try   FFileLength := 0;   FVendorID := '';   FillChar(FVBR, SizeOf(FVBR), 0);   FillChar(FFrame, SizeOf(FFrame), 0);   FFrame.VersionID := MPEG_VERSION_UNKNOWN;   FFrame.SampleRateID := MPEG_SAMPLE_RATE_UNKNOWN;   FFrame.ModeID := MPEG_CM_UNKNOWN;   FFrame.ModeExtensionID := MPEG_CM_EXTENSION_UNKNOWN;   FFrame.EmphasisID := MPEG_EMPHASIS_UNKNOWN;   FID3v1.ResetData;   FID3v2.ResetData; except   //not end; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetVersion: string; begin   { Get MPEG version name }   Result := MPEG_VERSION[FFrame.VersionID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetLayer: string; begin   { Get MPEG layer name }   Result := MPEG_LAYER[FFrame.LayerID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetBitRate: Word; begin   { Get bit rate, calculate average bit rate if VBR header found }   if (FVBR.Found) and (FVBR.Frames > 0) then     Result := Round((FVBR.Bytes / FVBR.Frames - GetPadding(FFrame)) *       GetSampleRate(FFrame) / GetCoefficient(FFrame) / 1000)   else     Result := GetBitRate(FFrame); end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetSampleRate: Word; begin   { Get sample rate }   Result := GetSampleRate(FFrame); end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetChannelMode: string; begin   { Get channel mode name }   Result := MPEG_CM_MODE[FFrame.ModeID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEmphasis: string; begin   { Get emphasis name }   Result := MPEG_EMPHASIS[FFrame.EmphasisID]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetFrames: Integer; var   MPEGSize: Integer; begin   { Get total number of frames, calculate if VBR header not found }   if FVBR.Found then     Result := FVBR.Frames   else   begin     if FID3v1.Exists then MPEGSize := FFileLength - FID3v2.Size - 128     else MPEGSize := FFileLength - FID3v2.Size;     Result := (MPEGSize - FFrame.Position) div GetFrameLength(FFrame);   end; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetDuration: Double; var   MPEGSize: Integer; begin   { Calculate song duration }   if FFrame.Found then     if (FVBR.Found) and (FVBR.Frames > 0) then       Result := FVBR.Frames * GetCoefficient(FFrame) * 8 /         GetSampleRate(FFrame)     else     begin       if FID3v1.Exists then MPEGSize := FFileLength - FID3v2.Size - 128       else MPEGSize := FFileLength - FID3v2.Size;       Result := (MPEGSize - FFrame.Position) / GetBitRate(FFrame) / 1000 * 8;     end   else     Result := 0; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetVBREncoderID: Byte; begin   { Guess VBR encoder and get ID }   Result := 0;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_LAME then     Result := MPEG_ENCODER_LAME;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_GOGO_NEW then     Result := MPEG_ENCODER_GOGO;   if Copy(FVBR.VendorID, 1, 4) = VENDOR_ID_GOGO_OLD then     Result := MPEG_ENCODER_GOGO;   if (FVBR.ID = VBR_ID_XING) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_LAME) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_GOGO_NEW) and     (Copy(FVBR.VendorID, 1, 4) <> VENDOR_ID_GOGO_OLD) then     Result := MPEG_ENCODER_XING;   if FVBR.ID = VBR_ID_FHG then     Result := MPEG_ENCODER_FHG; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetCBREncoderID: Byte; begin   { Guess CBR encoder and get ID }   Result := MPEG_ENCODER_FHG;   if (FFrame.OriginalBit) and     (FFrame.ProtectionBit) then     Result := MPEG_ENCODER_LAME;   if (GetBitRate(FFrame) <= 160) and     (FFrame.ModeID = MPEG_CM_STEREO) then     Result := MPEG_ENCODER_BLADE;   if (FFrame.CopyrightBit) and     (FFrame.OriginalBit) and     (not FFrame.ProtectionBit) then     Result := MPEG_ENCODER_XING;   if (FFrame.Xing) and     (FFrame.OriginalBit) then     Result := MPEG_ENCODER_XING;   if FFrame.LayerID = MPEG_LAYER_II then     Result := MPEG_ENCODER_QDESIGN;   if (FFrame.ModeID = MPEG_CM_DUAL_CHANNEL) and     (FFrame.ProtectionBit) then     Result := MPEG_ENCODER_SHINE;   if Copy(FVendorID, 1, 4) = VENDOR_ID_LAME then     Result := MPEG_ENCODER_LAME;   if Copy(FVendorID, 1, 4) = VENDOR_ID_GOGO_NEW then     Result := MPEG_ENCODER_GOGO; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEncoderID: Byte; begin   { Get guessed encoder ID }   if FFrame.Found then     if FVBR.Found then Result := FGetVBREncoderID     else Result := FGetCBREncoderID   else     Result := 0; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetEncoder: string; var   VendorID: string; begin   { Get guessed encoder name and encoder version for LAME }   Result := MPEG_ENCODER[FGetEncoderID];   if FVBR.VendorID <> '' then VendorID := FVBR.VendorID;   if FVendorID <> '' then VendorID := FVendorID;   if (FGetEncoderID = MPEG_ENCODER_LAME) and     (Length(VendorID) >= 8) and     (VendorID[5] in ['0'..'9']) and     (VendorID[6] = '.') and     (VendorID[7] in ['0'..'9']) and     (VendorID[8] in ['0'..'9']) then     Result :=       Result + #32 +       VendorID[5] +       VendorID[6] +       VendorID[7] +       VendorID[8]; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.FGetValid: Boolean; begin   { Check for right MPEG file data }   Result :=     (FFrame.Found) and     (FGetBitRate >= MIN_MPEG_BIT_RATE) and     (FGetBitRate <= MAX_MPEG_BIT_RATE) and     (FGetDuration >= MIN_ALLOWED_DURATION); end;    { ********************** Public functions & procedures ********************** }    constructor TMPEGaudio.Create; begin   { Object constructor }   inherited;   FID3v1 := TID3v1.Create;   FID3v2 := TID3v2.Create;   FResetData; end;    { --------------------------------------------------------------------------- }    destructor TMPEGaudio.Destroy; begin   { Object destructor }   FID3v1.Free;   FID3v2.Free;   inherited; end;    { --------------------------------------------------------------------------- }    function TMPEGaudio.ReadFromFile(const FileName: string): Boolean; var   SourceFile: file;   Data: array [1..MAX_MPEG_FRAME_LENGTH * 2] of Byte;   Transferred, AttrByte, kk: Integer; begin   Result := false;   FResetData;   { At first search for tags, then search for a MPEG frame and VBR data }   if (FID3v2.ReadFromFile(FileName)) and (FID3v1.ReadFromFile(FileName)) then     try       { Open file, read first block of data and search for a frame }       kk := 0;       AttrByte := FileGetAttr(FileName);       if AttrByte And faReadOnly = faReadOnly then       begin         FileSetAttr(FileName,0);         kk := 1;       end;       AssignFile(SourceFile, FileName);       FileMode := 2;       Reset(SourceFile, 1);       FFileLength := FileSize(SourceFile);       Seek(SourceFile, FID3v2.Size);       BlockRead(SourceFile, Data, SizeOf(Data), Transferred);       FFrame := FindFrame(Data, FVBR);       { Try to search in the middle if no frame at the beginning found }       if (not FFrame.Found) and (Transferred = SizeOf(Data)) then       begin         Seek(SourceFile, (FFileLength - FID3v2.Size) div 2);         BlockRead(SourceFile, Data, SizeOf(Data), Transferred);         FFrame := FindFrame(Data, FVBR);       end;       { Search for vendor ID at the end if CBR encoded }       if (FFrame.Found) and (not FVBR.Found) then       begin         if not FID3v1.Exists then Seek(SourceFile, FFileLength - SizeOf(Data))         else Seek(SourceFile, FFileLength - SizeOf(Data) - 128);         BlockRead(SourceFile, Data, SizeOf(Data), Transferred);         FVendorID := FindVendorID(Data, FFrame.Size * 5);       end;       CloseFile(SourceFile);       if kk = 1 then         FileSetAttr(FileName,0 Or faReadOnly);       Result := true;     except       if kk = 1 then         FileSetAttr(FileName,0 Or faReadOnly);     end;   if not FFrame.Found then FResetData; end;    end.
coldcoffee
一般會員


發表:60
回覆:22
積分:16
註冊:2003-05-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-01-09 20:02:49 IP:61.51.xxx.xxx 未訂閱
引言: MP3大小不是根据大小算的,请看下面范例: 这是个很好的单元,可以读取MP3文件的ID3 V1,V2的信息,文件长度,采样、时间等。 如果需要知道其他用法MAIL找我。
你怎么不都说全了,还要用mail跟你联系,你用QQ吗?我的号是:44657219,你加我吧!
Miles
尊榮會員


發表:27
回覆:662
積分:622
註冊:2002-07-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-01-12 18:25:01 IP:218.160.xxx.xxx 未訂閱
參考 http://delphi.about.com/library/weekly/aa112800a.htm 及Delphi Help 改寫如下 放一個TMediaplayer

  HMSRec = record
    Hours: byte;
    Minutes: byte;
    Seconds: byte;
    NotUsed: byte;
  end;    procedure TForm1.Button1Click(Sender: TObject);
var
  TheLength: LongInt;
begin
   MediaPlayer1.Close;
   { Set time format - note that some devices dont support tfHMS }
   MediaPlayer1.TimeFormat := tfHMS;
   MediaPlayer1.FileName := 'c:\Angel.mp3'; {MP3 File Name}
   MediaPlayer1.Open;
   TheLength := MediaPlayer1.Length;
  with HMSRec(TheLength) do { Typecast TheLength as a HMSRec record }
  begin
    Label1.Caption := IntToStr(Hours); { Display Hours in Label1 }
    Label2.Caption := IntToStr(Minutes); { Display Minutes in Label2 }
    Label3.Caption := IntToStr(Seconds); { Display Seconds in Label3 }
  end;    end;
我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
系統時間:2024-05-03 1:00:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!