pimenov.ai

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

Как редкие DJ-миксы, личные записи и обычная музыка стали тремя библиотеками на Synology с Navidrome, Arpeggi и управлением через Codex.

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

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

Архив продолжал расти. В MEGA появлялись новые миксы, на Synology нашлись мои кассетные записи девяностых, архив с Казантипа и коллекция обычной музыки.

Один каталог DJ-сетов превращался в домашнюю медиасистему. Нужно было разделить музыку, добавлять новые партии, сохранить оригиналы, исправить кодировки, оформить кассетные миксы и собрать плейлисты. Главным экзаменом снова стал iPhone.

Одна библиотека перестала вмещать разные смыслы

В «Архиве танцпола» лежат концертные записи, радиоэфиры и DJ-сеты. Для них важны дата выступления, площадка, город, страна и событие. Год здесь означает год записи или выступления.

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

Мы разделили систему на три самостоятельные библиотеки:

  • «Архив танцпола» — 3 545 записей с редкими DJ-миксами, радиоэфирами и живыми выступлениями;
  • «Музыка» — 8 766 записей слушательского архива;
  • «Моё» — 255 моих релизов и миксов.

На сервере это три отдельных версионированных каталога. Navidrome показывает их как независимые библиотеки, а в мобильном клиенте их можно открывать отдельно. Оригинальные папки при этом не меняются.

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

Новая музыка проходит один и тот же контролируемый путь

Первые партии мы обрабатывали почти вручную. После нескольких проходов стало ясно, что нужен постоянный протокол. Мы оформили его как skill для Codex — инструкцию с обязательным порядком действий и стоп-линиями.

Теперь процесс выглядит так:

  1. новая партия получает собственный реестр файлов;
  2. источник фиксируется как неизменяемый;
  3. каждому объекту назначается решение: добавить, пропустить как дубль, отложить или исключить;
  4. любые исправления выполняются только на производной копии;
  5. теги и названия нормализуются по правилам выбранной библиотеки;
  6. обложки создаются по утверждённой визуальной системе;
  7. полная новая версия собирается рядом с действующей;
  8. Navidrome переключается на неё только после проверок и с готовым откатом;
  9. финальное решение принимается после просмотра и прослушивания на iPhone.

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

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

MacBook управляет, Synology выполняет тяжёлую работу

Контур медиасистемы: MacBook управляет, Synology хранит и обрабатывает, Navidrome индексирует, приложения дают доступ по LAN и Tailscale.
Контур медиасистемы: MacBook управляет, Synology хранит и обрабатывает, Navidrome индексирует, приложения дают доступ по LAN и Tailscale.

Рабочий чат Codex открыт на MacBook. Здесь я голосом задаю правила, проверяю отчёты и принимаю спорные решения. Отсюда запускаются контролируемые операции на Synology.

Чтение и копирование сотен гигабайт происходит на Synology, где находятся исходники, производные версии, Navidrome и резервные копии. MacBook служит пультом управления.

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

Arpeggi стал главным окном в медиатеку

Архив танцпола на iPhone: библиотека, карточки миксов и отдельные коллекции артистов.
Архив танцпола на iPhone: библиотека, карточки миксов и отдельные коллекции артистов.

В первой версии я слушал музыку через Amperfy, позже перешёл на Arpeggi. По ощущениям он ближе к Apple Music и лучше показывает отдельные библиотеки, исполнителей, альбомы, обложки и плейлисты.

Дома приложение подключается по локальной сети, вне дома — через приватный контур Tailscale.

Arpeggi стал пользовательским стендом: на телефоне видны битые имена, пустые плейлисты, ошибочный год или длинный заголовок.

Казантип показал цену старых кодировок

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

Заменять все необычные символы опасно: в именах встречаются нормальная кириллица, диакритика и сценические написания. Поэтому детектор сузили до настоящего mojibake — обратимо испорченного текста.

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

Òðåê 1 → Трек 1
Çàêðûòèå → Закрытие

Так удалось восстановить имена в 69 файлах. Шесть неоднозначных записей отправились в отложенный реестр, а три битых дубля исключили из активной производной библиотеки. Исходники сохранились.

После повторного сканирования карточек артистов с обнаруженными признаками mojibake не осталось. Значения [Unknown Artist] и <Unknown> система не превращает в выдуманные имена.

Повреждённый файл не обязан тормозить всю библиотеку

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

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

Мои кассетные миксы получили собственное лицо

Та же медиатека на Mac в Cassette: обложки работают как полноценная визуальная система архива.
Та же медиатека на Mac в Cassette: обложки работают как полноценная визуальная система архива.

Отдельной частью коллекции стали оцифровки моих миксов, выходивших на кассетах в Ростове-на-Дону в девяностых. Им требовалась собственная визуальная идентичность.

Сначала мы сделали обложку с логотипом «НЕСПАТЬ!». Затем мой старый друг, дизайнер Вартан Чинчян, который делал оригинальные обложки кассет «НЕСПАТЬ!», подготовил референс, чистую заготовку и палитру. Вместо свободной генерации появилась строгая дизайн-система.

Мы зафиксировали шаблон размером 1080 × 1080 пикселей, зоны для названия и года, гарнитуры и соответствие цветов годам:

  • 1996 — жёлтый;
  • 1997 — красный;
  • 1998 — бирюзовый;
  • 1999 — зелёный;
  • неизвестный год — нейтральный графитовый.

Оранжевый зарезервирован для подтверждённых записей 2000 года.

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

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

