Čteme data z ID3v1 tagů v PHP
Pokud jste už někdy dělali vlastní stránku na upload, kam jste si mohli nahrát soubor a poté se zobrazoval v seznamu souborů i s několika informacemi o něm a byl snadno dostupný ke stažení, určitě byste ocenili možnost přidat k těmto informacím i data z ID3 tagů. Konkrétně z ID3v1 tagů, díky jejich jednoduché struktuře. Protože je v2 nepoměrně složitější, tak bych v tomto případě doporučil nějakou specializovanou třídu.
Nejprve je potřeba si ujasnit strukturu ID3v1 tagu v souboru. Ten tvoří posledních 128 bytů v souboru, a to následujícím způsobem :
- 3 znaky - string “TAG” pokud se jedna o ID3v1 tag
- 30 znaků - název písničky
- 30 znaků - umělec
- 30 znaků - název alba
- 4 znaky - rok vydání
- 30 znaků - komentář
- 1 byt - žánr
Možná bude výstižnější tento obrázek z http://www.id3.org/

Pro čtení souboru použijeme funkci fread(), která za nás obstará převod z binárních hodnot na textové, takže nebudeme muset data unpackovat.
Implementace vypadá nějak takto :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | function GetId3Tags($filename) { //otevreni souboru pro cteni $file = fopen($filename, "r"); //kontrola jestli dany soubor existuje if ($file === FALSE) { return false; } //nastaveni ukazatele na pozici 128 bytu pred koncem souboru if (fseek($file, -128, SEEK_END)) { return false; } //nacteni poslednich 128 bytu souboru (ID3v1 tag) $tagdata = fread($file, 128); //kontrola jestli prvni tri pismena techto dat odpovidaji ID3 tagu if(substr($tagdata, 0, 3) != "TAG") { return false; } $id3tag = array(); //cteni id3tagu $id3tag['title'] = substr($tagdata, 3, 30); $id3tag['artist'] = substr($tagdata, 33, 30); $id3tag['album'] = substr($tagdata, 63, 30); $id3tag['year'] = substr($tagdata, 93, 4); $id3tag['comment'] = substr($tagdata, 97, 30); //prevod zanru na slovo $genreNo = hexdec(bin2hex(substr($tagdata, 127, 1))); $id3tag['genre'] = $GLOBALS['genres'][$genreNo]; return $id3tag; } ?> |
Doufám, že kód mluví sám za sebe, jenom bych rád dovysvětlil pár důležitých věcí. Jako poslední byte načteme sice číslo žánru, ale v textové podobě, ne binární. Proto jej převedeme do šestnáctkové soustavy, odkud ho poté převedeme do standardní desítkové soustavy. A poté podle tohoto čísla a pole žánrů, kde každému číslu odpovídá jeden žánr určíme textovou reprezentaci tohoto žánru.
Pole žánrů (v příkladu $genres) je následující:
$genres = array( 0 => 'Blues', 1 => 'Classic Rock', 2 => 'Country', 3 => 'Dance', 4 => 'Disco', 5 => 'Funk', 6 => 'Grunge', 7 => 'Hip-Hop', 8 => 'Jazz', 9 => 'Metal', 10 => 'New Age', 11 => 'Oldies', 12 => 'Other', 13 => 'Pop', 14 => 'R&B', 15 => 'Rap', 16 => 'Reggae', 17 => 'Rock', 18 => 'Techno', 19 => 'Industrial', 20 => 'Alternative', 21 => 'Ska', 22 => 'Death Metal', 23 => 'Pranks', 24 => 'Soundtrack', 25 => 'Euro-Techno', 26 => 'Ambient', 27 => 'Trip-Hop', 28 => 'Vocal', 29 => 'Jazz+Funk', 30 => 'Fusion', 31 => 'Trance', 32 => 'Classical', 33 => 'Instrumental', 34 => 'Acid', 35 => 'House', 36 => 'Game', 37 => 'Sound Clip', 38 => 'Gospel', 39 => 'Noise', 40 => 'Alternative Rock', 41 => 'Bass', 42 => 'Soul', 43 => 'Punk', 44 => 'Space', 45 => 'Meditative', 46 => 'Instrumental Pop', 47 => 'Instrumental Rock', 48 => 'Ethnic', 49 => 'Gothic', 50 => 'Darkwave', 51 => 'Techno-Industrial', 52 => 'Electronic', 53 => 'Pop-Folk', 54 => 'Eurodance', 55 => 'Dream', 56 => 'Southern Rock', 57 => 'Comedy', 58 => 'Cult', 59 => 'Gangsta', 60 => 'Top 40', 61 => 'Christian Rap', 62 => 'Pop/Funk', 63 => 'Jungle', 64 => 'Native US', 65 => 'Cabaret', 66 => 'New Wave', 67 => 'Psychadelic', 68 => 'Rave', 69 => 'Showtunes', 70 => 'Trailer', 71 => 'Lo-Fi', 72 => 'Tribal', 73 => 'Acid Punk', 74 => 'Acid Jazz', 75 => 'Polka', 76 => 'Retro', 77 => 'Musical', 78 => 'Rock & Roll', 79 => 'Hard Rock', 80 => 'Folk', 81 => 'Folk-Rock', 82 => 'National Folk', 83 => 'Swing', 84 => 'Fast Fusion', 85 => 'Bebob', 86 => 'Latin', 87 => 'Revival', 88 => 'Celtic', 89 => 'Bluegrass', 90 => 'Avantgarde', 91 => 'Gothic Rock', 92 => 'Progressive Rock', 93 => 'Psychedelic Rock', 94 => 'Symphonic Rock', 95 => 'Slow Rock', 96 => 'Big Band', 97 => 'Chorus', 98 => 'Easy Listening', 99 => 'Acoustic', 100 => 'Humour', 101 => 'Speech', 102 => 'Chanson', 103 => 'Opera', 104 => 'Chamber Music', 105 => 'Sonata', 106 => 'Symphony', 107 => 'Booty Bass', 108 => 'Primus', 109 => 'Porn Groove', 110 => 'Satire', 111 => 'Slow Jam', 112 => 'Club', 113 => 'Tango', 114 => 'Samba', 115 => 'Folklore', 116 => 'Ballad', 117 => 'Power Ballad', 118 => 'Rhytmic Soul', 119 => 'Freestyle', 120 => 'Duet', 121 => 'Punk Rock', 122 => 'Drum Solo', 123 => 'Acapella', 124 => 'Euro-House', 125 => 'Dance Hall', 126 => 'Goa', 127 => 'Drum & Bass', 128 => 'Club-House', 129 => 'Hardcore', 130 => 'Terror', 131 => 'Indie', 132 => 'BritPop', 133 => 'Negerpunk', 134 => 'Polsk Punk', 135 => 'Beat', 136 => 'Christian Gangsta Rap', 137 => 'Heavy Metal', 138 => 'Black Metal', 139 => 'Crossover', 140 => 'Contemporary Christian', 141 => 'Christian Rock', 142 => 'Merengue', 143 => 'Salsa', 144 => 'Trash Metal', 145 => 'Anime', 146 => 'Jpop', 147 => 'Synthpop'); ?>
Jenom si dejte pozor, kdybyste chtěli získávat ID3v1.1 data, protože ty jsou trochu jinak strukturovaná. A to tak, že pole comment je zkráceno z o dva znaky, po něm následuje nula (0) a následující byt je pořadí skladby na albu. Poté už je žánr, jako v ID3v1.
Ještě příklad použití na konec:
$data = GetId3Tags("01_Porcupine Tree - Blackest Eyes.mp3");
a obsah $data bude
Array ( [title] => Blackest Eyes [artist] => Porcupine Tree [album] => XM [year] => 2003 [comment] => [genre] => Progressive Rock )