ID3 (от англ. Identify an MP3) — формат метаданных, наиболее часто используемый в MP3 файлах. ID3 подпись содержит данные о названии трека, альбома, имени исполнителя и т. д. Именно эти данные использует Winamp и все остальные проигрыватели при воспроизведении файла, показывая, какая песня сейчас играет.

http://ru.wikipedia.org/wiki/ID3_ (метаданные)

php_id3

http://ru2.php.net/manual/ru/book.id3.php

При его использовании натолкнулись на множество проблем. Во-первых, он не смог определить даже третей части тестовых файлов, а во-вторых он часто падает при открытии файла. В итоге мы от него отказались...

GetID3

http://getid3.sourceforge.net/

В поисках решения получше, я наткнулся на проект GetID3 и скачал самую последнюю версию данной библиотеки (Latest 2.x beta version: 2.0.0-b4).

Поддерживает следующие форматы тегов:

  • ID3v1 (v1.0 & v1.1)
  • ID3v2 (v2.2, v2.3 & v2.4)
  • APE tags (v1 & v2)
  • (Ogg) VorbisComment
  • Lyrics3 (v1 & v2)

Более подробное описание возможностей можно посмотреть на странице проекта, а мы пойдем дальше — посмотрим поближе саму библиотеку, так сказать в работе.

Добавил в проект данную библиотеку, открыл свою любимую IDE — Eclipse, и она меня сразу оповестила о ошибке в 403 строке файла write.id3v2.php, оказываеться, разработчики забыли открыть блок после else. Грубо конечно, но спишем все на бета-версию :)

Едем дальше, теперь все работает, скорость обработки достаточно быстрая!

Пример использования:

$getid3 = new getID3();
$getid3->encoding = 'UTF-8'; //указываем output-кодировку
$getid3->Analyze($filename); //путь до файла
var_dump($getid3->info['comments']); //посмотрим результаты работы

Боремся с обрезанием крайнего символа

Ещё одна проблема, крайние символы обрезаются на один символ больше. То есть, например «Алиса» будет «Алис». Итак, заходим в module.tag.id3v2.php (338) и заменяем

$parsed_frame['data'] = substr($frame_data, 0, $frame_size);

на

$parsed_frame['data'] = substr($frame_data, 0, $frame_size +1);

Ещё есть проблема с определением кодировки

Проблема состоит в том, что кодировку корректно данная библиотека не может определить, из-за этого все беды... Например, теги у нас в windows-1251, а библиотека определяет ее как iso-8859-1.

А беда в том, что в самом начале мы устанавливаем кодировку для вывода (UTF-8) и она конвертирует строку в кодировке windows-1251 в utf-8, при этом с параметрами iso-8859-1 и utf-8, соответственно. Поэтому приходиться конвертить из utf-8 в iso-8859-1, а потом из windows-1251 в utf-8 снова :)

Конечно можно указать чтобы она оставляла все в iso, но это проблему не решит... Всёравно она не может определить в какой кодировке теги...

Мы проблему решили на локальном уровне проекта, но надеюсь когда библиотека выйдет из бета-версии все изменится. Еще можно использовать более ранние версии данной библиотеки, возможно там нет данных проблем.


Комментарии (25) на запись «Получаем ID3-теги с помощью PHP»

