Add phone-based EAN scanning, scanner server for cover upload, Vision-LLM integration

New features:
- EAN/Barcode can now be entered by typing or by photographing the CD sleeve;
  Vision-LLM (extract_barcode_from_image) reads the barcode from the photo
- Scanner server (port 8765) starts at the beginning of every album loop,
  serving both EAN barcode scanning and back cover upload via QR code
- Vision-LLM analyses back cover in background thread while ripping;
  priority: Vision-LLM > MusicBrainz > CDDB
- _find_abcde_mbid reads MBID from abcde temp dirs for CAA cover download
  even when the CD barcode is not linked in MusicBrainz
- Concrete copy-paste apply commands shown after each album in 'Next steps'
- _sanitize_name: whitelist approach (removes brackets and punctuation)
- qrcode added as dependency for terminal QR code display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-02-19 14:05:59 +01:00
commit 32c84b9edb
15 changed files with 1027 additions and 92 deletions

View file

@ -26,6 +26,7 @@
| `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):
@ -33,6 +34,12 @@ Installation der externen Tools (Debian/Ubuntu):
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
@ -57,27 +64,41 @@ musiksammlung --help
musiksammlung rip
EAN/Barcode eingeben (Enter = überspringen)
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
│ Für jede Disc: "CD 1/3 einlegen, Enter" → Rip → Rename
│ album.json automatisch aus MusicBrainz-Daten
│ 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
Albumname eingeben → CD-Nummer → Rip → CDDB-Confirm
album.json aus CDDB-Daten (falls bestätigt)
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)
├─ album.json vorhanden?
│ ja → direkt weiter mit musiksammlung apply
└─ nein → 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
→ album.json prüfen/korrigieren
└─ 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
→ album.json prüfen/korrigieren
musiksammlung apply ← Umbenennen, Tags, Cover, Playlist
@ -112,6 +133,9 @@ Das Programm fragt zuerst nach dem EAN/Barcode. Bei einem MusicBrainz-Treffer st
| `-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
@ -129,6 +153,9 @@ 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
@ -143,21 +170,34 @@ EAN/Barcode (Enter = überspringen): 028943753227
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 <jellyfin-verzeichnis>
Next album? (y/n): n
```
**Ohne EAN (Fallback):**
**Ohne EAN (Fallback mit Backcover-Foto):**
```
--- Album 1 ---
EAN/Barcode (Enter = überspringen):
Album name (Enter = CDDB name / default 'Album1'): Beethoven Sinfonien
Album: Beethoven Sinfonien
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/Beethoven_Sinfonien/CD1
Ripping to: temp/Album1/CD1
--------------------------------------------------
Track 1/4 Allegro con brio
[████████████████░░░░░░░░░░░░░░] 54.3% 18.2 MB
@ -169,14 +209,64 @@ Album name (Enter = CDDB name / default 'Album1'): Beethoven Sinfonien
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 <jellyfin-verzeichnis>
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 Daten liefert:**
**Wenn CDDB/Vision-LLM Daten liefert:**
```
~/rip/
Beethoven_Sinfonien/
@ -184,11 +274,13 @@ Next album? (y/n): n
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
```
Direkt weiter mit `musiksammlung apply ~/rip/Beethoven_Sinfonien album.json`
Am Ende zeigt das Programm den fertigen `apply`-Befehl an (copy-paste-fähig).
**Wenn kein CDDB-Treffer:**
**Wenn kein CDDB-Treffer und kein Foto:**
```
~/rip/
Beethoven_Sinfonien/
@ -377,7 +469,9 @@ Ist bereits ein `frontcover.*` vorhanden (z.B. bei erneutem `apply`), wird es oh
Beispiel: `01_-_Allegro_con_brio_-_Karajan.flac`
- Leerzeichen und Satzzeichen → `_`
- 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
@ -424,11 +518,21 @@ musiksammlung process temp/Album/CD1 ~/Musik --back back.jpg
## 9. Tipps und Hinweise
**EAN/Barcode verfügbar? → Schnellster Weg**
- EAN-13 oder UPC-12 von der CD-Hülle ablesen (ggf. Barcode-Scanner-App nutzen)
- Beim `rip`-Befehl wird die EAN als erstes abgefragt — bei MusicBrainz-Treffer startet der Auto-Rip sofort (keine weiteren Fragen)
- Alternativ: `musiksammlung scan --barcode 0602557360561 -o album.json`
- Kein Bild, kein OCR, kein lokales LLM notwendig
**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
@ -443,6 +547,7 @@ musiksammlung process temp/Album/CD1 ~/Musik --back back.jpg
**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
@ -450,6 +555,16 @@ musiksammlung process temp/Album/CD1 ~/Musik --back back.jpg
- 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 <jellyfin-verzeichnis>
```
**Unterstützte Audio-Formate:**
| Format | Qualität high | Verwendung |