 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Bill Guest
|
Posted: Tue Dec 19, 2006 9:34 pm Post subject: MP3 tag info |
|
|
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
|
Posted: Tue Dec 19, 2006 10:42 pm Post subject: Re: MP3 tag info |
|
|
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
|
Posted: Mon Apr 02, 2007 1:09 am Post subject: Re: MP3 tag info - Class TID3v2 |
|
|
| 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
|
Posted: Tue May 01, 2007 8:11 am Post subject: Re: MP3 tag info |
|
|
| 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
|
Posted: Wed May 02, 2007 9:35 pm Post subject: Re: MP3 tag info |
|
|
| 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
|
Posted: Thu May 03, 2007 9:57 pm Post subject: Re: MP3 tag info |
|
|
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
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
|
Posted: Fri May 04, 2007 1:17 am Post subject: Re: MP3 tag info |
|
|
| Quote: | how long are you willing to wait?
Will wait weeks , not months
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
|
Posted: Tue May 08, 2007 8:12 am Post subject: Re: MP3 tag info |
|
|
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
|
Posted: Thu May 17, 2007 8:12 am Post subject: Re: MP3 tag info |
|
|
| 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 |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|