» Трекбеки скрыты, показать их?
  1. dallone | 13.11.2008 в 12:11

    Полезно однако.

    (: В закладки.

  2. dallone | 13.11.2008 в 12:27

    И снова я тестирую твою антиспам машину адворд. Когда же она заработает нормально?

  3. adw0rd | 13.11.2008 в 14:56

    Кстати по поводу кодировки, можно её автоматически определить, например с помощью библиотеки popoff.donetsk.ua/text/work/libs/a/charset/

  4. Моделирование успешных блогов | Мастерская интернет-разработчика | 25.03.2009 в 16:38

    [...] id3v2.php [...]

  5. FreeBSD. Восстановление root’ового пароля | Мастерская интернет-разработчика | 26.03.2009 в 15:19

    [...] запись id3 tag в UTF-8 Оставить комментарий | Comment RSS | Теги: FreeBSD Назад: Яндекс.Фотки — плагин для WordPress Далее: FreeBSD. Установка и настройка ProFTPD [...]

  6. Пейнтбол | Мастерская интернет-разработчика | 27.03.2009 в 10:20

    [...] php id3 теги [...]

  7. Hello, World! | Мастерская интернет-разработчика | 29.03.2009 в 01:46

    [...] id3 php [...]

  8. vasa_c | 12.05.2009 в 13:28

    Кодировку ещё умеет определять mb_detect_encoding ().

  9. vasa_c | 12.05.2009 в 15:59

    После некоторых танцев вокруг кодировок получилось что-то вроде:

        /**
         * Получить параметры записи
         * @param  string $filename путь к файлу
         * @return array  параметры или false при какой-нибудь ошибке
         *     "title"  - название
         *     "artist" - исполнитель
         *     "length" - длина в секундах
         */
        public static function getMP3Params($filename)
        {
            require_once(dirname(__FILE__).'/getid3/getid3/getid3.php');
            try {
                $g = new getID3();
                //$g->encoding = 'UTF-8'; // В примере было, ни на что не влияет
                @$g->analyze($filename); // Куча Strict Standarts
            } catch (Exception $e) {
                /* Не знаю, что за исключения, но в примере был try-catch */
                return false;
            }
            if (!isset($g->info)) {
                return false;
            }
            $info = $g->info;
            if (isset($info['error'])) {
                return false;
            }
            if ($info['fileformat'] != 'mp3') {
                return false;
            }
            $length = intval(
                    (($info['avdataend'] - $info['avdataoffset']) * 8) /
                    $info['audio']['bitrate']
            );
            $result = Array(
                'title'  => '',
                'artist' => '',
                'length' => $length,
            );
            if (isset($info['id3v2'])) {
                $info = $info['id3v2'];
            } elseif (isset($info['id3v1'])) {
                $info = $info['id3v1'];
            } else {
                return $result;
            }
            if (!isset($info['comments'])) {
                return $result;
            }
            $info = $info['comments'];
            if (isset($info['artist'])) {
                $artist = $info['artist'][0];
                /* Танцы с бубном */
                $ar     = mb_convert_encoding($artist, 'iso-8859-1', 'utf-8');
                $artist = $ar ? $ar : $artist;
                $artist = mb_convert_encoding($artist, 'utf-8', 'windows-1251');
                $result['artist'] = $artist;
            }
            if (isset($info['title'])) {
                $title = $info['title'][0];
                $tl    = mb_convert_encoding($title, 'iso-8859-1', 'utf-8');
                $title = $tl ? $tl : $title;
                $title = mb_convert_encoding($title, 'utf-8', 'windows-1251');
                $result['title'] = $title;
            }
            return $result;
        }

  10. adw0rd | 12.05.2009 в 16:07

    if (isset($info['id3v2'])) {
        $info = $info['id3v2'];
    } elseif (isset($info['id3v1'])) {
        $info = $info['id3v1'];
    } else {
        return $result;
    }

    $info['id3v1'] и $info['id3v2'] — массивы? Просто ты эту $info переопределяешь много где... А код вообще проверял?

  11. vasa_c | 12.05.2009 в 18:03

    да, массивы.

    Обрати внимание, что иногда хватает windows-1251 --> utf-8.

    Так что извращения utf8->iso (utf) ->win иногда излишни. А иногда нет.

    Плюс длину в секундах вычислил как

    intval((($info['avdataend'] - $info['avdataoffset']) * 8) /$info['audio']['bitrate']);

    . Кажется, работает.

  12. ElectroInjector | 28.06.2009 в 17:18

    Лагин под вордпресс на основе этого кода пользовался бы популярностью ;)

  13. adw0rd | 29.06.2009 в 01:04

    ElectroInjector, и какова аудитория?)

  14. flegg | 03.10.2009 в 03:11

    А чем не нравится MP3_Id?

    pear.php.net/package/MP3_Id/download

    2 vasa_c

    Кажется, Вы ненавидите сами себя :) Код ужасен.

  15. adw0rd | 03.10.2009 в 16:09

    flegg, не пользовался

  16. vasa_c | 03.10.2009 в 18:54

    flegg, мне похуй ;

  17. titov | 31.12.2009 в 04:30

    дайте код которым можно изменить ID3v2 теги в MP3 файле с помощю PHP

  18. adw0rd | 01.01.2010 в 15:12

    У меня нет такого кода, я никогда не менял через PHP теги.

    Может это поможет www.php.su/articles/?cat=others&page=013

  19. phpdude | 12.02.2010 в 01:09

    в последней od3 ест ошибка изза которой я както раз потерял часов 6. когда делаешь save () (или что там, writetags () ли)

    они пытаются создать темповый файл, а если стоит ограничение open_basedir, то их обработчик ошибок не пишет ошибку, хотя до этог овсе ошики которые он смог найти гладко шлет в обработчик, а вот эту злую нет :D

    это я к слову, если при записи вы видите что файл не перезаписывается — ид тоже не без ошибок, ищите :)

    эдво — ты ахуенен

  20. phpdude | 12.02.2010 в 01:09

    правда — правда, ты ахуенен! :)

  21. adw0rd | 12.02.2010 в 01:27

    phpdude, да ну нафиг, это ты ахуенен! :)

  22. titov | 01.03.2010 в 13:30

    Вобщем с долгими мучениями и поисками сделал то что хотел, а именно изменение ID3v2 тегов в MP3 файле, вот мануал ua2.php.net/manual/en/book.id3.php может кому пригодиться.

  23. adw0rd | 01.03.2010 в 16:05

    У меня раньше с этим модулем были траблы, я об этом в статье писал... Хотя может сейчас все наладили уже

  24. XomiaK | 20.11.2010 в 18:16

    adw0rd, огромное тебе спасибо!!! Потратил уйму времени, чё тока не делал, искал везде, находил много чего, но низера не подходило или не работало!

    СПС ЗА ЭТОТ КОД!!!

  25. Богдан | 11.03.2012 в 22:42

    Спасибо! )

Оставить комментарий