PHP extensions for working with MP3

PHP extensions for working with MP3

Nowadays online music shops such as Musikload[1] became very popular. In that article I’ll tell you how you can read the meta-information of the mp3 file by means of PHP. It will allow you to create music catalogs. It is very simple, database support isn’t required.

How does mp3-player know the information about artist or the name of the current track? There are no wonders! Such information is stored in the files. Other formats such as WMA or Ogg Vorbis also have the same information but in that article we’ll talk about mp3.

mp3 specification has the music data storing method but it doesn’t have an opportunity of storing the track’s metadata such name and artist. To omit such restrictions there were created the ID3 standard. According to that specification metadata should be put in the ID3 tags.ID3 tags of the version 1 (ID3v1-Tags) have very simple construction and they are written at the end of the file. Its size shouldn’t be more than 128 bytes. Tag’s structure is as follows: after the string value “TAG” there should be the information about name (30 symbols), artist (30 symbols), album (30 symbols), year (four figures), comment (30 symbols), and genre (1 byte). Tag with such kind of structure looks like ID3v1.0-Tag. Also there is another format - ID3v1.1-Tag, it allows to store information about the track’s number.

PEAR will help you!

For reading the information from the ID3v1 tags MP3_Id[3] pack has been added to the PEAR library. It allows either to extract information from the tag or write it. Listing 1 shows how you can read information from the tags. It creates the MP3_ID class object, reads the file and then getTag() method extracts the data. Listing 2 shows the result.

Listing 1.

<?php 
require_once "MP3/Id.php"

