Creating an ID3 Tags Reader with PHP

Date: 26th Aug 2011 Author: admin 8 Comments
Posted in: PHP

ID3 Tags Reader with PHP

ID3 Tags Reader with PHP

Today we will work with PHP again. Today I will show you how you can use PHP to obtain ID3 meta info from music files (mp3). Most easy way to store id3 info – winamp software. So you will able to test our result script with your music files. We will extract next fields: Title, Album, Author, Discription, Genre, Publisher, OriginalArtist, URL etc.

Live Demo
download in package

Now – download the example files and lets start coding !


Step 1. HTML

As usual, we start with the HTML. This is source of demo page layout:

main_page.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>ID3 Tags Reader with PHP | Script-tutorials</title>
    <link rel="stylesheet" href="css/main.css" type="text/css" media="all" />
</head>
<body>
    <div class="example" id="main">
        <table style="width:100%">
            <thead>
                <td><b>Title</b></td>
                <td><b>Album</b></td>
                <td><b>Author</b></td>
                <td><b>AlbumAuthor</b></td>
                <td><b>Track</b></td>
                <td><b>Year</b></td>
                <td><b>Lenght</b></td>
                <td><b>Lyric</b></td>
                <td><b>Desc</b></td>
                <td><b>Genre</b></td>
            </thead>
            __list__
        </table>

        <hr /><h3>Extra info</h3>
        <table style="width:100%">
            <thead>
                <td><b>Title</b></td>
                <td><b>Encoded</b></td>
                <td><b>Copyright</b></td>
                <td><b>Publisher</b></td>
                <td><b>OriginalArtist</b></td>
                <td><b>URL</b></td>
                <td><b>Comments</b></td>
                <td><b>Composer</b></td>
            </thead>
            __list2__
        </table>

    </div>
</body>
</html>

I prepared 2 tables to display ID3 infos of each enumerated file

Step 2. CSS

Here are used CSS styles:

css/main.css

