docs: add parallel metadata/ripping workflow plan (Phase A/B/C)
Describes the restructured workflow where metadata gathering (TOC, CDDB, MB, Vision-LLM) happens before ripping starts, so the user can review and edit album.json before committing to the long rip — not after. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c791812755
commit
6a7602387a
1 changed files with 131 additions and 0 deletions
|
|
@ -204,3 +204,134 @@ Testvorgaben:
|
|||
- Track-Matching bei unterschiedlicher Track-Anzahl
|
||||
- disc_id korrekt pro Disc zugeordnet
|
||||
- Fehlende Quellen (None) robust behandelt
|
||||
|
||||
---
|
||||
|
||||
## Parallelisierung: Informationsbeschaffung vor dem Rippen
|
||||
|
||||
### Kernidee
|
||||
|
||||
Die CD muss für zwei Operationen physisch im Laufwerk liegen, aber diese
|
||||
brauchen sich nicht zu überlappen:
|
||||
|
||||
```
|
||||
Operation A: TOC lesen (cd-discid) ~2 Sekunden
|
||||
Operation B: Audio rippen (cdparanoia) 20–60 Minuten pro Disc
|
||||
```
|
||||
|
||||
Heute sind beide in einem monolithischen Durchlauf verschmolzen. Das
|
||||
Umordnen kostet nichts — die CD darf ruhig zweimal im Laufwerk liegen.
|
||||
|
||||
### Neuer Ablauf (Drei Phasen A / B / C)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Phase A: Informationsbeschaffung (~30s – 5 min) │
|
||||
│ │
|
||||
│ 1. CD einlegen (einmalig oder pro Disc bei Multi-Disc) │
|
||||
│ 2. cd-discid → TOC: disc_id, Offsets, Laufzeiten │
|
||||
│ 3. CDDB-Lookup → artist, album, year, genre, tracks │
|
||||
│ 4. EAN-Scan → MusicBrainz → Album + MBID │
|
||||
│ 5. CAA-Download → front.jpg, back.jpg │
|
||||
│ 6. back.jpg → Vision-LLM (läuft parallel, ~1–3 min) │
|
||||
│ 7. merge_album() → album.json (preliminary) │
|
||||
│ 8. "album.json bereit — bitte prüfen." │
|
||||
│ 9. User editiert album.json (optional, zweites │
|
||||
│ Terminal oder nach Prompt) │
|
||||
│ 10. "Rippen starten? [Enter]" │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Phase B: Audio-Ripping (~20–60 min pro Disc) │
|
||||
│ │
|
||||
│ abcde läuft im Vordergrund (Terminal zeigt Progress) │
|
||||
│ Während des Rippens im zweiten Terminal: │
|
||||
│ - album.json editieren (jederzeit möglich) │
|
||||
│ - Vision-LLM-Ergebnis (falls noch ausstehend) │
|
||||
│ wird nach Abschluss nachgemergt │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Phase C: Apply (~30s) │
|
||||
│ │
|
||||
│ Liest finales album.json (evtl. editiert während B) │
|
||||
│ organize → tag → embed → playlist │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Was der Hauptgewinn ist
|
||||
|
||||
```
|
||||
Heute: Metadaten ── Rippen (60 min) ── album.json sehen ── editieren
|
||||
Neu: Metadaten ── album.json sehen ── [editieren] ── Rippen (60 min)
|
||||
└── Vision-LLM läuft parallel zum Rippen
|
||||
```
|
||||
|
||||
Der User sieht die Metadaten **vor** dem langen Warten. Editing erfolgt
|
||||
mit vollständiger Information, nicht blind im Nachhinein.
|
||||
|
||||
### Warum kein Hintergrund-Ripping
|
||||
|
||||
Hintergrund-Ripping (subprocess mit PID-Datei) ist technisch machbar,
|
||||
erhöht aber die Komplexität (PID-Management, Fehlerbehandlung, Status-
|
||||
Tracking) ohne entscheidenden Mehrwert: Der User kann während des
|
||||
Vordergrund-Rippings jederzeit ein zweites Terminal öffnen und album.json
|
||||
dort editieren. `$EDITOR album.json` reicht.
|
||||
|
||||
### Abcde: keine Änderung nötig
|
||||
|
||||
abcde hat Aktions-Flags (`-a cddb,read,encode,tag`), die eine Trennung
|
||||
erlauben würden. Da wir CDDB und TOC aber bereits **vor** abcde über
|
||||
eigene Module abfragen (`lookup_by_discid`, `cd-discid`), kann abcde
|
||||
unverändert für Phase B genutzt werden — nur mit dem Wissen, dass seine
|
||||
CDDB-Ausgabe bereits in album.json konsolidiert ist.
|
||||
|
||||
### Multi-Disc-Verhalten
|
||||
|
||||
```
|
||||
Disc 1: Phase A (~2 min) → "Rippen starten?" → Phase B Disc 1 (~45 min)
|
||||
Disc 2: Phase A (~2 min) → "Rippen starten?" → Phase B Disc 2 (~45 min)
|
||||
...
|
||||
```
|
||||
|
||||
Jede Disc wird sequenziell behandelt (ein Laufwerk). Phase A aller Discs
|
||||
könnte theoretisch vorab gebündelt werden (alle Discs kurz einlegen, TOC
|
||||
lesen), ist aber als optionale Optimierung einzustufen.
|
||||
|
||||
### Änderungsbedarf in ripper.py
|
||||
|
||||
Die heutige `interactive_rip`-Funktion wird aufgeteilt in:
|
||||
|
||||
```python
|
||||
def gather_metadata(disc_num, config, scanner) -> DiscMetadata:
|
||||
"""Phase A: TOC, CDDB, MB, Vision-LLM — kein Rippen."""
|
||||
...
|
||||
|
||||
def rip_disc(disc_num, config) -> Path:
|
||||
"""Phase B: abcde — kein Netzwerk, kein LLM."""
|
||||
...
|
||||
|
||||
def interactive_rip(config):
|
||||
"""Orchestriert: für jede Disc gather_metadata → confirm → rip_disc."""
|
||||
...
|
||||
```
|
||||
|
||||
`DiscMetadata` ist ein internes Dataclass/NamedTuple das alle Rohdaten
|
||||
einer Disc bis zum Merge trägt:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class DiscMetadata:
|
||||
disc_number: int
|
||||
discid_line: str # Rohstring aus cd-discid
|
||||
cddb_result: CddbResult | None
|
||||
mb_album: Album | None # nur bei erster Disc sinnvoll
|
||||
mb_mbid: str | None
|
||||
vision_album: Album | None # Ergebnis des Background-Threads
|
||||
uploaded_photo: Path | None
|
||||
```
|
||||
|
||||
Nach dem letzten `rip_disc`-Aufruf ruft `interactive_rip` einmalig
|
||||
`merge_album()` auf und schreibt album.json.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue