delphi 裁剪mp3_如何编辑mp3文件详细信息(Delphi)

我不记得这个单位是从哪里来的,但我前一阵子用它做了一个宠物项目:

unit ID3v2;

interface

uses

Classes, SysUtils;

const

TAG_VERSION_2_3 = 3; { Code for

ID3v2.3.0 tag }

type

{ Class TID3v2 }

TID3v2 = class(TObject)

private

{ Private declarations }

FExists: Boolean;

FVersionID: Byte;

FSize: Integer;

FTitle: string;

FArtist: string;

FAlbum: string;

FTrack: Byte;

FYear: string;

FGenre: string;

FComment: string;

public

{ Public declarations }

constructor Create; { Create

object }

procedure ResetData; { Reset

all data }

function ReadFromFile(const FileName: string): Boolean; {

Load tag }

property Exists: Boolean read FExists; { True if tag

found }

property VersionID: Byte read FVersionID; {

Version code }

property Size: Integer read FSize; { Total

tag size }

property Title: string read FTitle; { Song

title }

property Artist: string read FArtist; {

Artist name }

property Album: string read FAlbum; {

Album name }

property Track: Byte read FTrack; { Track

number }

property Year: string read FYear;

{ Year }

property Genre: string read FGenre; {

Genre name }

property Comment: string read FComment; {

Comment }

end;

implementation

const

{ Max. number of supported tag frames }

ID3V2_FRAME_COUNT = 7;

{ Names of supported tag frames }

ID3V2_FRAME: array [1..ID3V2_FRAME_COUNT] of string =

('TIT2', 'TPE1', 'TALB', 'TRCK', 'TYER', 'TCON', 'COMM');

type

{ ID3v2 frame header }

FrameHeader = record

ID: array [1..4] of AnsiChar; {

Frame ID }

Size: Integer; { Size excluding

header }

Flags: Word; {

Flags }

end;

{ ID3v2 header data - for internal use }

TagInfo = record

{ Real structure of ID3v2 header }

ID: array [1..3] of AnsiChar; { Always

"ID3" }

Version: Byte; { Version

number }

Revision: Byte; { Revision

number }

Flags: Byte; { Flags

of tag }

Size: array [1..4] of Byte; { Tag size excluding

header }

{ Extended data }

FileSize: Integer; { File size

(bytes) }

Frame: array [1..ID3V2_FRAME_COUNT] of string; { Information from

frames }

end;

{ ********************* Auxiliary functions & procedures

******************** }

function ReadHeader(const FileName: string; var Tag: TagInfo): Boolean;

var

SourceFile: file;

Transferred: Integer;

begin

try

Result := true;

{ Set read-access and open file }

AssignFile(SourceFile, FileName);

FileMode := 0;

Reset(SourceFile, 1);

{ Read header and get file size }

BlockRead(SourceFile, Tag, 10, Transferred);

Tag.FileSize := FileSize(SourceFile);

CloseFile(SourceFile);

{ if transfer is not complete }

if Transferred < 10 then Result := false;

except

{ Error }

Result := false;

end;

end;

{

---------------------------------------------------------------------------

}

function GetVersionID(const Tag: TagInfo): Byte;

begin

{ Get tag version from header }

Result := Tag.Version;

end;

{

---------------------------------------------------------------------------

}

function GetTagSize(const Tag: TagInfo): Integer;

begin

{ Get total tag size }

Result :=

Tag.Size[1] * $200000 +

Tag.Size[2] * $4000 +

Tag.Size[3] * $80 +

Tag.Size[4] + 10;

if Result > Tag.FileSize then Result := 0;

end;

{

---------------------------------------------------------------------------

}

procedure SetTagItem(const ID, Data: string; var Tag: TagInfo);

var

Iterator: Byte;

begin

{ Set tag item if supported frame found }

for Iterator := 1 to ID3V2_FRAME_COUNT do

if ID3V2_FRAME[Iterator] = ID then Tag.Frame[Iterator] := Data;

end;

{

---------------------------------------------------------------------------

}

function Swap32(const Figure: Integer): Integer;

var

ByteArray: array [1..4] of Byte absolute Figure;

begin

{ Swap 4 bytes }

Result :=

ByteArray[1] * $100000000 +

ByteArray[2] * $10000 +

ByteArray[3] * $100 +

ByteArray[4];

end;

{

---------------------------------------------------------------------------

}

procedure ReadFrames(const FileName: string; var Tag: TagInfo);

var

SourceFile: file;

Frame: FrameHeader;

Data: array [1..250] of AnsiChar;

DataPosition: Integer;

begin

try

{ Set read-access, open file }

AssignFile(SourceFile, FileName);

FileMode := 0;

Reset(SourceFile, 1);

Seek(SourceFile, 10);

while (FilePos(SourceFile) < GetTagSize(Tag)) and (not

EOF(SourceFile)) do

begin

FillChar(Data, SizeOf(Data), 0);

{ Read frame header }

BlockRead(SourceFile, Frame, 10);

DataPosition := FilePos(SourceFile);

{ Read frame data and set tag item if frame supported }

BlockRead(SourceFile, Data, Swap32(Frame.Size) mod SizeOf(Data));

SetTagItem(Frame.ID, Data, Tag);

Seek(SourceFile, DataPosition + Swap32(Frame.Size));

end;

CloseFile(SourceFile);

except

end;

end;

{

---------------------------------------------------------------------------

}

function GetTrack(const TrackString: string): Byte;

var

Index, Value, Code: Integer;

begin

{ Extract track from string }

Index := Pos('/', TrackString);

if Index = 0 then Val(Trim(TrackString), Value, Code)

else Val(Copy(Trim(TrackString), 1, Index), Value, Code);

if Code = 0 then Result := Value

else Result := 0;

end;

{

---------------------------------------------------------------------------

}

function GetGenre(const GenreString: string): string;

begin

{ Extract genre from string }

Result := Trim(GenreString);

if Pos(')', Result) > 0 then Delete(Result, 1, LastDelimiter(')',

Result));

end;

{ ********************** Public functions & procedures

********************** }

constructor TID3v2.Create;

begin

inherited;

ResetData;

end;

{

---------------------------------------------------------------------------

}

procedure TID3v2.ResetData;

begin

FExists := false;

FVersionID := 0;

FSize := 0;

FTitle := '';

FArtist := '';

FAlbum := '';

FTrack := 0;

FYear := '';

FGenre := '';

FComment := '';

end;

{

---------------------------------------------------------------------------

}

function TID3v2.ReadFromFile(const FileName: string): Boolean;

var

Tag: TagInfo;

begin

{ Reset data and load header from file to variable }

ResetData;

Result := ReadHeader(FileName, Tag);

{ Process data if loaded and header valid }

if (Result) and (Tag.ID = 'ID3') then

begin

FExists := true;

{ Fill properties with header data }

FVersionID := GetVersionID(Tag);

FSize := GetTagSize(Tag);

{ Get information from frames if version supported }

if (FVersionID = TAG_VERSION_2_3) and (FSize > 0) then

begin

ReadFrames(FileName, Tag);

{ Fill properties with data from frames }

FTitle := Trim(Tag.Frame[1]);

FArtist := Trim(Tag.Frame[2]);

FAlbum := Trim(Tag.Frame[3]);

FTrack := GetTrack(Tag.Frame[4]);

FYear := Trim(Tag.Frame[5]);

FGenre := GetGenre(Tag.Frame[6]);

FComment := Trim(Copy(Tag.Frame[7], 5, Length(Tag.Frame[7]) - 4));

end;

end;

end;

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值