feat(0.9): romaji sort-tags only, robust dupe detection, Mittelweg no-duration, autofill all fields

- Japanese tracks stored with original names in folder/filename/tags; romaji only in sort tags
- findExistingTrack: case-insensitive, searches all album folders under artist, strips release suffix
- --max-filesize 30M + 2x duration cap on all yt-dlp calls
- iTunes collectionArtistName captured as album_artist; fixes compilation album splitting
- album_artist tag uses mainArtist (not rawArtist) so all tracks in one album are consistent
- No-duration cascade: steps 5-8 (title-only/no-filter) removed — fail cleanly like with-duration
- Autofill iTunes: fills title, artist, albumArtist, discNum (was album/genre/year/track/total only)
- Autofill MusicBrainz: fills albumArtist, discNum (was missing both)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-21 13:26:11 +02:00
1 parent 8be3a515e6
commit fa4c954ab9
6 files changed
+148 -98

No files matched your search

+14 -5
View File
@@ -43,16 +43,22 @@ Backend runs in Docker (see `docker-compose.yml`); on the deploy host it lives a
- Downloads are **yt-dlp only** (the old squid.wtf/Qobuz backend was removed).
- **File naming:** `{NN - }Artist - Title.ext` with the release suffix stripped from the
title (no `- Single`/`- EP`). The **album folder keeps the full album name**. The cleaned
title (`cleanTitle`/`searchTitle`) drives both the filename and the embedded title tag.
title (no `- Single`/`- EP`). The **album folder keeps the full album name**. Original names
are used for folder, filename, and all main tags (artist/title/album/album\_artist) — even
for Japanese tracks. Romaji goes **only** into sort tags (TITLESORT / ARTISTSORT / etc.).
- **Search cascade** (`ytdlp.js`): YTM search first (`web_music` player client, Songs filter
param), then regular YouTube; each candidate filtered by duration (±10%, min 10s),
title keyword, artist channel, and variant exclusions (remix/cover/sped/…).
- **"Mittelweg" rule:** when the duration is known but nothing matches the duration window,
- **"Mittelweg" rule** (with AND without duration): when nothing matches in the filtered steps,
relax only the duration constraint while **still requiring the artist channel**. If nothing
matches, download **nothing** and fail cleanly with "Nicht eindeutig gefunden — bitte
Direktlink im Importer nutzen". Never fall back to a blind first-result grab (it pulled
same-titled videos by other uploaders).
Direktlink im Importer nutzen". Never fall back to a blind title-only/no-filter grab — it
pulled same-titled covers by other uploaders, and wrong Piano Echoes for Japanese tracks.
- **Size cap:** `--max-filesize 30M` on every yt-dlp call; Mittelweg steps also cap at 2×
expected duration. Prevents saving a 28-min video (52 MB) when the wrong result slips through.
- **Duplicate detection** (`metadata.js findExistingTrack`): searches case-insensitively across
all album folders under the matching artist folder; compares normalized artist+title ignoring
track prefix and release/variant suffix. Handles DJ OKAWARI vs DJ Okawari and "- Single" drift.
- **Known limitation:** yt-dlp's YTM/YouTube *search* can't surface very obscure Art Tracks by
ambiguously-named artists (e.g. "MINA") — the browser finds them, yt-dlp's API extraction
doesn't (confirmed across params/clients/deno). For those, the **direct link in the importer**
@@ -60,6 +66,9 @@ Backend runs in Docker (see `docker-compose.yml`); on the deploy host it lives a
- **File resolution for edit/delete:** Navidrome's stored path may use a different mount root
or a stale stem. `metadata.js` rebases the path and falls back to recursive/stem matching
(tolerant of release-suffix mismatch). A ghost Navidrome entry needs a full library rescan.
- **Album splitting:** prevented by consistent `album_artist` tag. All tracks in a download
share the same `mainArtist` value (= iTunes `collectionArtistName` when available, else
`albumArtist` param, else track artist). Never use `rawArtist` for `album_artist`.
## UI / references