// Create the object and read the file
$id3 = &new MP3_Id(); 
$result $id3->read("../data/Little-Big-Man.mp3"); 
if (
PEAR::isError($result)) { 
die(
$result->getMessage() . "n"); 


// Read the fields and print the information
echo "Name: " $id3->getTag("name") . "n"
echo 
"Artist: " $id3->getTag("artists") . "n"
echo 
"Album: " $id3->getTag("album") . "n"
echo 
"Year: " $id3->getTag("year") . "n"
echo 
"Comment: " $id3->getTag("comment") . "n"
echo 
"Genre: " $id3->getTag("genre") . "n"
echo 
"Genre (number): " $id3->getTag("genreno") . "n"
echo 
"Track: " $id3->getTag("track") . "n"
?>

Listing 2.

Name: Little Big Man 
Artist: Dirty Mac 
Album: Demo-Tape 
Year: 2001 
Comment: Song from the Demo-Tape album
Genre: Rock 
Genre (number): 17 
Track: 5

Listing 3 shows how you can change the content of the ID3 tags and create them. At first we create the MP3_ID class object (the same as in Listing 1), read the file and using the setTag($fieldname, $value) method write the required information to the tag. If you want to delete all tags look at the listing 4. For deleting the tags use remove() method.

Listing 3:

<?php 
require_once "MP3/Id.php"

// Create the object, read data
$id3 = &new MP3_Id(); 
$result $id3->read("../data/Little-Big-Man.mp3"); 
// Error "Tag not found" is ignored 
if (PEAR::isError($result) && $result->getCode() !== PEAR_MP3_ID_TNF) { 
die(
$result->getMessage() . "n"); 


// Define the information
$id3->setTag("name""Neuer Titel"); 
$id3->setTag("artists""Andere Band"); 
$id3->setTag("album""Schlagertraum #3"); 
$id3->setTag("year"1984); 
$id3->setTag("comment""Volksmusikal. Hochgenuss"); 
$id3->setTag("genre""Folk"); 
$id3->setTag("track"5); 

// Write the information to the tag
$result $id3->write(); 
if (
PEAR::isError($result)) { 
die(
$result->getMessage() . "n"); 


echo 
"Tag has been successfully recorded .! n"
?>

Listing 4:

<?php 
require_once "MP3/Id.php"

// // Create the object, read data
$id3 = &new MP3_Id(); 
$err $id3->read("../data/Little-Big-Man.mp3"); 
if (
PEAR::isError($err)) { 
die(
$err->getMessage() . "n"); 


// Remove the tag 
$result $id3->remove(); 
if (
PEAR::isError($result)) { 
die(
$result->getMessage() . "n"); 


echo 
" Tag has been successfully removed! n"
?>

Use PECL

In 2004 there appeared new PHP extension - ext/id3[7]. In contrast to MP3_ID that library is written on C, not PHP, that’s why it should work faster. If you want to use that extension you have to use PEAR-installer or compile the PHP with support of that extension.

That library allows to change the content of the ID3 tags. The only thing you should have is an array shown in the listing 6 and id3_set_tag() function. First parameter of that function is the name of the mp-3 file, second parameter is array with required information. Third parameter is optional one, it is the constant that shows the version of the ID3 tag. In the current version of that library id3_set_tag() works only with tags of 1.0 of 1.1 version. Listing 7 has the required php code. As an addition listing 8 shows how you can delete current tag using id3_remove_tag function.

Listing 5:

<?php 
// Name of the file 
$tag1 id3_get_tag("../data/Little-Big-Man.mp3"ID3_V1_1); 
print_r($tag1); 

// name of the file as URL 
$tag2 id3_get_tag("http://dirty-mac.com/sounds/little_big_man.mp3"ID3_V1_1); 
print_r($tag2); 

// Recourse identifier instead of the file name
$fd fopen("../data/Little-Big-Man.mp3""r"); 
$tag3 id3_get_tag($fdID3_V1_1); 
print_r($tag3); 
?>

Listing 6:

Array 

[title] => Little Big Man 
[artist] => Dirty Mac 
[album] => Demo-Tape 
[year] => 2001 
[comment] => Song vom Demo-Tape 
[track] => 5 
[genre] => 17 
)

Listing 7:

<?php 
$tag 
= array( 
"title" => "New title"
"artist" => "Other artist"
"album" => "Schlagertraum #3"
"year" => 1984
"genre" => id3_get_genre_id("Rock"), 
"comment" => "Great song"
"track" => 
); 

// Record the tag 
$result id3_set_tag("../data/Little-Big-Man.mp3"$tagID3_V1_1 ); 
if (
$result === false) { 
echo 
"Tag hasn’t been recorded! n"


echo 
"Tag has been recorded successfully! n";

Next generation

In spite of that fact that using the ID3v1 tags you can save important information about the mp3 file there appear some restrictions of 1.0 and 1.1 versions:

  • because of the fixed size of the tag saved information size is limited
  • amount of the saved attributes is limited

To overcome these restrictions there were created ID3 tags of the version 2[2] - ID3v2. ID3v2 tags are written at the beginning of the file. ID3v2 can contain more information than the ID3v1. It can be information about author's rights, BMP, or the text of the song. Because of the new opportunities of ID3v2 tags the process of reading is more complicated. If you execute the code in the listing 9 you’ll get the result shown in the listing 10.

Every frame of the ID3v2 tag has the unique ID. Ext/id3 has two functions that allow to learn the content of the frame. They are id3_get_frame_short() and id3_get_frame_long_name(). Their parameter is the frame’s id and return its description.

Listing 8

<?php 
// removes tag
$result id3_remove_tag("../data/Little-Big-Man.mp3"); 

if (
$result === false) { 
echo 
"Tag hasn’t been removed.! n"


echo 
" Tag has been removed successfully! n"
?>

Listing 9:

<?php 
//Read ID3v2 tag
$tag id3_get_tag("../data/Little-Big-Man.mp3"ID3_V2_3); 
print_r($tag); 
?>

Additional information

Using MP3_Id library you can not only read the information of the ID3 tags but also get the interesting information about the mp3 file. You can learn that information using study() method, and then using getTag() method you can select required data. Listing 12 shows its working. The result is shown in the listing 13.

Listing 10:

Array 

[copyright] => Dirty Mac 
[originalArtist] => Dirty Mac 
[composer] => Marcus Goetze 
[artist] => Dirty Mac 
[title] => Little Big Man 
[album] => Demo-Tape 
[track] => 5/12 
[genre] => (17)Rock 
[year] => 2001 
)

Listing 11:

<?php 
// Id ID3v2-Frames 
$frame "TOLY"
$short id3_get_frame_short_name($frame); 
$descr id3_get_frame_long_name($frame); 
echo 
"Frame: $frame n"
echo 
"Kurzform: $short n"
echo 
"Beschreibung: $descr n"
?>

Listing 12:

<?php 
require_once "MP3/Id.php"

// Create the object, read the data 
$id3 = &new MP3_Id(); 
$result $id3->read("../data/Little-Big-Man.mp3"); 
// Error "Tag not found" is ignored
if (PEAR::isError($result) && $result->getCode() !== PEAR_MP3_ID_TNF) { 
die(
$result->getMessage() . "n"); 


$result $id3->study(); 
if (
PEAR::isError($result)) { 
die(
$result->getMessage() . "n"); 


echo 
"MPEG " $id3->getTag("mpeg_ver") . " Layer " $id3->getTag("layer") . "n"
echo 
$id3->getTag("mode") . "n"
echo 
"File size: " $id3->getTag("filesize") . " Bytes n"
echo 
"Bitrate: " $id3->getTag("bitrate") . "kB/s n"
echo 
"Duration: " $id3->getTag("length") . " min n"
echo 
"Samplerate: " $id3->getTag("frequency") . "Hz n"
?>

Listing 13:

MPEG 1 Layer 3 
Joint Stereo 
Size: 4089856 Bytes 
Bitrate: 128kB/s 
Duration: 04:15 min 
Samplerate: 44100Hz

 

  • Top