body{background-color:#ddd;margin:0;padding:0}
.example{position:relative;background-color:#fff;width:980px;height:700px;border:1px #000 solid;margin:20px auto;padding:20px;-moz-border-radius:3px;-webkit-border-radius:3px}

Step 3. PHP

Our most important part of project – PHP.

index.php

<?php

// set error reporting level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE);

// gathering all mp3 files in 'mp3' folder into array
$sDir = 'mp3/';
$aFiles = array();
$rDir = opendir($sDir);
if ($rDir) {
    while ($sFile = readdir($rDir)) {
        if ($sFile == '.' or $sFile == '..' or !is_file($sDir . $sFile))
            continue;

        $aPathInfo = pathinfo($sFile);
        $sExt = strtolower($aPathInfo['extension']);
        if ($sExt == 'mp3') {
            $aFiles[] = $sDir . $sFile;
        }
    }
    closedir( $rDir );
}

// new object of our ID3TagsReader class
$oReader = new ID3TagsReader();

// passing through located files ..
$sList = $sList2 = '';
foreach ($aFiles as $sSingleFile) {
    $aTags = $oReader->getTagsInfo($sSingleFile); // obtaining ID3 tags info
    $sList .= '<tr><td>'.$aTags['Title'].'</td><td>'.$aTags['Album'].'</td><td>'.$aTags['Author'].'</td>
                    <td>'.$aTags['AlbumAuthor'].'</td><td>'.$aTags['Track'].'</td><td>'.$aTags['Year'].'</td>
                    <td>'.$aTags['Lenght'].'</td><td>'.$aTags['Lyric'].'</td><td>'.$aTags['Desc'].'</td>
                    <td>'.$aTags['Genre'].'</td></tr>';

    $sList2 .= '<tr><td>'.$aTags['Title'].'</td><td>'.$aTags['Encoded'].'</td><td>'.$aTags['Copyright'].'</td>
                    <td>'.$aTags['Publisher'].'</td><td>'.$aTags['OriginalArtist'].'</td><td>'.$aTags['URL'].'</td>
                    <td>'.$aTags['Comments'].'</td><td>'.$aTags['Composer'].'</td></tr>';
}

// main output
echo strtr(file_get_contents('main_page.html'), array('__list__' => $sList, '__list2__' => $sList2));

// class ID3TagsReader
class ID3TagsReader {

    // variables
    var $aTV23 = array( // array of possible sys tags (for last version of ID3)
        'TIT2',
        'TALB',
        'TPE1',
        'TPE2',
        'TRCK',
        'TYER',
        'TLEN',
        'USLT',
        'TPOS',
        'TCON',
        'TENC',
        'TCOP',
        'TPUB',
        'TOPE',
        'WXXX',
        'COMM',
        'TCOM'
    );
    var $aTV23t = array( // array of titles for sys tags
        'Title',
        'Album',
        'Author',
        'AlbumAuthor',
        'Track',
        'Year',
        'Lenght',
        'Lyric',
        'Desc',
        'Genre',
        'Encoded',
        'Copyright',
        'Publisher',
        'OriginalArtist',
        'URL',
        'Comments',
        'Composer'
    );
    var $aTV22 = array( // array of possible sys tags (for old version of ID3)
        'TT2',
        'TAL',
        'TP1',
        'TRK',
        'TYE',
        'TLE',
        'ULT'
    );
    var $aTV22t = array( // array of titles for sys tags
        'Title',
        'Album',
        'Author',
        'Track',
        'Year',
        'Lenght',
        'Lyric'
    );

    // constructor
    function ID3TagsReader() {}

    // functions
    function getTagsInfo($sFilepath) {
        // read source file
        $iFSize = filesize($sFilepath);
        $vFD = fopen($sFilepath,'r');
        $sSrc = fread($vFD,$iFSize);
        fclose($vFD);

        // obtain base info
        if (substr($sSrc,0,3) == 'ID3') {
            $aInfo['FileName'] = $sFilepath;
            $aInfo['Version'] = hexdec(bin2hex(substr($sSrc,3,1))).'.'.hexdec(bin2hex(substr($sSrc,4,1)));
        }

        // passing through possible tags of idv2 (v3 and v4)
        if ($aInfo['Version'] == '4.0' || $aInfo['Version'] == '3.0') {
            for ($i = 0; $i < count($this->aTV23); $i++) {
                if (strpos($sSrc, $this->aTV23[$i].chr(0)) != FALSE) {

                    $s = '';
                    $iPos = strpos($sSrc, $this->aTV23[$i].chr(0));
                    $iLen = hexdec(bin2hex(substr($sSrc,($iPos + 5),3)));

                    $data = substr($sSrc, $iPos, 9 + $iLen);
                    for ($a = 0; $a < strlen($data); $a++) {
                        $char = substr($data, $a, 1);
                        if ($char >= ' ' && $char <= '~')
                            $s .= $char;
                    }
                    if (substr($s, 0, 4) == $this->aTV23[$i]) {
                        $iSL = 4;
                        if ($this->aTV23[$i] == 'USLT') {
                            $iSL = 7;
                        } elseif ($this->aTV23[$i] == 'TALB') {
                            $iSL = 5;
                        } elseif ($this->aTV23[$i] == 'TENC') {
                            $iSL = 6;
                        }
                        $aInfo[$this->aTV23t[$i]] = substr($s, $iSL);
                    }
                }
            }
        }

        // passing through possible tags of idv2 (v2)
        if($aInfo['Version'] == '2.0') {
            for ($i = 0; $i < count($this->aTV22); $i++) {
                if (strpos($sSrc, $this->aTV22[$i].chr(0)) != FALSE) {

                    $s = '';
                    $iPos = strpos($sSrc, $this->aTV22[$i].chr(0));
                    $iLen = hexdec(bin2hex(substr($sSrc,($iPos + 3),3)));

                    $data = substr($sSrc, $iPos, 6 + $iLen);
                    for ($a = 0; $a < strlen($data); $a++) {
                        $char = substr($data, $a, 1);
                        if ($char >= ' ' && $char <= '~')
                            $s .= $char;
                    }

                    if (substr($s, 0, 3) == $this->aTV22[$i]) {
                        $iSL = 3;
                        if ($this->aTV22[$i] == 'ULT') {
                            $iSL = 6;
                        }
                        $aInfo[$this->aTV22t[$i]] = substr($s, $iSL);
                    }
                }
            }
        }
        return $aInfo;
    }
}

?>

After put your mp3 files near these code files thats all. Yes, there are a lot of code, but everything is close. Commonly – you can check code in beginning (before defining of class), and class itself. First half is very easy – passing through files of folder, and generating output. So about class itself (ID3TagsReader) – this is more difficult. We will read hex code of each MP3 file and looking for inner information (ID3). I will try to pick all ID3 tags which can be available in Winamp (mp3 player). But I can say that the total of all possible tags is much more.


Live Demo
download in archive

Conclusion

I hope today’s article was very interesting for you. This material can be of great interest for projects that work with the music. This will help you get a variety of information from music files without including another large libraries. Good luck in your work!

Enjoyed this Post?

If you enjoyed this article, feel free to share our tutorial with your friends.
   
   
   

Stay connected with us:

7 Comments

    • John More's Gravatar
    • Hello there, while trying to implement your ID3CLASSREADER class I came upon some things I wanted to share with you so that you can maybe help me out. So first thing I love using ezsql when working with php + sql, however it seems that your class turns ezsql useless lol which is nothing really serious but just so you know. The second thing I came across is the fact that a lot of mp3′s get they’re titles or albums chopped up by exactly one letter at the end, or at the begining, and sometimes both! Also some characters like “(” or “/” appear sometimes in the titles, artists or album titles. I was trying to use your class to get all the id3 of 1000 mp3′s inside a folder while retrieving them to a sql database. Just by “echo”ing it all I came up with those small bugs.

      I’ve been using other scripts but none was able to read as much id3 as yours, without those small bugs it would render this script perfect for me.

      Could you help me out?

      John More

    • sam's Gravatar
    • Shubham Sharma's Gravatar
    • Thank u..

      yoyr script is working correctly.

      but i also want to fetch the thumbnail of that mp3 file..

      can u help me in this…?

    • Shubham Sharma's Gravatar
  1. 40 Best Web Design And Development Tutorials From August 2011 | stylishwebdesigner on August 30, 2011 at 5:45 am

Leave a Reply

Your email address will not be published. Required fields are marked *

*


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>