{"config":{"lang":["de"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Ripster Handbuch","text":"
Dieses Dokumentationsset ist als Benutzerhandbuch aufgebaut: erst Bedienung und Alltag, dann Technik im Anhang.
"},{"location":"#schnellstart-in-3-schritten","title":"Schnellstart in 3 Schritten","text":"Jobs, Ripper, Converter, Audiobooks, Settings, Historie, Downloads, Database)REST- und WebSocket-Schnittstellen f\u00fcr Integration, Automatisierung und Debugging.
"},{"location":"api/#basis-url","title":"Basis-URL","text":"http://localhost:3001\n API-Prefix: /api
Health
Service-Liveness.
GET /api/health
Pipeline API
Analyse, Start/Retry/Cancel, Queue, Re-Encode.
Pipeline API
Settings API
Einstellungen, Skripte/Ketten, User-Presets.
Settings API
History API
Job-Historie, Orphan-Import, L\u00f6schoperationen.
History API
Cron API
Zeitgesteuerte Skript-/Kettenausf\u00fchrung.
Cron API
Converter API
Datei-Explorer, Upload, Job-Verwaltung f\u00fcr den Converter.
Converter API
Downloads API
Download-Queue f\u00fcr Ausgabedateien aus der Job-Historie.
Downloads API
Runtime Activities API
Laufende und abgeschlossene Aktivit\u00e4ten (Skripte, Ketten, Cron, Tasks).
Runtime Activities
:material-websocket: WebSocket Events
Pipeline-, Queue-, Disk-, Settings-, Cron-, Converter- und Download-Events.
WebSocket
Ripster hat keine eingebaute Authentifizierung und ist f\u00fcr lokalen, gesch\u00fctzten Betrieb gedacht.
"},{"location":"api/converter/","title":"Converter API","text":"Endpunkte f\u00fcr den Datei-Converter: Datei-Explorer, Upload, Job-Verwaltung.
Basis-Pfad: /api/converter
GET /api/converter/tree","text":"Vollst\u00e4ndiger Verzeichnisbaum des converter_raw_dir (FS-basiert, keine DB).
Response:
{\n \"tree\": [\n {\n \"name\": \"filme\",\n \"relPath\": \"filme\",\n \"isDir\": true,\n \"children\": [\n {\n \"name\": \"film.mkv\",\n \"relPath\": \"filme/film.mkv\",\n \"isDir\": false,\n \"size\": 10485760\n }\n ]\n }\n ]\n}\n"},{"location":"api/converter/#get-apiconverterbrowseparentrelpath","title":"GET /api/converter/browse?parent=relPath","text":"DB-basierter Datei-Explorer. Gibt Eintr\u00e4ge f\u00fcr einen Unterordner zur\u00fcck.
Query-Parameter:
Parameter Typ Beschreibungparent string Relativer Pfad zum Unterordner (leer = Root) Response:
{\n \"entries\": [\n {\n \"id\": 1,\n \"rel_path\": \"filme/film.mkv\",\n \"is_dir\": false,\n \"size\": 10485760,\n \"job_id\": null\n }\n ],\n \"rawDir\": \"/data/output/converter-raw\"\n}\n"},{"location":"api/converter/#post-apiconverterscan","title":"POST /api/converter/scan","text":"Manuellen Scan des converter_raw_dir ausl\u00f6sen. Aktualisiert converter_scan_entries in der DB.
Response:
{ \"result\": { \"added\": 3, \"removed\": 1 } }\n"},{"location":"api/converter/#jobs-erstellen","title":"Jobs erstellen","text":""},{"location":"api/converter/#post-apiconverterjobsfrom-selection","title":"POST /api/converter/jobs/from-selection","text":"Jobs aus im Datei-Explorer ausgew\u00e4hlten Dateien erstellen.
Body:
{\n \"relPaths\": [\"filme/film.mkv\", \"musik/track.flac\"],\n \"audioMode\": \"individual\"\n}\n Feld Typ Beschreibung relPaths string[] Relative Pfade der ausgew\u00e4hlten Dateien audioMode string individual (ein Job pro Datei) oder shared (ein gemeinsamer Job) Response:
{ \"jobs\": [{ \"id\": 42, \"status\": \"READY_TO_START\" }] }\n"},{"location":"api/converter/#post-apiconvertercreate-jobs","title":"POST /api/converter/create-jobs","text":"Jobs aus DB-Scan-Eintr\u00e4gen erstellen.
Body:
{\n \"entries\": [\n { \"relPath\": \"filme/film.mkv\", \"converterMediaType\": \"video\" }\n ]\n}\n"},{"location":"api/converter/#post-apiconverterupload","title":"POST /api/converter/upload","text":"Dateien hochladen (Multipart, max. 50 Dateien).
Form-Felder:
Feld Typ Beschreibungfiles File[] Hochzuladende Dateien folderName string (Optional) Ziel-Unterordner Response:
{\n \"folders\": [{ \"folderRelPath\": \"upload-2026-03-30\", \"fileCount\": 2 }]\n}\n"},{"location":"api/converter/#job-verwaltung","title":"Job-Verwaltung","text":""},{"location":"api/converter/#get-apiconverterjobs","title":"GET /api/converter/jobs","text":"Alle Converter-Jobs zur\u00fcckgeben.
Response:
{ \"jobs\": [{ \"id\": 42, \"status\": \"READY_TO_START\", \"title\": \"film.mkv\" }] }\n"},{"location":"api/converter/#get-apiconverterjobsjobid","title":"GET /api/converter/jobs/:jobId","text":"Einzelnen Converter-Job abrufen.
"},{"location":"api/converter/#post-apiconverterjobsjobidconfig","title":"POST /api/converter/jobs/:jobId/config","text":"Konfigurationsentwurf f\u00fcr einen Job speichern (persistiert in encode_plan_json).
Body: Partielles Konfig-Objekt (Ausgabeformat, Presets, Metadaten, Track-Auswahl).
"},{"location":"api/converter/#post-apiconverterjobsjobidassign-files","title":"POST /api/converter/jobs/:jobId/assign-files","text":"Dateien einem bestehenden (noch nicht gestarteten) Job hinzuf\u00fcgen.
Body:
{ \"relPaths\": [\"musik/track2.flac\"] }\n"},{"location":"api/converter/#post-apiconverterjobsjobidremove-file","title":"POST /api/converter/jobs/:jobId/remove-file","text":"Datei aus einem Job entfernen (per relativer Pfad).
Body:
{ \"relPath\": \"musik/track2.flac\" }\n"},{"location":"api/converter/#post-apiconverterjobsjobidremove-input","title":"POST /api/converter/jobs/:jobId/remove-input","text":"Datei aus einem Job entfernen (per absolutem Eingabepfad).
Body:
{ \"inputPath\": \"/data/output/converter-raw/musik/track2.flac\" }\n"},{"location":"api/converter/#post-apiconverterjobsjobidstart","title":"POST /api/converter/jobs/:jobId/start","text":"Job mit finaler Konfiguration starten.
Body:
{\n \"converterMediaType\": \"video\",\n \"outputFormat\": \"mkv\",\n \"userPreset\": \"H.264 MKV 1080p30\",\n \"trackSelection\": {},\n \"handBrakeTitleId\": 1,\n \"audioFormatOptions\": {}\n}\n"},{"location":"api/converter/#post-apiconverterjobsjobidcancel","title":"POST /api/converter/jobs/:jobId/cancel","text":"Laufenden Job abbrechen.
"},{"location":"api/converter/#delete-apiconverterjobsjobid","title":"DELETE /api/converter/jobs/:jobId","text":"Job aus der DB l\u00f6schen.
"},{"location":"api/converter/#datei-operationen","title":"Datei-Operationen","text":"Alle Datei-Operationen arbeiten direkt auf dem Dateisystem (ohne DB-Aktualisierung). Ein anschlie\u00dfender Scan-Aufruf synchronisiert die DB.
"},{"location":"api/converter/#delete-apiconverterfiles","title":"DELETE /api/converter/files","text":"Datei oder Ordner l\u00f6schen.
Body:
{ \"relPath\": \"filme/film.mkv\" }\n"},{"location":"api/converter/#post-apiconverterfilesrename","title":"POST /api/converter/files/rename","text":"Datei oder Ordner umbenennen.
Body:
{ \"relPath\": \"filme/film.mkv\", \"newName\": \"film-neu.mkv\" }\n"},{"location":"api/converter/#post-apiconverterfilesmove","title":"POST /api/converter/files/move","text":"Datei oder Ordner verschieben.
Body:
{ \"relPath\": \"filme/film.mkv\", \"targetParentRelPath\": \"archiv\" }\n targetParentRelPath = \"\" verschiebt in das Root-Verzeichnis.
POST /api/converter/files/folder","text":"Neuen Ordner anlegen.
Body:
{ \"parentRelPath\": \"filme\", \"name\": \"neu\" }\n"},{"location":"api/crons/","title":"Cron API","text":"Ripster enth\u00e4lt ein eingebautes Cron-System f\u00fcr Skripte und Skript-Ketten (sourceType: script|chain).
Listet alle Cron-Jobs.
{\n \"jobs\": [\n {\n \"id\": 1,\n \"name\": \"Nachtlauf Backup\",\n \"cronExpression\": \"0 2 * * *\",\n \"sourceType\": \"script\",\n \"sourceId\": 3,\n \"sourceName\": \"Backup-Skript\",\n \"enabled\": true,\n \"pushoverEnabled\": true,\n \"lastRunAt\": \"2026-03-10T02:00:00.000Z\",\n \"lastRunStatus\": \"success\",\n \"nextRunAt\": \"2026-03-11T02:00:00.000Z\",\n \"createdAt\": \"2026-03-01T10:00:00.000Z\",\n \"updatedAt\": \"2026-03-10T02:00:05.000Z\"\n }\n ]\n}\n"},{"location":"api/crons/#post-apicrons","title":"POST /api/crons","text":"Erstellt Cron-Job.
{\n \"name\": \"Nachtlauf Backup\",\n \"cronExpression\": \"0 2 * * *\",\n \"sourceType\": \"script\",\n \"sourceId\": 3,\n \"enabled\": true,\n \"pushoverEnabled\": true\n}\n Response: 201 mit { \"job\": { ... } }
Response:
{ \"job\": { \"id\": 1, \"name\": \"...\" } }\n"},{"location":"api/crons/#put-apicronsid","title":"PUT /api/crons/:id","text":"Aktualisiert Cron-Job. Felder wie bei POST.
Response:
{ \"job\": { ... } }\n"},{"location":"api/crons/#delete-apicronsid","title":"DELETE /api/crons/:id","text":"Response:
{ \"removed\": { \"id\": 1, \"name\": \"Nachtlauf Backup\" } }\n"},{"location":"api/crons/#get-apicronsidlogs","title":"GET /api/crons/:id/logs","text":"Liefert Ausf\u00fchrungs-Logs.
Query-Parameter:
Parameter Typ Default Beschreibunglimit number 20 Anzahl Eintr\u00e4ge, max. 100 Response:
{\n \"logs\": [\n {\n \"id\": 42,\n \"cronJobId\": 1,\n \"startedAt\": \"2026-03-10T02:00:01.000Z\",\n \"finishedAt\": \"2026-03-10T02:00:05.000Z\",\n \"status\": \"success\",\n \"output\": \"Backup abgeschlossen.\",\n \"errorMessage\": null\n }\n ]\n}\n status: running | success | error
Triggert Job manuell (asynchron).
Response:
{ \"triggered\": true, \"cronJobId\": 1 }\n Wenn Job bereits l\u00e4uft: 409.
Validiert 5-Felder-Cron-Ausdruck und berechnet n\u00e4chsten Lauf.
Request:
{ \"cronExpression\": \"*/15 * * * *\" }\n G\u00fcltige Response:
{\n \"valid\": true,\n \"nextRunAt\": \"2026-03-10T14:15:00.000Z\"\n}\n Ung\u00fcltige Response:
{\n \"valid\": false,\n \"error\": \"Cron-Ausdruck muss genau 5 Felder haben (Minute Stunde Tag Monat Wochentag).\",\n \"nextRunAt\": null\n}\n"},{"location":"api/crons/#cron-format","title":"Cron-Format","text":"Ripster unterst\u00fctzt 5 Felder:
Minute Stunde Tag Monat Wochentag\n Beispiele:
0 2 * * * t\u00e4glich 02:00*/15 * * * * alle 15 Minuten0 6 * * 1-5 Mo-Fr 06:00CRON_JOBS_UPDATED bei Create/Update/DeleteCRON_JOB_UPDATED bei Laufzeitstatus (running -> success|error)Endpunkte f\u00fcr die Download-Queue. Ausgabedateien aus der Job-Historie k\u00f6nnen als ZIP heruntergeladen werden.
Basis-Pfad: /api/downloads
GET /api/downloads","text":"Liste aller Download-Eintr\u00e4ge plus Zusammenfassung.
Response:
{\n \"items\": [\n {\n \"id\": \"dl-42-raw\",\n \"jobId\": 42,\n \"target\": \"raw\",\n \"status\": \"ready\",\n \"archiveName\": \"Job_42_raw.zip\",\n \"outputPath\": null,\n \"createdAt\": \"2026-03-30T10:00:00.000Z\",\n \"updatedAt\": \"2026-03-30T10:01:00.000Z\",\n \"errorMessage\": null\n }\n ],\n \"summary\": {\n \"total\": 3,\n \"pending\": 1,\n \"processing\": 0,\n \"ready\": 1,\n \"failed\": 1\n }\n}\n Status-Werte:
Status Beschreibungpending In der Queue, noch nicht gestartet processing ZIP wird gerade erstellt ready ZIP fertig, Download verf\u00fcgbar failed Fehler bei der Erstellung"},{"location":"api/downloads/#get-apidownloadssummary","title":"GET /api/downloads/summary","text":"Nur die Zusammenfassung der Download-Queue (ohne Item-Liste).
Response:
{\n \"summary\": {\n \"total\": 3,\n \"pending\": 1,\n \"processing\": 0,\n \"ready\": 1,\n \"failed\": 1\n }\n}\n"},{"location":"api/downloads/#post-apidownloadshistoryjobid","title":"POST /api/downloads/history/:jobId","text":"Job-Ausgabe in die Download-Queue einreihen.
Parameter:
Parameter Typ BeschreibungjobId number ID des Jobs in der Historie Body:
{\n \"target\": \"raw\",\n \"outputPath\": null\n}\n Feld Typ Default Beschreibung target string raw raw (RAW-Dateien) oder movie (Ausgabedateien) outputPath string null Optionaler expliziter Ausgabepfad Response (201 Created):
{\n \"created\": true,\n \"id\": \"dl-42-raw\",\n \"status\": \"pending\",\n \"summary\": { \"total\": 1, \"pending\": 1, \"processing\": 0, \"ready\": 0, \"failed\": 0 }\n}\n Ist der Eintrag bereits vorhanden, wird 201 durch 200 ersetzt und created: false zur\u00fcckgegeben.
GET /api/downloads/:id/file","text":"Fertige ZIP-Datei herunterladen.
Parameter:
Parameter Typ Beschreibungid string Download-ID (z. B. dl-42-raw) Response: Datei-Download (Content-Disposition: attachment).
Schl\u00e4gt fehl mit 404, wenn kein Download-Eintrag mit dieser ID existiert oder die Datei noch nicht bereit ist.
DELETE /api/downloads/:id","text":"Download-Eintrag l\u00f6schen (auch fertige ZIP-Dateien werden vom Dateisystem entfernt).
Response:
{\n \"ok\": true,\n \"summary\": { \"total\": 2, \"pending\": 0, \"processing\": 0, \"ready\": 2, \"failed\": 0 }\n}\n"},{"location":"api/downloads/#websocket","title":"WebSocket","text":"Status\u00e4nderungen werden \u00fcber DOWNLOADS_UPDATED in Echtzeit gemeldet. Vollst\u00e4ndige Dokumentation: WebSocket Events.
Endpunkte f\u00fcr Job-Historie, Metadaten-Nachpflege, Orphan-Import und L\u00f6schoperationen.
"},{"location":"api/history/#get-apihistory","title":"GET /api/history","text":"Liefert Jobs mit optionalen Filtern.
Query-Parameter:
Parameter Typ Beschreibungstatus string Einzelstatus-Filter (legacy-kompatibel). statuses string Mehrfachstatus als CSV, z. B. FINISHED,ERROR. search string Suche in Titel-/IMDb-Feldern. limit number Maximale Anzahl Ergebnisse. lite bool Ohne Dateisystem-Checks (schneller). includeChildren bool Child-Jobs (z. B. Serien-/Multipart-Kinder) explizit einbeziehen. Beispiel:
GET /api/history?statuses=FINISHED,ERROR&search=Inception&limit=50&lite=1\n Response (Beispiel):
{\n \"jobs\": [\n {\n \"id\": 42,\n \"status\": \"FINISHED\",\n \"title\": \"Inception\",\n \"job_kind\": \"bluray\",\n \"raw_path\": \"/mnt/raw/Inception - RAW - job-42\",\n \"output_path\": \"/mnt/movies/Inception (2010)/Inception (2010).mkv\",\n \"mediaType\": \"bluray\",\n \"ripSuccessful\": true,\n \"encodeSuccess\": true,\n \"created_at\": \"2026-03-10T08:00:00.000Z\",\n \"updated_at\": \"2026-03-10T10:00:00.000Z\"\n }\n ]\n}\n"},{"location":"api/history/#get-apihistoryid","title":"GET /api/history/:id","text":"Liefert Job-Detail.
Query-Parameter:
Parameter Typ Standard BeschreibungincludeLogs bool false Prozesslog laden. includeLiveLog bool false Live-/Tail-Log laden. includeAllLogs bool false vollst\u00e4ndiges Log statt Tail. logTailLines number 800 Tail-L\u00e4nge falls nicht includeAllLogs. lite bool false Detailantwort ohne FS-Checks. Response (Beispiel):
{\n \"job\": {\n \"id\": 42,\n \"status\": \"FINISHED\",\n \"makemkvInfo\": {},\n \"mediainfoInfo\": {},\n \"handbrakeInfo\": {},\n \"encodePlan\": {},\n \"log\": \"...\",\n \"log_count\": 1,\n \"logMeta\": {\n \"loaded\": true,\n \"total\": 800,\n \"returned\": 800,\n \"truncated\": true\n }\n }\n}\n"},{"location":"api/history/#get-apihistoryorphan-raw","title":"GET /api/history/orphan-raw","text":"Sucht RAW-Ordner ohne zugeh\u00f6rigen Job.
"},{"location":"api/history/#post-apihistoryorphan-rawimport","title":"POST /api/history/orphan-raw/import","text":"Importiert einen RAW-Ordner als Job und triggert optional die Analyse des Imports.
Request:
{ \"rawPath\": \"/mnt/raw/Inception (2010) [tt1375666] - RAW - job-99\" }\n Response (Beispiel):
{\n \"job\": { \"id\": 77, \"status\": \"FINISHED\" },\n \"activation\": { \"started\": true },\n \"activationError\": null\n}\n"},{"location":"api/history/#post-apihistoryidomdbassign","title":"POST /api/history/:id/omdb/assign","text":"Weist OMDb-/Filmdaten nachtr\u00e4glich zu.
"},{"location":"api/history/#post-apihistoryidcdassign","title":"POST /api/history/:id/cd/assign","text":"Weist CD-Metadaten (z. B. MusicBrainz) nachtr\u00e4glich zu.
"},{"location":"api/history/#post-apihistoryiderrorack","title":"POST /api/history/:id/error/ack","text":"Quittiert einen Fehlerzustand im Historieneintrag.
"},{"location":"api/history/#get-apihistoryiddelete-preview","title":"GET /api/history/:id/delete-preview","text":"Liefert eine Vorschau der l\u00f6schbaren Pfade (inkl. Scope auf verkn\u00fcpfte Jobs).
Query-Parameter:
Parameter Typ Standard BeschreibungincludeRelated bool true Verkn\u00fcpfte Jobs in die Vorschau einbeziehen. Response (Beispiel):
{\n \"preview\": {\n \"jobId\": 42,\n \"relatedJobs\": [{ \"id\": 42 }, { \"id\": 73 }],\n \"pathCandidates\": {\n \"raw\": [{ \"path\": \"/mnt/raw/...\", \"exists\": true, \"isDirectory\": true }],\n \"movie\": [{ \"path\": \"/mnt/movies/...\", \"exists\": true, \"isDirectory\": true }]\n }\n }\n}\n"},{"location":"api/history/#post-apihistoryiddelete-files","title":"POST /api/history/:id/delete-files","text":"L\u00f6scht Dateien eines Jobs, beh\u00e4lt DB-Eintrag.
Request:
{\n \"target\": \"both\",\n \"includeRelated\": true,\n \"selectedRawPaths\": [\"/mnt/raw/Inception - RAW - Disc1\"],\n \"selectedMoviePaths\": [\"/mnt/movies/Inception (2010)\"]\n}\n target: raw | movie | both
selectedRawPaths / selectedMoviePaths sind optional und begrenzen die L\u00f6schung auf ausgew\u00e4hlte Pfade aus der Vorschau.
L\u00f6scht Job aus DB; optional auch Dateien.
Request:
{\n \"target\": \"both\",\n \"includeRelated\": true,\n \"resetDriveState\": false,\n \"keepDetectedDevice\": true,\n \"preserveRawForImportJobs\": false,\n \"selectedRawPaths\": [\"/mnt/raw/Inception - RAW - Disc1\"],\n \"selectedMoviePaths\": [\"/mnt/movies/Inception (2010)\"]\n}\n target: none | raw | movie | both
Response (Beispiel):
{\n \"deleted\": true,\n \"jobId\": 42,\n \"fileTarget\": \"both\",\n \"fileSummary\": {\n \"target\": \"both\",\n \"raw\": { \"filesDeleted\": 10 },\n \"movie\": { \"filesDeleted\": 1 }\n },\n \"uiReset\": {\n \"reset\": true,\n \"state\": \"IDLE\"\n },\n \"safeguards\": {\n \"containsOrphanRawImportJob\": false,\n \"resetDriveStateApplied\": false,\n \"keepDetectedDeviceApplied\": true\n }\n}\n"},{"location":"api/history/#hinweise","title":"Hinweise","text":"409).includeRelated und Pfadselektionen den genauen Scope.Endpunkte zur Steuerung des Pipeline-Workflows.
"},{"location":"api/pipeline/#get-apipipelinestate","title":"GET /api/pipeline/state","text":"Liefert aktuellen Pipeline- und Hardware-Monitoring-Snapshot.
Response (Beispiel):
{\n \"pipeline\": {\n \"state\": \"READY_TO_ENCODE\",\n \"activeJobId\": 42,\n \"progress\": 0,\n \"eta\": null,\n \"statusText\": \"Mediainfo best\u00e4tigt - Encode manuell starten\",\n \"context\": {\n \"jobId\": 42\n },\n \"jobProgress\": {\n \"42\": {\n \"state\": \"MEDIAINFO_CHECK\",\n \"progress\": 68.5,\n \"eta\": null,\n \"statusText\": \"MEDIAINFO_CHECK 68.50%\"\n }\n },\n \"queue\": {\n \"maxParallelJobs\": 1,\n \"runningCount\": 1,\n \"queuedCount\": 2,\n \"runningJobs\": [],\n \"queuedJobs\": []\n }\n },\n \"hardwareMonitoring\": {\n \"enabled\": true,\n \"intervalMs\": 5000,\n \"updatedAt\": \"2026-03-10T09:00:00.000Z\",\n \"sample\": {\n \"cpu\": {},\n \"memory\": {},\n \"gpu\": {},\n \"storage\": {}\n },\n \"error\": null\n }\n}\n"},{"location":"api/pipeline/#post-apipipelineanalyze","title":"POST /api/pipeline/analyze","text":"Startet Disc-Analyse und legt Job an.
Response:
{\n \"result\": {\n \"jobId\": 42,\n \"detectedTitle\": \"INCEPTION\",\n \"omdbCandidates\": []\n }\n}\n"},{"location":"api/pipeline/#post-apipipelinerescan-disc","title":"POST /api/pipeline/rescan-disc","text":"Erzwingt erneute Laufwerkspr\u00fcfung.
Response (Beispiel):
{\n \"result\": {\n \"present\": true,\n \"changed\": true,\n \"emitted\": \"discInserted\",\n \"device\": {\n \"path\": \"/dev/sr0\",\n \"discLabel\": \"INCEPTION\",\n \"mediaProfile\": \"bluray\"\n }\n }\n}\n"},{"location":"api/pipeline/#post-apipipelinerescan-drive","title":"POST /api/pipeline/rescan-drive","text":"Erzwingt Rescan f\u00fcr ein konkretes Laufwerk.
Request:
{ \"devicePath\": \"/dev/sr0\" }\n"},{"location":"api/pipeline/#get-apipipelineomdbsearchq","title":"GET /api/pipeline/omdb/search?q= OMDb-Titelsuche.
Response:
{\n \"results\": [\n {\n \"imdbId\": \"tt1375666\",\n \"title\": \"Inception\",\n \"year\": \"2010\",\n \"type\": \"movie\",\n \"poster\": \"https://...\"\n }\n ]\n}\n","text":""},{"location":"api/pipeline/#get-apipipelinetmdbseriessearchqseason","title":"GET /api/pipeline/tmdb/series/search?q=&season= TMDb-Seriensuche (f\u00fcr Serien-Workflow bei DVD/Blu-ray).
","text":""},{"location":"api/pipeline/#get-apipipelinecddrives","title":"GET /api/pipeline/cd/drivesLiefert Snapshot der aktuell bekannten CD-Laufwerke.
","text":""},{"location":"api/pipeline/#get-apipipelinecdmusicbrainzsearchq","title":"GET /api/pipeline/cd/musicbrainz/search?q=MusicBrainz-Suche f\u00fcr CD-Metadaten.
","text":""},{"location":"api/pipeline/#get-apipipelinecdmusicbrainzreleasembid","title":"GET /api/pipeline/cd/musicbrainz/release/:mbIdL\u00e4dt Release-Details zu einer MusicBrainz-ID.
","text":""},{"location":"api/pipeline/#post-apipipelinecdselect-metadata","title":"POST /api/pipeline/cd/select-metadata\u00dcbernimmt CD-Metadaten f\u00fcr einen Job.
Request (Beispiel):
{\n \"jobId\": 91,\n \"title\": \"Album\",\n \"artist\": \"Artist\",\n \"year\": 2020,\n \"mbId\": \"f5093c06-23e3-404f-aeaa-40f72885ee3a\",\n \"coverUrl\": \"https://...\",\n \"tracks\": []\n}\n","text":""},{"location":"api/pipeline/#post-apipipelinecdstartjobid","title":"POST /api/pipeline/cd/start/:jobId Startet/queued CD-Rip mit Format-/Script-/Chain-Konfiguration.
","text":""},{"location":"api/pipeline/#post-apipipelineaudiobookupload","title":"POST /api/pipeline/audiobook/uploadUpload von AAX-Datei (Multipart/FormData).
FormData-Felder:
file (Pflicht)format (optional)startImmediately (optional)Zeigt AAX-Jobs mit fehlenden Activation-Bytes.
","text":""},{"location":"api/pipeline/#post-apipipelineaudiobookstartjobid","title":"POST /api/pipeline/audiobook/start/:jobIdStartet Audiobook-Job mit optionaler Konfiguration.
","text":""},{"location":"api/pipeline/#get-apipipelineaudiobookjobs","title":"GET /api/pipeline/audiobook/jobsLiefert Audiobook-Jobliste.
","text":""},{"location":"api/pipeline/#get-apipipelineaudiobookoutput-tree","title":"GET /api/pipeline/audiobook/output-treeRead-only Baumansicht des Audiobook-Ausgabeordners.
","text":""},{"location":"api/pipeline/#post-apipipelineselect-metadata","title":"POST /api/pipeline/select-metadataSetzt Metadaten (und optional Playlist) f\u00fcr einen Job.
Request:
{\n \"jobId\": 42,\n \"title\": \"Inception\",\n \"year\": 2010,\n \"imdbId\": \"tt1375666\",\n \"poster\": \"https://...\",\n \"fromOmdb\": true,\n \"selectedPlaylist\": \"00800\"\n}\n Wichtige optionale Felder:
selectedHandBrakeTitleId / selectedHandBrakeTitleIds: Titel-Auswahl f\u00fcr Review/MediaInfo.metadataProvider: omdb oder tmdb.workflowKind: bei Disc-Jobs typischerweise film oder series.discNumber: Pflicht f\u00fcr Serien-Disc-Zuordnung (workflowKind=series).duplicateAction: Duplikatverhalten bei Film-Metadaten (allow_new oder multipart_movie).existingJobId: optionaler Referenzjob f\u00fcr multipart_movie.existingDiscNumber: Disc-Nummer des bestehenden Jobs f\u00fcr multipart_movie.Response:
{ \"job\": { \"id\": 42, \"status\": \"READY_TO_START\" } }\n Konflikt-Response (Beispiel, HTTP 409):
{\n \"message\": \"Metadaten bereits in der Historie gefunden. Bitte Auswahl \u00fcbernehmen oder Multipart movie w\u00e4hlen.\",\n \"details\": [\n {\n \"code\": \"METADATA_DUPLICATE_FOUND\",\n \"mediaProfile\": \"bluray\",\n \"existingJob\": {\n \"id\": 17,\n \"title\": \"Inception\",\n \"year\": 2010,\n \"status\": \"FINISHED\",\n \"jobKind\": \"bluray\",\n \"discNumber\": 1,\n \"isMultipartMovie\": false\n }\n }\n ]\n}\n Relevante Fehlercodes (POST /api/pipeline/select-metadata):
METADATA_DUPLICATE_FOUND Film-Metadaten existieren bereits in der Historie (Konfliktdialog im UI). MULTIPART_DISC_REQUIRED F\u00fcr Multipart fehlen Disc-Nummern (discNumber/existingDiscNumber). MULTIPART_DISC_ALREADY_EXISTS Disc-Nummer im Multipart-Container bereits vergeben oder doppelt. MULTIPART_MEDIA_MISMATCH Multipart nur bei gleichem Medientyp (DVD oder Blu-ray). MULTIPART_SERIES_NOT_ALLOWED Multipart ist nur f\u00fcr Film-Jobs erlaubt, nicht f\u00fcr Serien-Workflow. MULTIPART_METADATA_MISMATCH Ausgew\u00e4hlter bestehender Job passt nicht zu den Film-Metadaten. SERIES_DISC_ALREADY_EXISTS Serien-Disc-Nummer innerhalb einer Staffel bereits vorhanden.","text":""},{"location":"api/pipeline/#post-apipipelinejobsjobidraw-decision","title":"POST /api/pipeline/jobs/:jobId/raw-decision Trifft Entscheidung bei vorhandenem RAW (continue oder restart je nach Dialogfluss).
Request:
{ \"decision\": \"continue\" }\n","text":""},{"location":"api/pipeline/#post-apipipelinestartjobid","title":"POST /api/pipeline/start/:jobId Startet vorbereiteten Job oder queued ihn (je nach Parallel-Limit).
M\u00f6gliche Responses:
{ \"result\": { \"started\": true, \"stage\": \"RIPPING\" } }\n { \"result\": { \"queued\": true, \"started\": false, \"queuePosition\": 2, \"action\": \"START_PREPARED\" } }\n","text":""},{"location":"api/pipeline/#post-apipipelineconfirm-encodejobid","title":"POST /api/pipeline/confirm-encode/:jobId Best\u00e4tigt Review-Auswahl (Tracks, Pre/Post-Skripte/Ketten, User-Preset).
Request (typisch):
{\n \"selectedEncodeTitleId\": 1,\n \"selectedTrackSelection\": {\n \"1\": {\n \"audioTrackIds\": [1, 2],\n \"subtitleTrackIds\": [3]\n }\n },\n \"selectedPreEncodeScriptIds\": [1],\n \"selectedPostEncodeScriptIds\": [2, 7],\n \"selectedPreEncodeChainIds\": [3],\n \"selectedPostEncodeChainIds\": [4],\n \"selectedUserPresetId\": 5,\n \"skipPipelineStateUpdate\": false\n}\n Response:
{ \"job\": { \"id\": 42, \"encode_review_confirmed\": 1 } }\n","text":""},{"location":"api/pipeline/#post-apipipelinecancel","title":"POST /api/pipeline/cancel Bricht laufenden Job ab oder entfernt Queue-Eintrag.
Request (optional):
{ \"jobId\": 42 }\n M\u00f6gliche Responses:
{ \"result\": { \"cancelled\": true, \"queuedOnly\": true, \"jobId\": 42 } }\n { \"result\": { \"cancelled\": true, \"queuedOnly\": false, \"jobId\": 42 } }\n { \"result\": { \"cancelled\": true, \"queuedOnly\": false, \"pending\": true, \"jobId\": 42 } }\n","text":""},{"location":"api/pipeline/#post-apipipelineretryjobid","title":"POST /api/pipeline/retry/:jobId Retry f\u00fcr ERROR/CANCELLED-Jobs (oder Queue-Einreihung).
Startet Re-Encode aus bestehendem RAW.
","text":""},{"location":"api/pipeline/#post-apipipelinerestart-reviewjobid","title":"POST /api/pipeline/restart-review/:jobIdBerechnet Review aus RAW neu.
","text":""},{"location":"api/pipeline/#post-apipipelinerestart-encodejobid","title":"POST /api/pipeline/restart-encode/:jobIdStartet Encoding mit letzter best\u00e4tigter Review neu.
","text":""},{"location":"api/pipeline/#post-apipipelinerestart-cd-reviewjobid","title":"POST /api/pipeline/restart-cd-review/:jobIdBerechnet CD-Review aus vorhandenem RAW neu.
","text":""},{"location":"api/pipeline/#post-apipipelineresume-readyjobid","title":"POST /api/pipeline/resume-ready/:jobIdL\u00e4dt READY_TO_ENCODE-Job nach Neustart wieder in aktive Session.
Liefert bekannte Output-Ordner entlang der Job-Lineage.
","text":""},{"location":"api/pipeline/#post-apipipelinedelete-output-foldersjobid","title":"POST /api/pipeline/delete-output-folders/:jobIdL\u00f6scht ausgew\u00e4hlte Output-Ordner.
Request:
{ \"folderPaths\": [\"/mnt/movies/Inception (2010)\"] }\n Alle Endpunkte liefern { result: ... } bzw. { job: ... }.
Liefert Queue-Snapshot.
{\n \"queue\": {\n \"maxParallelJobs\": 1,\n \"runningCount\": 1,\n \"queuedCount\": 3,\n \"runningJobs\": [\n {\n \"jobId\": 41,\n \"title\": \"Inception\",\n \"status\": \"ENCODING\",\n \"lastState\": \"ENCODING\"\n }\n ],\n \"queuedJobs\": [\n {\n \"entryId\": 11,\n \"position\": 1,\n \"type\": \"job\",\n \"jobId\": 42,\n \"action\": \"START_PREPARED\",\n \"actionLabel\": \"Start\",\n \"title\": \"Matrix\",\n \"status\": \"READY_TO_ENCODE\",\n \"lastState\": \"READY_TO_ENCODE\",\n \"hasScripts\": true,\n \"hasChains\": false,\n \"enqueuedAt\": \"2026-03-10T09:00:00.000Z\"\n },\n {\n \"entryId\": 12,\n \"position\": 2,\n \"type\": \"wait\",\n \"waitSeconds\": 30,\n \"title\": \"Warten 30s\",\n \"status\": \"QUEUED\",\n \"enqueuedAt\": \"2026-03-10T09:01:00.000Z\"\n }\n ],\n \"updatedAt\": \"2026-03-10T09:01:02.000Z\"\n }\n}\n"},{"location":"api/pipeline/#post-apipipelinequeuereorder","title":"POST /api/pipeline/queue/reorder","text":"Sortiert Queue-Eintr\u00e4ge neu.
Request:
{\n \"orderedEntryIds\": [12, 11]\n}\n Legacy fallback wird akzeptiert:
{\n \"orderedJobIds\": [42, 43]\n}\n"},{"location":"api/pipeline/#post-apipipelinequeueentry","title":"POST /api/pipeline/queue/entry","text":"F\u00fcgt Nicht-Job-Queue-Eintrag hinzu (script, chain, wait).
Request-Beispiele:
{ \"type\": \"script\", \"scriptId\": 3 }\n { \"type\": \"chain\", \"chainId\": 2, \"insertAfterEntryId\": 11 }\n { \"type\": \"wait\", \"waitSeconds\": 45 }\n Response:
{\n \"result\": { \"entryId\": 12, \"type\": \"wait\", \"position\": 2 },\n \"queue\": { \"...\": \"...\" }\n}\n"},{"location":"api/pipeline/#delete-apipipelinequeueentryentryid","title":"DELETE /api/pipeline/queue/entry/:entryId","text":"Entfernt Queue-Eintrag.
Response:
{ \"queue\": { \"...\": \"...\" } }\n"},{"location":"api/pipeline/#pipeline-zustande","title":"Pipeline-Zust\u00e4nde State Bedeutung IDLE Wartet auf Medium DISC_DETECTED Medium erkannt ANALYZING MakeMKV-Analyse l\u00e4uft METADATA_SELECTION Metadaten-Auswahl WAITING_FOR_USER_DECISION Nutzerentscheidung erforderlich (Playlist-Auswahl oder RAW-Entscheidung) READY_TO_START \u00dcbergang vor Start RIPPING MakeMKV-Rip l\u00e4uft MEDIAINFO_CHECK Titel-/Track-Auswertung READY_TO_ENCODE Review bereit ENCODING HandBrake-Encoding l\u00e4uft CD_METADATA_SELECTION CD-Metadatenauswahl aktiv CD_READY_TO_RIP CD-Job ist startbereit CD_ANALYZING CD-Struktur/Tracks werden vorbereitet CD_RIPPING CD-Ripping l\u00e4uft CD_ENCODING CD-Encode l\u00e4uft FINISHED Abgeschlossen DONE Abgeschlossen (v. a. Audiobook/Converter/CD-Varianten) CANCELLED Abgebrochen ERROR Fehler","text":""},{"location":"api/runtime-activities/","title":"Runtime Activities API","text":"Ripster verfolgt alle laufenden und k\u00fcrzlich abgeschlossenen Aktivit\u00e4ten (Skripte, Skript-Ketten, Cron-Jobs, interne Tasks) in Echtzeit \u00fcber den RuntimeActivityService.
Aktivit\u00e4ten entstehen, wenn Ripster intern Aktionen ausf\u00fchrt \u2013 z. B. beim Start eines Cron-Jobs, beim Ausf\u00fchren einer Skript-Kette oder beim Durchlaufen von Pipeline-Schritten. Sie sind nicht persistent (kein DB-Speicher) und werden nur im Arbeitsspeicher gehalten.
active): Laufen gerade.recent): Abgeschlossen, max. 120 Eintr\u00e4ge.\u00c4nderungen werden \u00fcber WebSocket (RUNTIME_ACTIVITY_CHANGED) in Echtzeit gesendet.
{\n \"id\": 7,\n \"type\": \"chain\",\n \"name\": \"Post-Encode Aufr\u00e4umen\",\n \"status\": \"running\",\n \"source\": \"cron\",\n \"message\": \"Schritt 2 von 3\",\n \"currentStep\": \"cleanup.sh\",\n \"currentStepType\": \"script\",\n \"currentScriptName\": \"cleanup.sh\",\n \"stepIndex\": 2,\n \"stepTotal\": 3,\n \"parentActivityId\": null,\n \"jobId\": 42,\n \"cronJobId\": 3,\n \"chainId\": 5,\n \"scriptId\": null,\n \"canCancel\": true,\n \"canNextStep\": false,\n \"outcome\": \"running\",\n \"errorMessage\": null,\n \"output\": null,\n \"stdout\": null,\n \"stderr\": null,\n \"stdoutTruncated\": false,\n \"stderrTruncated\": false,\n \"startedAt\": \"2026-03-10T10:00:00.000Z\",\n \"finishedAt\": null,\n \"durationMs\": null,\n \"exitCode\": null,\n \"success\": null\n}\n"},{"location":"api/runtime-activities/#felder","title":"Felder","text":"Feld Typ Beschreibung id number Eindeutige ID (Laufz\u00e4hler, nicht persistent) type string Art der Aktivit\u00e4t: script | chain | cron | task name string \\| null Anzeigename der Aktivit\u00e4t status string Aktueller Status: running | success | error source string \\| null Ausl\u00f6ser (z. B. cron, pipeline, manual) message string \\| null Kurztext zum aktuellen Zustand currentStep string \\| null Name des aktuell ausgef\u00fchrten Schritts currentStepType string \\| null Typ des Schritts (z. B. script, wait) currentScriptName string \\| null Name des Skripts im aktuellen Schritt stepIndex number \\| null Aktueller Schritt (1-basiert) stepTotal number \\| null Gesamtanzahl Schritte parentActivityId number \\| null ID der \u00fcbergeordneten Aktivit\u00e4t jobId number \\| null Verkn\u00fcpfte Job-ID cronJobId number \\| null Verkn\u00fcpfte Cron-Job-ID chainId number \\| null Verkn\u00fcpfte Skript-Ketten-ID scriptId number \\| null Verkn\u00fcpfte Skript-ID canCancel boolean Abbrechen \u00fcber API m\u00f6glich canNextStep boolean N\u00e4chster Schritt \u00fcber API ausl\u00f6sbar outcome string \\| null Abschluss-Ergebnis: success | error | cancelled | skipped | running errorMessage string \\| null Fehlermeldung (max. 2.000 Zeichen) output string \\| null Allgemeine Ausgabe (max. 12.000 Zeichen) stdout string \\| null Standardausgabe des Prozesses (max. 12.000 Zeichen) stderr string \\| null Fehlerausgabe des Prozesses (max. 12.000 Zeichen) stdoutTruncated boolean true, wenn stdout gek\u00fcrzt wurde stderrTruncated boolean true, wenn stderr gek\u00fcrzt wurde startedAt string ISO-8601-Zeitstempel des Starts finishedAt string \\| null ISO-8601-Zeitstempel des Endes durationMs number \\| null Laufzeit in Millisekunden exitCode number \\| null Exit-Code des Prozesses success boolean \\| null Erfolgsstatus (null bei laufender Aktivit\u00e4t)"},{"location":"api/runtime-activities/#snapshot-objekt","title":"Snapshot-Objekt","text":"Alle Aktivit\u00e4ts-Endpunkte geben einen Snapshot zur\u00fcck:
{\n \"active\": [ /* laufende Aktivit\u00e4ten, nach startedAt absteigend */ ],\n \"recent\": [ /* abgeschlossene Aktivit\u00e4ten, nach finishedAt absteigend, max. 120 */ ],\n \"updatedAt\": \"2026-03-10T10:05:00.000Z\"\n}\n"},{"location":"api/runtime-activities/#endpunkte","title":"Endpunkte","text":""},{"location":"api/runtime-activities/#get-apiruntimeactivities","title":"GET /api/runtime/activities","text":"Aktuellen Aktivit\u00e4ts-Snapshot abrufen.
Antwort:
{\n \"active\": [],\n \"recent\": [\n {\n \"id\": 5,\n \"type\": \"script\",\n \"name\": \"notify.sh\",\n \"status\": \"success\",\n \"outcome\": \"success\",\n \"startedAt\": \"2026-03-10T09:58:00.000Z\",\n \"finishedAt\": \"2026-03-10T09:58:02.000Z\",\n \"durationMs\": 2100,\n \"exitCode\": 0,\n \"success\": true,\n \"canCancel\": false,\n \"canNextStep\": false\n }\n ],\n \"updatedAt\": \"2026-03-10T10:05:00.000Z\"\n}\n"},{"location":"api/runtime-activities/#post-apiruntimeactivitiesidcancel","title":"POST /api/runtime/activities/:id/cancel","text":"Aktive Aktivit\u00e4t abbrechen (nur wenn canCancel: true).
Parameter:
Name In Typ Beschreibungid path number Aktivit\u00e4ts-ID reason body string Optionaler Abbruchgrund Request Body:
{ \"reason\": \"Manueller Abbruch durch Benutzer\" }\n Antwort (Erfolg):
{\n \"ok\": true,\n \"action\": null,\n \"snapshot\": { \"active\": [], \"recent\": [], \"updatedAt\": \"...\" }\n}\n Fehlercodes:
HTTP Bedeutung404 Aktivit\u00e4t nicht gefunden oder bereits abgeschlossen 409 Abbrechen wird von dieser Aktivit\u00e4t nicht unterst\u00fctzt"},{"location":"api/runtime-activities/#post-apiruntimeactivitiesidnext-step","title":"POST /api/runtime/activities/:id/next-step","text":"N\u00e4chsten Schritt einer Aktivit\u00e4t ausl\u00f6sen (nur wenn canNextStep: true).
Parameter:
Name In Typ Beschreibungid path number Aktivit\u00e4ts-ID Antwort (Erfolg):
{\n \"ok\": true,\n \"action\": null,\n \"snapshot\": { \"active\": [], \"recent\": [], \"updatedAt\": \"...\" }\n}\n Fehlercodes:
HTTP Bedeutung404 Aktivit\u00e4t nicht gefunden 409 N\u00e4chster Schritt wird von dieser Aktivit\u00e4t nicht unterst\u00fctzt"},{"location":"api/runtime-activities/#post-apiruntimeactivitiesclear-recent","title":"POST /api/runtime/activities/clear-recent","text":"Alle abgeschlossenen Aktivit\u00e4ten aus recent l\u00f6schen.
Antwort:
{\n \"ok\": true,\n \"removed\": 14,\n \"snapshot\": { \"active\": [], \"recent\": [], \"updatedAt\": \"...\" }\n}\n"},{"location":"api/runtime-activities/#grenzwerte","title":"Grenzwerte","text":"Wert Limit Maximale recent-Eintr\u00e4ge 120 Maximale L\u00e4nge stdout / stderr / output 12.000 Zeichen Maximale L\u00e4nge errorMessage / message 2.000 Zeichen Maximale L\u00e4nge outcome 40 Zeichen Gek\u00fcrzte Ausgaben erhalten den Suffix ...[gek\u00fcrzt] (bei Inline-Text) bzw. \\n...[gek\u00fcrzt] (bei mehrzeiligem Output).
\u00c4nderungen werden automatisch als RUNTIME_ACTIVITY_CHANGED WebSocket-Event gesendet. Die Frontend-Komponente braucht GET /api/runtime/activities nur beim initialen Laden aufzurufen.
Endpunkte f\u00fcr Einstellungen, Skripte, Skript-Ketten und User-Presets.
"},{"location":"api/settings/#get-apisettings","title":"GET /api/settings","text":"Liefert alle Einstellungen kategorisiert.
Response (Struktur):
{\n \"categories\": [\n {\n \"category\": \"Pfade\",\n \"settings\": [\n {\n \"key\": \"raw_dir\",\n \"label\": \"Raw Ausgabeordner\",\n \"type\": \"path\",\n \"required\": true,\n \"description\": \"...\",\n \"defaultValue\": \"data/output/raw\",\n \"options\": [],\n \"validation\": { \"minLength\": 1 },\n \"value\": \"data/output/raw\",\n \"orderIndex\": 100\n }\n ]\n }\n ]\n}\n"},{"location":"api/settings/#put-apisettingskey","title":"PUT /api/settings/:key","text":"Aktualisiert eine einzelne Einstellung.
Request:
{ \"value\": \"/mnt/storage/raw\" }\n Response:
{\n \"setting\": {\n \"key\": \"raw_dir\",\n \"value\": \"/mnt/storage/raw\"\n },\n \"reviewRefresh\": {\n \"triggered\": false,\n \"reason\": \"not_ready\"\n }\n}\n reviewRefresh ist null oder ein Objekt mit Status der optionalen Review-Neuberechnung.
Aktualisiert mehrere Einstellungen atomar.
Request:
{\n \"settings\": {\n \"raw_dir\": \"/mnt/storage/raw\",\n \"movie_dir\": \"/mnt/storage/movies\",\n \"handbrake_preset_bluray\": \"H.264 MKV 1080p30\"\n }\n}\n Response:
{\n \"changes\": [\n { \"key\": \"raw_dir\", \"value\": \"/mnt/storage/raw\" },\n { \"key\": \"movie_dir\", \"value\": \"/mnt/storage/movies\" }\n ],\n \"reviewRefresh\": {\n \"triggered\": true,\n \"jobId\": 42,\n \"relevantKeys\": [\"handbrake_preset_bluray\"]\n }\n}\n Bei Validierungsfehlern kommt 400 mit error.details[].
Liest Preset-Liste via HandBrakeCLI -z (mit Fallback auf konfigurierte Presets).
Response (Beispiel):
{\n \"source\": \"handbrake-cli\",\n \"message\": null,\n \"options\": [\n { \"label\": \"General/\", \"value\": \"__group__general\", \"disabled\": true, \"category\": \"General\" },\n { \"label\": \" Fast 1080p30\", \"value\": \"Fast 1080p30\", \"category\": \"General\" }\n ]\n}\n"},{"location":"api/settings/#post-apisettingspushovertest","title":"POST /api/settings/pushover/test","text":"Sendet Testnachricht \u00fcber aktuelle PushOver-Settings.
Request (optional):
{\n \"title\": \"Test\",\n \"message\": \"Ripster Test\"\n}\n Response:
{\n \"result\": {\n \"sent\": true,\n \"eventKey\": \"test\",\n \"requestId\": \"...\"\n }\n}\n Wenn PushOver deaktiviert ist oder Credentials fehlen, kommt i. d. R. ebenfalls 200 mit sent: false + reason.
Basis: /api/settings/scripts
{ \"scripts\": [ { \"id\": 1, \"name\": \"...\", \"scriptBody\": \"...\", \"orderIndex\": 1, \"createdAt\": \"...\", \"updatedAt\": \"...\" } ] }\n"},{"location":"api/settings/#post-apisettingsscripts","title":"POST /api/settings/scripts","text":"{ \"name\": \"Move\", \"scriptBody\": \"mv \\\"$RIPSTER_OUTPUT_PATH\\\" /mnt/movies/\" }\n Response: 201 mit { \"script\": { ... } }
Body wie POST, Response { \"script\": { ... } }.
Response { \"removed\": { ... } }.
{ \"orderedScriptIds\": [3, 1, 2] }\n Response { \"scripts\": [ ... ] }.
F\u00fchrt Skript als Testlauf aus.
{\n \"result\": {\n \"scriptId\": 1,\n \"scriptName\": \"Move\",\n \"success\": true,\n \"exitCode\": 0,\n \"signal\": null,\n \"timedOut\": false,\n \"durationMs\": 120,\n \"stdout\": \"...\",\n \"stderr\": \"...\",\n \"stdoutTruncated\": false,\n \"stderrTruncated\": false\n }\n}\n"},{"location":"api/settings/#umgebungsvariablen-fur-skripte","title":"Umgebungsvariablen f\u00fcr Skripte","text":"Diese Variablen werden beim Ausf\u00fchren gesetzt:
RIPSTER_SCRIPT_RUN_ATRIPSTER_JOB_IDRIPSTER_JOB_TITLERIPSTER_MODERIPSTER_INPUT_PATHRIPSTER_OUTPUT_PATHRIPSTER_RAW_PATHRIPSTER_SCRIPT_IDRIPSTER_SCRIPT_NAMERIPSTER_SCRIPT_SOURCEBasis: /api/settings/script-chains
Eine Kette hat Schritte vom Typ:
script (scriptId erforderlich)wait (waitSeconds 1..3600)Response { \"chains\": [ ... ] } (inkl. steps[]).
Response { \"chain\": { ... } }.
{\n \"name\": \"After Encode\",\n \"steps\": [\n { \"stepType\": \"script\", \"scriptId\": 1 },\n { \"stepType\": \"wait\", \"waitSeconds\": 15 },\n { \"stepType\": \"script\", \"scriptId\": 2 }\n ]\n}\n Response: 201 mit { \"chain\": { ... } }
Body wie POST, Response { \"chain\": { ... } }.
Response { \"removed\": { ... } }.
{ \"orderedChainIds\": [2, 1, 3] }\n Response { \"chains\": [ ... ] }.
Response:
{\n \"result\": {\n \"chainId\": 2,\n \"chainName\": \"After Encode\",\n \"steps\": 3,\n \"succeeded\": 3,\n \"failed\": 0,\n \"aborted\": false,\n \"results\": []\n }\n}\n"},{"location":"api/settings/#user-presets","title":"User-Presets","text":"Basis: /api/settings/user-presets
Optionaler Query-Parameter: media_type=bluray|dvd|other|all
{\n \"presets\": [\n {\n \"id\": 1,\n \"name\": \"Blu-ray HQ\",\n \"mediaType\": \"bluray\",\n \"handbrakePreset\": \"H.264 MKV 1080p30\",\n \"extraArgs\": \"--encoder-preset slow\",\n \"description\": \"...\",\n \"createdAt\": \"...\",\n \"updatedAt\": \"...\"\n }\n ]\n}\n"},{"location":"api/settings/#post-apisettingsuser-presets","title":"POST /api/settings/user-presets","text":"{\n \"name\": \"Blu-ray HQ\",\n \"mediaType\": \"bluray\",\n \"handbrakePreset\": \"H.264 MKV 1080p30\",\n \"extraArgs\": \"--encoder-preset slow\",\n \"description\": \"optional\"\n}\n Response: 201 mit { \"preset\": { ... } }
Body mit beliebigen Feldern aus POST, Response { \"preset\": { ... } }.
Response { \"removed\": { ... } }.
Liefert aufgel\u00f6ste, effektiv genutzte Pfade aus den Settings (f\u00fcr UI- und Diagnosezwecke).
"},{"location":"api/settings/#post-apisettingscoverartrecover","title":"POST /api/settings/coverart/recover","text":"Startet eine manuelle Coverart-Recovery.
Response (Beispiel):
{\n \"result\": { \"started\": true },\n \"scheduler\": { \"enabled\": true }\n}\n"},{"location":"api/settings/#activation-bytes-aax","title":"Activation Bytes (AAX)","text":""},{"location":"api/settings/#get-apisettingsactivation-bytes","title":"GET /api/settings/activation-bytes","text":"Liest gecachte AAX-Activation-Bytes.
"},{"location":"api/settings/#post-apisettingsactivation-bytes","title":"POST /api/settings/activation-bytes","text":"Speichert Activation-Bytes.
Request:
{\n \"checksum\": \"abc123...\",\n \"activationBytes\": \"1a2b3c4d\"\n}\n"},{"location":"api/settings/#laufwerke","title":"Laufwerke","text":""},{"location":"api/settings/#get-apisettingsdrives","title":"GET /api/settings/drives","text":"Liefert erkannte optische Laufwerke (/dev/...) inkl. MakeMKV-Disc-Index.
Erzwingt Entsperren aktiver Laufwerkslocks.
Hinweis: Expertenmodus (ui_expert_mode) ist erforderlich, sonst 403.
Request (ein Laufwerk):
{ \"devicePath\": \"/dev/sr0\" }\n Request (alle):
{ \"all\": true }\n"},{"location":"api/settings/#ui-preferences","title":"UI Preferences","text":""},{"location":"api/settings/#get-apisettingsprefskey","title":"GET /api/settings/prefs/:key","text":"Liest einen persistierten UI-Preference-Wert.
"},{"location":"api/settings/#put-apisettingsprefskey","title":"PUT /api/settings/prefs/:key","text":"Speichert einen persistierten UI-Preference-Wert.
Request:
{ \"value\": \"{\\\"columns\\\":[\\\"id\\\",\\\"status\\\"]}\" }\n"},{"location":"api/websocket/","title":"WebSocket Events","text":"Ripster sendet Echtzeit-Updates \u00fcber /ws.
const ws = new WebSocket('ws://localhost:3001/ws');\n\nws.onmessage = (event) => {\n const msg = JSON.parse(event.data);\n console.log(msg.type, msg.payload);\n};\n"},{"location":"api/websocket/#nachrichtenformat","title":"Nachrichtenformat","text":"Die meisten Broadcasts haben dieses Schema:
{\n \"type\": \"EVENT_TYPE\",\n \"payload\": {},\n \"timestamp\": \"2026-03-10T09:00:00.000Z\"\n}\n Ausnahme: WS_CONNECTED beim Verbindungsaufbau enth\u00e4lt kein timestamp.
Sofort nach erfolgreicher Verbindung.
{\n \"type\": \"WS_CONNECTED\",\n \"payload\": {\n \"connectedAt\": \"2026-03-10T09:00:00.000Z\"\n }\n}\n"},{"location":"api/websocket/#pipeline_state_changed","title":"PIPELINE_STATE_CHANGED","text":"Neuer Pipeline-Snapshot.
{\n \"type\": \"PIPELINE_STATE_CHANGED\",\n \"payload\": {\n \"state\": \"ENCODING\",\n \"activeJobId\": 42,\n \"progress\": 62.5,\n \"eta\": \"00:12:34\",\n \"statusText\": \"ENCODING 62.50%\",\n \"context\": {},\n \"jobProgress\": {\n \"42\": {\n \"state\": \"ENCODING\",\n \"progress\": 62.5,\n \"eta\": \"00:12:34\",\n \"statusText\": \"ENCODING 62.50%\"\n }\n },\n \"queue\": {\n \"maxParallelJobs\": 1,\n \"runningCount\": 1,\n \"queuedCount\": 2,\n \"runningJobs\": [],\n \"queuedJobs\": []\n }\n }\n}\n"},{"location":"api/websocket/#pipeline_progress","title":"PIPELINE_PROGRESS","text":"Laufende Fortschrittsupdates.
{\n \"type\": \"PIPELINE_PROGRESS\",\n \"payload\": {\n \"state\": \"ENCODING\",\n \"activeJobId\": 42,\n \"progress\": 62.5,\n \"eta\": \"00:12:34\",\n \"statusText\": \"ENCODING 62.50%\"\n }\n}\n"},{"location":"api/websocket/#pipeline_queue_changed","title":"PIPELINE_QUEUE_CHANGED","text":"Queue-Snapshot aktualisiert.
"},{"location":"api/websocket/#disc_detected-disc_removed","title":"DISC_DETECTED / DISC_REMOVED","text":"Disc-Insertion/-Removal.
{\n \"type\": \"DISC_DETECTED\",\n \"payload\": {\n \"device\": {\n \"path\": \"/dev/sr0\",\n \"discLabel\": \"INCEPTION\",\n \"model\": \"ASUS BW-16D1HT\",\n \"fstype\": \"udf\",\n \"mountpoint\": null,\n \"mediaProfile\": \"bluray\"\n }\n }\n}\n mediaProfile: bluray | dvd | other | null
Snapshot aus Hardware-Monitoring.
{\n \"type\": \"HARDWARE_MONITOR_UPDATE\",\n \"payload\": {\n \"enabled\": true,\n \"intervalMs\": 5000,\n \"updatedAt\": \"2026-03-10T09:00:00.000Z\",\n \"sample\": {\n \"cpu\": {},\n \"memory\": {},\n \"gpu\": {},\n \"storage\": {}\n },\n \"error\": null\n }\n}\n"},{"location":"api/websocket/#pipeline_error","title":"PIPELINE_ERROR","text":"Fehler bei Disc-Event-Verarbeitung in Pipeline.
"},{"location":"api/websocket/#disk_detection_error","title":"DISK_DETECTION_ERROR","text":"Fehler in Laufwerkserkennung.
"},{"location":"api/websocket/#settings_updated","title":"SETTINGS_UPDATED","text":"Einzelnes Setting wurde gespeichert.
"},{"location":"api/websocket/#settings_bulk_updated","title":"SETTINGS_BULK_UPDATED","text":"Bulk-Settings gespeichert.
{\n \"type\": \"SETTINGS_BULK_UPDATED\",\n \"payload\": {\n \"count\": 3,\n \"keys\": [\"raw_dir\", \"movie_dir\", \"handbrake_preset_bluray\"]\n }\n}\n"},{"location":"api/websocket/#settings_scripts_updated","title":"SETTINGS_SCRIPTS_UPDATED","text":"Skript ge\u00e4ndert (created|updated|deleted|reordered).
Skript-Kette ge\u00e4ndert (created|updated|deleted|reordered).
User-Preset ge\u00e4ndert (created|updated|deleted).
Cron-Config ge\u00e4ndert (created|updated|deleted).
Laufzeitstatus eines Cron-Jobs ge\u00e4ndert.
{\n \"type\": \"CRON_JOB_UPDATED\",\n \"payload\": {\n \"id\": 1,\n \"lastRunStatus\": \"running\",\n \"lastRunAt\": \"2026-03-10T10:00:00.000Z\",\n \"nextRunAt\": null\n }\n}\n"},{"location":"api/websocket/#runtime_activity_changed","title":"RUNTIME_ACTIVITY_CHANGED","text":"Vollst\u00e4ndiger Snapshot aller laufenden und k\u00fcrzlich abgeschlossenen Aktivit\u00e4ten.
Wird ausgel\u00f6st, wenn eine Aktivit\u00e4t gestartet, aktualisiert oder abgeschlossen wird sowie nach clear-recent.
{\n \"type\": \"RUNTIME_ACTIVITY_CHANGED\",\n \"payload\": {\n \"active\": [\n {\n \"id\": 7,\n \"type\": \"chain\",\n \"name\": \"Post-Encode Aufr\u00e4umen\",\n \"status\": \"running\",\n \"source\": \"cron\",\n \"message\": \"Schritt 2 von 3\",\n \"currentStep\": \"cleanup.sh\",\n \"currentStepType\": \"script\",\n \"stepIndex\": 2,\n \"stepTotal\": 3,\n \"canCancel\": true,\n \"canNextStep\": false,\n \"outcome\": \"running\",\n \"startedAt\": \"2026-03-10T10:00:00.000Z\",\n \"finishedAt\": null,\n \"durationMs\": null\n }\n ],\n \"recent\": [],\n \"updatedAt\": \"2026-03-10T10:00:05.000Z\"\n }\n}\n Vollst\u00e4ndige Feldbeschreibung: Runtime Activities API.
"},{"location":"api/websocket/#converter_scan_update","title":"CONVERTER_SCAN_UPDATE","text":"Wird nach einem Scan des Converter-Eingangsordners gesendet (manuell oder per Polling).
{\n \"type\": \"CONVERTER_SCAN_UPDATE\",\n \"payload\": {\n \"entryCount\": 12\n }\n}\n"},{"location":"api/websocket/#downloads_updated","title":"DOWNLOADS_UPDATED","text":"Wird bei jeder Status\u00e4nderung in der Download-Queue gesendet.
{\n \"type\": \"DOWNLOADS_UPDATED\",\n \"payload\": {\n \"reason\": \"ready\",\n \"item\": {\n \"id\": \"dl-1\",\n \"jobId\": 42,\n \"status\": \"ready\",\n \"archiveName\": \"Job_42_movie.zip\",\n \"createdAt\": \"2026-03-30T10:00:00.000Z\"\n },\n \"summary\": {\n \"total\": 3,\n \"pending\": 1,\n \"processing\": 0,\n \"ready\": 1,\n \"failed\": 1\n }\n }\n}\n M\u00f6gliche reason-Werte: queued, processing, ready, failed, deleted.
useWebSocket verbindet bei Abbruch automatisch neu:
1500msDieser Bereich enth\u00e4lt die technische Referenz hinter dem Benutzerhandbuch.
"},{"location":"appendix/#inhalt","title":"Inhalt","text":"Ripster ist eine Client-Server-Anwendung mit REST + WebSocket und externen CLI-Tools.
"},{"location":"architecture/#systemuberblick","title":"System\u00fcberblick","text":"graph TB\n subgraph Browser[\"Browser (React)\"]\n Ripper[Ripper]\n Settings[Einstellungen]\n History[Historie]\n end\n\n subgraph Backend[\"Node.js Backend\"]\n API[REST API\\nExpress]\n WS[WebSocket\\n/ws]\n Pipeline[pipelineService]\n Cron[cronService]\n DB[(SQLite)]\n end\n\n subgraph Tools[\"Externe Tools\"]\n MakeMKV[makemkvcon]\n HandBrake[HandBrakeCLI]\n MediaInfo[mediainfo]\n end\n\n Browser <-->|HTTP| API\n Browser <-->|WebSocket| WS\n Pipeline --> MakeMKV\n Pipeline --> HandBrake\n Pipeline --> MediaInfo\n API --> DB\n Pipeline --> DB\n Cron --> DB"},{"location":"architecture/#details","title":"Details","text":"Das Backend ist in Services aufgeteilt, die von Express-Routen orchestriert werden. Seit v0.12.0 erfolgt die Medienverarbeitung \u00fcber ein Plugin-System.
"},{"location":"architecture/backend/#plugin-system-srcplugins","title":"Plugin-System (src/plugins/)","text":"Ab v0.12.0 ist die Pipeline modular aufgebaut. Jeder Medientyp wird von einem eigenen Plugin verwaltet.
"},{"location":"architecture/backend/#basisklassen","title":"Basisklassen","text":"PluginBase.js \u2014 Abstrakte Basisklasse SourcePlugin mit Lifecycle-MethodenPluginRegistry.js \u2014 Dynamische Plugin-Erkennung, priorit\u00e4tsbasierte Auswahl, Settings-Schema-AggregationPluginContext.js \u2014 Ausf\u00fchrungskontext (Logger, Callbacks, Signals) f\u00fcr Plugin-AufrufeJedes Plugin implementiert die folgenden Methoden:
Methode Beschreibungdetect(discInfo) Medientyp-Erkennung analyze(devicePath, job, ctx) Analyse / Metadaten-Extraktion rip(job, ctx) Rohdaten-Extraktion review(job, ctx) Optionale Vorschau-Vorbereitung encode(job, ctx) Finales Encoding/Konvertierung finalize(job, ctx) Nachbearbeitung onCancel(job, ctx) Bereinigung bei Abbruch onRetry(job, ctx) Zustand-Reset vor Retry"},{"location":"architecture/backend/#implementierte-plugins","title":"Implementierte Plugins","text":"BluRayPlugin.js \u2014 Blu-ray via MakeMKV (Backup-Modus)DVDPlugin.js \u2014 DVD via MakeMKV (MKV-Modus)CdPlugin.js \u2014 Audio-CD via cdparanoia + FFmpeg (experimentell)AudiobookPlugin.js \u2014 AAX/M4B via FFmpeg mit Kapitel-SplittingConverterPlugin.js \u2014 Generische Audio/Video-Konvertierung via FFmpegVideoDiscPlugin.js \u2014 Gemeinsame Basis f\u00fcr Blu-ray/DVD (MediaInfo-Parsing)pipelineService.js","text":"Zentrale Workflow-Orchestrierung.
Aufgaben:
pipeline_state)script|chain|wait Eintr\u00e4ge)createConverterJobFromEntry, uploadConverterFiles, startConverterJob)Wichtige Methoden:
analyzeDisc()selectMetadata()startPreparedJob()confirmEncodeReview()cancel()retry()reencodeFromRaw()restartReviewFromRaw()restartEncodeWithLastSettings()resumeReadyToEncodeJob()enqueueNonJobEntry(), reorderQueue(), removeQueueEntry()createConverterJobFromEntry(), createConverterJobsFromSelection()uploadConverterFiles(), startConverterJob()diskDetectionService.js","text":"Pollt Laufwerk(e) und emittiert:
discInserteddiscRemovederrorZusatz:
auto oder explicitmediaProfile-Erkennung (bluray/dvd/other)rescanAndEmit() f\u00fcr manuellen TriggersettingsService.js","text":"Settings-Layer mit Validation/Serialisierung.
Features:
getCategorizedSettings() f\u00fcr UI-FormsetSettingValue() / setSettingsBulk()resolveEffectiveToolSettings)HandBrakeCLI -zmakemkv_registration_keyhistoryService.js","text":"Historie + Dateioperationen.
Features:
raw|movie|both)none|raw|movie|both)audiobookService.js","text":"Audiobook-Verarbeitung (AAX/M4B).
Features:
{author}, {title}, {year}, {narrator}, {series}, {part})activationBytesService.js","text":"Verwaltung von Audible-Activation-Bytes f\u00fcr AAX-DRM-Handling.
Features:
aax_activation_bytes-Tabelle cachenaudnexService (wenn konfiguriert)converterScanService.js","text":"Dateisystem-\u00dcberwachung des Converter-Eingangsordners.
Features:
getTree())getEntries())CONVERTER_SCAN_UPDATEdownloadService.js","text":"Download-Queue f\u00fcr Ausgabedateien aus der Historie.
Features:
enqueueHistoryJob)archiver)res.download()DOWNLOADS_UPDATED bei Status-\u00c4nderungencronService.js","text":"Integriertes Cron-System ohne externe Parser-Library.
Features:
nextRun-Berechnungscript oder chaincron_run_logs)CRON_JOBS_UPDATED, CRON_JOB_UPDATEDruntimeActivityService.js","text":"In-Memory-Tracking aller laufenden und k\u00fcrzlich abgeschlossenen Aktivit\u00e4ten (Skripte, Ketten, Cron-Jobs, Tasks).
Features:
startActivity(type, payload) \u2192 Aktivit\u00e4t registrieren, ID zur\u00fcckgebenupdateActivity(id, patch) \u2192 Laufende Aktivit\u00e4t aktualisierencompleteActivity(id, payload) \u2192 Aktivit\u00e4t abschlie\u00dfen und in recent verschiebensetControls(id, { cancel, nextStep }) \u2192 Steuer-Handler registrieren (f\u00fcr canCancel/canNextStep)requestCancel(id) / requestNextStep(id) \u2192 Steuer-Handler aufrufenclearRecent() \u2192 Abgeschlossene Aktivit\u00e4ten l\u00f6schengetSnapshot() \u2192 Snapshot mit active + recent + updatedAtRUNTIME_ACTIVITY_CHANGED \u00fcber WebSocket bei jeder \u00c4nderungLimits:
recent max. 120 Eintr\u00e4gestdout/stderr/output max. 12.000 Zeichenmessage/errorMessage max. 2.000 ZeichenVollst\u00e4ndige API-Dokumentation: Runtime Activities API
"},{"location":"architecture/backend/#weitere-services","title":"Weitere Services","text":"scriptService.js (CRUD + Test + Wrapper-Ausf\u00fchrung)scriptChainService.js (CRUD + Step-Execution)userPresetService.js (HandBrake User-Presets)hardwareMonitorService.js (CPU/RAM/GPU/Storage)websocketService.js (Client-Registry + Broadcast)notificationService.js (PushOver)cdRipService.js (CD-Ripping mit cdparanoia)musicBrainzService.js (MusicBrainz-Metadaten-Lookup)audnexService.js (Audnex-API f\u00fcr Audiobook-Metadaten)coverArtRecoveryService.js (Cover-Art-Wiederherstellung)thumbnailService.js (Vorschaubild-Generierung)omdbService.js (OMDb-Metadaten-Suche)logger.js (rotierende Datei-Logs)src/index.js)","text":"Beim Start:
/wsRipster verwendet SQLite (backend/data/ripster.db).
settings_schema\nsettings_values\njobs\njob_lineage_artifacts\njob_output_folders\npipeline_state\nscripts\nscript_chains\nscript_chain_steps\nuser_presets\ncron_jobs\ncron_run_logs\naax_activation_bytes\nuser_prefs\nconverter_scan_entries\n"},{"location":"architecture/database/#jobs","title":"jobs","text":"Speichert Pipeline-Lifecycle und Artefakte pro Job.
Zentrale Felder:
title, year, imdb_id, poster_url, omdb_json, selected_from_omdbstart_time, end_time, status, last_stateraw_path, output_path, encode_input_pathmakemkv_info_json, handbrake_info_json, mediainfo_info_json, encode_plan_jsonencode_review_confirmed, rip_successful, error_messagemedia_type (bluray|dvd|cd|audiobook|converter)job_kind, parent_job_idis_multipart_movie, disc_number, metadata_fingerprintaax_checksum (f\u00fcr AAX-Dateien)created_at, updated_atTypische job_kind-Werte:
bluray, dvd, cd, audiobook, converter_audio, converter_video, converter_isodvd_series_container, dvd_series_childmultipart_movie_container, multipart_movie_childWichtige Indizes:
idx_jobs_statusidx_jobs_parent_job_ididx_jobs_job_kindidx_jobs_disc_numberidx_jobs_metadata_fingerprintjob_lineage_artifacts","text":"Verkn\u00fcpft Jobs mit ihren Quell-Jobs (z. B. Re-Encode aus einem vorherigen Rip).
Felder:
job_id \u2014 der abgeleitete Jobsource_job_id \u2014 der Quell-Jobartifact_type \u2014 Art der Verkn\u00fcpfung (z. B. reencode, restart_review)created_atjob_output_folders","text":"Verfolgt Ausgabepfade pro Job (mehrere Ausgaben m\u00f6glich, z. B. bei Kapitel-Splitting).
Felder:
job_idfolder_pathlabel \u2014 optionaler Bezeichnercreated_atpipeline_state","text":"Singleton-Tabelle (id = 1) f\u00fcr aktiven Snapshot:
stateactive_job_idprogressetastatus_textcontext_jsonupdated_atsettings_schema + settings_values","text":"settings_schema: Definition (Typ, Default, Validation, Reihenfolge)settings_values: aktueller Wert pro Keyscripts, script_chains, script_chain_steps","text":"scripts: Shell-Skripte (name, script_body, order_index)script_chains: Ketten (name, order_index)script_chain_steps: Schritte je Kettestep_type: script oder waitscript_id oder wait_secondsuser_presets","text":"Benannte HandBrake-Preset-Sets:
namemedia_type (bluray|dvd|other|all)handbrake_presetextra_argsdescriptioncron_jobs + cron_run_logs","text":"cron_jobs: Zeitplan + Statuscron_run_logs: einzelne L\u00e4ufestatus: running|success|erroroutputerror_messageaax_activation_bytes","text":"Cache f\u00fcr Audible-Activation-Bytes (AAX-DRM).
Felder:
checksum \u2014 SHA-1-Pr\u00fcfsumme der AAX-Datei (Prim\u00e4rschl\u00fcssel)activation_bytes \u2014 Hex-String der Activation Bytescreated_atuser_prefs","text":"Benutzer-spezifische Einstellungen (Key-Value).
Felder:
keyvalueupdated_atconverter_scan_entries","text":"DB-seitige Erfassung gescannter Dateien im Converter-Eingangsordner.
Felder:
rel_path \u2014 relativer Pfad zum converter_raw_diris_dir \u2014 Verzeichnis-Flagsize \u2014 Dateigr\u00f6\u00dfe in Bytesmodified_at \u2014 Datei-\u00c4nderungsdatumjob_id \u2014 zugewiesener Converter-Job (falls vorhanden)scanned_atBeim Start werden Schema und Settings-Metadaten automatisch abgeglichen.
Bei korruptem SQLite-File:
backend/data/corrupt-backups/ verschobensqlite3 backend/data/ripster.db\n\n.mode table\nSELECT id, status, title, media_type, created_at FROM jobs ORDER BY created_at DESC;\nSELECT id, parent_job_id, job_kind, is_multipart_movie, disc_number FROM jobs ORDER BY created_at DESC;\nSELECT key, value FROM settings_values ORDER BY key;\nSELECT checksum, activation_bytes FROM aax_activation_bytes;\nSELECT rel_path, job_id FROM converter_scan_entries;\n"},{"location":"architecture/frontend/","title":"Frontend-Komponenten","text":"Frontend: React + PrimeReact + Vite.
"},{"location":"architecture/frontend/#hauptseiten","title":"Hauptseiten","text":""},{"location":"architecture/frontend/#jobsinboxpagejsx","title":"JobsInboxPage.jsx","text":"Zentrale Job-Inbox:
Ripper/Converter)RipperPage.jsx","text":"Pipeline-Steuerung:
SettingsPage.jsx","text":"Konfiguration:
DynamicSettingsForm)CronJobsTab)HistoryPage.jsx","text":"Historie:
ConverterPage.jsx","text":"Datei-Converter:
AudiobooksPage.jsx","text":"Dedizierter AAX-/Audiobook-Flow:
DownloadsPage.jsx","text":"Download-Queue:
DatabasePage.jsx","text":"Expert-Modus:
PipelineStatusCard.jsx \u2014 Pipeline-Status-Anzeige mit ProgressMetadataSelectionDialog.jsx \u2014 OMDb-Metadaten-AuswahlMediaInfoReviewPanel.jsx \u2014 Track-Auswahl-Interface (Video/Audio/Untertitel)JobDetailDialog.jsx \u2014 Job-Detailansicht mit LogsCronJobsTab.jsx \u2014 Cron-Job-VerwaltungDynamicSettingsForm.jsx \u2014 Schema-gesteuertes EinstellungsformularConverterJobCard.jsx \u2014 Converter-Job-DarstellungCdRipConfigPanel.jsx \u2014 Konfiguration f\u00fcr Audio-CD-Rippingapi/client.js)","text":"request() mit JSON-HandlingError(message) gemapptVITE_API_BASE default /apihooks/useWebSocket.js)","text":"VITE_WS_URL oder automatisch ws(s)://<host>/wsIn App.jsx werden u. a. verarbeitet:
PIPELINE_STATE_CHANGEDPIPELINE_PROGRESSPIPELINE_QUEUE_CHANGEDHARDWARE_MONITOR_UPDATEDOWNLOADS_UPDATEDCONVERTER_SCAN_UPDATERUNTIME_ACTIVITY_CHANGED# dev\nnpm run dev --prefix frontend\n\n# prod build\nnpm run build --prefix frontend\n"},{"location":"architecture/overview/","title":"Architektur-\u00dcbersicht","text":""},{"location":"architecture/overview/#kernprinzipien","title":"Kernprinzipien","text":""},{"location":"architecture/overview/#event-getriebene-pipeline","title":"Event-getriebene Pipeline","text":"pipelineService h\u00e4lt einen Snapshot der State-Machine und broadcastet \u00c4nderungen sofort via WebSocket.
State-\u00c4nderung -> PIPELINE_STATE_CHANGED/PIPELINE_PROGRESS -> Frontend-Update\n"},{"location":"architecture/overview/#service-layer","title":"Service-Layer","text":"Route -> Service -> DB/Tool-Execution\n Routes enthalten kaum Business-Logik.
"},{"location":"architecture/overview/#schema-getriebene-settings","title":"Schema-getriebene Settings","text":"Settings sind DB-schema-getrieben (settings_schema + settings_values), UI rendert dynamisch aus diesen Daten.
WebSocket l\u00e4uft auf /ws.
Wichtige Events:
PIPELINE_STATE_CHANGED, PIPELINE_PROGRESS, PIPELINE_QUEUE_CHANGEDHARDWARE_MONITOR_UPDATESETTINGS_UPDATED, SETTINGS_BULK_UPDATEDSETTINGS_SCRIPTS_UPDATED, SETTINGS_SCRIPT_CHAINS_UPDATED, USER_PRESETS_UPDATEDCRON_JOBS_UPDATED, CRON_JOB_UPDATEDPIPELINE_ERROR, DISK_DETECTION_ERRORExterne Tools werden als Child-Processes gestartet (processRunner):
progressParsers.js)SQLite-Datei: backend/data/ripster.db
Kern-Tabellen:
jobs, pipeline_statesettings_schema, settings_valuesscripts, script_chains, script_chain_stepsuser_presetscron_jobs, cron_run_logsBeim Start werden Schema und Settings-Migrationen automatisch ausgef\u00fchrt.
"},{"location":"architecture/overview/#fehlerbehandlung","title":"Fehlerbehandlung","text":"Zentrales Error-Handling liefert:
{\n \"error\": {\n \"message\": \"...\",\n \"statusCode\": 400,\n \"reqId\": \"...\",\n \"details\": []\n }\n}\n Fehlgeschlagene Jobs bleiben in der Historie (Fehler oder Abgebrochen) und k\u00f6nnen erneut gestartet werden.
CORS_ORIGIN default: *LOG_LEVEL default: infoDB_PATH/LOG_DIR konfigurierbarDieser Abschnitt ist die technische Referenz zu allen Konfigurationsarten in Ripster.
"},{"location":"configuration/#inhalte","title":"Inhalte","text":"Einstellungsreferenz
Vollst\u00e4ndige Liste aller UI-Settings (Typ, Default, Hinweise).
Einstellungsreferenz
Umgebungsvariablen
backend/.env und frontend/.env inkl. Priorit\u00e4ten.
Umgebungsvariablen
Umgebungsvariablen steuern Backend/Vite au\u00dferhalb der DB-basierten UI-Settings.
"},{"location":"configuration/environment/#backend-backendenv","title":"Backend (backend/.env)","text":"Variable Default (Code) Beschreibung PORT 3001 Express-Port DB_PATH backend/data/ripster.db SQLite-Datei (relativ zu backend/) LOG_DIR backend/logs Fallback-Logverzeichnis (wenn log_dir-Setting nicht gesetzt/lesbar) CORS_ORIGIN * CORS-Origin f\u00fcr API LOG_LEVEL info debug, info, warn, error Beispiel:
PORT=3001\nDB_PATH=/var/lib/ripster/ripster.db\nLOG_DIR=/var/log/ripster\nCORS_ORIGIN=http://192.168.1.50:5173\nLOG_LEVEL=info\n Hinweis: backend/.env.example enth\u00e4lt bewusst dev-freundliche Werte (z. B. lokaler CORS_ORIGIN).
frontend/.env)","text":"Variable Default Beschreibung VITE_API_BASE /api API-Basis f\u00fcr Fetch-Client VITE_WS_URL automatisch aus window.location + /ws Optional explizite WebSocket-URL VITE_PUBLIC_ORIGIN leer \u00d6ffentliche Vite-Origin (Remote-Dev) VITE_ALLOWED_HOSTS true Komma-separierte Hostliste f\u00fcr Vite allowedHosts VITE_HMR_PROTOCOL abgeleitet aus VITE_PUBLIC_ORIGIN HMR-Protokoll (ws/wss) VITE_HMR_HOST abgeleitet aus VITE_PUBLIC_ORIGIN HMR-Host VITE_HMR_CLIENT_PORT abgeleitet aus VITE_PUBLIC_ORIGIN HMR-Client-Port Beispiele:
# lokal (mit Vite-Proxy)\nVITE_API_BASE=/api\n # remote dev\nVITE_API_BASE=http://192.168.1.50:3001/api\nVITE_WS_URL=ws://192.168.1.50:3001/ws\nVITE_PUBLIC_ORIGIN=http://192.168.1.50:5173\nVITE_ALLOWED_HOSTS=192.168.1.50,ripster.local\nVITE_HMR_PROTOCOL=ws\nVITE_HMR_HOST=192.168.1.50\nVITE_HMR_CLIENT_PORT=5173\n"},{"location":"configuration/environment/#prioritat","title":"Priorit\u00e4t","text":".envDiese Seite listet die Felder so, wie sie in der GUI unter Settings angezeigt werden.
Hinweis: Interne Schl\u00fcsselnamen werden hier bewusst nicht verwendet. Falls du sie f\u00fcr Integrationen brauchst, nutze die API-Dokumentation.
"},{"location":"configuration/settings-reference/#profil-system","title":"Profil-System","text":"Viele Felder sind pro Medientyp getrennt vorhanden:
${title} \u2014 Titel${year} \u2014 Erscheinungsjahr${imdbId} \u2014 IMDb-ID{author} \u2014 Autor{title} \u2014 Titel{year} \u2014 Erscheinungsjahr{narrator} \u2014 Sprecher{series} \u2014 Buchreihe{part} \u2014 Teil-Nummer{format} \u2014 Ausgabeformat{title}, {year}{artist}, {title}, {album}, {year}, {trackNr}Nicht gesetzte Werte werden zu unknown.
Raw Ausgabeordner path data/output/raw Raw Ausgabeordner (Blu-ray) path null Raw Ausgabeordner (DVD) path null Raw Ausgabeordner (Sonstiges) path null Eigent\u00fcmer Raw-Ordner (Blu-ray) string null Eigent\u00fcmer Raw-Ordner (DVD) string null Eigent\u00fcmer Raw-Ordner (Sonstiges) string null Film Ausgabeordner path data/output/movies Film Ausgabeordner (Blu-ray) path null Film Ausgabeordner (DVD) path null Film Ausgabeordner (Sonstiges) path null Eigent\u00fcmer Film-Ordner (Blu-ray) string null Eigent\u00fcmer Film-Ordner (DVD) string null Eigent\u00fcmer Film-Ordner (Sonstiges) string null Log Ordner path data/logs Audiobook RAW-Ordner path null Eigent\u00fcmer Audiobook RAW-Ordner string null Audiobook Output-Ordner path null Eigent\u00fcmer Audiobook Output-Ordner string null Output Template (Audiobook) string {author}/{author} - {title} ({year}) Audiobook RAW Template string {author} - {title} ({year}) Converter Raw-Ordner path null Converter Ausgabe (Video) path null Converter Ausgabe (Audio) path null Output-Template (Video) string {title} Output-Template (Audio) string {artist} - {title}"},{"location":"configuration/settings-reference/#kategorie-laufwerk","title":"Kategorie: Laufwerk","text":"Feldname in der GUI Typ Default Hinweis Laufwerksmodus select auto Auto Discovery oder Explizites Device Device Pfad path /dev/sr0 relevant bei Explizites Device MakeMKV Source Index number 0 Disc-Index im Auto-Modus Disc Auto-Erkennung aktiviert boolean true Automatische Disc-Erkennung per Polling Polling Intervall (ms) number 4000 1000..60000"},{"location":"configuration/settings-reference/#kategorie-monitoring","title":"Kategorie: Monitoring","text":"Feldname in der GUI Typ Default Hardware Monitoring aktiviert boolean true Hardware Monitoring Intervall (ms) number 5000"},{"location":"configuration/settings-reference/#kategorie-tools-global","title":"Kategorie: Tools (global)","text":"Feldname in der GUI Typ Default MakeMKV Kommando string makemkvcon MakeMKV Key string null Mediainfo Kommando string mediainfo Minimale Titellaenge (Minuten) number 60 HandBrake Kommando string HandBrakeCLI FFmpeg Kommando string ffmpeg FFprobe Kommando string ffprobe Encode-Neustart: unvollst\u00e4ndige Ausgabe l\u00f6schen boolean true Parallele Jobs number 1"},{"location":"configuration/settings-reference/#blu-ray-spezifisch","title":"Blu-ray-spezifisch","text":"Feldname in der GUI Typ Default Mediainfo Extra Args (Blu-ray) string null MakeMKV Rip Modus (Blu-ray) select backup MakeMKV Analyze Extra Args (Blu-ray) string null MakeMKV Rip Extra Args (Blu-ray) string null HandBrake Preset (Blu-ray) string H.264 MKV 1080p30 HandBrake Extra Args (Blu-ray) string null Ausgabeformat (Blu-ray) select mkv Dateiname Template (Blu-ray) string ${title} (${year}) Ordnername Template (Blu-ray) string null"},{"location":"configuration/settings-reference/#dvd-spezifisch","title":"DVD-spezifisch","text":"Feldname in der GUI Typ Default Mediainfo Extra Args (DVD) string null MakeMKV Rip Modus (DVD) select mkv MakeMKV Analyze Extra Args (DVD) string null MakeMKV Rip Extra Args (DVD) string null HandBrake Preset (DVD) string H.264 MKV 480p30 HandBrake Extra Args (DVD) string null Ausgabeformat (DVD) select mkv Dateiname Template (DVD) string ${title} (${year}) Ordnername Template (DVD) string null"},{"location":"configuration/settings-reference/#kategorie-converter","title":"Kategorie: Converter","text":"Feldname in der GUI Typ Default Hinweis Erlaubte Datei-Endungen* string mkv,mp4,m2ts,iso,avi,mov,flac,mp3,wav,m4a,ogg,opus In der UI als Checkbox-Liste, ohne Punkt Auto-Scan (Polling) boolean false Converter-Ordner automatisch scannen Polling-Intervall (Sekunden) number 300 30..86400"},{"location":"configuration/settings-reference/#kategorie-metadaten","title":"Kategorie: Metadaten","text":"Feldname in der GUI Typ Default OMDb API Key string null OMDb Typ select movie"},{"location":"configuration/settings-reference/#kategorie-benachrichtigungen-pushover","title":"Kategorie: Benachrichtigungen (PushOver)","text":"Feldname in der GUI Typ Default PushOver aktiviert boolean false PushOver Token string null PushOver User string null PushOver Device (optional) string null PushOver Titel-Pr\u00e4fix string Ripster PushOver Priority number 0 PushOver Timeout (ms) number 7000 Bei Metadaten-Auswahl senden boolean true Bei Rip-Start senden boolean true Bei Encode-Start senden boolean true Bei Erfolg senden boolean true Bei Fehler senden boolean true Bei Abbruch senden boolean true Bei Re-Encode Start senden boolean true Bei Re-Encode Erfolg senden boolean true"},{"location":"deployment/","title":"Anhang: Deployment","text":"Technische Betriebsdokumentation f\u00fcr Entwicklung und Produktion.
Entwicklungsumgebung
Lokale Entwicklung mit Hot-Reload.
Entwicklung
Produktion
Installation und Betrieb auf Servern.
Produktion
makemkvcon, HandBrakeCLI, mediainfo)./start.sh\n Startet:
http://localhost:3001, mit nodemon)http://localhost:5173, mit Vite HMR)Stoppen: Ctrl+C.
cd backend\nnpm install\nnpm run dev\n"},{"location":"deployment/development/#frontend","title":"Frontend","text":"cd frontend\nnpm install\nnpm run dev\n"},{"location":"deployment/development/#vite-proxy-dev","title":"Vite-Proxy (Dev)","text":"frontend/vite.config.js proxied standardm\u00e4\u00dfig:
/api -> http://127.0.0.1:3001/ws -> ws://127.0.0.1:3001Beispiel frontend/.env.local:
VITE_API_BASE=http://192.168.1.100:3001/api\nVITE_WS_URL=ws://192.168.1.100:3001/ws\nVITE_PUBLIC_ORIGIN=http://192.168.1.100:5173\nVITE_ALLOWED_HOSTS=192.168.1.100,ripster.local\nVITE_HMR_PROTOCOL=ws\nVITE_HMR_HOST=192.168.1.100\nVITE_HMR_CLIENT_PORT=5173\n"},{"location":"deployment/development/#nutzliche-kommandos","title":"N\u00fctzliche Kommandos","text":"# Root dev (backend + frontend)\nnpm run dev\n\n# einzeln\nnpm run dev:backend\nnpm run dev:frontend\n\n# Frontend Build\nnpm run build:frontend\n"},{"location":"deployment/production/","title":"Produktions-Deployment","text":""},{"location":"deployment/production/#automatische-installation-empfohlen","title":"Automatische Installation (empfohlen)","text":"Das mitgelieferte install.sh richtet Ripster vollautomatisch ein \u2013 inklusive Node.js, MakeMKV, HandBrake, nginx und systemd-Dienst.
Unterst\u00fctzte Systeme laut Script: Debian, Ubuntu, Linux Mint, Pop!_OS Voraussetzung: root-Rechte, Internetzugang
"},{"location":"deployment/production/#schnellstart-via-curl","title":"Schnellstart via curl","text":"curl -fsSL https://raw.githubusercontent.com/Mboehmlaender/ripster/main/install.sh | sudo bash\n Oder mit wget:
wget -qO- https://raw.githubusercontent.com/Mboehmlaender/ripster/main/install.sh | sudo bash\n Optionen nur via Datei
Beim Pipen von curl/wget k\u00f6nnen keine Argumente \u00fcbergeben werden. F\u00fcr benutzerdefinierte Optionen zuerst herunterladen und dann mit sudo bash install.sh [Optionen] ausf\u00fchren.
--branch <branch> dev Git-Branch f\u00fcr die Installation --dir <pfad> /opt/ripster Installationsverzeichnis --user <benutzer> ripster Systembenutzer f\u00fcr den Dienst --port <port> 3001 Backend-Port --host <hostname> Auto (Maschinen-IP) Hostname/IP f\u00fcr die Weboberfl\u00e4che --no-makemkv \u2013 MakeMKV-Installation \u00fcberspringen --no-handbrake \u2013 HandBrake-Installation \u00fcberspringen --no-nginx \u2013 nginx-Einrichtung \u00fcberspringen --reinstall \u2013 Bestehende Installation aktualisieren (Daten bleiben erhalten) -h, --help \u2013 Hilfe anzeigen"},{"location":"deployment/production/#beispiele","title":"Beispiele","text":"# Standard-Installation\nsudo bash install.sh\n\n# Anderen Branch und Port verwenden\nsudo bash install.sh --branch dev --port 8080\n\n# Ohne MakeMKV (bereits installiert)\nsudo bash install.sh --no-makemkv\n\n# Bestehende Installation aktualisieren\nsudo bash install.sh --reinstall\n\n# Ohne nginx (eigener Reverse-Proxy)\nsudo bash install.sh --no-nginx --host mein-server.local\n"},{"location":"deployment/production/#was-das-skript-erledigt","title":"Was das Skript erledigt","text":"curl, wget, git, mediainfo, udev u. a.--no-makemkv \u00fcbersprungen werden)apt install handbrake-cli)bin/HandBrakeCLIripster \u2013 ohne Login-Shell und ohne Home-Verzeichnis; Gruppen werden (falls vorhanden) erg\u00e4nzt: cdrom, optical, disk, video, render--dir (bei --reinstall: sichert backend/data, aktualisiert Repo, stellt Daten wieder her)backend/data, backend/logs, backend/data/output/raw, backend/data/output/movies, backend/data/logsnpm run build mit relativen API-URLs (nginx-kompatibel).env \u2013 wird automatisch generiert (bei --reinstall bleibt bestehende .env erhalten)ripster:ripster auf Installationsverzeichnis; bei sudo-Aufruf werden Output-/Log-Ordner auf <aufrufender user>:ripster mit 775 gesetzt; .env wird auf 600 gesetzt~/.MakeMKV f\u00fcr den aufrufenden Benutzerripster-backend.service erstellt, aktiviert und gestartet/api/ und /ws (kann mit --no-nginx \u00fcbersprungen werden)# Status pr\u00fcfen\nsudo systemctl status ripster-backend\n\n# Logs verfolgen\nsudo journalctl -u ripster-backend -f\n\n# Neustart\nsudo systemctl restart ripster-backend\n\n# Aktualisieren\nsudo bash /opt/ripster/install.sh --reinstall\n Zugriff: http://<Maschinen-IP> (oder der mit --host angegebene Hostname)
Bei nicht-interaktiver Ausf\u00fchrung (Pipe von curl) wird automatisch die Standard-Version gew\u00e4hlt. F\u00fcr die GPU-Version zuerst herunterladen:
curl -fsSL https://raw.githubusercontent.com/Mboehmlaender/ripster/main/install.sh -o install.sh\nsudo bash install.sh\n# \u2192 Interaktive Auswahl: Option 2 f\u00fcr NVDEC\n Das geb\u00fcndelte Binary liegt unter bin/HandBrakeCLI und wird nach /usr/local/bin/HandBrakeCLI kopiert.
Die folgenden Abschnitte beschreiben die einzelnen Schritte f\u00fcr manuelle oder angepasste Setups.
"},{"location":"deployment/production/#empfohlene-architektur","title":"Empfohlene Architektur","text":"Client\n -> nginx (Reverse Proxy + statisches Frontend)\n -> Backend API/WebSocket (Node.js, Port 3001)\n Wichtig: Das Backend serviert im aktuellen Stand keine frontend/dist-Dateien automatisch.
cd frontend\nnpm install\nnpm run build\n Artefakte liegen in frontend/dist/.
Beispiel /etc/systemd/system/ripster-backend.service:
[Unit]\nDescription=Ripster Backend\nAfter=network.target\n\n[Service]\nType=simple\nUser=ripster\nWorkingDirectory=/opt/ripster/backend\nExecStart=/usr/bin/env node src/index.js\nRestart=on-failure\nRestartSec=5\nEnvironment=NODE_ENV=production\nEnvironment=PORT=3001\nEnvironment=LOG_LEVEL=info\n\n[Install]\nWantedBy=multi-user.target\n Aktivieren:
sudo systemctl daemon-reload\nsudo systemctl enable --now ripster-backend\nsudo systemctl status ripster-backend\n"},{"location":"deployment/production/#3-nginx-konfigurieren","title":"3) nginx konfigurieren","text":"Beispiel /etc/nginx/sites-available/ripster:
server {\n listen 80;\n server_name ripster.local;\n client_max_body_size 8G;\n\n root /opt/ripster/frontend/dist;\n index index.html;\n\n location / {\n try_files $uri $uri/ /index.html;\n }\n\n location /api/ {\n proxy_pass http://127.0.0.1:3001;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n\n location /ws {\n proxy_pass http://127.0.0.1:3001;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n proxy_set_header Host $host;\n }\n}\n Aktivieren:
sudo ln -s /etc/nginx/sites-available/ripster /etc/nginx/sites-enabled/\nsudo nginx -t\nsudo systemctl reload nginx\n Hinweis: Fuer groessere Uploads wie .aax-Audiobooks muss client_max_body_size ausreichend hoch gesetzt sein. Im mitgelieferten Beispiel sind 8G hinterlegt.
sqlite3 /opt/ripster/backend/data/ripster.db \\\n \".backup '/var/backups/ripster-$(date +%Y%m%d).db'\"\n"},{"location":"deployment/production/#sicherheit","title":"Sicherheit","text":".env, Settings-Felder).Dieses Kapitel ist f\u00fcr den Betrieb von Ripster im Alltag geschrieben.
"},{"location":"getting-started/#zielgruppe","title":"Zielgruppe","text":"Nach der Installation erfolgt die t\u00e4gliche Konfiguration fast vollst\u00e4ndig in der GUI unter Settings.
Vor dem ersten echten Job m\u00fcssen Pfade, Tools und Metadatenzugriff sauber gesetzt sein.
"},{"location":"getting-started/configuration/#reihenfolge-empfohlen","title":"Reihenfolge (empfohlen)","text":""},{"location":"getting-started/configuration/#1-settings-tab-konfiguration","title":"1.Settings -> Tab Konfiguration","text":"Setze zuerst diese Pflichtwerte:
Bereich Wichtige Felder PfadeRaw Ausgabeordner, Film Ausgabeordner, Log Ordner Tools MakeMKV Kommando, HandBrake Kommando, Mediainfo Kommando Metadaten OMDb API Key, optional OMDb Typ Danach \u00c4nderungen speichern.
Wenn du Blu-ray und DVD unterschiedlich behandeln willst, pflege die profilbezogenen Felder:
*_bluray*_dvd*_otherTypische Beispiele:
HandBrake Preset (Blu-ray und DVD)Raw Ausgabeordner (Blu-ray und DVD)Dateiname Template (Blu-ray und DVD)Parallele Jobs f\u00fcr den gleichzeitigen DurchsatzHardware Monitoring aktiviert + Hardware Monitoring Intervall (ms) f\u00fcr Live-Metriken im RipperIn den Benachrichtigungsfeldern setzen:
PushOver aktiviertPushOver TokenPushOver UserDann \u00fcber PushOver Test direkt pr\u00fcfen.
Ripper \u00f6ffnenAnalyse startenBereit zum Encodieren laufen lassenWenn diese Schritte funktionieren, ist die Grundkonfiguration korrekt.
"},{"location":"getting-started/configuration/#wenn-werte-nicht-gespeichert-werden","title":"Wenn Werte nicht gespeichert werden","text":"Die empfohlene Installation l\u00e4uft \u00fcber install.sh und richtet Ripster vollst\u00e4ndig ein.
Du musst daf\u00fcr keine Tools manuell vorinstallieren. Das Skript installiert die ben\u00f6tigten Abh\u00e4ngigkeiten automatisch, sofern sie nicht explizit mit --no-* \u00fcbersprungen werden.
debian, ubuntu, linuxmint, poproot (oder via sudo)wget -qO install.sh https://raw.githubusercontent.com/Mboehmlaender/ripster/main/install.sh\n"},{"location":"getting-started/installation/#2-installation-ausfuhren","title":"2. Installation ausf\u00fchren","text":"sudo bash install.sh\n W\u00e4hrend der Installation w\u00e4hlst du den HandBrake-Modus:
1 Standard (Paketinstallation)2 GPU/NVDEC (geb\u00fcndeltes Binary)sudo systemctl status ripster-backend\n"},{"location":"getting-started/installation/#4-weboberflache-offnen","title":"4. Weboberfl\u00e4che \u00f6ffnen","text":"http://<Server-IP>--no-nginx): API auf http://<Server-IP>:3001/apiinstall.sh konkret einrichtet","text":"curl, wget, git, mediainfo, udev ...)ripster an (ohne Login-Shell, ohne Home) und erg\u00e4nzt Gruppen (cdrom, optical, disk, video, render, falls vorhanden)/opt/ripster (oder aktualisiert bei --reinstall)/opt/ripster/backend/data/opt/ripster/backend/logs/opt/ripster/backend/data/output/raw/opt/ripster/backend/data/output/movies/opt/ripster/backend/data/logsbackend/.env (bei --reinstall bleibt bestehende .env erhalten)~/.MakeMKV f\u00fcr den aufrufenden Benutzerripster-backend.service--branch <branch> dev Branch f\u00fcr die Installation --dir <pfad> /opt/ripster Installationsverzeichnis --user <benutzer> ripster Service-Benutzer --port <port> 3001 Backend-Port --host <hostname> automatisch ermittelte Host-IP Hostname/IP f\u00fcr Webzugriff/CORS --no-makemkv aus MakeMKV-Installation \u00fcberspringen --no-handbrake aus HandBrake-Installation \u00fcberspringen --no-nginx aus nginx-Setup \u00fcberspringen --reinstall aus bestehende Installation aktualisieren Beispiele:
sudo bash install.sh --branch dev\nsudo bash install.sh --port 8080 --host ripster.local\nsudo bash install.sh --reinstall\n"},{"location":"getting-started/installation/#betrieb-im-alltag","title":"Betrieb im Alltag","text":"# Logs live ansehen\nsudo journalctl -u ripster-backend -f\n\n# Dienst neu starten\nsudo systemctl restart ripster-backend\n\n# Update aus bestehender Installation\nsudo bash /opt/ripster/install.sh --reinstall\n"},{"location":"getting-started/installation/#haufige-stolperstellen","title":"H\u00e4ufige Stolperstellen","text":"--no-*: Tool nachinstallieren oder Befehl in Settings korrigierenDie Voraussetzungen h\u00e4ngen davon ab, wie du Ripster betreibst.
"},{"location":"getting-started/prerequisites/#produktionsbetrieb-mit-installsh-standard","title":"Produktionsbetrieb mitinstall.sh (Standard)","text":"F\u00fcr den normalen Betrieb sind nur wenige Punkte vorab n\u00f6tig.
"},{"location":"getting-started/prerequisites/#pflicht","title":"Pflicht","text":"root-Rechteinstall.sh installiert die ben\u00f6tigten Tools selbst (u. a. Node.js, MakeMKV, HandBrakeCLI, MediaInfo), sofern sie nicht explizit per --no-* \u00fcbersprungen werden.
ls /dev/sr*\nlsblk | grep rom\n Wenn n\u00f6tig Rechte setzen (Beispiel):
sudo chmod a+rw /dev/sr0\n"},{"location":"getting-started/prerequisites/#optional-vorab","title":"Optional vorab","text":"Settings gesetzt werden)Wenn du lokal entwickelst (./start.sh, npm run dev), gelten zus\u00e4tzliche Voraussetzungen:
makemkvcon, HandBrakeCLI, mediainfo im PATHDetails: Entwicklungsumgebung
"},{"location":"getting-started/prerequisites/#abschluss-checkliste","title":"Abschluss-Checkliste","text":"Dieser Ablauf zeigt einen vollst\u00e4ndigen Job aus Anwendersicht: von Disc-Erkennung bis fertiger Datei.
"},{"location":"getting-started/quickstart/#1-ripper-offnen-und-disc-einlegen","title":"1. Ripper \u00f6ffnen und Disc einlegen","text":"Erwartung:
Medium erkanntDisk-Information sind Laufwerksdaten sichtbarWenn nichts passiert: Laufwerk neu lesen.
Aktion im Ripper:
Analyse startenErwartung:
AnalyseIm Dialog Metadaten ausw\u00e4hlen:
Auswahl \u00fcbernehmenRippen -> Mediainfo-Pruefung -> Bereit zum EncodierenMediainfo-Pruefung -> Bereit zum EncodierenWarte auf Auswahl (Playlist ausw\u00e4hlen und \u00fcbernehmen)Bereit zum Encodieren","text":"Im aufgeklappten Job (Pipeline-Status):
Dann Encoding starten.
W\u00e4hrend Encodieren:
Pipeline-StatusBei Fertig:
Historie \u00f6ffnenHistorie -> OMDb neu zuordnenRAW neu encodierenReview neu startenRipster hat sieben Hauptseiten in der Navigation plus eine Expert-Seite.
"},{"location":"gui/#seitenuberblick","title":"Seiten\u00fcberblick","text":"Seite Zweck Jobs zentrale Inbox mit allen Jobs (Ripper, Converter, Audiobooks) Ripper Live-Betrieb: Pipeline, Queue, Aktivit\u00e4ten, Disc-Infos Audiobooks AAX-Upload, Audiobook-Jobsteuerung und Output-Explorer Settings Konfiguration, Skripte, Ketten, Presets, Cronjobs Historie abgeschlossene/laufende Jobs durchsuchen und nachbearbeiten Converter Audio/Video-Dateien konvertieren, Datei-Explorer, Upload Downloads Ausgabedateien als ZIP herunterladen Database (Expert) tabellarische Rohsicht inkl. Orphan-RAW-Import"},{"location":"gui/#empfohlene-nutzung-im-alltag","title":"Empfohlene Nutzung im Alltag","text":"JobsRipperConverterAudiobooksSettingsHistorieDownloadsDatabaseJobs, Ripper, Converter, Audiobooks, Settings, Historie und Downloads sind direkt in der Kopfnavigation.Database ist als Expert-Route verf\u00fcgbar: /database.Die Seite Audiobooks ist die dedizierte Oberfl\u00e4che f\u00fcr AAX- und Audiobook-Jobs.
Audiobooks UploadAudiobook JobsAudiobook Output ExplorerHier werden AAX-Dateien hochgeladen und als Job vorbereitet.
Typische Schritte:
W\u00e4hrend des Uploads zeigt die Seite Fortschritt und Status an.
"},{"location":"gui/audiobooks/#2-audiobook-jobs","title":"2) Audiobook Jobs","text":"Aktive Audiobook-Jobs werden als Karten dargestellt (mit Status und Fortschritt).
Pro Job sind je nach Zustand Aktionen verf\u00fcgbar:
Zus\u00e4tzlich:
Im Ripper springt in die HauptansichtRead-only Baumansicht des konfigurierten Audiobook-Ausgabeordners:
Audio/Video-Datei-Konvertierung l\u00e4uft weiterhin auf der Seite Converter. Der AAX-spezifische Flow (Upload, Start, Jobsteuerung, Output-Explorer) liegt auf Audiobooks.
Die Converter-Seite erm\u00f6glicht das Konvertieren vorhandener Audio- und Video-Dateien.
"},{"location":"gui/converter/#uberblick","title":"\u00dcberblick","text":"Der Converter arbeitet mit einem konfigurierbaren Eingangsordner (converter_raw_dir). Dateien werden dort abgelegt (manuell oder per Upload) und dann als Converter-Jobs in die Pipeline eingereiht.
Der Datei-Explorer zeigt den Inhalt des converter_raw_dir als Baumstruktur.
Dateien k\u00f6nnen per Checkbox ausgew\u00e4hlt werden. Aus der Auswahl lassen sich Jobs erstellen:
Erlaubte Dateiendungen werden in den Settings unter Converter > Erlaubte Datei-Endungen* als Checkboxen konfiguriert.
Nach der Auswahl und Job-Erstellung erscheinen die Jobs in der Job-Liste.
"},{"location":"gui/converter/#job-konfiguration","title":"Job-Konfiguration","text":"Jeder Job kann konfiguriert werden:
mkv, mp4, m4b, mp3, flacJobs starten sofort oder reihen sich in die Queue ein (abh\u00e4ngig von Parallele Jobs).
Wenn in den Settings Converter > Auto-Scan (Polling) aktiviert ist, wird der Eingangsordner automatisch in regelm\u00e4\u00dfigen Abst\u00e4nden gescannt. Neue Dateien werden in der DB erfasst und im Explorer angezeigt.
Das Scan-Intervall wird unter Converter > Polling-Intervall (Sekunden) konfiguriert (Standard: 300 Sekunden).
Der dedizierte AAX-/Audiobook-Flow ist auf der Seite Audiobooks dokumentiert.
"},{"location":"gui/converter/#einstellungen","title":"Einstellungen","text":"Setting Pfad in GUI EingangsordnerSettings > Pfade > Converter Raw-Ordner Videoausgabe Settings > Pfade > Converter Ausgabe (Video) Audioausgabe Settings > Pfade > Converter Ausgabe (Audio) Erlaubte Endungen Settings > Converter > Erlaubte Datei-Endungen* Auto-Scan Settings > Converter > Auto-Scan (Polling) Scan-Intervall Settings > Converter > Polling-Intervall (Sekunden) Output-Template Video Settings > Pfade > Output-Template (Video) Output-Template Audio Settings > Pfade > Output-Template (Audio)"},{"location":"gui/database/","title":"Database (Expert)","text":"/database ist eine erweiterte Ansicht f\u00fcr Power-User und Recovery-F\u00e4lle.
/databaseGefundene RAW-Eintr\u00e4ge","text":"Listet RAW-Ordner, die keinen zugeh\u00f6rigen Job-Eintrag haben.
Aktionen:
RAW pr\u00fcfen (Scan der konfigurierten RAW-Pfade)Job anlegen (Orphan-RAW in Historie importieren)Diese Seite erlaubt Eingriffe mit direkter Auswirkung auf Datenbestand und Historie. Vor L\u00f6sch- oder Importaktionen Pfade und Zieljob sorgf\u00e4ltig pr\u00fcfen.
"},{"location":"gui/downloads/","title":"Downloads","text":"Die Downloads-Seite erm\u00f6glicht es, Ausgabedateien aus abgeschlossenen Jobs als ZIP-Archiv herunterzuladen.
"},{"location":"gui/downloads/#uberblick","title":"\u00dcberblick","text":"Jobs, die in der Historie abgeschlossen sind, k\u00f6nnen in die Download-Queue eingereiht werden. Ripster erstellt daraus ein ZIP-Archiv, das direkt im Browser heruntergeladen werden kann.
"},{"location":"gui/downloads/#download-queue","title":"Download-Queue","text":"Die Queue zeigt alle aktuellen Download-Eintr\u00e4ge mit ihrem Status:
Status Beschreibung Ausstehend In der Queue, ZIP-Erstellung noch nicht gestartet Wird verarbeitet ZIP-Archiv wird gerade erstellt Bereit ZIP fertig, Download-Button verf\u00fcgbar Fehlgeschlagen Fehler bei der ZIP-Erstellung"},{"location":"gui/downloads/#download-einreihen","title":"Download einreihen","text":"Downloads k\u00f6nnen \u00fcber die Historie eingereiht werden:
RAW-Dateien oder AusgabedateienSobald der Status Bereit angezeigt wird, kann die ZIP-Datei mit dem Download-Button heruntergeladen werden.
ZIP-Dateinamen folgen dem Muster: Job_<id>_<target>.zip
Abgeschlossene oder fehlerhafte Eintr\u00e4ge k\u00f6nnen einzeln gel\u00f6scht werden. Die dazugeh\u00f6rige ZIP-Datei wird dabei ebenfalls vom Server entfernt.
"},{"location":"gui/downloads/#echtzeit-updates","title":"Echtzeit-Updates","text":"Die Downloads-Seite aktualisiert sich automatisch per WebSocket (DOWNLOADS_UPDATED). Status\u00e4nderungen (z. B. von Wird verarbeitet zu Bereit) werden ohne Seiten-Reload angezeigt.
Die Seite Historie ist f\u00fcr Suche, Pr\u00fcfung und Nachbearbeitung bestehender Jobs.
Filter und Werkzeuge:
Blu-ray, DVD, Sonstiges)Jeder Eintrag zeigt:
Klick auf einen Eintrag \u00f6ffnet die Detailansicht.
"},{"location":"gui/history/#job-detaildialog","title":"Job-Detaildialog","text":"Bereiche:
Tail, Vollst\u00e4ndig)Bei Serien-Containern zeigt der Dialog statt eines globalen Log-Blocks einen Disks-Bereich mit einzelnen Disk-Akkordeons. Jede Disk kann dort separat gepr\u00fcft und bearbeitet werden.
OMDb neu zuordnenEncode neu startenReview neu startenRAW neu encodierenRAW l\u00f6schen, Movie l\u00f6schen, Beides l\u00f6schenHistorieneintrag l\u00f6schenAus Queue l\u00f6schenZus\u00e4tzlich bei Serien-Container-Disks:
Im Ripper \u00f6ffnen (f\u00fcr READY_TO_ENCODE-Kinder)RAW, Folgen, Beides) mit Child-/Subjob-ScopeOMDb neu zuordnen mit gleicher best\u00e4tigter Auswahl neu encodieren Encode neu starten Titel-/Spurpr\u00fcfung komplett neu berechnen Review neu starten aus vorhandenem RAW erneut encodieren RAW neu encodieren Speicher freigeben Dateil\u00f6schaktionen"},{"location":"gui/history/#loschen-mit-vorschau","title":"L\u00f6schen mit Vorschau","text":"Beim L\u00f6schen eines Historieneintrags (Eintrag l\u00f6schen) gibt es eine Pfadvorschau:
RAW und Ausgabe (Movie/Folgen)Neu im RAW-Bereich:
Die Buttons (Eintrag + nur RAW, Eintrag + nur ..., Eintrag + RAW + ...) ber\u00fccksichtigen die aktuelle Pfadauswahl und deaktivieren sich bei unvollst\u00e4ndiger Auswahl.
Tail laden (800) f\u00fcr schnelle FehleranalyseVollst\u00e4ndiges Log laden f\u00fcr vollst\u00e4ndige NachverfolgungDie Seite Jobs ist die zentrale Inbox \u00fcber alle Job-Typen.
Jobs zeigt denselben Datenbestand in einer einheitlichen Liste:
Die Seite eignet sich als schneller Einstieg, bevor man in den jeweiligen Fachbereich springt.
"},{"location":"gui/jobs/#filter-und-ansicht","title":"Filter und Ansicht","text":""},{"location":"gui/jobs/#view-filter","title":"View-Filter","text":"Alle JobsRipper-ViewConverter-ViewAudiobooksAlleAktivFehler/AbbruchZus\u00e4tzlich gibt es eine Freitextsuche (Titel, Status, IMDb, Job-Kind etc.) und eine Paginierung.
"},{"location":"gui/jobs/#was-ein-eintrag-zeigt","title":"Was ein Eintrag zeigt","text":"Die Liste aktualisiert sich zyklisch automatisch.
"},{"location":"gui/jobs/#aktion","title":"Aktion","text":"Pro Eintrag gibt es einen Schnellzugriff:
Im Ripper \u00f6ffnen f\u00fcr Disc-/Audiobook-orientierte JobsIm Converter \u00f6ffnen f\u00fcr Converter-JobsSo gelangst du mit einem Klick in die passende Detailoberfl\u00e4che.
"},{"location":"gui/ripper/","title":"Ripper","text":"Das Ripper ist die Betriebszentrale f\u00fcr laufende Jobs.
"},{"location":"gui/ripper/#aufbau-der-seite","title":"Aufbau der Seite","text":"Die Bereiche erscheinen in dieser Reihenfolge:
Hardware MonitoringJob QueueSkript- / Cron-StatusJob \u00dcbersichtDisk-InformationZeigt live:
Wichtig f\u00fcr den Betrieb:
Settings aktivierbar/deaktivierbar (Hardware Monitoring aktiviert)Zwei Spalten:
Laufende JobsWarteschlangeM\u00f6gliche Aktionen:
X)+):Hinweis:
Parallel zeigt den Wert aus Settings -> Parallele Jobs.Zeigt:
M\u00f6gliche Aktionen:
N\u00e4chster SchrittAbbrechenListe leerenKompakte Jobliste mit Status, Fortschritt, ETA. Klick auf einen Job klappt die Detailsteuerung auf.
Zus\u00e4tzliche Kennzeichnungen in der Liste:
Serien-Container/Serien-Disk f\u00fcr Staffel-WorkflowsMultipart Movie bei zusammengef\u00fchrten Film-DiscsDisc 2 | Container #123)Im aufgeklappten Zustand erscheint die Karte Pipeline-Status mit allen zustandsabh\u00e4ngigen Aktionen.
Medium erkannt / Bereit Analyse starten Metadatenauswahl Metadaten \u00f6ffnen Warte auf Auswahl Playlist w\u00e4hlen und Playlist \u00fcbernehmen Startbereit Job starten Bereit zum Encodieren Tracks/Skripte pr\u00fcfen, dann Encoding starten laufend (Analyse/Rippen/Encodieren) Abbrechen Fehler / Abgebrochen Retry Rippen, Disk-Analyse neu starten Zus\u00e4tzlich je nach Job:
Review neu startenEncode neu startenAus Queue l\u00f6schenBereit zum Encodieren)","text":"Im selben Block siehst du:
Zeigt aktuelles Laufwerk und Disc-Metadaten (Pfad, Modell, Disc-Label, Mount).
Aktionen:
Laufwerk neu lesenDisk neu analysierenMetadaten-Modal \u00f6ffnenHinweis:
Laufwerk neu lesen ist nicht mehr an einen festen Pipeline-State gebunden und kann genutzt werden, solange kein Rescan-Request l\u00e4uft.Auswahl \u00fcbernehmen startet den n\u00e4chsten Pipeline-SchrittBei Film-Duplikaten in der Historie \u00f6ffnet sich ein Konfliktdialog:
\u00dcbernahme erzwingen: legt trotzdem einen neuen Job mit denselben Metadaten anMultipart movie: verkn\u00fcpft bestehenden und neuen Job in einem Multipart-Container (mit separaten Disc-Nummern)Zur\u00fcck zur Auswahl: zur\u00fcck in die MetadatenlisteNach Abbruch kann Ripster optional fragen, ob erzeugte RAW- oder Movie-Dateien gel\u00f6scht werden sollen.
"},{"location":"gui/ripper/#queue-eintrag-einfugen","title":"Queue-Eintrag einf\u00fcgen","text":"Erstellt gezielt einen Skript-, Ketten- oder Warte-Eintrag an einer bestimmten Queue-Position.
"},{"location":"gui/settings/","title":"Settings","text":"Die Seite Settings steuert Konfiguration und Automatisierung.
Konfiguration alle Kernsettings (Pfade, Tools, Monitoring, Metadaten, Queue, Benachrichtigungen) Scripte einzelne Bash-Skripte verwalten und testen Skriptketten Sequenzen aus Skript- und Warte-Schritten bauen Encode-Presets benutzerdefinierte Presets f\u00fcr das Review im Ripper Cronjobs zeitgesteuerte Skript-/Kettenausf\u00fchrung"},{"location":"gui/settings/#tab-konfiguration","title":"Tab Konfiguration","text":"Wichtiges Bedienmuster:
\u00c4nderungen speichern\u00c4nderungen verwerfen oder Neu ladenZus\u00e4tzlich:
PushOver Test sendet eine TestnachrichtScripte","text":"Funktionen:
Test)Praxis:
Skriptketten","text":"Funktionen:
Im Ketten-Editor:
Warten, vorhandene Skripte)Encode-Presets","text":"Ein Preset b\u00fcndelt:
-Z)Universell, Blu-ray, DVD, Sonstiges)Verwendung:
Bereit zum Encodieren).Cronjobs","text":"Funktionen:
Jetzt ausf\u00fchrenAktiviert und Pushover toggelnHilfen:
crontab.guru im EditorKonfiguration sauber setzenDieser Abschnitt beschreibt die technische Pipeline-Logik hinter den UI-Workflows.
Workflow & Zust\u00e4nde
Zustandsmodell, \u00dcberg\u00e4nge, Queue-Verhalten.
Workflow
Encode-Planung
Aufbereitung von Titeln/Tracks und Best\u00e4tigungslogik.
Encoding
Playlist-Analyse
Bewertung mehrdeutiger Blu-ray-Playlists.
Playlist-Analyse
Pre-/Post-Encode-Ausf\u00fchrungen
Skript- und Kettenlauf vor/nach dem Encoding.
Encode-Skripte
Vor dem eigentlichen Encoding erstellt Ripster einen Encode-Plan und zeigt ihn im Review an.
"},{"location":"pipeline/encoding/#ablauf","title":"Ablauf","text":"Quelle bestimmen (Disc/RAW)\n -> HandBrake-Scan (--scan --json)\n -> Plan erstellen (Titel, Audio, Untertitel)\n -> Status: Bereit zum Encodieren\n -> Benutzer bestaetigt Auswahl\n -> finaler HandBrake-Aufruf\n"},{"location":"pipeline/encoding/#review-inhalt-status-bereit-zum-encodieren","title":"Review-Inhalt (Status: Bereit zum Encodieren)","text":"burnInforceddefaultTrackconfirm-encode)","text":"Typischer Payload:
{\n \"selectedEncodeTitleId\": 1,\n \"selectedTrackSelection\": {\n \"1\": {\n \"audioTrackIds\": [1, 2],\n \"subtitleTrackIds\": [3]\n }\n },\n \"selectedPreEncodeScriptIds\": [1],\n \"selectedPostEncodeScriptIds\": [2],\n \"selectedPreEncodeChainIds\": [3],\n \"selectedPostEncodeChainIds\": [4],\n \"selectedUserPresetId\": 5\n}\n Die best\u00e4tigte Auswahl wird im Job gespeichert und f\u00fcr Neustarts wiederverwendet.
"},{"location":"pipeline/encoding/#handbrake-aufruf","title":"HandBrake-Aufruf","text":"Grundstruktur:
HandBrakeCLI \\\n -i <input> \\\n -o <output> \\\n -t <titleId> \\\n -Z \"<preset>\" \\\n <extra-args> \\\n -a <audioTrackIds|none> \\\n -s <subtitleTrackIds|none>\n Untertitel-Flags werden bei Bedarf erg\u00e4nzt:
--subtitle-burned=<id>--subtitle-default=<id>--subtitle-forced=<id> oder --subtitle-forcedFehlerverhalten:
Fehler (Encode startet nicht)Fertig bleiben, enth\u00e4lt aber Fehlerhinweis/Script-SummaryDer finale Outputpfad wird aus den Templates in den Settings aufgebaut.
Platzhalter:
${title}${year}${imdbId}Ung\u00fcltige Dateizeichen werden bereinigt.
"},{"location":"pipeline/playlist-analysis/","title":"Playlist-Analyse","text":"Ripster analysiert bei Blu-ray-\u00e4hnlichen Quellen Playlists und fordert bei Mehrdeutigkeit eine manuelle Auswahl an.
"},{"location":"pipeline/playlist-analysis/#ziel","title":"Ziel","text":"Erkennen, welche Playlist sehr wahrscheinlich der Hauptfilm ist, statt versehentlich eine Fake-/Dummy-Playlist zu verwenden.
"},{"location":"pipeline/playlist-analysis/#eingabedaten","title":"Eingabedaten","text":"Die Analyse basiert auf MakeMKV-Infos (u. a. Playlist-/Segment-Struktur, Laufzeiten, Titelzuordnung).
"},{"location":"pipeline/playlist-analysis/#auswertung-vereinfacht","title":"Auswertung (vereinfacht)","text":"F\u00fcr Kandidaten werden u. a. ber\u00fccksichtigt:
Daraus entstehen intern Kandidatenlisten, Bewertungen und eine Empfehlung.
"},{"location":"pipeline/playlist-analysis/#wann-muss-der-benutzer-entscheiden","title":"Wann muss der Benutzer entscheiden?","text":"Wenn nach Filterung mehr als ein relevanter Kandidat \u00fcbrig bleibt, wechselt der Job in der GUI auf:
Warte auf AuswahlDann muss eine Playlist best\u00e4tigt werden, bevor der Workflow weiterl\u00e4uft.
"},{"location":"pipeline/playlist-analysis/#konfigurationseinfluss","title":"Konfigurationseinfluss","text":"Feld inSettings Wirkung Minimale Titellaenge (Minuten) Mindestlaufzeit f\u00fcr Kandidaten Default ist aktuell 60 Minuten.
Bei manueller Entscheidung zeigt das Ripper Kandidaten inkl. Score/Bewertung und markiert eine Empfehlung.
Nach Best\u00e4tigung:
Mediainfo-PruefungStartbereit / RippenRipster kann Skripte und Skript-Ketten vor und nach dem Encode ausf\u00fchren.
"},{"location":"pipeline/post-encode-scripts/#ablauf","title":"Ablauf","text":"Bereit zum Encodieren\n -> Pre-Encode Skripte/Ketten\n -> HandBrake Encoding\n -> Post-Encode Skripte/Ketten\n -> Fertig oder Fehler\n"},{"location":"pipeline/post-encode-scripts/#auswahl-im-review","title":"Auswahl im Review","text":"Im Review-Panel kannst du getrennt w\u00e4hlen:
selectedPreEncodeScriptIdsselectedPostEncodeScriptIdsselectedPreEncodeChainIdsselectedPostEncodeChainIdsFehler.Fertig sein (mit Fehlerzusatz im Status/Log).Beim Script-Run werden gesetzt:
RIPSTER_SCRIPT_RUN_ATRIPSTER_JOB_IDRIPSTER_JOB_TITLERIPSTER_MODERIPSTER_INPUT_PATHRIPSTER_OUTPUT_PATHRIPSTER_RAW_PATHRIPSTER_SCRIPT_IDRIPSTER_SCRIPT_NAMERIPSTER_SCRIPT_SOURCEKetten unterst\u00fctzen zwei Step-Typen:
script (f\u00fchrt ein hinterlegtes Skript aus)wait (wartet waitSeconds)Bei Fehler in einem Script-Step wird die Kette abgebrochen.
"},{"location":"pipeline/post-encode-scripts/#testlaufe","title":"Testl\u00e4ufe","text":"POST /api/settings/scripts/:id/testPOST /api/settings/script-chains/:id/testErgebnisse enthalten Erfolg/Exit-Code, Laufzeit und stdout/stderr.
"},{"location":"pipeline/workflow/","title":"Workflow & Zust\u00e4nde","text":"Ripster steuert den Ablauf als Zustandsmaschine.
"},{"location":"pipeline/workflow/#zustandsdiagramm-vereinfacht","title":"Zustandsdiagramm (vereinfacht)","text":"flowchart LR\n A[Bereit] --> B[Medium erkannt]\n B --> C[Analyse]\n C --> D[Metadatenauswahl]\n D --> E[Startbereit]\n E --> F[Rippen]\n E --> G[Mediainfo-Pruefung]\n G --> H[Warte auf Auswahl]\n H --> G\n G --> I[Bereit zum Encodieren]\n I --> J[Encodieren]\n J --> K[Fertig]\n J --> L[Fehler]\n F --> L\n F --> M[Abgebrochen]"},{"location":"pipeline/workflow/#statusliste-gui-anzeige","title":"Statusliste (GUI-Anzeige)","text":"Status in der GUI Bedeutung Bereit Wartet auf Disc Medium erkannt Disc wurde erkannt Analyse MakeMKV-Analyse l\u00e4uft Metadatenauswahl Metadaten m\u00fcssen best\u00e4tigt werden Warte auf Auswahl Playlist-Auswahl ist erforderlich Warte auf Auswahl auch f\u00fcr RAW-Entscheidung bei vorhandenen Quelldaten genutzt Startbereit kurzer \u00dcbergang vor Start Rippen MakeMKV-Rip l\u00e4uft Mediainfo-Pruefung Titel/Spuren werden ausgewertet Bereit zum Encodieren Review ist bereit Encodieren HandBrake l\u00e4uft CD-Metadatenauswahl CD-Metadaten m\u00fcssen best\u00e4tigt werden CD-Startbereit CD-Job wartet auf Start CD-Analyse CD-Track-/Strukturaufbereitung CD-Rippen Audio-CD-Rip l\u00e4uft CD-Encodieren CD-Encode l\u00e4uft Fertig erfolgreich abgeschlossen Abgebrochen manuell oder technisch abgebrochen Fehler fehlgeschlagen"},{"location":"pipeline/workflow/#typische-pfade","title":"Typische Pfade","text":""},{"location":"pipeline/workflow/#standardfall-kein-vorhandenes-raw","title":"Standardfall (kein vorhandenes RAW)","text":"Startbereit springt direkt zu Mediainfo-Pruefung (kein neuer Rip).
Mediainfo-Pruefung -> Warte auf Auswahl bis Playlist best\u00e4tigt wurde.
Metadatenauswahl -> Warte auf Auswahl bis Entscheidung f\u00fcr Weiterverarbeitung (continue) oder Neustart getroffen wurde.
CD-Metadatenauswahl -> CD-Startbereit -> CD-Rippen -> CD-Encodieren -> Fertig
Wenn der Wert Parallele Jobs erreicht ist:
Skript, Kette, Warten)Abbrechen: laufenden Job stoppen oder Queue-Eintrag entfernenRetry Rippen: Fehler-/Abbruch-Job erneut startenRAW neu encodieren: aus vorhandenem RAW neu encodierenReview neu starten: Review aus RAW neu aufbauenEncode neu starten: Encoding mit letzter best\u00e4tigter Auswahl neu startenRipster orchestriert externe CLI-Tools. Dieser Abschnitt erkl\u00e4rt deren Rolle im Gesamtsystem.
MakeMKV
Disc-Analyse und Ripping.
MakeMKV
HandBrake
Video-Encoding inklusive Preset-Logik.
HandBrake
MediaInfo
Track-/Containeranalyse f\u00fcr Review und Auswahl.
MediaInfo
Ripster verwendet HandBrakeCLI f\u00fcr Scan und Encode.
HandBrakeCLI --scan --json -i <input> -t 0\n"},{"location":"tools/handbrake/#encode-vereinfacht","title":"Encode (vereinfacht)","text":"HandBrakeCLI \\\n -i <input> \\\n -o <output> \\\n -t <titleId> \\\n -Z \"<preset>\" \\\n <extra-args> \\\n -a <audioTrackIds|none> \\\n -s <subtitleTrackIds|none>\n Optional erg\u00e4nzt Ripster:
--subtitle-burned=<id>--subtitle-default=<id>--subtitle-forced=<id> oder --subtitle-forcedRipster liest Presets mit:
HandBrakeCLI -z\n"},{"location":"tools/handbrake/#relevante-felder-in-settings","title":"Relevante Felder in Settings","text":"Feldname in der GUI Bedeutung HandBrake Kommando CLI-Binary HandBrake Preset (Blu-ray/DVD) profilspezifisches Preset HandBrake Extra Args (Blu-ray/DVD) profilspezifische Zusatzargumente Ausgabeformat (Blu-ray/DVD) Dateiendung der finalen Datei Encode-Neustart: unvollst\u00e4ndige Ausgabe l\u00f6schen unvollst\u00e4ndige Ausgabe bei Neustart l\u00f6schen"},{"location":"tools/handbrake/#fortschritts-parsing","title":"Fortschritts-Parsing","text":"Ripster parst HandBrake-Stderr (Prozent/ETA/Detail) und sendet WebSocket-Progress (PIPELINE_PROGRESS).
HandBrakeCLI -z pr\u00fcfen--encoder-preset)Das Produktions-Installer-Script install.sh bietet eine Option zur Installation eines geb\u00fcndelten HandBrakeCLI-Binaries mit NVDEC-Unterst\u00fctzung (NVIDIA GPU-Dekodierung). Diese Option erscheint interaktiv w\u00e4hrend der Installation.
Ripster nutzt makemkvcon f\u00fcr Disc-Analyse und Rip.
makemkvcon -r info <source>\n <source> ist typischerweise:
disc:<index> (Auto-Modus)dev:/dev/sr0 (explicit)file:<path> (Datei/Ordner-Analyse)makemkvcon mkv <source> <title-or-all> <rawDir> [--minlength=...] [...extraArgs]\n"},{"location":"tools/makemkv/#rip-backup-modus","title":"Rip (Backup-Modus)","text":"makemkvcon backup <source> <rawDir> --decrypt\n"},{"location":"tools/makemkv/#registrierungsschlussel-optional","title":"Registrierungsschl\u00fcssel (optional)","text":"Wenn in Settings ein MakeMKV Key gesetzt ist, f\u00fchrt Ripster vor Analyse/Rip aus:
makemkvcon reg <key>\n"},{"location":"tools/makemkv/#relevante-felder-in-settings","title":"Relevante Felder in Settings","text":"Feldname in der GUI Bedeutung MakeMKV Kommando CLI-Binary MakeMKV Source Index Source-Index im Auto-Modus Minimale Titellaenge (Minuten) Mindestlaufzeitfilter MakeMKV Rip Modus (Blu-ray/DVD) mkv oder backup MakeMKV Analyze Extra Args (Blu-ray/DVD) Zusatzargumente f\u00fcr Analyse MakeMKV Rip Extra Args (Blu-ray/DVD) Zusatzargumente f\u00fcr Rip"},{"location":"tools/makemkv/#hinweise","title":"Hinweise","text":"makemkvInfo im Job gespeichert.Ripster nutzt mediainfo zur JSON-Analyse von Medien-Dateien.
mediainfo --Output=JSON <input>\n Der Input ist typischerweise eine RAW-Datei oder ein vom Workflow gew\u00e4hlter Inputpfad.
"},{"location":"tools/mediainfo/#verwendung-in-ripster","title":"Verwendung in Ripster","text":"mediainfoInfo im Jobmediainfo_command CLI-Binary mediainfo_extra_args_bluray / _dvd profilspezifische Zusatzargumente"},{"location":"tools/mediainfo/#troubleshooting","title":"Troubleshooting","text":"mediainfo --Output=JSON <datei>und (undetermined)Diese Seite beschreibt typische Abl\u00e4ufe mit den passenden UI-Aktionen.
"},{"location":"workflows/#workflow-1-standardlauf-disc-fertige-datei","title":"Workflow 1: Standardlauf (Disc -> fertige Datei)","text":"Ripper: Disc einlegen, Analyse startenBereit zum Encodieren Titel/Tracks pr\u00fcfenEncoding startenHistorie kontrollierenWarte auf AuswahlPipeline-Status Playlist-Kandidaten vergleichenPlaylist \u00fcbernehmenBereit zum EncodierenSettings \u00fcber Parallele Jobs setzenJob QueueIn Historie -> Detaildialog:
OMDb neu zuordnenEncode neu startenReview neu startenRAW neu encodierenSettings -> Scripte: Skripte anlegen und testenSettings -> Skriptketten: Ketten bauen und testenSettings -> Cronjobs: zeitgesteuerte Ausf\u00fchrung konfigurierenSkript- / Cron-Status) \u00fcberwachenRetry Rippen oder Disk-Analyse neu startenBereit zum Encodieren, ist aber nicht aktive Session","text":"Historie: Im Ripper \u00f6ffnen/database \u00f6ffnenGefundene RAW-Eintr\u00e4geJob anlegenRipper -> Metadaten ausw\u00e4hlen f\u00fcr einen Film-JobMultipart movie w\u00e4hlenHistorie den gemeinsamen Multipart-Container pr\u00fcfenHistorie einen Job \u00f6ffnen und Historieneintrag l\u00f6schenRAW + Ausgabe)Eintrag + nur RAW, Eintrag + nur ..., Eintrag + RAW + ...)Audiobooks \u00f6ffnenAudiobook Output Explorer und in der Historie pr\u00fcfen