BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

MP3 tag info

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Multimedia
View previous topic :: View next topic  
Author Message
Bill
Guest





PostPosted: Tue Dec 19, 2006 9:34 pm    Post subject: MP3 tag info Reply with quote



Greetings,

I am sitting here listening to Christmas music from the internet as I
work and invaribly a few stinkers pop up. Currently, when a stinker
comes up, the volume automatically goes down to mute. I have several
stations listed in a radio group so I can hope around. Right now all I
have is the ULR listed. Winamp has the ability to scan the stations
and retreive the song played on the various stations.

Does anyone know of a way to poll a url to read the stream MP3 tag info
(in order to get the file info) My intent is to have the player
display the song name in the radio group (my pre-set radio stations)
instead of the url.

Regards and Merry Christmas,
Bill
Back to top
Mikas
Guest





PostPosted: Tue Dec 19, 2006 10:42 pm    Post subject: Re: MP3 tag info Reply with quote



Bill wrote:
Quote:
Greetings,

I am sitting here listening to Christmas music from the internet as I
work and invaribly a few stinkers pop up. Currently, when a stinker
comes up, the volume automatically goes down to mute. I have several
stations listed in a radio group so I can hope around. Right now all I
have is the ULR listed. Winamp has the ability to scan the stations
and retreive the song played on the various stations.

Does anyone know of a way to poll a url to read the stream MP3 tag info
(in order to get the file info) My intent is to have the player
display the song name in the radio group (my pre-set radio stations)
instead of the url.

Regards and Merry Christmas,
Bill

Hi...
Maybe this can help you out:

///////////////////////////////////////////////////////////////////////////

