pimenov.ai

Я хотел просто слушать редкие DJ-миксы, а построил личный музыкальный архив

Как я с помощью Codex превратил закрытую коллекцию редких DJ-миксов в приватный музыкальный архив на Synology с Navidrome и Amperfy.

КейсПрактикаCodex

Всё началось с доступа к закрытому архиву оцифрованных DJ-миксов. В нём собраны записи мировых диджеев примерно за сорок лет: кассеты, радиоэфиры, клубные сеты и живые выступления.

Во всём архиве больше 3 500 миксов. Это масштаб исходной коллекции, а не количество уже скачанных и обработанных файлов. Архив продолжает пополняться, поэтому конечного числа у проекта пока нет.

Сначала моя задача звучала просто: собрать интересующие меня записи и слушать их с телефона. Быстро выяснилось, что между «получить файлы» и «получить удобную музыкальную библиотеку» лежит отдельный инфраструктурный проект.

Нужно было безопасно забрать файлы из облака, сохранить оригиналы, привести в порядок метаданные, создать обложки, развернуть музыкальный сервер и организовать приватный доступ с iPhone. Всё это было бы практически невозможно без Codex, с которым я сейчас делаю все свои задачи. Он помогал исследовать исходные данные, проектировать архитектуру, писать и проверять сценарии, разбирать ошибки и контролировать массовые проходы.

Так появился «Архив танцпола». Сейчас я каждый день выбираю из него несколько миксов и выкладываю их в своём личном Telegram-канале. Архив стал не только технической системой, но и способом заново открывать музыку и делиться найденными записями.

Часть первая. Как найденная музыка стала архивом

MEGA оказался удобным местом для сбора коллекции

До проекта я знал о MEGA, но почти не пользовался сервисом. Исходники находились в нескольких аккаунтах mega.nz, и мне требовалось собрать их в одном доступном мне пространстве.

Я зарегистрировал собственный аккаунт MEGA и начал переносить туда коллекцию. Сервис оказался очень удобным для сбора разрозненных архивов: он сохранял структуру каталогов и позволял продолжать добавлять материалы.

Особенно полезным оказался официальный MEGAcmd. С ним работа стала автоматизируемой и проверяемой. Сложилась связка: MEGA → MEGAcmd → контролируемый накопительный импорт на Synology без перезаписи существующих файлов.

Облако отвечает за удобный сбор. Synology становится долговременным хранилищем. Ежедневный импорт проверяет, что появилось в MEGA, и забирает только новые объекты.

В последнем подтверждённом срезе на Synology находилось 1 936 исходных файлов общим объёмом около 246,8 ГБ. Это не финальный размер: скачивание продолжается, MEGA пополняется, а ежедневный накопительный импорт приносит новые файлы следующими проходами.

Почему папка с музыкой ещё не медиатека

Файлы уже лежали на моём Synology и воспроизводились, но пользоваться коллекцией как библиотекой было сложно. Где-то имя диджея находилось в тегах, где-то только в названии файла. Даты записывались по-разному. Название вечеринки смешивалось с клубом, городом и страной. Встречались Various Artists, Unknown Album, числовые жанры и заглушки artist, title, genre.

Некоторые записи длятся несколько часов. В архиве из тысяч длинных миксов название Live DJ Set превращает поиск в угадайку. Структура папок рассказывала, откуда получен файл, но почти не помогала понять, кто играет, где, когда и на каком событии.

Мне требовалось сохранить историю получения файлов и одновременно построить поверх неё нормальный музыкальный каталог.

Оригиналы нельзя было переименовывать

Главное архитектурное решение появилось рано: исходные файлы остаются нетронутыми.

Каталог /volume1/DJ-Mixes стал неизменяемым источником. Импорт добавляет новые объекты, сохраняет существующие и не перезаписывает их молча. Если переименовать локальный файл, при следующей сверке его старый облачный путь может показаться отсутствующим, и импортёр скачает объект повторно.

Поэтому нормализация выполняется в отдельной производной библиотеке. Оригинал сохраняет путь, имя, содержимое и время изменения. Теги, названия и обложки меняются только в копиях. Любую производную версию можно перестроить заново, если изменятся правила или обнаружится ошибка.

Исходный архив остаётся нетронутым, а все изменения происходят только в отдельной производной библиотеке.
Исходный архив остаётся нетронутым, а все изменения происходят только в отдельной производной библиотеке.

Как устроен импорт с MEGA

Импортёр получает реестр облачных объектов с относительными путями и размерами, затем сравнивает его с хранилищем. Существующий совпадающий файл пропускается. Новый сначала скачивается во временный путь и только после проверки размера переносится на постоянное место завершённой операцией.

Коллизия не приводит к тихой замене: подозрительный объект отправляется в карантин, а событие попадает в журнал. По отчёту каждого запуска видно, что найдено, загружено или сохранено без изменений.

