# Workflow & Zustände - Ripster
Halbautomatische Disc-Ripping-Plattform für DVDs & Blu-rays mit HandBrake-Encoding
Author: Michael

Zum Inhalt

# Workflow & Zustände

Der Ripping-Workflow von Ripster ist als State Machine implementiert. Jeder Zustand hat klar definierte Übergangsbedingungen und Aktionen.

## Zustandsdiagramm

    flowchart LR
        START(( )) --> IDLE

        IDLE -->|Disc erkannt| DD[DISC_DETECTED]
        DD -->|Analyse starten| META[METADATA\nSELECTION]

        META -->|Metadaten übernommen| RTS[READY_TO\nSTART]
        META -->|vorhandenes RAW +\nPlaylist offen| WUD[WAITING_FOR\nUSER_DECISION]

        RTS -->|Auto-Start| RIP[RIPPING]
        RTS -->|Auto-Start mit RAW| MIC[MEDIAINFO\nCHECK]
        RIP -->|MKV fertig| MIC
        RIP -->|Fehler| ERR
        RIP -->|Abbruch| CAN([CANCELLED])

        MIC -->|Playlist offen (Backup)| WUD
        WUD -->|Playlist bestätigt| MIC
        WUD -->|Playlist bestätigt,\nnoch kein RAW| RTS
        MIC --> RTE[READY_TO\nENCODE]
        RTE -->|Encoding starten\n(bestätigt bei Bedarf automatisch)| ENC[ENCODING]

        ENC -->|inkl. Post-Skripte| FIN([FINISHED])
        ENC -->|Fehler| ERR
        ENC -->|Abbruch| CAN

        ERR([ERROR]) -->|Retry / Cancel| IDLE
        CAN -->|Retry / Neu-Analyse| IDLE
        FIN -->|Neue Disc| IDLE

        style FIN fill:#e8f5e9,stroke:#66bb6a,color:#2e7d32
        style ERR fill:#ffebee,stroke:#ef5350,color:#c62828
        style CAN fill:#fff3e0,stroke:#fb8c00,color:#e65100
        style WUD fill:#fff8e1,stroke:#ffa726,color:#e65100
        style ENC fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a
        style RIP fill:#e3f2fd,stroke:#42a5f5,color:#1565c0
        style MIC fill:#e3f2fd,stroke:#42a5f5,color:#1565c0

## UI-Badge-Bezeichnungen

Die Status-Badges im Dashboard verwenden diese Labels:

State | Badge-Label
--- | ---
`IDLE` | `Bereit`
`DISC_DETECTED` | `Medium erkannt`
`METADATA_SELECTION` | `Metadatenauswahl`
`WAITING_FOR_USER_DECISION` | `Warte auf Auswahl`
`READY_TO_START` | `Startbereit`
`RIPPING` | `Rippen`
`MEDIAINFO_CHECK` | `Mediainfo-Pruefung`
`READY_TO_ENCODE` | `Bereit zum Encodieren`
`ENCODING` | `Encodieren`
`FINISHED` | `Fertig`
`CANCELLED` | `Abgebrochen`
`ERROR` | `Fehler`
Queue (kein eigener State) | `In der Queue`

## Zustandsbeschreibungen

### IDLE

Ausgangszustand. Ripster wartet auf eine Disc.

- `diskDetectionService` pollt das Laufwerk im konfigurierten Intervall
- Bei Disc-Erkennung: automatischer Übergang zu `DISC_DETECTED`
- WebSocket-Event: `DISC_DETECTED`

### DISC_DETECTED

Disc erkannt, wartet auf Benutzeraktion.

- Dashboard-Badge: "Medium erkannt"
- Status-Text: "Neue Disk erkannt"
- "Analyse starten"-Button wird aktiv
- Kein Prozess läuft noch

Übergang: Benutzer klickt "Analyse starten" → `METADATA_SELECTION`

### METADATA_SELECTION

Metadaten-Auswahl läuft.

