Creating an ID3 Tags Reader with PHP

Tutorials

Today we will work with PHP again. Today’s tutorial will tell you about how you can use PHP to obtain ID3 meta info from music files (mp3). The easiest way to save id3 info – winamp software (try to find it in old archives). 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

[sociallocker]

download in package

[/sociallocker]


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

01 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
02 <head>
03     <title>ID3 Tags Reader with PHP | Script-tutorials</title>
04     <link rel="stylesheet" href="css/main.css" type="text/css" media="all" />
05 </head>
06 <body>
07     <div class="example" id="main">
08         <table style="width:100%">
09             <thead>
10                 <td><b>Title</b></td>
11                 <td><b>Album</b></td>
12                 <td><b>Author</b></td>
13                 <td><b>AlbumAuthor</b></td>
14                 <td><b>Track</b></td>
15                 <td><b>Year</b></td>
16                 <td><b>Lenght</b></td>
17                 <td><b>Lyric</b></td>
18                 <td><b>Desc</b></td>
19                 <td><b>Genre</b></td>
20             </thead>
21             __list__
22         </table>
23         <hr /><h3>Extra info</h3>
24         <table style="width:100%">
25             <thead>
26                 <td><b>Title</b></td>
27                 <td><b>Encoded</b></td>
28                 <td><b>Copyright</b></td>
29                 <td><b>Publisher</b></td>
30                 <td><b>OriginalArtist</b></td>
31                 <td><b>URL</b></td>
32                 <td><b>Comments</b></td>
33                 <td><b>Composer</b></td>
34             </thead>
35             __list2__
36         </table>
37     </div>
38 </body>
39 </html>

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

Step 2. CSS

Here are used CSS styles:

css/main.css