{
***************************************************************************
}
{
}
{ Audio Tools Library (Freeware)
}
{ Class TID3v2 - for extracting information from ID3v2 tags
}
{
}
{ Copyright (c) 2001 by Jurgen Faul
}
{ E-mail: jfaul (AT) gmx (DOT) de
}
{ http://jfaul.de/atl
}
{
}
{ Version 1.1 (21 August 2001)
}
{ - Added public procedure ResetData
}
{
}
{ Version 1.0 (14 August 2001)
}
{ - Reading support for ID3v2.3.x tags
}
{ - Tag info: title, artist, album, track, year, genre, comment
}
{
}
{
***************************************************************************
}

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 Char; {
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 Char; { 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 Char;
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.
////////////////////////////////////////////////////////////////////////
Back to top
Jim Davis
Guest





PostPosted: Mon Apr 02, 2007 1:09 am    Post subject: Re: MP3 tag info - Class TID3v2 Reply with quote



Quote:
{ Audio Tools Library (Freeware) Delphi }
{ Class TID3v2 - for extracting information from ID3v2 tags }
{ Copyright (c) 2001 by Jurgen Faul }
{ E-mail: jfaul (AT) gmx (DOT) de }
{ http://jfaul.de/atl }
{ Version 1.1 (21 August 2001) }

"extracting" implies not writing edits to MP3 file ?

In XP , I have C++ BCB 4 and I am rusty compiling Pascal !

Thanks , Jim D
Back to top
Jim Davis
Guest





PostPosted: Tue May 01, 2007 8:11 am    Post subject: Re: MP3 tag info Reply with quote

Quote:
{ Class TID3v2 - for extracting information from ID3v2 tags
{ Copyright (c) 2001 by Jurgen Faul
{ E-mail: jfaul (AT) gmx (DOT) de
{ http://jfaul.de/atl
{ - Reading support for ID3v2.3.x tags
{ - Tag info: title, artist, album, track, year, genre, comment

But I need tag writes and BPM .

I am hereby threating to do MP3 tag edit object in C++ Builder ,
if Delphi lacks it .
Back to top
Lee_Nover
Guest





PostPosted: Wed May 02, 2007 9:35 pm    Post subject: Re: MP3 tag info Reply with quote

Quote:
{ Class TID3v2 - for extracting information from ID3v2 tags
{ Copyright (c) 2001 by Jurgen Faul
{ E-mail: jfaul (AT) gmx (DOT) de
{ http://jfaul.de/atl
{ - Reading support for ID3v2.3.x tags
{ - Tag info: title, artist, album, track, year, genre, comment

But I need tag writes and BPM .

I am hereby threating to do MP3 tag edit object in C++ Builder ,
if Delphi lacks it .



how long are you willing to wait?
I'm just finishing read support for ID3v2.3 and .4 tags (as a subset of a larger Tag reader project)
as I don't need write support for this project, it'll be done at some later time
Back to top
Jim Davis
Guest





PostPosted: Thu May 03, 2007 9:57 pm    Post subject: Re: MP3 tag info Reply with quote

Lee_Nover <Lee_Nover@delphi-si.com> wrote in
news:op.trpkd6fa9gasuk@leenover-pc:

Quote:
{ Class TID3v2 - for extracting information from ID3v2 tags
{ Copyright (c) 2001 by Jurgen Faul
{ E-mail: jfaul (AT) gmx (DOT) de
{ http://jfaul.de/atl
{ - Reading support for ID3v2.3.x tags
{ - Tag info: title, artist, album, track, year, genre, comment

But I need tag writes and BPM .
I am hereby threating to do MP3 tag edit object in C++ Builder ,
if Delphi lacks it .

how long are you willing to wait?
I'm just finishing read support for ID3v2.3 and .4 tags (as a subset of a
larger Tag reader project)
as I don't need write support for this project, it'll be done at some
later time


Will wait weeks , not months Smile
Currently collecting C & C++ tag edit code :
http://download.sourceforge.net/id3lib/ , 2002 , ver 3.8.3 , 4.1 MB
MP3ID3 , yubodong (AT) gmail (DOT) com , 2006 , no BPM , 52 KB source

Do you know of other C code ?
Are you working from code samples , specs ?
Back to top
Lee_Nover
Guest





PostPosted: Fri May 04, 2007 1:17 am    Post subject: Re: MP3 tag info Reply with quote

Quote:
how long are you willing to wait?
Will wait weeks , not months Smile
Currently collecting C & C++ tag edit code :
http://download.sourceforge.net/id3lib/ , 2002 , ver 3.8.3 , 4.1 MB
MP3ID3 , yubodong (AT) gmail (DOT) com , 2006 , no BPM , 52 KB source

Do you know of other C code ?
Are you working from code samples , specs ?

ohh, ok then
I have the reader almost complete (still need to add v2.2 support)
I'm working from the specs, also checking out some other code and checking with a few other apps

will be off a couple of days, just got a new pc and need to setup everything
Back to top
Jim Davis
Guest





PostPosted: Tue May 08, 2007 8:12 am    Post subject: Re: MP3 tag info Reply with quote

Lee_Nover <Lee_Nover@delphi-si.com> wrote in
news:op.trrpbocb9gasuk@leenover-pc:

Quote:
Currently collecting C & C++ tag edit code :
http://download.sourceforge.net/id3lib/ 2002 ver 3.8.3

I have the reader almost complete (still need to add v2.2 support)
I'm working from the specs, also checking out some other code

I'm now wrapping id3lib into BCB6 object .
Need binary format of Volume Adjust Frame / Field
Need to extract kilo bytes per second encoding
Back to top
Lee_Nover
Guest





PostPosted: Thu May 17, 2007 8:12 am    Post subject: Re: MP3 tag info Reply with quote

Quote:
I'm now wrapping id3lib into BCB6 object .
Need binary format of Volume Adjust Frame / Field
Need to extract kilo bytes per second encoding

how's that going? :)

for what I need, ID3 reading is complete
I've added a special Relative Volume Adjustment frame
for V2.4 frames the units are expressed as (dB * 512), so, to get the dB value, use (TRVAChannelInfo.VolumeAdjustment / 512)
for V2.2 and 2.3 I have no clue what the units are :/

I will also add a common tag agnostic frame specifier and a mapper for frame types
eg: 'RVAD', 'RVA2', 'RVA' > ftRelativeVolumeAdjustment
also, when loading/saving, tags and frames will get updated to the newest version; 'RVA' > 'RVA2', 'PIC' > 'APIC', ...

note that the code is Delphi2006 and newer beucase I'm using records with methods and operator overloading!
you can checkout the latest from: svn://leenover.homeip.net/Public/DTag
or view it online: http://leenover.homeip.net/isapi/pas2html.dll/pas2html?File=/delphi/Projects/DTag/
or download the zip: http://leenover.homeip.net/delphi/Projects/DTag.zip

to get the RVA data do:

uses DTag.ID3, DTag.ID3.Frames;

LID3Tagger := TID3Tagger.Create;
if not LID3Tagger.OpenFile(...) then handleNoID3Tag;
// go through Tags or use the first one
LTag := LID3Tagger.Tags[0];
// go through frames and find the RVA frame
LFrame := LTag.Frames[I];
if LFrame is TID3RelativeVolumeAdjustment then
begin
LRVAFrame := TID3RelativeVolumeAdjustment(LFrame);
LRVAFrame.GetChannel() to get channel info
Back to top
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Multimedia All times are GMT
Page 1 of 1

 
 


Powered by phpBB © 2001, 2006 phpBB Group
.