CDDB→album.json + LLM-Prompts mit Track-Künstler

ripper: nach erfolgreichem CDDB-Rip album.json im Album-Verzeichnis
speichern (Artist, Titel, alle Discs mit Track-Künstlern) — Workflow-
Lücke zwischen rip und apply geschlossen.

llm_parser, vision_llm: Prompts erklären das optionale Track-artist-
Feld; LLM setzt es nur wenn Track-Interpret vom Album-Künstler abweicht.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-02-18 00:16:44 +01:00
commit bafea5f335
3 changed files with 40 additions and 8 deletions

View file

@ -17,20 +17,23 @@ SYSTEM_PROMPT = """\
Du bist ein Parser für CD-Tracklisten. Extrahiere die Metadaten als JSON.
REGELN:
- "artist": Wenn verschiedene Interpreten pro Track "Various Artists". \
NUR wenn alle Tracks denselben Interpreten haben, nimm diesen als artist.
- "artist" (Album-Ebene): Hauptinterpret. Bei Samplern/Compilations "Various Artists".
- "album": Der Albumtitel (z.B. "Deutsche Volkslieder").
- "year": NUR wenn ein Jahr explizit im Text steht. Sonst null. NICHTS ERFINDEN.
- "title": NUR der Songtitel. KEINE Komponisten, KEINE Interpreten, KEINE Zeitangaben.
- "title": NUR der Songtitel. KEINE Komponisten, KEINE Zeitangaben.
Beispiel: "Wer recht in Freuden wandern will" NICHT \
"Wer recht in Freuden wandern will (Klauer Geibel)"
- "artist" (Track-Ebene, optional): NUR setzen wenn der Track-Interpret vom Album-Künstler \
abweicht (z.B. bei Samplern oder Klassik mit verschiedenen Solisten/Dirigenten). \
Ist der Interpret überall gleich, dieses Feld weglassen.
- Jede Tracknummer darf nur EINMAL vorkommen. Keine Duplikate.
- "CD 1", "CD 2", "Disc 1" etc. eigene disc_number. Sonst disc_number=1.
Gib ausschließlich valides JSON zurück:
{"artist":"Various Artists","album":"Albumname","year":null,\
"discs":[{"disc_number":1,"name":null,\
"tracks":[{"track_number":1,"title":"Nur der Songtitel"}]}]}
"tracks":[{"track_number":1,"title":"Songtitel","artist":"Interpret A"},\
{"track_number":2,"title":"Songtitel","artist":"Interpret B"}]}]}
/no_think"""

View file

@ -11,6 +11,9 @@ from typing import NamedTuple
from pydantic import BaseModel
from musiksammlung.config import AudioFormat
from musiksammlung.models import Album as AlbumModel
from musiksammlung.models import Disc as DiscModel
from musiksammlung.models import Track as TrackModel
logger = logging.getLogger(__name__)
@ -433,6 +436,7 @@ def interactive_rip(config: RipperConfig) -> None:
album_name = f"Album{album_counter}"
disc_counter = 1
all_discs: list[DiscModel] = []
while True:
print(f"\n Album: {album_name}")
@ -466,6 +470,17 @@ def interactive_rip(config: RipperConfig) -> None:
print(f" ✓ Done — {len(tracks)} tracks")
for t in tracks:
print(f" {t.track_number:2d}. {t.title} [{t.artist}]")
all_discs.append(DiscModel(
disc_number=disc_num,
tracks=[
TrackModel(
track_number=t.track_number,
title=t.title,
artist=t.artist,
)
for t in tracks
],
))
else:
print(" ✓ Done (no CDDB data)")
@ -483,6 +498,17 @@ def interactive_rip(config: RipperConfig) -> None:
disc_counter += 1
if all_discs:
artist = all_discs[0].tracks[0].artist or album_name
album_model = AlbumModel(artist=artist, album=album_name, discs=all_discs)
album_root = config.output_dir / _sanitize_name(album_name)
json_path = album_root / "album.json"
json_path.write_text(
album_model.model_dump_json(indent=2), encoding="utf-8"
)
print(f"\n album.json gespeichert: {json_path}")
print(" → Weiter mit: musiksammlung apply <album-verzeichnis> album.json")
raw_album = input("\nNext album? (y/n): ")
if _clean_input(raw_album).lower() != "y":
break

View file

@ -20,14 +20,17 @@ Lies das Foto einer CD-Rückseite oder eines Booklets ab. Das Bild kann gedreht
Extrahiere daraus die Metadaten und die vollständige Trackliste.
WICHTIG:
- "artist" ist der Hauptinterpret oder "Various Artists" bei Samplern/Compilations.
- "artist" (Album-Ebene): Hauptinterpret oder "Various Artists" bei Samplern/Compilations.
- "album" ist der Albumtitel (z.B. "Deutsche Volkslieder", "Abbey Road").
- "year" ist das Erscheinungsjahr (Zahl oder null wenn nicht sichtbar).
- Lies die Tracktitel GENAU so ab, wie sie auf der CD stehen.
- Achte besonders auf korrekte deutsche Umlaute (ä, ö, ü, ß).
- Lasse Zeitangaben (z.B. "3:12") aus dem Titel weg.
- "artist" (Track-Ebene, optional): NUR setzen wenn der Interpret dieses Tracks vom \
Album-Künstler abweicht (z.B. bei Samplern oder Klassik mit verschiedenen Solisten). \
Ist der Interpret überall gleich, dieses Feld weglassen.
- Wenn "CD 1", "CD 2", "Disc 1" etc. sichtbar sind, erstelle mehrere Einträge in "discs".
- Ohne Disc-Angabe: eine Disc mit disc_number=1.
- Lasse Zeitangaben (z.B. "3:12") und Interpretenangaben pro Track weg.
- MEHRSPALTIGE LAYOUTS: CD-Rückseiten haben oft 2, 3 oder 4 Spalten nebeneinander.
Lies ALLE Spalten vollständig von oben nach unten, bevor du zur nächsten Spalte gehst.
Überspringen oder Auslassen von Spalten ist ein häufiger Fehler lies jede Spalte komplett.
@ -36,8 +39,8 @@ Antworte NUR mit dem JSON, ohne Erklärung. Beispiel:
{"artist":"Various Artists","album":"Deutsche Volkslieder","year":null,""" # noqa: E501
VISION_PROMPT += """"discs":[{"disc_number":1,"name":null,"tracks":["""
VISION_PROMPT += """{"track_number":1,"title":"Erster Song"},"""
VISION_PROMPT += """{"track_number":2,"title":"Zweiter Song"}]}]}"""
VISION_PROMPT += """{"track_number":1,"title":"Erster Song","artist":"Interpret A"},"""
VISION_PROMPT += """{"track_number":2,"title":"Zweiter Song","artist":"Interpret B"}]}]}"""
VISION_PROMPT += """
Jetzt lies das Bild ab und gib das vollständige JSON aus. /no_think"""