- Extract 11-char YouTube video IDs from audio filenames
- Fetch title, uploader, chapters via yt-dlp (--dump-json)
- Use chapters as tracklist when no .txt tracklist is available
- Store yt_title / yt_uploader in AlbumHints for LLM prompt context
- Fall back to YouTube video title as track title for single-file albums
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pop schema: TT_-_Artist_-_Title.ext
Classical schema: TT_-_Performer_-_Komponist_-_Werk[-_Orchester_Dirigent].ext
triggered when albumartist ≠ track artist (pianist vs composer)
All spaces in names → underscores; separator _-_ between parts.
Missing parts (orchestra, conductor) are omitted.
models.py: added conductor/orchestra optional fields to TrackProposal.
executor.py: sanitize_dir_names() tries NameToUnix first, falls back to detox.
Called after all renames in a directory are complete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scanner: nicht in Unterordner wenn Root Audio-Dateien enthält (verhindert
Doppel-Scan bei versehentlichen Unterordner-Kopien); nur Disc-Ordner
(CD1, Disc 2…) werden bei Multi-CD-Alben rekursiert.
hint_extractor: M3U/Playlist-Dateien als Track-Reihenfolge-Quelle; BOM-
Bereinigung; Tracklist-Matching auch per Titel (nicht nur per Nummer);
tracknumber=0 wird als 'keine Nummer' gewertet.
metadata_resolver: sequenzielle Fallback-Nummerierung (1,2,3…) für Tracks
ohne Tracknummer — verhindert '00'-Präfix beim --rename; dir_artist hat
Vorrang vor 'Various Artists'-Heuristik; LLM darf bei Konfidenz <0.3
auch bestehende Werte korrigieren (Tippfehler im Verzeichnisnamen).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AI-powered per-album pipeline: scan → local hints → MusicBrainz/Discogs/Claude
resolve → cover art → interactive or auto review → tag write + rename + report.
All external dependencies optional; 17/17 unit tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>