1 body{background-color:#ddd;margin:0;padding:0}
2 .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

001 <?php
002 // set error reporting level
003 if (version_compare(phpversion(), '5.3.0''>=') == 1)
004   error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
005 else
006   error_reporting(E_ALL & ~E_NOTICE);
007 // gathering all mp3 files in 'mp3' folder into array
008 $sDir 'mp3/';
009 $aFiles array();
010 $rDir = opendir($sDir);
011 if ($rDir) {
012     while ($sFile = readdir($rDir)) {
013         if ($sFile == '.' or $sFile == '..' or !is_file($sDir $sFile))
014             continue;
015         $aPathInfo pathinfo($sFile);
016         $sExt strtolower($aPathInfo['extension']);
017         if ($sExt == 'mp3') {
018             $aFiles[] = $sDir $sFile;
019         }
020     }
021     closedir$rDir );
022 }
023 // new object of our ID3TagsReader class
024 $oReader new ID3TagsReader();
025 // passing through located files ..
026 $sList $sList2 '';
027 foreach ($aFiles as $sSingleFile) {
028     $aTags $oReader->getTagsInfo($sSingleFile); // obtaining ID3 tags info
029     $sList .= '<tr><td>'.$aTags['Title'].'</td><td>'.$aTags['Album'].'</td><td>'.$aTags['Author'].'</td>
030                     <td>'.$aTags['AlbumAuthor'].'</td><td>'.$aTags['Track'].'</td><td>'.$aTags['Year'].'</td>
031                     <td>'.$aTags['Lenght'].'</td><td>'.$aTags['Lyric'].'</td><td>'.$aTags['Desc'].'</td>
032                     <td>'.$aTags['Genre'].'</td></tr>';
033     $sList2 .= '<tr><td>'.$aTags['Title'].'</td><td>'.$aTags['Encoded'].'</td><td>'.$aTags['Copyright'].'</td>
034                     <td>'.$aTags['Publisher'].'</td><td>'.$aTags['OriginalArtist'].'</td><td>'.$aTags['URL'].'</td>
035                     <td>'.$aTags['Comments'].'</td><td>'.$aTags['Composer'].'</td></tr>';
036 }
037 // main output
038 echo strtr(file_get_contents('main_page.html'), array('__list__' => $sList'__list2__' => $sList2));
039 // class ID3TagsReader
040 class ID3TagsReader {
041     // variables
042     var $aTV23 array// array of possible sys tags (for last version of ID3)
043         'TIT2',
044         'TALB',
045         'TPE1',
046         'TPE2',
047         'TRCK',
048         'TYER',
049         'TLEN',
050         'USLT',
051         'TPOS',
052         'TCON',
053         'TENC',
054         'TCOP',
055         'TPUB',
056         'TOPE',
057         'WXXX',
058         'COMM',
059         'TCOM'
060     );
061     var $aTV23t array// array of titles for sys tags
062         'Title',
063         'Album',
064         'Author',
065         'AlbumAuthor',
066         'Track',
067         'Year',
068         'Lenght',
069         'Lyric',
070         'Desc',
071         'Genre',
072         'Encoded',
073         'Copyright',
074         'Publisher',
075         'OriginalArtist',
076         'URL',
077         'Comments',
078         'Composer'
079     );
080     var $aTV22 array// array of possible sys tags (for old version of ID3)
081         'TT2',
082         'TAL',
083         'TP1',
084         'TRK',
085         'TYE',
086         'TLE',
087         'ULT'
088     );
089     var $aTV22t array// array of titles for sys tags
090         'Title',
091         'Album',
092         'Author',
093         'Track',
094         'Year',
095         'Lenght',
096         'Lyric'
097     );
098     // constructor
099     function ID3TagsReader() {}
100     // functions
101     function getTagsInfo($sFilepath) {
102         // read source file
103         $iFSize filesize($sFilepath);
104         $vFD fopen($sFilepath,'r');
105         $sSrc fread($vFD,$iFSize);
106         fclose($vFD);
107         // obtain base info
108         if (substr($sSrc,0,3) == 'ID3') {
109             $aInfo['FileName'] = $sFilepath;
110             $aInfo['Version'] = hexdec(bin2hex(substr($sSrc,3,1))).'.'.hexdec(bin2hex(substr($sSrc,4,1)));
111         }
112         // passing through possible tags of idv2 (v3 and v4)
113         if ($aInfo['Version'] == '4.0' || $aInfo['Version'] == '3.0') {
114             for ($i = 0; $i count($this->aTV23); $i++) {
115                 if (strpos($sSrc$this->aTV23[$i].chr(0)) != FALSE) {
116                     $s '';
117                     $iPos strpos($sSrc$this->aTV23[$i].chr(0));
118                     $iLen = hexdec(bin2hex(substr($sSrc,($iPos + 5),3)));
119                     $data substr($sSrc$iPos, 9 + $iLen);
120                     for ($a = 0; $a strlen($data); $a++) {
121                         $char substr($data$a, 1);
122                         if ($char >= ' ' && $char <= '~')
123                             $s .= $char;
124                     }
125                     if (substr($s, 0, 4) == $this->aTV23[$i]) {
126                         $iSL = 4;
127                         if ($this->aTV23[$i] == 'USLT') {
128                             $iSL = 7;
129                         elseif ($this->aTV23[$i] == 'TALB') {
130                             $iSL = 5;
131                         elseif ($this->aTV23[$i] == 'TENC') {
132                             $iSL = 6;
133                         }
134                         $aInfo[$this->aTV23t[$i]] = substr($s$iSL);
135                     }
136                 }
137             }
138         }
139         // passing through possible tags of idv2 (v2)
140         if($aInfo['Version'] == '2.0') {
141             for ($i = 0; $i count($this->aTV22); $i++) {
142                 if (strpos($sSrc$this->aTV22[$i].chr(0)) != FALSE) {
143                     $s '';
144                     $iPos strpos($sSrc$this->aTV22[$i].chr(0));
145                     $iLen = hexdec(bin2hex(substr($sSrc,($iPos + 3),3)));
146                     $data substr($sSrc$iPos, 6 + $iLen);
147                     for ($a = 0; $a strlen($data); $a++) {
148                         $char substr($data$a, 1);
149                         if ($char >= ' ' && $char <= '~')
150                             $s .= $char;
151                     }
152                     if (substr($s, 0, 3) == $this->aTV22[$i]) {
153                         $iSL = 3;
154                         if ($this->aTV22[$i] == 'ULT') {
155                             $iSL = 6;
156                         }
157                         $aInfo[$this->aTV22t[$i]] = substr($s$iSL);
158                     }
159                 }
160             }
161         }
162         return $aInfo;
163     }
164 }
165 ?>

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

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!

Rate article