Версия для печати

PHP расширения для работы с MP3

Сегодня музыкальные интернет-магазины, как, например Musikload, приобрели большую популярность. В этой статье я расскажу вам о считывании метаинформации mp3 файлов посредством PHP, что позволит вам создавать музыкальные каталоги. Это довольно просто, поддержка базы данных не требуется.

Откуда mp3 плеер знает информацию об исполнителе или названии проигрываемого трека? В этом нет никаких чудес! Эта информация хранится в файлах. Музыкальные файлы других форматов, таких как WMA или Ogg Vorbis, также содержат эту информацию, но в этой статье мы поговорим о формате mp3.

Спецификация mp3 определяет способ хранения музыкальных данных, но не предусматривает возможности сохранения метаданных трека, например названия или имени исполнителя. Чтобы миновать эти ограничения, был создан стандарт ID3. Согласно этой спецификации, метаданные должны быть помещены в ID3-теги. ID3-теги первой версии (ID3v1-Tags) имеют простую конструкцию и пишутся в конце файла. Их размер не должен превышать 128 байтов. Структура тегов следующая: за строковым значением «TAG» должна следовать информация о названии (30 символов), исполнителе (30 символов), альбоме (30 символов), годе выпуска (четырехзначное число), а также комментарий (30 символов) и жанр (1 байт). Тэг с такой структурой выглядит так: ID3v1.0-Tag. Существует еще один формат - ID3v1.1-Tag. Он позволяет хранить информацию о порядковом номере трека.

Для считывания информации с ID3v1-тегов в библиотеку PEAR уже включили пакет MP3_Id[3]. Это позволят извлекать информацию из тега и записывать ее. Листинг 1 показывает, как считывать информацию с тегов. При этом создается объект класса MP3_ID, далее происходит считывание файла, после чего методом getTag() производится извлечение информации. Результаты показаны в Листинге 2.

Листинг 1
  1. <?php
  2.  
  3. require_once "MP3/Id.php";
  4.  
  5. // Создаём объект и читаем файл
  6.  
  7. $id3 = &new MP3_Id();
  8. $result = $id3->read("../data/Little-Big-Man.mp3");
  9.  
  10. if (PEAR::isError($result)) {
  11. die($result->getMessage() . "\n");
  12. }
  13.  
  14. // Читаем поля и выволдим информацию
  15. echo "Имя: " . $id3->getTag("name") . "\n";
  16. echo "Исполнитель: " . $id3->getTag("artists") . "\n";
  17. echo "Альбом: " . $id3->getTag("album") . "\n";
  18. echo "Год: " . $id3->getTag("year") . "\n";
  19. echo "Комментарий: " . $id3->getTag("comment") . "\n";
  20. echo "Жанр: " . $id3->getTag("genre") . "\n";
  21. echo "Жанр (номер): " . $id3->getTag("genreno") . "\n";
  22. echo "Трэк: " . $id3->getTag("track") . "\n";
  23.  
  24. ?>

Листинг 1
Имя: Little Big Man
Исполнитель: Dirty Mac
Альбом: Demo-Tape
Год: 2001
Комментарий: Song from the Demo-Tape album
Жанр: Rock
Жанр (номер): 17
Трэк: 5

Листинг 3 показывает, как можно менять содержимое ID3-тегов, а также создавать их. Сначала создается объект класса MP3_ID (так же, как в Листинге 1), затем происходит считывание файла, а после, посредством использования метода setTag($fieldname, $value), в тег помещается нужная информация. Если вы хотите удалить все теги, ознакомьтесь с Листингом 4. Для удаления тегов используйте метод remove().

