# Bedienungsanleitung – Musiksammlung > **ACHTUNG! Das Programm ist nicht fertig!** ## Inhaltsverzeichnis 1. [Voraussetzungen](#1-voraussetzungen) 2. [Installation](#2-installation) 3. [Workflow-Überblick](#3-workflow-überblick) 4. [Schritt 1: CDs rippen](#4-schritt-1-cds-rippen) 5. [Schritt 2: Album-Metadaten ermitteln](#5-schritt-2-album-metadaten-ermitteln) 6. [Schritt 3: Dateien organisieren und taggen](#6-schritt-3-dateien-organisieren-und-taggen) 7. [Tags und Cover prüfen](#7-tags-und-cover-prüfen) 8. [Komplett-Pipeline](#8-komplett-pipeline) 9. [Tipps und Hinweise](#9-tipps-und-hinweise) --- ## 1. Voraussetzungen | Programm | Zweck | Pflicht | |----------|-------|---------| | Python 3.11+ | Laufzeitumgebung | ja | | `abcde` | CD-Ripping | ja | | `cdparanoia` | CD-Lesefehler korrigieren (von abcde genutzt) | ja | | `flac` / `lame` / `opusenc` / `ffmpeg` | Encoder je nach Format | je nach Format | | `tesseract` | OCR für Coverbilder | nein (optional) | | Ollama / OpenAI-API | LLM für Tracklisten-Extraktion | nein (optional) | | Ollama / OpenAI-API | Vision-LLM für Backcover-Analyse (parallel zum Ripping) | nein (optional) | Installation der externen Tools (Debian/Ubuntu): ```bash sudo apt install abcde cdparanoia flac lame opus-tools ffmpeg tesseract-ocr ``` Firewall (falls aktiv): Port 8765 für Smartphone-Upload freigeben: ```bash sudo ufw allow 8765/tcp ``` --- ## 2. Installation ```bash git clone cd Musiksammlung pip install -e ".[dev]" ``` Danach steht der Befehl `musiksammlung` zur Verfügung: ```bash musiksammlung --help ``` --- ## 3. Workflow-Überblick ``` musiksammlung rip │ ▼ Scanner-Server starten (Port 8765) + QR-Code im Terminal │ ▼ EAN/Barcode eingeben ODER CD-Hülle fotografieren │ ├─ Foto → KI liest Barcode → Bestätigung/Korrektur │ ├─ MusicBrainz-Treffer → Auto-Rip │ Zeige: Artist – Album (Year), N Discs, M Tracks │ CAA-Cover herunterladen (frontcover.jpg + backcover.jpg) │ Vision-LLM im Hintergrund starten (analysiert backcover.jpg) ←─┐ │ Für jede Disc: "CD 1/3 einlegen, Enter" → Rip → Rename │ parallel │ Vision-LLM-Ergebnis abwarten (max. 120 s, oft schon fertig) ───┘ │ Priorität: Vision-LLM > MusicBrainz │ album.json gespeichert │ → direkt weiter mit musiksammlung apply │ └─ Kein Treffer / EAN leer → Fallback QR-Code im Terminal + Scanner-Server starten (Port 8765) Albumname eingeben ODER Backcover-Foto hochladen (Auto-Continue) CD-Nummer → Rip → CDDB-Confirm Backcover-Foto → Vision-LLM im Hintergrund ←─┐ abcde sucht MBID → CAA-Cover herunterladen │ parallel Weitere Discs rippen ───┘ Vision-LLM-Ergebnis abwarten Priorität: Vision-LLM > CDDB album.json gespeichert (ggf. Verzeichnis umbenannt) │ └─ ohne Vision-LLM und ohne CDDB-Treffer: album.json manuell erzeugen: A: musiksammlung scan --from-text trackliste.txt B: musiksammlung scan back.jpg C: musiksammlung scan back.jpg --vision D: musiksammlung scan --barcode 0602557360561 E: musiksammlung scan --from-photo cover.jpg → album.json prüfen/korrigieren │ ▼ musiksammlung apply ← Umbenennen, Tags, Cover, Playlist │ ├─ --in-place (Standard): Dateien bleiben im Quellverzeichnis │ temp/Album/CD1/01_-_Titel_-_Kuenstler.flac │ └─ mit output_dir: Dateien in Jellyfin-Struktur verschieben ~/Musik/Kuenstler/Album/CD1/01_-_Titel_-_Kuenstler.flac ``` --- ## 4. Schritt 1: CDs rippen ### Grundbefehl ```bash musiksammlung rip ``` Das Programm fragt zuerst nach dem EAN/Barcode. Bei einem MusicBrainz-Treffer startet ein automatischer Rip-Vorgang für alle Discs des Albums. Ohne EAN oder bei Fehltreffer wird der manuelle Ablauf gestartet (Album-Name, CD-Nummer, CDDB-Bestätigung). ### Wichtige Optionen | Option | Beschreibung | Empfehlung | |--------|-------------|------------| | `-f flac` | Audio-Format | `flac` für Archiv, `mp3` für Kompatibilität | | `-q high` | Qualität (low/medium/high), Standard: `high` | `high` für Archiv | | `-j 0` | Alle CPU-Kerne für paralleles Encoding | empfohlen | | `-P` | Pipes-Modus (kein WAV-Zwischenspeicher) | empfohlen bei wenig Speicher | | `-o /pfad` | Ausgabe-Verzeichnis | Standard: `./temp` | | `-d /dev/sr0` | CD-Laufwerk | falls nicht `/dev/cdrom` | | `--no-cddb` | CDDB-Lookup deaktivieren | bei Offline-Betrieb | | `--vision-model` | Vision-LLM-Modell für Backcover-Analyse | Standard: `qwen3-vl:235b-cloud` | | `--vision-url` | Ollama/OpenAI-Basis-URL für Vision-LLM | Standard: `http://localhost:11434` | | `--scanner-port` | Port des Smartphone-Upload-Servers | Standard: `8765` | ### Beispiel: Schnelles FLAC-Ripping mit allen Kernen ```bash musiksammlung rip -f flac -q high -j 0 -P -o ~/rip ``` ### Interaktiver Ablauf **Mit EAN (Auto-Rip):** ``` --- Album 1 --- EAN/Barcode (Enter = überspringen): 028943753227 MusicBrainz-Suche nach Barcode 028943753227 ... ✓ Herbert von Karajan – Beethoven: 9 Symphonies (1963, 5 Disc(s), 50 Tracks) Cover-Download: frontcover.jpg, backcover.jpg [Vision-LLM analysiert backcover.jpg im Hintergrund...] CD 1/5 einlegen und Enter drücken (9 Tracks) ... Ripping to: temp/Beethoven__9_Symphonies/CD1 -------------------------------------------------- Track 1/9 Allegro con brio [████████████████░░░░░░░░░░░░░░] 54.3% 18.2 MB ... Umbenennen (CDDB-Daten) ... CD 2/5 einlegen und Enter drücken (4 Tracks) ... ... album.json gespeichert: temp/Beethoven__9_Symphonies/album.json Next steps: Album 1: Beethoven__9_Symphonies (1963) 1. Prüfen/bearbeiten: temp/Beethoven__9_Symphonies/album.json 2. musiksammlung apply temp/Beethoven__9_Symphonies/CD1 \ temp/Beethoven__9_Symphonies/album.json Next album? (y/n): n ``` **Ohne EAN (Fallback mit Backcover-Foto):** ``` --- Album 1 --- EAN/Barcode (Enter = überspringen): Scanner-Server gestartet: http://192.168.1.42:8765 [QR-Code im Terminal] Smartphone öffnen → Backcover fotografieren → automatisch weiter Album name (Enter = CDDB name / default 'Album1'): [Warten auf Foto oder Texteingabe] → Foto empfangen! Vision-LLM analysiert im Hintergrund... [Programm fährt automatisch fort] CD Drive: /dev/cdrom CD number [1]: 1 Ripping to: temp/Album1/CD1 -------------------------------------------------- Track 1/4 Allegro con brio [████████████████░░░░░░░░░░░░░░] 54.3% 18.2 MB ... CDDB-Treffer: 'Karajan / Beethoven Sinfonien' — 4 Tracks: 1. Allegro con brio [Karajan] 2. Andante con moto [Karajan] Treffer korrekt? (j/n) [j]: j Umbenennen ... Vision-LLM: Karajan / Beethoven Sinfonien (1963, 4 Tracks) Verzeichnis umbenannt: temp/Album1 → temp/Beethoven_Sinfonien Next CD for this album? (y/n): n album.json gespeichert: temp/Beethoven_Sinfonien/album.json Next steps: Album 1: Beethoven_Sinfonien 1. Prüfen/bearbeiten: temp/Beethoven_Sinfonien/album.json 2. musiksammlung apply temp/Beethoven_Sinfonien/CD1 \ temp/Beethoven_Sinfonien/album.json Next album? (y/n): n ``` ### Barcode / EAN per Smartphone scannen Das Programm startet zu Beginn jedes Albums automatisch einen lokalen HTTP-Server und zeigt einen QR-Code im Terminal an. Das Smartphone kann damit: 1. **EAN scannen** — CD-Hülle fotografieren → KI liest den Barcode automatisch aus 2. **Backcover hochladen** — Rückseite fotografieren → Vision-LLM analysiert parallel Der Server läuft für das gesamte Album (EAN + Backcover). Beim nächsten Album startet er neu. Ablauf EAN-Scan: ``` Scanner bereit: http://192.168.1.42:8765 [QR-Code] EAN/Barcode (Enter = überspringen): [Foto hochladen oder tippen] Barcode wird per KI erkannt... Erkannter Barcode: 0028943753227 Korrekt? (Enter = ja, neuer Wert = tippen): ``` ### Backcover-Foto per Smartphone hochladen Im Fallback-Modus (kein MusicBrainz-Treffer) kann derselbe laufende Scanner-Server auch für das Backcover genutzt werden: ``` Scanner-Server gestartet: http://192.168.1.42:8765 [█████████████] [█ ██ █ ] ← QR-Code im Terminal [█████████████] → Smartphone: QR-Code scannen → Backcover fotografieren ``` **Voraussetzungen:** - Smartphone im gleichen WLAN wie der Rip-Rechner - Firewall-Port 8765 offen: `sudo ufw allow 8765/tcp` Nach dem Hochladen fährt das Programm automatisch fort und startet die Vision-LLM-Analyse im Hintergrund. Sobald der Ripping-Prozess abgeschlossen ist, wird das Ergebnis übernommen. Bei MusicBrainz-Treffern wird `backcover.jpg` aus dem Cover Art Archive heruntergeladen — kein Foto nötig. ### Ergebnis-Verzeichnis **Wenn CDDB/Vision-LLM Daten liefert:** ``` ~/rip/ Beethoven_Sinfonien/ CD1/ 01_-_Allegro_con_brio_-_Karajan.flac 02_-_Andante_con_moto_-_Karajan.flac ... frontcover.jpg ← aus CAA oder automatisch hinzugefügt backcover.jpg ← aus CAA oder Smartphone-Foto album.json ← automatisch gespeichert ``` → Am Ende zeigt das Programm den fertigen `apply`-Befehl an (copy-paste-fähig). **Wenn kein CDDB-Treffer und kein Foto:** ``` ~/rip/ Beethoven_Sinfonien/ CD1/ track01.flac track02.flac ... ``` → In diesem Fall weiter mit Schritt 2 (Metadaten ermitteln). --- ## 5. Schritt 2: Album-Metadaten ermitteln Dieser Schritt ist nur nötig, wenn CDDB keine vollständigen Daten geliefert hat (Dateien heißen noch `track01.flac` etc.). ### Variante A: Textdatei (z.B. von Wikipedia/Perplexity kopiert) ```bash musiksammlung scan --from-text trackliste.txt -o album.json ``` ### Variante B: Coverbild per OCR + LLM ```bash musiksammlung scan back.jpg -o album.json --lang deu+eng ``` Standard-Modell: `gemma3:12b` (via Ollama). Anderes Modell: ```bash musiksammlung scan back.jpg -o album.json --model llama3.3:latest ``` ### Variante C: Vision-LLM (Bild direkt an LLM, empfohlen) Besser als OCR bei komplexen Layouts (mehrere Spalten, schwierige Schriften): ```bash musiksammlung scan back.jpg --vision -o album.json ``` Standard-Modell: `qwen3-vl:235b-cloud` (via Ollama). Anderes Modell: ```bash musiksammlung scan back.jpg --vision --vision-model qwen3-vl:7b -o album.json ``` ### Variante D: EAN/Barcode → MusicBrainz (schnellste Methode) Wenn die EAN-13- oder UPC-12-Nummer der CD bekannt ist (aufgedruckt auf der Hülle), kann das Programm die Metadaten direkt aus der [MusicBrainz](https://musicbrainz.org)-Datenbank laden — ohne Bild, ohne OCR, ohne lokales LLM: ```bash musiksammlung scan --barcode 0602557360561 -o album.json ``` Die EAN lässt sich auch mit einem Barcode-Scanner oder einer Smartphone-App ablesen. MusicBrainz liefert bei einem Treffer: Interpret, Albumtitel, Erscheinungsjahr und vollständige Trackliste. Kein API-Schlüssel erforderlich. Beim interaktiven Rip-Befehl (`musiksammlung rip`) wird die EAN als erstes abgefragt. Bei einem MusicBrainz-Treffer startet automatisch der Rip-Vorgang für alle Discs — kein Albumname, keine CDDB-Bestätigung nötig. Das `album.json` wird direkt aus den MusicBrainz-Daten gespeichert. ### Variante E: EAN per Foto (Vision-LLM liest Barcode) Wenn die EAN nicht bekannt ist, aber ein Foto der CD-Hülle vorliegt, kann ein Vision-LLM den Barcode automatisch auslesen: ```bash musiksammlung scan --from-photo cover.jpg -o album.json ``` Das Programm schickt das Bild an das Vision-LLM (Standard: `qwen3-vl:235b-cloud`), extrahiert die EAN-Ziffern und führt anschließend einen MusicBrainz-Lookup durch — identisch zu Variante D. Anderes Modell oder URL: ```bash musiksammlung scan --from-photo cover.jpg --vision-model qwen3-vl:7b --url http://localhost:11434 -o album.json ``` ### album.json prüfen und bearbeiten Das Programm prüft automatisch, ob die Anzahl der erkannten Tracks mit den gerippten Dateien übereinstimmt. Bei Abweichungen erscheint eine Fehlermeldung: ``` FEHLER: Track-Diskrepanz zwischen gerippten Dateien und album.json: [OK] Disc 1: 25 Datei(en), 25 JSON-Track(s) [!!] Disc 2: 23 Datei(en), 20 JSON-Track(s) → 3 Track(s) fehlen im JSON (Tracks 21–23 eintragen) Bitte album.json korrigieren und erneut aufrufen. ``` In diesem Fall `album.json` manuell ergänzen, dann `apply` erneut aufrufen. ```json { "artist": "Karajan", "album": "Beethoven Sinfonien", "year": 1963, "genre": "Classical", "discs": [ { "disc_number": 1, "tracks": [ {"track_number": 1, "title": "Allegro con brio"}, {"track_number": 2, "title": "Andante con moto"} ] } ] } ``` Das Feld `"genre"` ist **optional** und wird automatisch befüllt, wenn GnuDB ein DGENRE liefert. Das Feld `"artist"` auf Track-Ebene ist **optional**. Wird es gesetzt, überschreibt es den Album-Künstler für diesen Track — sinnvoll bei Samplern oder Klassik mit verschiedenen Solisten: ```json {"track_number": 3, "title": "Klavierkonzert Nr. 5", "artist": "Brendel"}` ``` --- ## 6. Schritt 3: Dateien organisieren und taggen ### In-place (Dateien bleiben im Quellverzeichnis) ```bash musiksammlung apply ~/rip/Beethoven_Sinfonien album.json ``` Oder explizit: ```bash musiksammlung apply ~/rip/Beethoven_Sinfonien album.json --in-place ``` Das Programm: - Benennt Audiodateien um (`track01.flac` → `01_-_Allegro_con_brio_-_Karajan.flac`) - Setzt ID3/FLAC-Tags (Titel, Künstler, Album, Jahr, Track-Nummer, Disc-Nummer) - Kopiert Cover-Bilder (`back.jpg`) - Erzeugt eine M3U-Playlist - **Benennt das Album-Verzeichnis automatisch um** (wenn `input_dir` ein CD-Unterverzeichnis ist, z.B. `CD1`) Ergebnis: ``` ~/rip/Beethoven_Sinfonien (2024)/ ← automatisch umbenannt CD1/ 01_-_Allegro_con_brio_-_Karajan.flac 02_-_Andante_con_moto_-_Karajan.flac ... CD2/ ... back.jpg Beethoven_Sinfonien.m3u ``` > **Hinweis zur Auto-Umbenennung:** Das Album-Verzeichnis wird automatisch umbenannt, wenn `input_dir` ein CD-Unterverzeichnis (`CD1`, `CD2` ...) ist. Wird stattdessen das Album-Wurzelverzeichnis übergeben, gibt das Programm einen `mv`-Hinweis aus, aber benennt nicht selbst um. ### In Jellyfin-Verzeichnis verschieben ```bash musiksammlung apply ~/rip/Beethoven_Sinfonien album.json ~/Musik \ --front front.jpg --back back.jpg ``` Ergebnis: ``` ~/Musik/ Karajan/ Beethoven_Sinfonien_1963/ CD1/ 01_-_Allegro_con_brio_-_Karajan.flac ... back.jpg Beethoven_Sinfonien.m3u ``` ### Optionen | Option | Beschreibung | |--------|-------------| | `--in-place` | Dateien im Quellverzeichnis umbenennen (kein output_dir nötig) | | `--front cover.jpg` | Front-Cover-Bild | | `--back back.jpg` | Rückseiten-Bild | | `--dry-run` | Nur anzeigen, nichts ändern | ### Cover-Konvention Im Album-Verzeichnis werden folgende Dateinamen erwartet: | Datei | Zweck | |-------|-------| | `frontcover.jpg` oder `frontcover.png` | Front-Cover | | `backcover.jpg` oder `backcover.png` | Rückseiten-Cover | Symbolische Links auf diese Namen sind erlaubt. `apply` kopiert die mit `--front`/`--back` angegebenen Bilder automatisch als `frontcover.jpg` bzw. `backcover.jpg` ins Album-Verzeichnis und bettet das Frontcover anschließend in alle Audio-Dateien ein (skaliert auf max. 500 px). Ist bereits ein `frontcover.*` vorhanden (z.B. bei erneutem `apply`), wird es ohne `--front`-Option verwendet. ### Dateinamen-Schema ``` _-__-_. ``` Beispiel: `01_-_Allegro_con_brio_-_Karajan.flac` - Leerzeichen → `_` - Klammern `()[]{}` und Satzzeichen `,;:!?.'"` → werden entfernt - Nur Buchstaben, Ziffern, Unterstriche und Bindestriche bleiben erhalten - Mehrere `_` hintereinander → ein `_` - Umlaute (ä, ö, ü, ß) bleiben erhalten - Künstler pro Track: falls im `album.json` ein Track-`artist` gesetzt ist, wird dieser verwendet; sonst der Album-Künstler --- ## 7. Tags und Cover prüfen Nach `apply` lässt sich der Zustand aller Dateien mit einem Befehl prüfen: ```bash musiksammlung check ~/rip/Beethoven_Sinfonien ``` Ausgabe: ``` Verzeichnis: ~/rip/Beethoven_Sinfonien frontcover: frontcover.jpg backcover: backcover.jpg CD1/ [♪] 01_-_Allegro_con_brio_-_Karajan.flac Titel: Allegro con brio Künstler: Karajan | AlbumArtist: Karajan Album: Beethoven Sinfonien | Jahr: 1963 Track: 1/4 | Disc: 1 ... ``` `[♪]` zeigt an, dass ein Cover eingebettet ist. `[ ]` bedeutet kein eingebettetes Cover. --- ## 8. Komplett-Pipeline Für einfache Fälle (alles in einem Schritt): ```bash musiksammlung process temp/Album/CD1 ~/Musik --back back.jpg ``` --- ## 9. Tipps und Hinweise **EAN/Barcode eingeben → Schnellster Weg** - Beim `rip`-Befehl erscheint direkt ein QR-Code im Terminal - **Option A (tippen):** EAN-13 oder UPC-12 von der CD-Hülle ablesen und eingeben - **Option B (fotografieren):** CD-Hülle mit dem Smartphone fotografieren → KI liest Barcode automatisch → Bestätigung/Korrektur möglich - Bei MusicBrainz-Treffer startet der Auto-Rip sofort (keine weiteren Fragen) - Cover (Front + Rückseite) werden automatisch aus dem Cover Art Archive heruntergeladen - Alternativ ohne `rip`: `musiksammlung scan --barcode 0602557360561 -o album.json` **Backcover-Foto per Smartphone hochladen** - Derselbe QR-Code / Scanner-Server wird für EAN und Backcover genutzt - Smartphone muss im gleichen WLAN sein - Firewall-Port 8765 (TCP) muss offen sein: `sudo ufw allow 8765/tcp` - Nach dem Hochladen fährt das Programm automatisch fort - Vision-LLM analysiert das Foto parallel zum Ripping — kein Warten nötig - Anderes Modell oder URL: `--vision-model qwen3-vl:7b --vision-url http://localhost:11434` **CDDB-Lookup schlägt fehl?** - Internetverbindung prüfen - `--no-cddb` verwenden und Metadaten per `scan --barcode` oder `scan` (Bild) ermitteln **Falsches oder kein CDDB-Ergebnis?** - Tracks sind trotzdem korrekt gerippt (als `track01.flac` etc.) - `musiksammlung scan --barcode EAN` verwenden (wenn EAN bekannt) - Oder `musiksammlung scan` mit Coverbild oder Textdatei aufrufen - `album.json` manuell korrigieren, dann `musiksammlung apply` ausführen **Mehrspaltige Trackliste auf dem Backcover?** - OCR erkennt mehrspaltige Layouts oft unvollständig - Vision-LLM verwenden: `--vision --vision-model qwen3-vl:235b-cloud` - Beim `rip`-Befehl: Backcover per Smartphone hochladen → Vision-LLM läuft automatisch **Mehrere CDs eines Albums (Multi-Disc)?** - Bei EAN-Treffer: MusicBrainz kennt die Disc-Anzahl, der Auto-Rip fordert automatisch jede CD an - Ohne EAN: Bei der Abfrage "Next CD for this album?" mit `y` antworten - Jede CD erhält ein eigenes Unterverzeichnis `CD1`, `CD2`, ... - `apply` einmal mit dem Album-Verzeichnis aufrufen (nicht pro CD) **Copy-paste-fähige `apply`-Befehle** - Am Ende des Rippens zeigt das Programm für jedes Album konkrete Kommandos an: ``` Next steps: Album 1: Beethoven_Sinfonien (1963) 1. Prüfen/bearbeiten: ~/rip/Beethoven_Sinfonien/album.json 2. musiksammlung apply ~/rip/Beethoven_Sinfonien/CD1 \ ~/rip/Beethoven_Sinfonien/album.json ``` **Unterstützte Audio-Formate:** | Format | Qualität high | Verwendung | |--------|--------------|------------| | `flac` | Verlustfrei | Archiv | | `mp3` | VBR -V0 | maximale Kompatibilität | | `opus` | 192 kbit/s | modern, effizient | | `aac` | Qualität 4 | Apple-Geräte | | `wav` | Verlustfrei | maximale Kompatibilität, groß |