How to edit mp3 file details (Delphi)

馋奶兔 提交于 2019-12-04 10:07:13
PA.

You may probably be able to manipulate not only ID3V1 but ID3V2 as well.

so, this is library that may help you

http://www.3delite.hu/Object Pascal Developer Resources/id3v2library.html

ioan ghip

I don't remember where I got this unit from, but I used it for a pet project a while ago:

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. 

Take a look at id3mgmnt.pas, it looks like what you're for.

Never tested it, just publishing first google result.

You can use TJvID3v1 or TJvID3v2 components from http://www.delphi-jedi.org/

I used parts of Jürgen Faul's Audio Tools Library a while ago. It's a bit old (2002), but this library has been maintained by other people until 2005. You can get the old 2002 version from various component repositories or get the "latest" one from http://mac.sourceforge.net/atl/. I don't know if these are up to the latest ID3 standard, but the 2002 code still fetches data from MP3 files for my old audio player project.

@ioan: the unit you posted comes actually from some version of this library.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!