Листинг 3
  1. <?php
  2.  
  3. require_once 'MP3/Id.php';
  4.  
  5. // создаем объект, читаем данные
  6. $id3 = &new MP3_Id();
  7. $result = $id3->read('../data/Little-Big-Man.mp3');
  8.  
  9. // Ошибка "Tag not found" игнорируется
  10. if (PEAR::isError($result) && $result->getCode() !== PEAR_MP3_ID_TNF) {
  11. die($result->getMessage() . "\n");
  12. }
  13.  
  14. // Определяем информацию
  15. $id3->setTag('name', 'Neuer Titel');
  16. $id3->setTag('artists', 'Andere Band');
  17. $id3->setTag('album', 'Schlagertraum #3');
  18. $id3->setTag('year', 1984);
  19. $id3->setTag('comment', 'Volksmusikal. Hochgenuss');
  20. $id3->setTag('genre', 'Folk');
  21. $id3->setTag('track', 5);
  22.  
  23. // Записываем информацию в тег
  24. $result = $id3->write();
  25. if (PEAR::isError($result)) {
  26. die($result->getMessage() . "\n");
  27. }
  28.  
  29. echo "Тег успешно записан!\n";
  30.  
  31. ?>
Листинг 4
  1. <?php
  2. require_once 'MP3/Id.php';
  3.  
  4. // Создаем объект, читаем файл
  5. $id3 = &new MP3_Id();
  6. $err = $id3->read('../data/Little-Big-Man.mp3');
  7. if (PEAR::isError($err)) {
  8. die($err->getMessage() . "\n");
  9. }
  10.  
  11. // Удаляем тег
  12. $result = $id3->remove();
  13. if (PEAR::isError($result)) {
  14. die($result->getMessage() . "\n");
  15. }
  16.  
  17. echo "Тег успешно стерт!\n";
  18. ?>

Использование PECL

В 2004 году появилось новое PHP расширение - ext/id3[7]. В отличие от MP3_ID эта библиотека написана на языке С, а не PHP, поэтому она должна работать быстрее. Для того чтобы использовать это расширение, следует воспользоваться PEAR-installer или компилировать PHP, включив поддержку этого расширения. Эта библиотека позволяет изменять содержимое ID3-тегов. Для этого вам потребуется всего лишь массив, как в Листинге 6, а также функция id3_set_tag(). Первым параметром данной функции является название mp3 файла. Второй параметр – массив с необходимой информацией. Третий параметр – необязательный. Он представляет собой константу, показывающую версию ID3-тега. В настоящей версии библиотеки функция id3_set_tag() работает только с тегами версии 1.0 и 1.1. В Листинге 7 содержится необходимый код php. В дополнение к этому Листинг 8 показывает, как удалить настоящий тег, используя функцию id3_remove_tag.

Листинг 5
  1. <?php
  2.  
  3. // имя файла на локальном диске
  4. $tag1 = id3_get_tag('../data/Little-Big-Man.mp3', ID3_V1_1);
  5. print_r($tag1);
  6.  
  7. // имя файла в виде URL
  8. // Внимание! Или вы подключаетесь к DSL, или ждете ;-)
  9. $tag2 = id3_get_tag('http://dirty-mac.com/sounds/little_big_man.mp3', ID3_V1_1);
  10. print_r($tag2);
  11.  
  12. // идентификатор ресурса вместо имени файла
  13. $fd = fopen('../data/Little-Big-Man.mp3', 'r');
  14. $tag3 = id3_get_tag($fd, ID3_V1_1);
  15. print_r($tag3);
  16. ?>
Листинг 6
 
Array 
( 
[title] => Little Big Man 
[artist] => Dirty Mac 
[album] => Demo-Tape 
[year] => 2001 
[comment] => Song vom Demo-Tape 
[track] => 5 
[genre] => 17 
)

Листинг 7
  1.  
  2. <?php
  3.  
  4. $tag = array(
  5. 'title' => 'Новое название',
  6. 'artist' => 'Другая группа',
  7. 'album' => 'Schlagertraum #3',
  8. 'year' => 1984,
  9. 'genre' => id3_get_genre_id('Rock'),
  10. 'comment' => 'Отличная популярная мелодия',
  11. 'track' => 5
  12. );
  13.  
  14. // Записываем тег
  15. $result = id3_set_tag('../data/Little-Big-Man.mp3', $tag, ID3_V1_1 );
  16. if ($result === false) {
  17. echo "Тег не был успешно записан!\n";
  18. }
  19.  
  20. echo "Тег успешно записан!\n";
  21.  
  22. ?>