Сейчас автоматически выполняется только накопительный импорт. Нормализация, создание обложек, сборка производной версии и её подключение к Navidrome остаются контролируемыми запусками. Более полный процесс уже спроектирован, но пока не работает непрерывно.

Почему я сначала попробовал Plex

Plex уже работал на Synology, поэтому начать с него было естественно.

Проблема проявилась в каталоге: длинные миксы с неоднородными тегами распадались на Various Artists и Unknown Album. Plex решает широкий круг задач, а мне были особенно важны музыкальные метаданные и удобный клиент на iPhone.

Plex остался работать рядом. Для «Архива танцпола» я выбрал отдельную связку.

Navidrome хранит каталог, Amperfy даёт доступ с телефона

Navidrome читает производную библиотеку и строит каталог по тегам. На iPhone к нему подключается Amperfy. Synology хранит файлы, Navidrome индексирует активную библиотеку, Amperfy отвечает за интерфейс на телефоне.

Вся система работает на моём Synology DS220+. В него установлена дополнительная память, общий объём оперативной памяти составляет 10 ГБ. Для домашнего хранилища это скромная машина, но при ограничении нагрузки её хватило и для хранения, и для длительной обработки библиотеки.

Доступ работает через LAN и приватный контур Tailscale. Публичный порт и публичный домен для Navidrome не понадобились. Я могу искать записи, запускать длинные сеты, загружать музыку для автономного прослушивания и пользоваться CarPlay.

У Amperfy есть ограничение: после принудительной выгрузки приложения из памяти позиция внутри длинного микса может не сохраниться. Это наблюдение о мобильном клиенте, а не о хранении или индексации в Navidrome.

Часть вторая. Как архив стал понятным

Метаданные оказались важнее папок

Архив DJ-миксов требует больше контекста, чем обычная музыкальная коллекция. У записи могут быть имя диджея, название микса, радиошоу или вечеринка, клуб, город, страна, дата, тип и источник.

В проекте закрепилась такая модель:

ПолеЧто в нём хранится
ARTISTDJ или исполнитель
ALBUMARTISTосновной DJ или исполнитель
TITLEпонятное название записи
ALBUMсобытие, серия или выступление
DATEподтверждённая полная или частичная дата
YEARгод
COUNTRYстрана
CITYгород
VENUEклуб или площадка
EVENTфестиваль, вечеринка или радиошоу
SETTYPEтип записи
GENREподтверждённый жанр
SOURCEдопустимый источник записи

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

Главное поле для слушателя — TITLE

На телефоне мне нужно сразу понимать, какую запись я открываю. Поэтому TITLE должен быть информативным сам по себе.

Правило простое: `ARTIST` содержит имя артиста, а `TITLE` — максимум подтверждённого контекста: название микса, событие, площадку, место и дату. Имя артиста внутри TITLE не повторяется, заглушки и неизвестные части даты удаляются.

ARTIST: DJ Marky
TITLE: Pulse Club & Lounge — Goiânia, Brazil — 28 July 2000
Live DJ Set
→ Pulse Club & Lounge — Goiânia, Brazil — 28 July 2000
Stars X2 — 1999.12.xx
→ Stars X2 — December 1999

Последний пример применяется только при подтверждённых месяце и годе. Если известен один год, остаётся только год. Такой TITLE полезнее классификации, которую мобильный клиент всё равно не показывает в списке.

Почему массовая обработка началась с пилота

Ошибку в одном файле легко исправить. Ошибка в правиле может одинаково испортить тысячи записей.

Сначала была собрана репрезентативная выборка: разные форматы, хорошие и плохие теги, полные и частичные даты, площадки и сложные названия событий. Результат просматривался глазами слушателя — сначала в Navidrome, потом в Amperfy на iPhone.

Автоматическая проверка подтверждает, что поле записалось без ошибки. Но только просмотр в реальном интерфейсе показывает, удобно ли выбирать между несколькими трёхчасовыми миксами.

Как проходила безопасная обработка всей библиотеки

Работа выполнялась на Synology DS220+ с 10 ГБ памяти. Mac использовался для команд и контроля, основная обработка шла на хранилище.

Новая производная библиотека строилась рядом с действующей. Механизм копирования при записи Btrfs позволял создавать независимые копии без немедленного физического дублирования всего файла. Это экономит место на старте, но не отменяет контроль целостности и резервные версии.

Для каждого объекта проверялось, что копия имеет отдельный системный идентификатор, исходник не изменился, теги записаны только в копию, результат присутствует в реестре и журнале, а процесс можно продолжить после остановки.

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

Во время сборки библиотеки с обложками проверка прошла для всех 1 830 медиафайлов: аудиопоток до и после совпал, метаданные без изображения сохранились, а исходный и производный файлы имели разные системные идентификаторы.

Полная сборка и проверка заняли несколько часов. Synology справился благодаря поэтапной обработке, ограничению нагрузки и возможности продолжить работу после остановки.

