[2026-09-27] eagle: family/how-to/navidrome-truenas-android.md family/plans/music-jellyfin-lidarr-taiga.md personal/tech/jellyfin-music-library-pitfalls.md personal/tech/jellyfin-tags-cp1251-unreadable.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 10:36:34 +06:00
1 parent 43ac43aae0
commit 01c7fe6d03
4 files changed
+478 -25

No files matched your search

+37 -3
View File
@@ -15,7 +15,7 @@
| Источник имени артиста | **имя папки** перекрывает тег | **только тег** |
| Структура папок | требуется `Artist/Album/Track` | **игнорируется полностью** |
| Наша структура `категория/подпапка/файл` | ломает навигацию | **работает как есть** |
| Интернет-метаданные артистов | тянет из MusicBrainz → левые артисты (`Maria Makarova (organ)`) | **не тянет** |
| Интернет-метаданные артистов | тянет из MusicBrainz → левые артисты | **не тянет** |
| Пишет в файлы | может | **никогда** (by design) |
**Официальная дока Navidrome (Tagging Guidelines), прямая цитата:**
@@ -66,13 +66,47 @@
⚠️ **Но выявлен новый пробел:** в файлах **отсутствует `TPE2` (albumartist)** — проверено
`154/154`. Его **не было в плане правок** (`tag-fix-plan.csv` не содержит колонки `album_artist`).
Navidrome строит **альбомы** по `AlbumArtist`; артисты будут правильные и без него,
но альбомы могут склеиваться. **Желательно добавить `TPE2` перед запуском.**
### ✅ `ALBUMARTIST` для Navidrome — НЕ обязателен (проверено 2026-09-27)
**Не блокирует запуск.** Мейнтейнер Navidrome `deluan` (обсуждение #5924):
> «when an album artist tag is missing, Navidrome substitutes the **track artist** in its place»
| Ситуация | Результат |
|---|---|
| `ALBUMARTIST` у всех треков | 1 альбом ✅ |
| Нет `ALBUMARTIST`, сольный альбом | 1 альбом ✅ |
| Нет `ALBUMARTIST`, 4 фита | **5 альбомов** вместо 1 ❌ |
| Нет `ALBUMARTIST`, сборник 18 треков | **до 18 альбомов** ❌ |
**Обход без правки файлов — конфиг:**
```toml
PID.Album = "musicbrainz_albumid|albumartist,album,albumversion,releasedate"
```
> 🔑 Сырое `albumartist`, **НЕ** `albumartistid` (тот никогда не пуст). `folder` в спеку
> класть нельзя. ⚠️ Смена `PID.Album` → полный рескан + новые ID → **бэкапить `navidrome.db`**.
### ✅ Новые закачки тегирует Lidarr сам
Lidarr матчит по MusicBrainz release groups и пишет полные теги, **включая `Album Artist`**
(действие `Write Metadata Tags`). Связка [`navidrome-lidarr-bridge`](https://github.com/danielbanariba/navidrome-lidarr-bridge)
— закачанное Lidarr'ом подхватывается Navidrome автоматически.
### ⚠️ Что реально стоит починить до запуска: СЕМАНТИКА `artist`
Файлы `!Классика` содержат **семантически мусорные** `artist` — формально валидные теги:
```
artist=Классика в современной обработке ← это не артист
artist=Классика для детей П.И. Чайковский ← это не артист
artist=Maria Makarova (organ) ← исполнитель вместо композитора
```
**Navidrome покажет их как артистов** — надо смотреть и чистить.
Детали — [[personal/tech/jellyfin-tags-cp1251-unreadable]] §ИНВЕНТАРИЗАЦИЯ.
## Следующие шаги
- [x] ~~Сначала: ремонт тегов 7906 файлов~~ → ✅ выполнен (волна 38)
- [ ] **Аудит семантики `artist`** — убрать «Классика в современной обработке» и подобное
- [ ] **Опционально:** добавить `TPE2` = `TPE1` (нужен НОВЫЙ план правок с колонкой `album_artist`)
- [ ] Поднять Navidrome в Docker на TrueNAS
- [ ] Пробросить порт / настроить Caddy subdomain (Caddyfile root-owned → через alpine-контейнер)
+95 -13
View File
@@ -1,19 +1,101 @@
# Music → Jellyfin + Lidarr на Тайге — план (v6, 2026-09-27)
# Music → Jellyfin + Lidarr на Тайге — план (v7, 2026-09-27)
> ✅ **СТАТУС v6: ОТКАТ ЗАВЕРШЁН И ПОДТВЕРЖДЁН.** БД Jellyfin восстановлена на версию до импорта
> музыки. Итог: 6 библиотек, Audio=0, MusicArtist=0, Music отсутствует. Jellyfin работает.
> **MD5 внутри контейнера = `b71b5d659a1262fa98b85a6ab0003f24`** — совпал с бэкапом.
> Задача Lidarr — **не начата, отложена** (Alex не возвращался к ней после отката).
> ✅ **СТАТУС v7: JELLYFIN ОТКАЧЕН И СТАБИЛЕН. КУРС СМЕНЁН НА NAVIDROME.**
> БД Jellyfin восстановлена на версию до импорта музыки: 6 библиотек, Audio=0, MusicArtist=0.
> **MD5 `b71b5d659a1262fa98b85a6ab0003f24`** — совпал с бэкапом.
>
> 🔴 **ГЛАВНОЕ ОТКРЫТИЕ v6: поведение Jellyfin — это ОФИЦИАЛЬНО ПОДТВЕРЖДЁННЫЙ БАГ
> [`jellyfin/jellyfin#18162`](https://github.com/jellyfin/jellyfin/issues/18162), а НЕ проблема
> наших тегов.** Jellyfin берёт имя артиста **из имени папки**, перекрывая теги. Гипотеза
> «в файлах нет `TPE2`» **смягчена**: `TPE2` отсутствует у 154/154 (факт), но баг перекрывает
> теги именем папки **даже при валидном `ALBUMARTIST`**.
> 🔀 **РЕШЕНИЕ СЕССИИ: Jellyfin для музыки НЕПРИГОДЕН — ставим Navidrome.**
> Причина — подтверждённый баг [`jellyfin/jellyfin#18162`](https://github.com/jellyfin/jellyfin/issues/18162)
> (имя папки перекрывает теги) + наша 4-уровневая структура. Navidrome читает **только теги**,
> папки игнорирует полностью, бага не имеет. Сравнение движков —
> [[personal/tech/jellyfin-tags-cp1251-unreadable]].
>
> ✅ **Найденное решение: Navidrome** — читает теги, **папки игнорирует полностью**, бага не имеет.
> Детали и сравнение движков — [[personal/tech/jellyfin-tags-cp1251-unreadable]].
> Деплой-план — [[family/how-to/navidrome-truenas-android]].
> 🔴 **ИСТОЧНИК `Maria Makarova (organ)` НАЙДЕН (v7):** это **наш собственный тег**
> `artist=Maria Makarova (organ)` в файле `!Классика/Бах — Toccata and Fugue in D minor.mp3`.
> **НЕ MusicBrainz, НЕ «Маша Макарова» из Ногу Свело** — обе версии опровергнуты.
>
> ⏳ **ОТКРЫТЫЕ ЗАДАЧИ (см. §Открытые задачи в конце):**
> 1. Дополнение `Music/backup` — скан готов (1436 файлов не хватало), **ждёт решения Alex** по `.avi`/`.mpg`/`.DS_Store`;
> 2. Бэкап CSV на Mac — ✅ **выполнено**;
> 3. Аудит семантики `artist` — **не начат**;
> 4. Деплой Navidrome — **не начат**;
> 5. Lidarr — **не начат, отложен**.
>
> 📌 **Lidarr:** задача из исходной команды Alex остаётся в силе, но **отложена** —
> сначала библиотека в Navidrome. Новые закачки Lidarr тегирует **сам** через MusicBrainz
> (включая `Album Artist`), поэтому ручная правка нужна только для существующих 7861 файла.
## 🔀 v7: РЕШЕНИЕ — NAVIDROME ВМЕСТО JELLYFIN ДЛЯ МУЗЫКИ
**Проверено по официальной доке Navidrome и GitHub (2026-09-27).**
| | Jellyfin (баг #18162) | Navidrome |
|---|---|---|
| Источник имени артиста | **имя папки** перекрывает тег | **только тег** |
| Структура папок | обязательна `Artist/Album/Track` | **игнорируется** |
| Наша структура `категория/подпапка/файл` | ломает навигацию | **работает как есть** |
| Интернет-метаданные артистов | тянет из MusicBrainz | **не тянет** |
| Пишет в файлы | может | **никогда** (by design) |
| Видео | ✅ (видеотека остаётся здесь) | ❌ |
**Официальная дока Navidrome:**
> «Navidrome organizes your music library **entirely** based on the metadata tags in your audio
> files. Unlike some music players, **it does not use folder names or file names to group tracks**.»
### `ALBUMARTIST` в Navidrome — НЕ обязателен (ответ на вопрос Alex)
**Navidrome подставляет `artist`, если `albumartist` отсутствует** — цитата мейнтейнера
`deluan` (обсуждение #5924):
> «when an album artist tag is missing, Navidrome substitutes the **track artist** in its place»
**Что при этом происходит:**
| Ситуация | Результат |
|---|---|
| `ALBUMARTIST` у всех треков | 1 альбом ✅ |
| Нет `ALBUMARTIST`, 4 фита | **5 альбомов** вместо 1 ❌ |
| Нет `ALBUMARTIST`, сборник 18 треков | **до 18 альбомов** ❌ |
**Обход без правки тегов — конфиг `PID.Album`:**
```toml
PID.Album = "musicbrainz_albumid|albumartist,album,albumversion,releasedate"
```
> 🔑 Использовать **сырое `albumartist`**, НЕ `albumartistid` (последний никогда не пуст —
> вычисляется после подстановки track artist). `folder` в спеку класть нельзя как fallback.
> ⚠️ Смена `PID.Album` → полный рескан + новые ID → **бэкапить `navidrome.db`**.
### ✅ Новые закачки тегирует Lidarr сам
Lidarr матчит по **MusicBrainz release groups** и пишет полные теги, включая `Album Artist`
(штатное действие `Write Metadata Tags`). Существует официальная связка
[`navidrome-lidarr-bridge`](https://github.com/danielbanariba/navidrome-lidarr-bridge):
закачанное Lidarr'ом попадает в папку Navidrome и подхватывается автоматически.
## 📌 ОТКРЫТЫЕ ЗАДАЧИ (v7, для следующей сессии)
| # | Задача | Статус | Детали |
|---|---|---|---|
| 1 | Дополнить `Music/backup` | 🟡 **скан готов, ждёт решения** | не хватало **1436 файлов** (876 mp3, 287 jpg, 6 mpg, 5 avi, 18 `.DS_Store`). Вопрос Alex по видео/мусору — ответа нет |
| 2 | Бэкап CSV на Mac | ✅ **выполнено** | `/Users/admin/milestones/music-csv-2026-09-26/` — 3 CSV + MD5SUMS + README |
| 3 | Аудит семантики `artist` | 🔴 не начат | `artist=Классика в современной обработке`, `Maria Makarova (organ)` и т.п. — формально валидны, семантически мусор |
| 4 | Деплой Navidrome | 🔴 не начат | план — [[family/how-to/navidrome-truenas-android]] |
| 5 | Проставить `TPE2` | ⏸ отложено | нужно **только** если в Navidrome раздробятся сборники; для Jellyfin бессмысленно (баг) |
| 6 | Lidarr | 🔴 не начат | задача из исходной команды, отложена до библиотеки |
| 7 | Починить авто-бэкап Jellyfin | 🔴 не начат | `SQLiteBackups` пуста с 3 июня |
### 📦 Milestone: CSV сохранены на Mac (2026-09-27)
```
/Users/admin/milestones/music-csv-2026-09-26/
├── tag-inventory.csv 1.6 МБ md5 ca2d1767fd784771c44290529972a201
├── tag-inventory2.csv 1.7 МБ md5 52d90e676930110a76c979c0a2fa800c
├── tag-fix-plan.csv 2.2 МБ md5 8742abff7387e1ae719f3e35c6cf0176
├── MD5SUMS.txt
└── README.md
```
Копии read-only, оригиналы на NAS. **README содержит** описание колонок, распределение
`verdict`/`action`, и главную находку — **отсутствие `album_artist` в плане правок**.
## 🔴 v6: БАГ JELLYFIN #18162 — имя папки перекрывает теги
@@ -0,0 +1,136 @@
# Skill: jellyfin-music-library-pitfalls — зеркало навыка
**Скилл:** `devops/jellyfin-music-library-pitfalls`
**Путь:** `~/.hermes/hermes-whale/skills/devops/jellyfin-music-library-pitfalls/SKILL.md`
**Создан:** 2026-09-27
**Category:** devops
> Зеркало для vault. Полный текст — в SKILL.md скилла.
## Когда применять
Любая работа с **музыкальной** библиотекой Jellyfin на удалённом Docker-хосте
(TrueNAS/Taiga, Kraken): добавление, отладка неверной навигации, откат.
**Сначала читать в vault:**
- [[personal/tech/jellyfin-tags-cp1251-unreadable]] — почему Jellyfin не читает теги
- [[family/plans/music-jellyfin-lidarr-taiga]] — план проекта
## Ключевые правила (краткая версия)
### 🔴 RULE 0 — бэкап БД ДО создания библиотеки
Создание библиотеки + скан пишет тысячи строк в `BaseItems`. **Без бэкапа БД откат невозможен.**
```bash
docker stop jellyfin
docker cp jellyfin:/config/data/data/jellyfin.db /home/truenas_admin/jellyfin.db.bak-$(date +%Y%m%d-%H%M%S)
docker start jellyfin
```
- **WAL чекпоинтится только при остановленном контейнере** — иначе копия битая.
- **`SQLiteBackups/` часто ПУСТА** — не полагаться на авто-бэкапы Jellyfin, проверять.
- **Снапшоты ZFS часто 0 штук** — проверять `zfs list -t snapshot | wc -l`.
### 🔴 Почему Jellyfin игнорирует ID3-теги — три причины
1. **Баг `jellyfin/jellyfin#18162`** (confirmed, In Progress): имя MusicArtist берётся
**из имени ПАПКИ**, перекрывая `ARTIST`/`ALBUMARTIST`. Если имя папки произвольное —
Jellyfin идёт в **MusicBrainz** и создаёт артиста оттуда.
2. **Отсутствует `TPE2` (albumartist)** — ключевое поле для иерархии Artist→Album→Track.
При пустом `TPE2` Jellyfin уходит в fallback на папки и **перестаёт читать `TPE1` вообще**.
3. **4-уровневая структура** `категория/подпапка/релиз/файл` — Jellyfin читает как
`Artist/Album`.
**Сигнатура дефекта:** `число MusicArtist == число папок верхнего уровня`.
### 🔬 Диагностика — через `od`, НЕ `ffprobe`
`ffprobe` нормализует вывод и **угадывает кодировку** → может показать `album_artist`,
которого нет как фрейма `TPE2` (из ID3v1-хвоста или TXXX).
```bash
od -A d -t x1z -N 200 "/path/file.mp3" # заголовок + первые фреймы
od -A d -t x1z -N 2000 "$F" | grep -oE "[A-Z][A-Z0-9]{3}" | sort -u # все фреймы
od -A d -t x1z -N 4000 "$F" | grep "P E 2" # есть ли TPE2
```
**Питфоллы:**
- `-of default=nw=1:nk=1` срезает префиксы `TAG:` → ложный вывод «теги пустые».
- `TAG:ID3v1 Comment=` — это **128-байтный ID3v1-хвост**, где CP1251 нормальна.
Цитировать как доказательство CP1251 в ID3v2 — **ошибка вывода**.
- **Валидация ffprobe ≠ доказательство читаемости для потребителя.** Проверять движком,
который читает в проде. Выборка 1% (108 из 7861) ничего не доказывает.
### 🔴 НИКОГДА не использовать `DELETE /Items` — он удаляет ФАЙЛЫ
Удаляет медиафайл с диска, не только запись БД. При rw-монтировании **снесёт музыку**.
Спасает только `ro`-mount. `POST /Library/Media/Deleted` → **404**; `POST /Library/Media/Updated`
→ **415** без JSON body.
**Для удаления только записей — править SQLite напрямую при остановленном контейнере.**
### Безопасный откат БД
Полная процедура (5 шагов) — в SKILL.md. Ключевое:
1. `docker stop` → бэкап текущей БД;
2. распаковка архивной БД + **проверка MD5**;
3. удаление WAL/SHM **при ЗАПУЩЕННОМ контейнере** (`docker exec` не работает на остановленном);
4. `docker cp` БД внутрь + `chown abc:abc` + `docker start`;
5. **проверка `md5sum` ВНУТРИ контейнера** — не по коду возврата.
### Питфоллы (проверено)
| # | Питфолл |
|---|---|
| 1 | `docker exec` НЕ работает на остановленном контейнере → WAL удалять при запущенном |
| 2 | `docker cp` может вернуть `container is not running`, **НО копия проходит** → проверять `md5sum` |
| 3 | Глоб `jellyfin.db*` не раскрывается в zsh контейнера → ложное «файла нет» |
| 4 | `docker stop` возвращает `Exited (137)` (SIGKILL) — не признак поломки данных |
| 5 | Хост и контейнер показывают разное время одного файла (PDT vs +07) — это НЕ расхождение |
| 6 | **Не запускать скрипт-мутатор «для проверки»** — создаст библиотеку обратно |
| 7 | `"a"+"b"` в bash/zsh → пустая строка → HTTP 401. Правильно `"${A}${B}"` |
| 8 | Токен/`os.environ` в файле искажается санитайзером → внешняя обёртка + `export`, сверять `md5sum` |
### Выбор движка: Jellyfin vs Navidrome
| | Jellyfin | Navidrome |
|---|---|---|
| Источник имени артиста | **папка перекрывает тег** (баг #18162) | **только тег** |
| Структура папок | `Artist/Album/Track` обязательна | **игнорируется полностью** |
| Интернет-метаданные | тянет MusicBrainz | **не тянет** |
| Пишет в файлы | может | **никогда** |
| Видео | ✅ | ❌ |
**`ALBUMARTIST` в Navidrome НЕ обязателен** — мейнтейнер `deluan` (#5924):
> «when an album artist tag is missing, Navidrome substitutes the track artist in its place»
Обход без правки тегов:
```toml
PID.Album = "musicbrainz_albumid|albumartist,album,albumversion,releasedate"
```
- **сырое `albumartist`**, НЕ `albumartistid` (тот никогда не пуст);
- `folder` в спеку как fallback класть **нельзя**;
- смена `PID.Album` → полный рескан + новые ID → **бэкапить `navidrome.db`**.
**Lidarr пишет теги сам** при импорте (MusicBrainz + `Write Metadata Tags`) — новые закачки
приходят с `Album Artist`. Связка: `navidrome-lidarr-bridge`.
### Ловушка: семантически валидные, но бессмысленные теги
```
artist=Классика в современной обработке ← не артист
artist=Классика для детей П.И. Чайковский ← не артист
artist=Maria Makarova (organ) ← исполнитель вместо композитора
```
Проходят любую проверку на мойибаке/кодировку. **Если имя артиста в UI удивляет — сначала
grep по тегу `artist` реальных файлов**, прежде чем строить версии про внешние базы.
## Связанные заметки
- [[personal/tech/jellyfin-tags-cp1251-unreadable]] — полный разбор дефекта
- [[family/plans/music-jellyfin-lidarr-taiga]] — план проекта, открытые задачи
- [[family/how-to/navidrome-truenas-android]] — план деплоя Navidrome
- [[personal/tech/jellyfin-db-schema-mismatch]] — схема БД Jellyfin
@@ -204,18 +204,50 @@ TAG:ID3v1 Comment=ñêàçêà ← 🔑 МАРКЕР
^^^^^^^^^^^^ имя папки в запросе
```
### 🎯 ЭТО ОБЪЯСНЯЕТ `Maria Makarova (organ)`
### 🎯 ЭТО ОБЪЯСНЯЕТ `Maria Makarova (organ)` — v7: ИСТОЧНИК НАЙДЕН, ЭТО НАШИ ТЕГИ
Alex указал на несоответствие: `Maria Makarova` в UI Jellyfin — это **органистка
(Maria Makarova, organ)**, а НЕ «Маша Макарова» из Ногу Свело.
> 🔴 **v7 (2026-09-27, финальная сессия): версия «имя пришло из MusicBrainz» тоже НЕВЕРНА.**
> Источник — **собственный тег `artist` в нашем файле.** Ниже сохранены обе ошибочные версии
> как история; **актуальный факт — в этом блоке.**
- В наших файлах есть только фит: `!Rock&Folk/Ногу Свело!/2004 - Откровенные фотографии/10.Ногу свело - Реки (feat. Маша Макарова).mp3`
- Файлов с тегом `Makarova`/`Макарова` в библиотеке **не найдено** поиском по тегам.
- **Вывод: имя пришло ИЗ ВНЕШНЕЙ БАЗЫ (MusicBrainz/TheAudioDB)**, куда Jellyfin пошёл по
имени папки/файла и получил первое совпадение — западную органистку.
**Файл-источник (найден фактом через CSV + чтение тегов):**
> 🔴 **Версия «она прошла потому, что имя ASCII/латиница» — ОКОНЧАТЕЛЬНО ОПРОВЕРГНУТА.**
> Не тиражировать ни в какой форме.
```
/storage/Music/!Классика/Бах — Toccata and Fugue in D minor.mp3
TAG:title=J.S. Bach: Toccata and Fugue (D minor) BWV565
TAG:artist=Maria Makarova (organ) ← 🔑 ВОТ ОНА, в НАШЕМ теге
raw TPE2 в файле: НЕТ
```
**`Maria Makarova (organ)` записан в тег `artist` этого файла** — исполнительница Баха.
Jellyfin честно создал по нему артиста. **Отсюда в UI ровно один артист** —
не баг, не MusicBrainz, не «feat. Маша Макарова», а **наши собственные данные.**
**Следствие для ремонта:** это **семантическая ошибка в тегах**, а не техническая.
У Баха артист должен быть «И.С. Бах», а исполнитель — в отдельном поле (`TPE2`/`composer`).
Такие файлы стоит искать отдельным аудитом семантики `artist`.
> ⚠️ **ДВЕ опровергнутые версии этого же имени (не тиражировать ни одну):**
> 1. «feat. Маша Макарова из Ногу Свело» — **неверно**, это фит в другом файле
> (`!Rock&Folk/Ногу Свело!/.../10.Ногу свело - Реки (feat. Маша Макарова).mp3`),
> к органистке отношения не имеет;
> 2. «пришло из MusicBrainz/TheAudioDB» — **неверно**, имя лежит в теге нашего файла.
> 3. «прошла потому что латиница/ASCII» — **неверно** (см. ниже).
### ⚠️ Уточнение к v6: где именно ломается навигация
Баг #18162 **подтверждён официально**, но в **нашем** случае действуют **оба** фактора,
и разделить их точно не удалось:
| Фактор | Статус |
|---|---|
| `TPE2` отсутствует у 154/154 (факт) | ✅ подтверждён |
| Баг #18162 перекрывает теги именем папки | ✅ подтверждён в upstream |
| Наша 4-уровневая структура `категория/папка/папка/файл` | ✅ вклад есть |
**Практический вывод:** Jellyfin для нашей структуры **непригоден** независимо от того,
какой из факторов главный. Поэтому решение — **сменить движок на Navidrome**, а не
чинить `TPE2` ради Jellyfin.
### Следствие: `TPE2` — НЕ единственная и, вероятно, не главная причина
@@ -272,6 +304,80 @@ Alex указал на несоответствие: `Maria Makarova` в UI Jell
правильные (по `TPE1`), но альбомы могут склеиваться/дробиться. `TPE2` желателен, но
**не блокирует запуск** — в отличие от Jellyfin.
### 🔬 `ALBUMARTIST` в Navidrome — НЕ обязателен (ответ на вопрос Alex, 2026-09-27)
**Вопрос Alex:** «Ты уверен, что Navidrome это поле обязательно? А новые закачки как в него
попали бы, если оно нигде не заполнено?»
**Ответ получен из первоисточников.**
**① Не обязательно — Navidrome подставляет `artist`.** Из официального обсуждения
Navidrome **#5924**, ответ **мейнтейнера `deluan`**:
> «when an album artist tag is missing, Navidrome substitutes the **track artist** in its place»
**Что при этом происходит:**
| Ситуация | Результат в Navidrome |
|---|---|
| `ALBUMARTIST` у всех 12 треков | 1 альбом, 12 треков ✅ |
| `ALBUMARTIST` у 10 из 12 | 1 альбом + 2 «сироты» ⚠️ |
| Нет `ALBUMARTIST`, 4 фита | **5 альбомов** вместо 1 ❌ |
| Нет `ALBUMARTIST`, сборник 18 треков | **до 18 альбомов** ❌ |
Из технического разбора (dev.to, «tagging and mount anti-patterns»):
> «Because it is the only tag that tells Navidrome **who owns the album**, and when it is absent
> the scanner falls back to the per track `ARTIST` value. On a solo record that fallback is
> harmless. On anything with a featured guest, a duet, a remixer or an orchestra credit, it
> **shatters one album into several one-track albums**.»
> **Правило:** `ARTIST` описывает исполнение; `ALBUMARTIST` описывает «полку» — должен быть
> **идентичен у каждого файла альбома**.
**② Имена тегов по контейнерам:** `TPE2` (ID3v2/MP3), `ALBUMARTIST` (Vorbis/FLAC),
`aART` (MP4/AAC/ALAC).
**③ Обход без правки тегов — есть конфиг.** Если `ALBUMARTIST` отсутствует массово, можно
поправить **группировку**, не трогая файлы:
```toml
# navidrome.toml
PID.Album = "musicbrainz_albumid|albumartist,album,albumversion,releasedate"
```
> 🔑 **Ключевой нюанс от `deluan`:** использовать в спеке **сырое имя тега `albumartist`**,
> а **НЕ `albumartistid`** — последний вычисляется **после** подстановки track artist и
> поэтому **никогда не пустой**. Сырой `albumartist` = реальное значение тега.
>
> ⚠️ **Использовать в спеку `folder` НЕЛЬЗЯ как «fallback»** — секция спеки пропускается
> только когда **все** её значения пусты, а `album` всегда непуст → первая секция всегда матчится.
>
> ⚠️ **Смена `PID.Album` → полный рескан и новые ID.** Бэкапить `navidrome.db` перед этим:
> play counts / рейтинги / starred привязаны к старым ID.
**④ Оговорка:** PID управляет **только группировкой, не отображаемым именем**. Слитый альбом
всё равно покажет одного из track-артистов как album artist — это в доке признано и требует
изменения кода.
### ✅ Новые закачки: Lidarr пишет `albumartist` сам
**Lidarr работает через MusicBrainz и проставляет полные теги при импорте:**
> «It scans a root folder, matches what it finds to **MusicBrainz release groups**, and imports
> matched files» (Servarr Wiki, Lidarr Library)
**В Lidarr есть штатное действие записи тегов:** `Write Metadata Tags` (в меню Select Artists
для массовой операции над выбранными артистами).
**То есть:** новые закачки приходят с полным набором тегов, **включая `Album Artist`** —
MusicBrainz отдаёт его для каждого релиза. Ручная простановка нужна только для **существующей**
библиотеки (7861 файл).
**Связка Lidarr + Navidrome — штатный, поддерживаемый сценарий:** существует отдельный проект
[`navidrome-lidarr-bridge`](https://github.com/danielbanariba/navidrome-lidarr-bridge) —
звёздочка артиста в Navidrome запускает мониторинг в Lidarr, а закачанное Lidarr'ом попадает
прямо в папку Navidrome и подхватывается автоматически.
**Наша библиотека готова к Navidrome:** 7826 файлов, теги `artist`/`title`/`album` в UTF-16.
**Минусы Navidrome:** нет просмотра по папкам вообще (разработчик отказал принципиально:
@@ -356,6 +462,101 @@ fix 2935 no_change 1582
+ артисты-значения: Savant 237, Сектор Газа 191, Infected Mushroom 187, Ленинград 161, Enigma 107, Любэ 103
```
### 🔍 Что такое `clean`-файлы и есть ли у них `albumartist` (ответ Alex)
**Вопрос Alex:** «В тех которые clean — это какие например? В них есть albumartist?»
**`clean` = заполнены `title` + `artist`, мойибаке нет.** Критерий — «не кракозябры»,
**не** «полный набор тегов».
**Выборка 12 файлов со `status_title=clean` И `status_artist=clean`** (все из `!Классика`):
| # | Файл | `artist` | `album_artist` в CSV | raw `TPE2` |
|---|---|---|---|---|
| 1 | Чайковский — Танец маленьких лебедей | Пётр Ильич Чайковский | пусто | НЕТ |
| 2 | Моцарт — Турецкий марш | Классика в современной обработке | пусто | НЕТ |
| 3 | Григ — В пещере горного короля | Эдвард Григ | пусто | НЕТ |
| 4 | Вивальди — Зима | Вивальди | пусто | НЕТ |
| 5 | Бетховен — К Элизе | Людвиг ван Бетховен | пусто | НЕТ |
| 6 | Сен-Санс — Пляска смерти | Kevin MacLeod | **Kevin MacLeod** | НЕТ |
| 7 | **Бах — Toccata and Fugue** | **Maria Makarova (organ)** | пусто | НЕТ |
| 8 | Вагнер — Полёт валькирий | Рихард Вагнер | пусто | НЕТ |
| 9 | Прокофьев — Танец рыцарей | КЛАССИКА. Сергей Прокофьев | пусто | НЕТ |
| 10 | Чайковский — Танец феи Драже | Классика для детей П.И. Чайковский | пусто | НЕТ |
| 11 | Вивальди — Лето | Популярная классика | пусто | НЕТ |
| 12 | Свиридов — Метель | Georgy Sviridov (Moscow City Symphony) | пусто | НЕТ |
**Итог: 11 из 12 — `album_artist` пуст; `raw TPE2` НЕТ ни у одного.**
> 🔑 **Важный питфолл:** у файла №6 ffprobe **показывает** `album_artist=Kevin MacLeod`,
> но `raw TPE2` в байтах **не найден**. Значит ffprobe читает это значение **НЕ из `TPE2`**,
> а из другого источника (ID3v1-хвост или TXXX-фрейм). Это объясняет расхождение:
> в CSV `album_artist` заполнен у **3507**, но в реальных ID3v2-фреймах `TPE2` **нет**.
> **Не доверять ffprobe для проверки наличия `TPE2` — только `od` по байтам.**
### ⚠️ Семантика `artist` — отдельный класс дефектов
Файлы `!Классика` показывают **семантическую**, не техническую проблему:
```
artist=Классика в современной обработке ← это не артист
artist=Классика для детей П.И. Чайковский ← это не артист
artist=КЛАССИКА. Сергей Прокофьев ← это не артист
artist=Maria Makarova (organ) ← исполнитель вместо композитора
```
Теги **формально валидны** (заполнены, UTF-16), но **семантически мусорные**. Такие файлы
не ловятся ни `verdict`, ни проверкой на мойибаке. **Нужен отдельный аудит семантики `artist`**
перед тем, как библиотека пойдёт в Navidrome — иначе в списке артистов будут
«Классика в современной обработке».
### 📦 Дополнение бэкапа: 1436 файлов не хватало (2026-09-27)
**Задача Alex:** «дополни music/backup файлами которые в него не попали из music».
**Скан (сравнение по относительному пути, `comm -23`):**
```
в backup уже есть: 7041 файлов
в основной библиотеке: 8421 файлов (не только mp3!)
НЕ ХВАТАЕТ: 1436 файлов
```
**Разбивка нехватки по расширениям:**
| Расширение | Файлов | |
|---|---:|---|
| `mp3` | **876** | ← основное |
| `jpg` | 287 | обложки |
| `ini` | 65 | |
| `m3u` | 50 | плейлисты |
| `db` | 28 | |
| `nfo` | 22 | |
| `sfv` | 21 | |
| `gif` | 20 | |
| `.DS_Store` | 18 | мусор macOS |
| `url` | 8 | |
| `txt` | 8 | |
| `mpg` | **6** | видео в папке музыки |
| `directory` | 5 | |
| `avi` | **5** | видео в папке музыки |
| `jpeg` | 4 | |
**Разбивка по верхним папкам:**
```
!Pop, Club, Любэ 566 !Рэп 64
!Rock&Folk 542 z Другое 55
!A Not sorted 109 !Retro 52
!Барды 36 !Классика 11 !Детские 1
```
⚠️ **Решение Alex по спорным категориям (видео `.avi`/`.mpg`, `.DS_Store`) не принято** —
вопрос задан, копирование не запущено.
**Скрипт сканирования:** `/tmp/bkfill_scan.sh` на NAS (чтение-только, списки в `/tmp/bkfill/`).
**Правило сравнения:** строго по **относительному пути** — в библиотеке есть **дубли имён
в разных папках**, сравнение по имени файла ловит оба.
## Ремонт (предложен, НЕ выполнен)
**Цель:** перекодировать ID3v2.3 → **UTF-16 с BOM** (или ID3v2.4 + UTF-8), чтобы Jellyfin читал.