Новое поколение

Несмотря на то, что использование ID3-тегов позволяет сохранять важную информацию о содержимом mp3 файлов, существует несколько ограничений для версий 1.0 и 1.1:

в связи с фиксированным размером тега ограничен размер сохраняемой информации;

ограничено количество сохраняемых атрибутов.

Для того чтобы устранить эти ограничения, были созданы ID3-теги версии 2[2] - ID3v2. Теги ID3v2 записываются в начале файла. Они могут содержать больше информации, чем ID3v1-теги. Такой информацией может быть информация об авторских правах, BMP или тексте песен. Новые возможности тегов ID3v2 значительно усложнили процесс считывания информации. При исполнении кода из Листинга 9 получится результат, указанный в Листинге 10.

Каждый фрейм ID3v2-тега обладает уникальным ID. Ext/id3 имеет две функции, которые позволяют узнавать содержимое фрейма. Это id3_get_frame_short() и id3_get_frame_long_name(). В качестве параметра они принимают id фрейма и возвращают его описание.

Листинг 8
  1. <?php
  2.  
  3. // удаляет тег
  4. $result = id3_remove_tag('../data/Little-Big-Man.mp3');
  5.  
  6. if ($result === false) {
  7. echo "Тег не удален!\n";
  8. }
  9.  
  10. echo "Тег успешно удален!\n";
  11.  
  12. ?>
Листинг 9
  1. <?php
  2.  
  3. //Читаем ID3v2 тег
  4. $tag = id3_get_tag("../data/Little-Big-Man.mp3", ID3_V2_3);
  5. print_r($tag);
  6.  
  7. ?>

Дополнительная информация

Использование библиотеки MP3_Id позволяет не только считывать информацию ID3-тегов, но также получать интересную информацию о самом mp3 файле. Получение данной информации возможно при использовании метода study(), а после, используя метод getTag(), вы можете выбирать необходимую информацию. Листинг 12 показывает, как это работает. Результаты показаны в Листинге 13.

Листинг 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 
)

Листинг 11
  1. <?php
  2.  
  3. // Id ID3v2-Frames
  4. $frame = "TOLY";
  5. $short = id3_get_frame_short_name($frame);
  6. $descr = id3_get_frame_long_name($frame);
  7. echo "Frame: $frame\n";
  8. echo "Kurzform: $short\n";
  9. echo "Beschreibung: $descr\n";
  10.  
  11. ?>

Листинг 12
  1. <?php
  2. require_once "MP3/Id.php";
  3.  
  4. // создаем объект, считываем данные
  5. $id3 = &new MP3_Id();
  6. $result = $id3->read("../data/Little-Big-Man.mp3");
  7.  
  8.  
  9. // Ошибки типа "Тег не найден" игнорируются
  10. if (PEAR::isError($result) && $result->getCode() !== PEAR_MP3_ID_TNF) {
  11. die($result->getMessage() . "\n");
  12. }
  13. $result = $id3->study();
  14. if (PEAR::isError($result)) {
  15. die($result->getMessage() . "\n");
  16. }
  17.  
  18. echo "MPEG " . $id3->getTag("mpeg_ver") . " Layer " . $id3->getTag("layer") . "\n";
  19. echo $id3->getTag("mode"). "\n";
  20. echo "Размер файла: " . $id3->getTag("filesize") . " Bytes\n";
  21. echo "Качество: " . $id3->getTag("bitrate") . "kB/s n";
  22. echo "Продолжительность: " . $id3->getTag("length") . " min\n";
  23. echo "Частота оцифровки: " . $id3->getTag("frequency") . "Hz\n";
  24.  
  25. ?>

Листинг 13
MPEG 1 Layer 3 
Joint Stereo 
Размер: 4089856 Bytes 
Качество: 128kB/s 
Продолжительность: 04:15 min 
Частота оцифровки: 44100Hz

Понравилась статья?

Прочитано 7475 раз