1. Job wird erstellt (`status = METADATA_SELECTION`)
2. OMDb-Vorsuche mit erkanntem Disc-Label
3. `MetadataSelectionDialog` öffnet sich mit vorgeladenen Ergebnissen
4. Benutzer wählt Filmtitel (oder gibt manuell ein)
5. Nach Bestätigung wird der Job automatisch für Start/Queue vorbereitet (`selectMetadata` + `startPreparedJob`)

Übergang (automatisch nach Metadaten-Bestätigung):

Ergebnis | Nächster Zustand
--- | ---
Kein verwertbares RAW vorhanden | `READY_TO_START` → automatisch `RIPPING` (oder Queue)
Verwertbares RAW vorhanden | `READY_TO_START` → automatisch `MEDIAINFO_CHECK` (oder Queue)
Vorhandenes RAW + offene Playlist-Entscheidung | `WAITING_FOR_USER_DECISION`

### WAITING_FOR_USER_DECISION

Playlist-Obfuskierung erkannt – manuelle Auswahl erforderlich.

Neu seit „Skript Integration + UI Anpassungen"

Dieser Zustand wurde eingeführt, um Blu-rays mit mehreren Playlists ähnlicher Länge korrekt zu behandeln.

- Playlist-Auswahl-Dialog wird im Dashboard angezeigt
- Alle Kandidaten mit Score, Laufzeit und Bewertungslabel
- Empfohlene Playlist ist vorausgewählt
- Benutzer bestätigt mit "Playlist übernehmen"
- Tritt häufig nach `MEDIAINFO_CHECK` auf (Backup-Analyse), seltener direkt nach `METADATA_SELECTION` bei vorhandenem RAW

Darstellung im Dashboard:

    ┌──────────────────────────────────────────────────────────┐
    │ Playlist-Auswahl erforderlich                            │
    │ Es wurden mehrere Titel mit ähnlicher Laufzeit gefunden. │
    ├──────────┬──────────┬────────┬──────────────────────────┤
    │ Playlist │ Laufzeit │ Score  │ Bewertung                 │
    ├──────────┼──────────┼────────┼──────────────────────────┤
    │ ● 00800  │ 2:28:05  │  +18   │ wahrscheinlich korrekt    │
    │ ○ 00801  │ 2:28:12  │   −4   │ Auffällige Segmentfolge   │
    │ ○ 00900  │ 2:28:05  │  −32   │ Fake-Struktur             │
    └──────────┴──────────┴────────┴──────────────────────────┘
                                  [Playlist übernehmen]

Übergang: `selectMetadata(jobId, { selectedPlaylist })` setzt die Pipeline automatisch fort:

- mit vorhandenem RAW nach `MEDIAINFO_CHECK`
- ohne RAW über `READY_TO_START` weiter Richtung `RIPPING`

Mehr Details: Playlist-Analyse

### READY_TO_START

Übergangs-/Fallback-Zustand vor dem eigentlichen Start.

- Wird nach Metadaten-Bestätigung kurz gesetzt
- `startPreparedJob()` wird danach automatisch ausgeführt
- Wenn Parallel-Limit erreicht ist, wird der Start stattdessen in die Queue eingereiht
- "Job starten" ist primär für Sonderfälle/Fallback sichtbar

Sonderfall – RAW-Datei bereits vorhanden: Wenn für diesen Job bereits ein verwertbares RAW unter `raw_dir` existiert, wird Ripping übersprungen und direkt `MEDIAINFO_CHECK` gestartet.

Übergang: `startPreparedJob(jobId)` → `RIPPING` oder direkt `MEDIAINFO_CHECK`

### RIPPING

MakeMKV rippt die Disc.

MKV-Modus (Standard)Backup-Modus

    makemkvcon mkv disc:0 all /path/to/raw/ --minlength=900 -r

Erstellt MKV-Datei(en) direkt aus den gewählten Titeln.

    makemkvcon backup disc:0 /path/to/raw/backup/ --decrypt -r

Erstellt vollständiges Disc-Backup inkl. Menüs.

Live-Updates aus MakeMKV-Ausgabe:

    PRGV:2048,0,65536  → Fortschritt-Berechnung
    PRGT:5011,0,"..."  → Aktueller Task-Name

Typische Dauer: DVD 20–45 min · Blu-ray 45–120 min

### MEDIAINFO_CHECK

HandBrake-Scan und Encode-Plan-Erstellung.

Dieser Zustand umfasst je nach Quelle mehrere Phasen:

1. Optional: Playlist-Auflösung bei Blu-ray-Backup (inkl. MakeMKV/HandBrake-Zuordnung)
2. HandBrake-Scan (`HandBrakeCLI --scan`) auf RAW-Input
3. Encode-Plan-Erstellung mit automatischer Track-Vorauswahl

Kein Benutzereingriff – läuft automatisch durch.

Übergänge:

- Eindeutige Quelle/Titelwahl möglich → `READY_TO_ENCODE`
- Mehrdeutige Playlist erkannt → `WAITING_FOR_USER_DECISION`

### READY_TO_ENCODE

Encode-Plan bereit.

Das `MediaInfoReviewPanel` zeigt:

- Titel-Auswahl (bei Discs mit mehreren langen Titeln)
- Audio-Tracks mit Encoder-Vorschau (Copy/Transcode/Fallback)
- Untertitel-Tracks mit Flags (Einbrennen, Forced, Default)
- Post-Encode-Skripte – Auswahl und Reihenfolge der auszuführenden Skripte

Im Frontend startet "Encoding starten" (bzw. "Backup + Encoding starten" im Pre-Rip-Modus) den nächsten Schritt. Falls die Review noch nicht bestätigt wurde, wird `confirmEncodeReview(...)` automatisch vor dem Start aufgerufen.

Übergang: `startPreparedJob(jobId)` → `ENCODING` (oder im Pre-Rip-Fall zuerst `RIPPING`)

### ENCODING

HandBrake encodiert die Datei.

    HandBrakeCLI \
      -i <quelle> -o <ziel> \
      -t <titelId> \
      --preset "H.265 MKV 1080p30" \
      -a 1,2 -E copy:ac3,av_aac \
      -s 1 --subtitle-default 1

Live-Updates aus HandBrake-stderr:

    Encoding: task 1 of 1, 73.50 % (45.23 fps, avg 44.12 fps, ETA 00h12m34s)

Post-Encode-Skripte werden innerhalb dieses Zustands sequenziell ausgeführt (kein separater Pipeline-State).

Skriptfehler

Skriptfehler führen zum Abbruch der Skriptkette, der Job bleibt jedoch im Abschlusszustand `FINISHED` mit entsprechendem Hinweis im Status-Text/Log.

### FINISHED

Job erfolgreich abgeschlossen.

- Ausgabedatei liegt im konfigurierten `movie_dir`
- Job-Status in Datenbank: `FINISHED`
- PushOver-Benachrichtigung (falls konfiguriert)
- WebSocket-Event: `PIPELINE_STATE_CHANGED` (State `FINISHED`)

### CANCELLED

Job wurde vom Benutzer abgebrochen.

- Entsteht bei aktivem Abbruch (`/api/pipeline/cancel`) während laufender Phase
- Job-Status in Datenbank: `CANCELLED`
- Im Dashboard stehen danach u. a. `Retry Rippen`, `Review neu starten` oder `Encode neu starten` (kontextabhängig) zur Verfügung

### ERROR

Fehler aufgetreten.

- Fehlerdetails im Job-Datensatz gespeichert
- Fehler-Logs in History abrufbar
- Retry: Neustart vom Fehlerzustand
- Neu analysieren: Disc erneut als neuer Job starten

## Abbrechen & Retry

### Pipeline abbrechen

    POST /api/pipeline/cancel

- SIGINT → graceful exit (Timeout: 10 s) → SIGKILL
- Laufender Job landet in `CANCELLED` (oder Queue-Eintrag wird entfernt, falls noch nicht gestartet)

### Job wiederholen

    POST /api/pipeline/retry/:jobId

- Startet den Job neu in `RIPPING` (oder reiht den Retry in die Queue ein)
- Metadaten bleiben erhalten; Encode-/Scan-Daten werden neu erzeugt

### Re-Encode

    POST /api/pipeline/reencode/:jobId

- Encodiert bestehende Raw-MKV neu
- Ermöglicht neue Track-Auswahl und andere Skripte
- Kein Ripping erforderlich