|
ID3v2
The Programmer's Reference Guide: ID3v2 Class
PHP-Reader Documentation: ID3v2 ClassBy wphilipw, svollbehr, buttza IntroductionThe ID3v2 class provides a full implementation of the ID3v2.3.0 and ID3v2.4.0 standards as defined by ID3.org. The ID3 tag can be used with various files including MPEG Layer III, or MP3 files. The class is capable of both reading and writing tag information. Table of Contents
Class Information
ExamplesExample #1: How to read ID3v2 informationThe simplest way to use the ID3v2 class is to have it get a specific frame by its identifier. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
$frame = $id3->getFramesByIdentifier("TIT2"); // for song title; or TALB for album title; ..
$title = $frame[0]->getText();
$frame = $id3->getFramesByIdentifier("APIC"); // for attached picture
$image = $frame[0]->getImageType();As already so familiar from the ID3v1 class, the class also supports shorthands for retrieving and assigning frames and their fields. The above code could also be written as shown below. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
$title = $id3->tit2->text; // contains the first song title; or talb->text for album title; ...
$image = $id3->apic->imageType; // contains the first attached picture typePlease note that should you access a frame that does not exist no error is triggered. Instead, the frame gets implicitly created and added to the class instance. The newly created instance is then passed to the caller. So if you call for $id3->time->text and there is no TIME frame in the tag, you will get the default value of a newly created TIME frame object instance, or an empty string. This is a feature that allows one to quickly set frame values without explicitly adding the frame to the tag. However, this might lead to a problem of determining whether the tag contains a particular frame. The following code shows how to check frame existance. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
if ($id3->hasFrame("TIME"))
echo "The value of TIME is " . $id3->time->text . "\n";
// or with isset ..
if (isset($id3->time))
echo "The value of TIME is " . $id3->time->text . "\n";Example #2: Other ways to read ID3v2 informationAs the most common reason to read ID3 tags is to get the song information, it is often sufficient to get out just the textual information of an ID3v2 tag. This can easily be done with just a few lines of code by using tag selector as shown below. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
$id3info = array()
foreach ($id3->getFramesByIdentifier("T*") as $frame)
$id3info[$frame->identifier] = $frame->text;
print_r($id3info); // will print all textual information found from the tagHowever, more often than not, there is not just one single piece of information that you would like to output, but rather, you would like to output as much information as possible. You can loop through all the frames and create custom output for individual frame types as shown in the example below. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
foreach ($id3->frames as $frames) {
foreach ($frames as $frame) {
echo $frame->identifier;
if ($frame instanceof ID3_Frame_AbstractText)
echo ": " . $frame->text;
if ($frame instanceof ID3_Frame_AbstractLink)
echo ": " . $frame->link;
if ($frame instanceof ID3_Frame_APIC)
echo ": " . $frame->imageType;
// etc..
echo "\n";
}
}Example #3: How to write ID3v2 informationWriting an ID3v2 tag is no harder than writing an ID3v1 tag. One may simply create an instance of the class, assign needed values and commit the changes. <?php
require_once("ID3v2.php");
$id3 = new ID3v2();
$tit2 = new ID3_Frame_TIT2();
$tit2->setText("My song title");
$id3->addFrame($tit2);
$id3->write("file.mp3");It is also possible to read current tag content, alter it and then rewrite it back to the media file. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
$id3->getFramesByIdentifier("TIT2")[0]->setText
($id3->getFramesByIdentifier("TIT2")[0]->getText() . " by me!"); // append something to the title
$talb = new ID3_Frame_TALB();
$talb = "My album";
$id3->addFrame($talb);
$id3->write();Similarly to when you read the tag information, you can also use the class shorthands to assign the information. The above code can also be written as follows. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
$id3->tit2->text = "{$id3->tit2->text} by me!"; // append something to the title
$id3->talb->text = "My album";
$id3->write();Example #4: Case study: How to display album cover imageID3v2 can also contain images you might say. Well, there is a way to read them. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3");
header("Content-Type: " . $id3->apic->mimeType);
echo $id3->apic->imageData;No harder than that! Example #5: Case study: How to extract cover images from music filesIn a slightly harder example we extract the cover images from a directory full of music files. In this example we first scan the whole directory looking for MP3 files. After ensuring the file contains a valid ID3v2 tag and actually has a cover image, we gather information about the image and write the image data to a separate file, or the same file with an added image suffix. <?php
require_once("ID3v2.php");
$directory = "../change/path/to/mp3/directory/here";
/* Retrieve all files in the directory */
foreach (glob($directory . "/*.mp3") as $file) {
echo "Reading " . $file . "\n";
/* Attempt to parse the file, catching any exceptions */
try {
$id3 = new ID3v2($file);
}
catch (ID3_Exception $e) {
echo " " . $e->getMessage() . "\n";
continue;
}
if (isset($id3->apic)) {
echo " Found a cover image, writing image data to a separate file..\n";
/* Write the image */
$type = split("/", $id3->apic->mimeType, 2);
if (($handle = fopen
($image = $file . "." . $type[1], "wb")) !== false) {
if (fwrite($handle, $id3->apic->imageData,
$id3->apic->imageSize) != $id3->apic->imageSize)
echo " Found a cover image, but unable to write image file: " .
$image . "\n";
fclose($handle);
}
else echo " Found a cover image, but unable to open image file " .
"for writing: " . $image . "\n";
} else
echo " No cover image found!\n";
}
?>One can run the script from a command prompt or terminal. With a little tuning, one could even take the source directory from the command line arguments. Example #6: Case study: How to bulk edit ID3 tagsBulk editing ID3 tags might come in handy in several occations. Say, you forgot to enter the year to all of the songs ripped in the whole last month, or you want to update the link to your website. Whatever the case, in this example, similarly to the last example, we go through all the files of a directory, and perform a single edit or multiple edits at once to each file one at a time. Changes can be written back to the original file or saved to an alternate location. <?php
require_once("ID3v2.php");
$directory = "../change/path/to/mp3/directory/here";
/* Retrieve all files in the directory */
foreach (glob($directory . "/*.mp3") as $file) {
echo "Reading " . $file . "\n";
/* Attempt to parse and edit the file, catching any exceptions */
try {
$id3 = new ID3v2($file);
// Edit the following to match your editing needs
$id3->txxx->text = "Edited by PHP Reader http://php-reader.googlecode.com/";
// Finally, write changes back to the original file
$id3->write();
// ..or to an another file
$id3->write("another/directory/" . basename($file));
// ..or both
echo " File successfully edited!\n";
}
catch (ID3_Exception $e) {
echo " " . $e->getMessage() . "\n";
continue;
}
}
?>One can run the script from a command prompt or terminal. Example #7: Version jugglingBy default, the ID3v2 class recognizes the version of the standard used to write the tag. When you write a new tag, the class defaults to the newest version 4.0. You can change this behaviour by giving an options array to the constructor as shown below. <?php
require_once("ID3v2.php");
$id3 = new ID3v2(array("version" => 3.0));
$id3->tyer->text = "2000";
$id3->write(); // writes ID3v2.3.0 compliant tagIt is also possible to change the version information on a read tag. However, you must be carefull not to leave any deprecated or unsupported frames to the tag. <?php
require_once("ID3v2.php");
$id3 = new ID3v2("file.mp3"); // read ID3v2.4.0 by default
$id3->getHeader()->setVersion(3.0);
$id3->write(); // write ID3v2.3.0See the class documentation found in the source package for the documentation for all the available tag frames and their fields. Also, leave a comment if you come up with an idea for an example that would be nice to have added here! |
Sign in to add a comment
Programme foireux sur la fonction write. Impossible de ré-écrire les tags sur le même fichier ouvert par fopen. Merci de corriger, ça évitera qu'on se prenne la tête pour rien.
when doing this <?php require_once("ID3v2.php");
$id3 = new ID3v2(); $tit2 = new ID3_Frame_TIT2(); $tit2->setText("My song title"); $id3->addFrame($tit2); $id3->write("file.mp3");
i get a error : unexpected T_CLASS in /audio/php-reader-1.6.3/lib/ID3v2.php on line 71
I'd like to see an example of how to write to a tag in ISO88591 encoding, as Windows Media Player can not play a mp3 that has an UTF encoded tag.
This code seems to have a bug. When I attempt to modify an MP3 with an ID3v2.3.0 tag, it corrupts the file such that it can no longer be played. Here is the code I tried:
require_once("ID3v2.php"); $filename = 'STE-003.mp3'; echo "<pre>\n"; $newAlbum = "Test set Album again"; $id3 = new ID3v2($filename); $type = 'id3v2'; $title = $id3->tit2->text; $version = $id3->getHeader()->getVersion(); $album = $id3->talb->text;
echo "The $type version $version title of $filename is '$title' and the album is '$album'\n"; $id3->talb->text = $newAlbum; echo "modifying the original file $filename to the album $newAlbum\n"; //$id3->getHeader()->setVersion(4.0); $id3->write(); // with the new album name echo "</pre>\n";
I set the ID3 tags on the file using audacity 1.2.6. The output of the test run was:
The id3v2 version 3 title of STE-003.mp3 is 'title set in audacity' and the album is 'album set in audacity' modifying the original file STE-003.mp3 to the album Test set Album again
If I set the version to 4.0 before the write() (see the commented out line), the file remains playable, but my version of windows media player (9.00.00.4530) does not see the tag.
I'd like to use this code, if it could read AND write version 3.0 correctly.
Thanks, David
I can confirm this bug: this php id3v2 lib has critical issues with version 3.0 of the id3v2 tag.
In my case, i cant even set the version properly from 3.0 to 4.0 as the call to id3->write() never returns.
This appears to work with id3v2.3
http://getid3.sourceforge.net/
my apologies if its inappropriate to list other projects like this. Hope it helps someone.