132 плейлиста прошли проверку и всё равно оказались неправильными

Самый полезный сбой произошёл со Smart Playlists — автоматическими плейлистами Navidrome. Мы создали первый набор из 132 определений по годам, артистам и жанрам. Серверная проверка прошла: правила были синтаксически корректны и находили строки в подготовленной проекции базы.

В Arpeggi я увидел множество пустых плейлистов. А внутри «Музыка · Год · 2018» оказались треки, которые явно не относились к 2018 году.

Причин было две. Краткий список Navidrome может показывать songCount=0 для лениво вычисляемого Smart Playlist, хотя подробный запрос возвращает записи. Источником истины стал подробный запрос самого Navidrome.

Во-вторых, число 2018 в части каталогов было кодом коллекции, а не годом релиза. Папки и альбомы 18-004, 18-005 и 17-100 внешне напоминали даты. Первое правило приняло их за годы и разнесло 41 файл по неправильным выборкам.

Мы убрали неподтверждённые значения DATE и YEAR, не подставляя другие даты. Затем построили плейлисты только по нормализованным тегам, которые действительно существуют в полной кандидатной библиотеке. Годы создаются даже для одной записи, артисты и места — минимум для двух, жанры — минимум для пяти.

Каждое определение проверялось реальным вычислителем Navidrome. Семьдесят пять пустых правил удалили; ещё два пустых артистических плейлиста обнаружились в следующих проходах и тоже не попали в публикацию.

В результате осталось 1 239 непустых автоматически созданных плейлистов. Это ещё не окончательное число: по мере оптимизации медиатеки набор будет сокращаться, объединяться и становиться удобнее. Вместе с 16 прежними файловыми и семью пользовательскими плейлистами в базе сейчас 1 262 позиции. Исправленный плейлист «Музыка · Год · 2018» содержит 23 записи и больше не включает треки с коллекционными кодами вместо года. Жанровый плейлист Jazz содержит 48 записей.

Валидатор доказал, что запрос можно выполнить. Телефон показал, можно ли пользоваться результатом.

Старые данные пришлось удалить не с диска, а из базы

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

Scanner.PurgeMissing = "never"

Она защищает историю от автоматического удаления, но одновременно сохраняет записи о пропавших .nsp-файлах. Поэтому очистка каталога на диске не убрала старые плейлисты из интерфейса.

Navidrome остановили, базу дополнительно сохранили, а затем транзакционно удалили ровно 132 устаревшие строки с известным служебным префиксом. Новые 1 239 определений, 16 прежних файловых и семь пользовательских плейлистов не затрагивались. После операции проверка базы вернула ok.

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

В финальном проходе Codex предложил прогнать ffprobe по примерно 12,5 тысячи файлов и повторно прочитать почти терабайт данных. Это заняло бы несколько часов и повторило проверки отдельных партий.

Я остановил этот план как избыточный. Мы оставили изолированное сканирование Navidrome, вычисление плейлистов через реальный API, резервную копию базы, проверку её целостности, полный скан после публикации и доступ через локальную сеть и Tailscale.

Дополнительно появилась стоп-линия: если проход выходит за 30–40 минут, агент должен остановиться, показать состояние и запросить дальнейшее решение.

Агент способен предложить максимально строгую процедуру. Владелец системы определяет, соответствует ли её стоимость реальному риску.

Публикация всегда имеет путь назад

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

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

Текущую версию я проверил на iPhone и зафиксировал как рабочую. В ней остаются места для улучшения, но перед следующей итерацией нужен понятный принятый срез.

Что получилось

Личная музыкальная библиотека на iPhone: собственные релизы, кассетные DJ-миксы и сохранённые альбомы.
Личная музыкальная библиотека на iPhone: собственные релизы, кассетные DJ-миксы и сохранённые альбомы.

Один архив DJ-миксов вырос в систему из трёх библиотек: редкие записи, обычная музыка и мои собственные работы больше не смешиваются.

Новую папку или партию из MEGA теперь можно принять как отдельную задачу: построить реестр, исправить доказуемые проблемы, создать обложки и выпустить новую версию с откатом.

Дизайн стал частью инфраструктуры. Вартан превратил мои кассетные миксы в самостоятельную визуальную серию, а его решение стало версионированными данными для локального рендерера.

Главный контроль остаётся человеческим. Codex может обработать тысячи строк и выполнить десятки проверок. Только я решаю, достаточно ли информативен TITLE, похож ли год на правду, удобно ли выглядит список в Arpeggi и стоит ли тратить несколько часов на очередную техническую проверку.

Мне хотелось собрать музыку, которую жалко потерять и невозможно найти в стриминговых сервисах. Теперь это развиваемая домашняя медиасистема: Synology хранит и обрабатывает, Navidrome индексирует, Arpeggi даёт красивый доступ с телефона, дизайнер задаёт визуальный язык, а Codex помогает управлять всем процессом.

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

После первой публикации я увидел гигантский интерес к этой истории. Мне начали писать и спрашивать, как подключиться к моей медиатеке, чтобы слушать этот архив, и можно ли заказать создание такой системы для себя. Готового ответа у меня пока нет. Сейчас я думаю, как организовать доступ к коллекции и во что превратить накопленный процесс: в отдельный формат для слушателей, в услугу по созданию личных медиасистем или во что-то ещё.

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

Если вы хотите собрать такой контур на своём Synology, начните с руководства «Navidrome на Synology: домашняя музыкальная медиатека с Amperfy».

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

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

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