[2026-09-26] eagle: personal/plans/music-tags-review/1-needs-decision.sync-conflict-20260926-150525-XJRJQB2.md personal/plans/music-tags-review/1-needs-decision.sync-conflict-20260926-165021-C6DYBCZ.md personal/tech/music-tags-repair-truenas.md
This commit is contained in:
1 parent
c001e3fec7
commit
680da87d49
3 files changed
+72
-1727
No files matched your search
-1530
File diff suppressed because it is too large.
Load diff
-182
@@ -1,182 +0,0 @@
|
||||
---
|
||||
title: Music Tags — Требует решения
|
||||
type: task
|
||||
namespace: personal
|
||||
tags: [music, jellyfin, tags, review, truenas]
|
||||
status: awaiting-approval
|
||||
block: cannot
|
||||
---
|
||||
|
||||
# Требует решения
|
||||
|
||||
**Файлов:** 28 · **Папок:** 13
|
||||
|
||||
> [!info] Исполнитель неоткуда взять однозначно — разобрано вручную.
|
||||
> Ставь `- [x]` напротив согласных правок и скажи «go».
|
||||
|
||||
[[music-tags-review|← к обзору]]
|
||||
|
||||
## Оглавление
|
||||
|
||||
- `!A Not sorted` — 1
|
||||
- `!Pop, Club, Любэ` — 1
|
||||
- `!Pop, Club, Любэ/!Radio/t 2009-07 c6Or_NICK/base` — 1
|
||||
- `!Pop, Club, Любэ/!Radio/t 2009-07 c6Or_NICK/рап` — 1
|
||||
- `!Pop, Club, Любэ/!Radio/v 2009-03 mIr.vEsNЫ` — 5
|
||||
- `!Pop, Club, Любэ/!Radio/x 2008-04` — 1
|
||||
- `!Pop, Club, Любэ/!Radio/y OOF` — 8
|
||||
- `!Pop, Club, Любэ/!Radio/z Старое` — 2
|
||||
- `!Retro` — 5
|
||||
- `!Детские` — 1
|
||||
- `z Другое, Enigma, Ленинград/Саундтреки` — 2
|
||||
|
||||
---
|
||||
|
||||
## А. Исполнитель вписан вручную — очевидно (8 файлов)
|
||||
|
||||
## z Другое, Enigma, Ленинград/Саундтреки
|
||||
|
||||
- [ ] **Pirates of the Caribbean.mp3**
|
||||
- `artist`: ⟨мусор-релиз⟩ → **Hans Zimmer feat. Dimitri Vegas & Like Mike**
|
||||
- `title`: Hans Zimmer feat. Dimitri Vegas & Like Mike - Hes A Pirate (Bonus Track) → **He's a Pirate (Bonus Track)**
|
||||
- [ ] **Interstellar.mp3**
|
||||
- `artist`: Interstellar - OST Интерстеллар - Саундтрек [Score] (2014) → **Hans Zimmer**
|
||||
- `title`: Hans Zimmer - No Time For Caution → **No Time for Caution**
|
||||
|
||||
## !Retro
|
||||
|
||||
- [ ] **Кольщик.mp3**
|
||||
- `title`: ⟨повреждено⟩ → **Кольщик**
|
||||
- `artist`: ⟨повреждено⟩ → **Михаил Круг**
|
||||
- [ ] **Пропаганда-Супер детка.mp3**
|
||||
- `artist`: ⟨повреждено⟩ → **Пропаганда**
|
||||
- `title`: ⟨повреждено⟩ → **Супер детка**
|
||||
|
||||
## !Pop, Club, Любэ
|
||||
|
||||
- [ ] **detskiy_hor_benassi_satisfaction.mp3**
|
||||
- `title`: ⟨повреждено⟩ → **Satisfaction**
|
||||
- `artist`: ⟨повреждено⟩ → **Детский хор + Benny Benassi**
|
||||
- `album`: ⟨повреждено⟩ → **—**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/t 2009-07 c6Or_NICK/base
|
||||
|
||||
- [ ] **01 Hit The Road Jack (Kub vs Ray Charles).mp3**
|
||||
- `artist`: — → **Kub vs Ray Charles**
|
||||
- `title`: — → **Hit the Road Jack**
|
||||
- `track`: — → **1**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/v 2009-03 mIr.vEsNЫ/1 novo.E
|
||||
|
||||
- [ ] **06 Benassi I am a Dj.mp3**
|
||||
- `artist`: — → **Benassi**
|
||||
- `title`: — → **I Am a DJ**
|
||||
- `track`: — → **6**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/y OOF
|
||||
|
||||
- [ ] **Mymij_troll_kontrabanda.mp3**
|
||||
- `artist`: — → **Мумий Тролль**
|
||||
- `title`: — → **Контрабанда**
|
||||
- [ ] **lil jon.mp3**
|
||||
- `artist`: — → **Lil Jon**
|
||||
- `title`: — → *(имя папки/файла не содержит названия — оставить пусто)*
|
||||
|
||||
---
|
||||
|
||||
## Б. Исполнителя взять неоткуда — только title (20 файлов)
|
||||
|
||||
Ставь `- [x]`, если согласен с title. Artist остаётся пустым (Jellyfin → Unknown Artist).
|
||||
|
||||
## !A Not sorted
|
||||
|
||||
- [ ] **НАШЕСТВИЕ 2009 - ДЕНЬ ВТОРОЙ.mp3**
|
||||
- `title`: — → **НАШЕСТВИЕ 2009 — День второй**
|
||||
- _примечание: это фестиваль, не артист_
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/t 2009-07 c6Or_NICK/рап
|
||||
|
||||
- [ ] **Нарк.mp3**
|
||||
- `title`: — → **Нарк**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/v 2009-03 mIr.vEsNЫ/2 y.MATno.E
|
||||
|
||||
- [ ] **БОДРЯЧКОМ.mp3**
|
||||
- `title`: — → **Бодрячком**
|
||||
- [ ] **Бык, не быкуй!.mp3**
|
||||
- `title`: — → **Бык, не быкуй!**
|
||||
- [ ] **волна по ебалу на.mp3**
|
||||
- `title`: — → **Волна по ебалу**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/v 2009-03 mIr.vEsNЫ/3 clubNИчкоvo.E
|
||||
|
||||
- [ ] **Kazantip 2008 - Beat (zvukoff.ru).mp3**
|
||||
- `artist`: Kazantip 2008 → **—**
|
||||
- `title`: — → **Beat**
|
||||
- _примечание: Kazantip — событие, не артист_
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/x 2008-04
|
||||
|
||||
- [ ] **Sensation White (2008) - Matisse (Remix).mp3**
|
||||
- `artist`: — → **Matisse**
|
||||
- `title`: — → **Sensation White (Remix)**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/y OOF
|
||||
|
||||
- [ ] **029_Mast.mp3**
|
||||
- `title`: — → **Mast**
|
||||
- `track`: — → **29**
|
||||
- [ ] **Dj Riga ceh-126 Track.mp3**
|
||||
- `artist`: — → **DJ Riga**
|
||||
- `title`: — → **ceh-126 Track**
|
||||
- [ ] **I M P R E Z A.mp3**
|
||||
- `title`: — → **Impressa**
|
||||
- [ ] **dj toll.mp3**
|
||||
- `title`: — → **DJ Toll**
|
||||
- [ ] **i am instructor.mp3**
|
||||
- `title`: — → **I Am Instructor**
|
||||
- [ ] **клубняк3.mp3**
|
||||
- `title`: — → **Клубняк 3**
|
||||
|
||||
## !Pop, Club, Любэ/!Radio/z Старое
|
||||
|
||||
- [ ] **Вертолет башку сорвет!(dj karas extra club).mp3**
|
||||
- `artist`: — → **DJ Karas**
|
||||
- `title`: — → **Вертолёт башку сорвёт (Extra Club Mix)**
|
||||
- [ ] **Перец.mp3**
|
||||
- `title`: — → **Перец**
|
||||
|
||||
## !Retro
|
||||
|
||||
- [ ] **Казанова.mp3**
|
||||
- `title`: ⟨повреждено⟩ → **Казанова**
|
||||
- `artist`: ⟨повреждено⟩ → **—**
|
||||
- [ ] **Младший лейтенант.mp3**
|
||||
- `title`: ⟨повреждено⟩ → **Младший лейтенант**
|
||||
- `artist`: ⟨повреждено⟩ → **—**
|
||||
- _вероятно Сектор Газа / Воровайки — не угадываю_
|
||||
- [ ] **Остаёмся зимовать.MP3**
|
||||
- `title`: ⟨повреждено⟩ → **Остаёмся зимовать**
|
||||
- `artist`: ⟨повреждено⟩ → **—**
|
||||
- `album`: ⟨повреждено⟩ → **—**
|
||||
|
||||
## !Детские
|
||||
|
||||
- [ ] **Из чего же.mp3**
|
||||
- `title`: Èç ÷åãî æå, èç ÷åãî æå, èç ÷åãî æå → **Из чего же, из чего же, из чего же**
|
||||
- `artist`: Íåèçâåñòíûé èñïîëíèòåëü → **—**
|
||||
- `album`: Íåèçâåñòíîå íàçâàíèå → **—**
|
||||
|
||||
---
|
||||
|
||||
## Итог
|
||||
|
||||
| Категория | Файлов |
|
||||
|---|---:|
|
||||
| Artist вписан вручную (А) | **10** |
|
||||
| Только title, artist пусто (Б) | **18** |
|
||||
| **Всего** | **28** |
|
||||
|
||||
**Осталось 8 файлов без artist** (`Казанова`, `Младший лейтенант`, `Остаёмся зимовать`, `БОДРЯЧКОМ` и др.) — источника нет, не угадываю.
|
||||
|
||||
[[music-tags-review|← к обзору]]
|
||||
@@ -26,7 +26,7 @@ related:
|
||||
> третья волна по замечаниям Alex → 3 бага (en-dash + подстроковый поиск стоп-слов),
|
||||
> **четвёртая волна (ручной проход) → 10 багов (track-номера, disc-track, восклицательные знаки, регистр)**,
|
||||
> **пятая волна (ручной разбор блока 1 глазами) → 28 файлов, 10 артистов вписано вручную**,
|
||||
> **шестая волна (Alex правит мои md + ACL-фикс синка) → найдены баг `ÿþ`-BOM и конфликтные файлы**.
|
||||
> **шестая волна (Alex правит мои md + ACL-фикс синка) → найден и ПОЧИНЕН баг `ÿþ`-BOM в парсере ID3**.
|
||||
> Итог v5: 6773 `fix`, mojibake = 0, 121 тест PASS, блок «требует решения» 296 → 28.
|
||||
|
||||
## 🔴 ШЕСТАЯ ВОЛНА: ALEX ПРАВИТ МОИ НОТЫ + ACL-ФИКС СИНКА (2026-09-26)
|
||||
@@ -59,26 +59,83 @@ Alex: **«Needs decision — забирай из syncthing. Medium confidence
|
||||
> Alex поправил `title` на `Цех-126 Track` (кириллица). Вывод: в папках `!Radio/*`
|
||||
> artist почти всегда = первые 1–3 слова имени, остальное = название. Проверять это первым.
|
||||
|
||||
### 🔴 БАГ: `ÿþ` (UTF-16 BOM) «починен» в мусор — 4 строки в `2-medium-confidence.md`
|
||||
### ✅ БАГ `ÿþ` (UTF-16 BOM) — НАЙДЕНА ПЕРВОПРИЧИНА, ПАРСЕР ПОЧИНЕН
|
||||
|
||||
Alex: **«Какого хуя ты мне подсовываешь мусор со сбитой кодировкой?! Там cp1251 а не мусор!!»** —
|
||||
замечание по сути верное, но диагноз оказался глубже: там **не CP1251 и не mojibake**,
|
||||
а **битый ID3-тег: BOM при `enc_byte=0`**.
|
||||
|
||||
#### Что реально в байтах (дамп файла, `dump_id3.py`)
|
||||
|
||||
```
|
||||
06 Steel Deluxe - Сердце открой.mp3
|
||||
title: ÿþ!@54F5 B:@>9 → яю!@54F5 B:@>9 ← МУСОР вместо названия
|
||||
10 Boom (Bimbo Jones Mix).mp3
|
||||
title: ÿþY → яюY
|
||||
artist: ÿþd → яюd
|
||||
album: ÿþY → яюY
|
||||
header: ID3 ver=3.0
|
||||
frame TIT2 enc_byte=0 payload = 00 FF FE 21 40 35 34 46 35 20 42 3A 40 3E 39
|
||||
frame TPE1 enc_byte=0 payload = 00 FF FE 53 74 65 65 6C 20 44 65 6C 75 78 65
|
||||
frame TALB enc_byte=0 payload = 00 "Record Super Chart ¹ 90 (30.05.2009)"
|
||||
```
|
||||
|
||||
**Причина:** байты `FF FE` в начале строки — это **UTF-16 BOM**, а не CP1251→Latin-1 mojibake.
|
||||
`fix_encoding` конвертировал их как mojibake → `ÿþ` → `яю`. Результат **хуже исходного**.
|
||||
**Суть:** заголовок кадра объявляет `enc=0` (latin-1), а **содержимое начинается с `FF FE`** —
|
||||
UTF-16 BOM. Так писали древние теггеры: BOM поставили, байт кодировки оставили нулевым,
|
||||
а текст после BOM — **обычные 8-битные символы**, не UTF-16.
|
||||
|
||||
> 🔴 **ПИТФОЛЛ: `ÿþ` (0xFF 0xFE) в начале тега — это BOM, не mojibake.**
|
||||
> Не конвертировать. Настоящее значение — в имени файла (`Сердце открой`), artist — из имени.
|
||||
> **Ложное срабатывание grep:** строки `Òåðÿþ ñâåò → Теряю свет` в `3-high-confidence.md`
|
||||
> содержат `ÿþ` **внутри слова «Теряю»** — это корректная конвертация, НЕ баг. Различать по позиции.
|
||||
Отсюда `ÿþSteel Deluxe` (= `FF FE` + ASCII «Steel Deluxe») — а не сломанная кириллица.
|
||||
|
||||
**Реальных багов — 4 строки (1 файл), не 2096.** Проверять адресно, а не по всему файлу.
|
||||
> 🔴 **ПИТФОЛЛ: `ÿþ` (0xFF 0xFE) в начале тега — это BOM-префикс, а НЕ UTF-16-текст и НЕ mojibake.**
|
||||
> Текст за ним читать как **8-битный**, сам BOM — отбросить.
|
||||
> **Ловушка:** наивное `payload.decode("utf-16")` склеивает ASCII-пары →
|
||||
> `Steel Deluxe` → `瑓敥\u206c敄畬數`. Проверено на живом файле: первая версия фикса дала именно это.
|
||||
|
||||
#### Фикс — `id3_direct.py`, функция `decode_text()`
|
||||
|
||||
```python
|
||||
raw = data[1:]
|
||||
# Broken tagger: encoding byte says latin-1 (0), payload starts with a
|
||||
# UTF-16 BOM. In practice the BOM is a bogus prefix and the remaining
|
||||
# bytes are 8-bit text -- decode them, don't let the BOM win.
|
||||
if enc == 0 and raw[:2] in (b"\xff\xfe", b"\xfe\xff"):
|
||||
raw = raw[2:]
|
||||
text = raw.decode(codec, errors="replace")
|
||||
return text.strip("\x00").strip().lstrip("\uffff\ufffe").strip("\ufeff")
|
||||
```
|
||||
|
||||
**Проверено на `06 Steel Deluxe - Сердце открой.mp3`:**
|
||||
```
|
||||
artist: 'Steel Deluxe' ← было 'ÿþSteel Deluxe' / '瑓敥…' → ВОССТАНОВЛЕН ✅
|
||||
title : '!@54F5 B:@>9' ← мусор в самом теге → брать из имени файла
|
||||
```
|
||||
|
||||
#### Два класса дефекта (различать!)
|
||||
|
||||
| Класс | Пример | Как чинить |
|
||||
|---|---|---|
|
||||
| **BOM + валидный 8-бит текст** | TPE1 = `FF FE` + `Steel Deluxe` | отбросить BOM → **artist готов** ✅ |
|
||||
| **BOM + мусор в теге** | TIT2 = `FF FE` + `21 40 35 34 46 35` | взять из **имени файла** |
|
||||
|
||||
#### Масштаб — 4 файла, НЕ 2096 (`scan_bom.py` по всем 7906 строкам CSV)
|
||||
|
||||
```
|
||||
❌ 10 Boom (Bimbo Jones Mix) title='ÿþY' artist='ÿþd' → title из имени
|
||||
❌ 06 Steel Deluxe - Сердце открой title='ÿþ!@54F5 B:@>9' → title из имени (artist OK)
|
||||
❌ 12 Whizzkids Feat. Inusa Dawuda title="'ÿþRumours…" artist=';ÿþWhizzkids…' → оба из имени
|
||||
❌ 31 Inna - Love (Play & Win Club Mix) title='7ÿþoLve…' artist='ÿþInna' → оба из имени
|
||||
```
|
||||
|
||||
> ⚠️ **Ложное срабатывание grep — 5 строк в `3-high-confidence.md`:**
|
||||
> `Òåðÿþ ñâåò → Теряю свет`, `Ïîçäðàâëÿþ → Поздравляю` — здесь `ÿþ` **внутри слова** («Теряю»),
|
||||
> это корректная CP1251-конвертация. Различать по позиции: начало значения ≠ середина слова.
|
||||
|
||||
У всех 4 файлов artist/title выводятся из имени — правки возможны **без участия Alex**.
|
||||
|
||||
**Скрипты, появившиеся в этой волне:**
|
||||
|
||||
| Файл | Что делает |
|
||||
|---|---|
|
||||
| `dump_id3.py` | Дамп сырых байтов ID3-кадров (`enc_byte`, hex, repr, попытки декодирования). Незаменим при разборе кодировок |
|
||||
| `scan_bom.py` | Поиск `ÿþ` по всем полям CSV-плана — отделяет реальный BOM от середины слова |
|
||||
|
||||
> 📌 **Правило диагностики кодировок: сначала дамп байтов, потом гипотеза.** Я дважды ошибся,
|
||||
> угадывая («это CP1251» → «это UTF-16»), пока не посмотрел `payload.hex()`.
|
||||
> `dump_id3.py --file <mp3>` показывает `enc_byte` и сырые байты за один прогон.
|
||||
|
||||
### 📂 Конфликтные файлы Syncthing — зачем и что с ними
|
||||
|
||||
|
||||
Reference in new issue
Block a user