Содержание статьи
- Как FFmpeg подвел меня
- Выбор подхода
- Подготовка инструмента
- Изготовление приспособления
- Основы тега
- От теории — к делу!
- Детальное устройство тега
- Уточнение плана операции
- Разборка тега на составные части
- Анатомия тел фреймов
- Извлечение тел фреймов
- Препарирование тел фреймов
- Сборка тега из составных частей
- Правка метаданных
- Все было не зря!
«Нам песня строить и жить помогает!» — заявлял Леонид Утесов. Сегодня строить и жить нам помогают подкасты, лекции и аудиокниги. Современные технологии позволяют держать всю аудиоколлекцию под рукой и не зависеть от погоды, исполнителей и расписаний выступлений.
В то же время аудиоколлекция требует заботы — сохранности и доступности нужных материалов. Доступность подразумевает, что ты знаешь, где что находится. Поддерживать порядок среди материальных предметов помогают этикетки на коробочках, ярлыки на бутылочках и описи содержимого ящиков, шкафов и сейфов. Для цифровых аудиозаписей ярлыками служат метаданные, записанные в медиафайлы.
Музыка чаще всего хранится в MP3, а стандарт хранения метаданных в MP3 называется ID3.
Как FFmpeg подвел меня
Для обработки медиафайлов есть превосходный инструмент командной строки — программа FFmpeg. Я часто использовал его для перекодирования аудиозаписей и корректировки их метаданных. Но однажды он меня подвел.
Аудиоматериалы нередко представлены отдельными фрагментами, например композициями альбома или главами аудиокниги. Обычно это удобно, но иногда лучше иметь один файл с целым произведением.
Аудиоданные в MP3-файле представляют собой последовательность блоков, каждый со своим заголовком. Декодеры MP3 ищут в потоке данных корректные заголовки и обрабатывают соответствующие блоки, игнорируя все остальное. Поэтому фрагменты part1., part2. и part3. можно склеить в монолитный файл all. простой командой. В Windows:
COPY /B part1.mp3 + part2.mp3 + part3.mp3 all.mp3
В Linux:
cat part1.mp3 part2.mp3 part3.mp3 > all.mp3
Некоторые медиаплееры неправильно отображают длительность полученного файла, но обычно воспроизводят его без проблем.
Такой элементарный подход допустим, но мне больше приглянулась реализация в специализированной утилите Mp3Wrap. Она формирует пригодный для прослушивания монолитный MP3-файл без перекодирования и потери качества, а при необходимости позволяет точно восстановить исходные файлы‑фрагменты. Это удобно для архивного хранения коллекции: в монолит, помимо аудиофайлов, можно добавить любые другие данные.
Mp3Wrap
Исходные тексты и бинарные файлы Mp3Wrap можешь загрузить с официального сайта. Для восстановления файлов из монолита понадобится утилита Mp3splt с ее сайта.
В статье мы не будем ее использовать, но тебе могут пригодиться другие ее функции. Она позволяет разбивать MP3-, OGG- и FLAC-файлы на части фиксированной длительности, по заданным отметкам времени или с помощью встроенного детектора тишины.
Далее я покажу обработку MP3-файлов из альбома vintage исполнителя Robert80z. Чтобы повторить эксперименты, можешь загрузить с Archive.org архив jamendo-130889.zip с этими файлами. Он занимает около 14 Мбайт и содержит три аудиотрека.
Чтобы объединить треки 01-1097626-Robert80z-Time , 02-1097624-Robert80z-Boat в файл album_MP3WRAP., я выполнил команду
mp3wrap album_MP3WRAP.mp3 *Robert80z*.mp3
Созданный монолитный MP3-файл почти полностью меня устроил, если бы не один принципиальный момент. В файле начисто отсутствовали метаданные о записанных аудиоматериалах.
Мне бы хотелось, чтобы при воспроизведении монолита плеер показывал название альбома, имя исполнителя и обложку. Вместо этого я увидел множество рекламных надписей о том, что файл собран с помощью программы Mp3Wrap. И, естественно, никакой обложки.
Покупайте наших слонов!
В документации к программе сказано, что метаданные можно изменять без перекодирования файла. Я попробовал с помощью FFmpeg установить для параметра album (Название ) значение vintage:
ffmpeg -i album_MP3WRAP.mp3 -c:a copy -id3v2_version 3 -metadata album="vintage" music_MP3WRAP.mp3
И проверил целостность результата командой
mp3wrap -l music_MP3WRAP.mp3
Вместо списка файлов‑фрагментов на экране появилось сообщение:
Error: this is not a valid mp3wrap file!
Программа FFmpeg сочла данные, внедренные в файл утилитой Mp3Wrap, информационным мусором и вместе с исправлением метаданных произвела «уборку». Поэтому от привычного инструмента пришлось отказаться.
Выбор подхода
Как же быть? Быстрый поиск в интернете подсказал три подхода к решению задачи:
- онлайн‑сервисы;
- специализированные утилиты;
- прямое редактирование MP3-файла.
Первый вариант я отверг с негодованием, второй отложил на крайний случай, а третий вызвал неожиданный интерес. У меня как раз появилось свободное время, чтобы узнать что‑то новое. А организация метаданных в MP3-файле — не космическая наука, доступная лишь избранным.
Поразмыслив, я решил научиться редактировать описания MP3-файлов на самом низком уровне. Поскольку ручная работа байт за байтом в двоичном редакторе вряд ли доставила бы мне удовольствие, я стал выбирать средство автоматизации.
Как оказалось, в стандартных библиотеках знакомых мне языков программирования нет средств работы с метаданными медиафайлов. Для Python, на который я сильно рассчитывал, обычно используют дополнительный модуль Mutagen.
Тогда почему бы не попробовать PHP? На мой взгляд, у некоторых специалистов сложилось к нему снисходительное отношение как к несерьезному языку, чему‑то вроде бейсика в 1980-х. В управляющих структурах PHP действительно есть черты бейсика (а еще языка управления базами данных DBase, особенно в альтернативном синтаксисе без фигурных скобок).
Но, как и бейсик, PHP — универсальный язык программирования для решения любых задач обработки данных. Тебя, как хакера, не может не воодушевить, что PHP, в отличие от Python, можно обнаружить практически на любом веб‑сервере, — это стандартный компонент даже бесплатного shared-хостинга.
В этой статье мы будем использовать PHP в режиме командной строки, без привязки к веб‑серверу. Проверь доступность PHP командой php : она должна отобразить его версию. На момент написания статьи актуальна версия 8.5.8, но описанные сценарии будут работать и в версии 5.5.38. Ну а если вместо номера версии у тебя появилось сообщение о неправильной команде, PHP надо установить и добавить в пути.
Подготовка инструмента
Для установки PHP в Linux на базе Debian или Ubuntu выполни команду
sudo apt install php-cli php-mbstring
В Windows загрузи с официального сайта ZIP-архив с бинарными файлами для нужной архитектуры — x86 или x64. Там представлены два варианта: потокобезопасный Thread Safe и для выполнения в отдельных процессах Non Thread Safe — в файлах с суффиксом nts. Если не знаешь, какой нужен, выбирай более универсальный Thread Safe. Для задач из этой статьи подойдет любой вариант.
Распакуй дистрибутивный ZIP-архив в каталог на диске, например C:\, и скопируй конфиг php. в php.. Можешь добавить путь к этому каталогу в переменную среды PATH. Иначе для выполнения сценария script. придется набирать в командной строке
C:\PHP\php.exe script.php
Чтобы выполнять описанные в статье сценарии, надо активировать модуль работы с текстом в многобайтовых кодировках. Для этого в конфиге php., расположенном в папке с исполняемым файлом Windows или в каталоге / Linux, надо раскомментировать строку ; — удалить начальную точку с запятой. Возможно, придется указать путь к дополнительным модулям: extension_dir .
Как запускать скрипты на PHP
Если ты раньше не использовал PHP, нужны некоторые пояснения. Исходный текст сценария сохраняй в простом текстовом файле между тегами < и ?>. Все имена переменных в PHP начинаются со знака доллара. Это отличает их от других идентификаторов и ключевых слов и предотвращает множество ошибок. Константа PHP_EOL обозначает символ перевода строки, принятый в используемой операционной системе.
Проблем с отображением символов национальных алфавитов не возникнет, если кодировка файла соответствует локали операционной системы. Узнать кодировку локали в Linux можно командой locale . Скорее всего, это будет UTF-8. В Windows команда MODE — она обычно показывает CP866. Для единообразия проще переключить командную строку Windows на UTF-8 командой CHCP .
Чтобы больше не возвращаться к настройке среды выполнения, создай текстовый файл start. в кодировке UTF-8 без BOM с таким сценарием:
start.php
<?php$intenc = mb_internal_encoding ();echo "Внутренняя кодировка: $intenc", PHP_EOL;?>Затем попробуй выполнить сценарий командой php . Возможны несколько вариантов.
- На экране появилось сообщение о внутренней кодировке многобайтовых строк PHP. Она может отличаться от кодировки файлов и локали — пусть это тебя не смущает. Тест пройден, двигайся дальше.
- Появилось сообщение о вызове неопределенной функции
mb_internal_encoding. PHP не смог подключить модульmbstring. Проверь текст программы, настройки PHP и наличие модуля. - Операционная система не смогла выполнить
php. Либо PHP не установлен, либо путь к нему не прописан в переменной окруженияPATH. Исправляй! - Вместо сообщения о внутренней кодировке отобразилось содержимое файла
start.. Скорее всего, ты забыл или неправильно набрал префиксphp <, поэтому интерпретатор не выполнил файл.?php - Отобразилось сообщение об ошибке, например
PHP. Проверь все символы, исправь ошибку и попробуй снова.Parse error
Изготовление приспособления
Надеюсь, ты справился с установкой и настройкой PHP. Идем дальше.
Предлагаю решать задачу последовательно, чередуя изучение теории с практикой. Постигать детали реализации удобно на готовых, проверенных образцах. Такими образцами в этой статье послужат «студийные» MP3-файлы.
Сначала разберемся, как в них внедрены метаданные, извлечем их из файла в оперативную память, а потом научимся формировать информационные блоки для записи в файлы. Освоив такую разборку‑сборку и убедившись, что выполняем ее правильно, мы сможем перед выгрузкой поправить метаданные для решения исходной задачи.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