Разрозненные записи проходят контролируемую обработку и становятся понятным каталогом для приватного прослушивания.
Разрозненные записи проходят контролируемую обработку и становятся понятным каталогом для приватного прослушивания.

Как безликая библиотека получила 1 830 обложек

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

Сначала модель помогла найти несколько визуальных направлений. Мы посмотрели пилот и утвердили четыре серии: архивную карточку, цветовую систему, рейв-флаер и ультраминимализм.

Дальше важно разделить этапы. Модель участвовала в поиске направлений пилота. Массовые 1 830 JPEG создал локальный генератор на Python с Pillow. Отдельного обращения к модели или внешнему сервису для каждого файла не было.

Генератор берёт из реестра артиста, TITLE, дату, событие и локацию, по устойчивому правилу выбирает серию и строит обложку 1200×1200. В углу размещается небольшой pimenov.ai.

Распределение: архивная серия — 319, цветовая — 281, минималистичная — 452, рейв-серия — 778. Один и тот же реестр с той же версией кода воспроизводит для записи ту же обложку.

Для 1 807 MP3 изображение встроено в файл. В остальных поддерживаемых случаях используется соседний cover.jpg, чтобы не переписывать небезопасные контейнеры и два исходно повреждённых MP3.

Четыре настоящие обложки проекта: по одному примеру из архивной, цветовой, рейв- и минималистичной серий.
Четыре настоящие обложки проекта: по одному примеру из архивной, цветовой, рейв- и минималистичной серий.

Ошибки, которые сделали проект практическим

Почти каждый полезный принцип системы связан с найденной проблемой. Неверный путь к Python исправили после Error(127). Устаревший путь к ffmpeg заменили фактическим вместо установки второй копии программы.

Два повреждённых MP3 не ремонтировали автоматически и не исключали молча: в производной библиотеке остались побайтово идентичные копии с резервными метаданными. Девять MP4 сохранены, но Navidrome не проиндексировал их как музыку.

После переключения версий в базе оставались 347 исторических отсутствующих строк. Это не потерянные исходники и не активная музыка. Они сохраняются из-за консервативной настройки:

Scanner.PurgeMissing = "never"

Очистка не выполнялась, поэтому история осталась в базе, не влияя на активную библиотеку.

Что работает сейчас

По последнему подтверждённому состоянию:

  • в исходном срезе — 1 936 файлов, около 246,8 ГБ;
  • в производной библиотеке — 1 830 медиафайлов;
  • Navidrome индексирует 1 821 запись;
  • девять MP4 сохранены, но не индексируются как музыка;
  • все 1 821 активная запись имеют эффективную обложку;
  • для всех 1 830 медиафайлов пройдена проверка целостности;
  • Navidrome 0.63.2 читает библиотеку через /music:ro только для чтения;
  • LAN и приватный доступ через Tailscale проверены;
  • воспроизведение в Amperfy на iPhone подтверждено;
  • Plex продолжает работать рядом.

Число 1 936 не является итогом. MEGA пополняется, скачивание продолжается, ежедневный накопительный импорт приносит на Synology новые файлы.

В Navidrome они пока не появляются автоматически. После импорта проходят аудит, нормализацию, создание обложек, сборку новой версии и пользовательскую проверку. Эта осторожность устраивает меня больше поспешной автоматизации.

Как теперь выглядит обычное прослушивание

На iPhone включён Tailscale, а Amperfy подключается к приватному адресу Navidrome. В библиотеке можно найти артиста и увидеть в названии событие, площадку, город и дату, если данные подтверждены. Запись можно запустить дома, через приватный доступ или загрузить на устройство.

Исходный архив продолжает пополняться с MEGA и остаётся нетронутым на Synology. Navidrome видит только отдельную версионированную библиотеку в режиме чтения.

Что я понял по итогам

Самым полезным решением стало сохранение неизменяемого источника. Оно позволило экспериментировать с тегами, именами и обложками без риска для коллекции.

Для длинного DJ-архива хороший TITLE часто полезнее сложной классификации, которой нет на экране телефона. Реестр, журнал и продолжение после остановки делают массовую обработку управляемой, а пилот в реальном интерфейсе защищает от ошибок, которых не замечает формальная проверка.

Обычный Synology DS220+ с 10 ГБ памяти справился с большой библиотекой при контролируемой нагрузке. Публичный музыкальный сервер не понадобился: LAN и приватного доступа через Tailscale оказалось достаточно.

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

Коллекция перестала быть набором файлов. Теперь это личный музыкальный архив, который можно сохранять, развивать, слушать самому и постепенно открывать читателям моего Telegram-канала.

Следующий шаг

Если вы тоже храните музыку дома, продолжение — «Своя музыка вместо стримингов: Plex и пять альтернатив для Synology».

Связанные материалы

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

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov