fix(worker): Hardware-Encoder und CPU-Merkmale auf Windows - plus ehrliche Transcode-Fehler
Aus dem gescheiterten Test-Rip des Commanders (Job 95afdc89) und seiner
UI-Durchsicht. Der Reihe nach.
## 1. Der externe Encoder wurde SEHR WOHL gesehen (Diagnose-Korrektur)
Der Commander schloss aus der Meldung, das System sehe seinen PC nicht. Live
gemessen sagt das Gegenteil:
meta.transcode_node = tobisnicerpc@TobisNicerPC
VM-Worker-Log = nur rip_disc, KEIN transcode_files
22:19:41.271 Kompression eingereiht
22:19:41.453 "Keine Roh-MKVs gefunden" <- 182 ms spaeter
Das Routing hat funktioniert. Sein PC nahm die Aufgabe an und lehnte sie sofort
ab, weil er /app/media/rippy/<job> nicht finden kann - ein Pfad, der nur INNEN
im Container existiert. Der Rip war vollstaendig (79,6 GB auf der NAS).
## 2. Der Hardware-Encoder-Bug war meiner
leite_backends_ab() verlangte zusaetzlich ein Geraet: /dev/dri fuer
VAAPI/QSV/VCE bzw. nvidia-smi fuer NVENC. Unter WINDOWS gibt es beides nicht -
der PC des Commanders (RX 9070 XT) meldete deshalb nur CPU-Encoder, obwohl
HandBrakes Windows-Build vce_*/nvenc_*/qsv_* beherrscht. Der Bug traf genau den
Anwendungsfall, fuer den externe Worker gedacht sind.
Die Pruefung war ausserdem ueberfluessig: HandBrake probiert Hardware beim
Start selbst an und listet nur Nutzbares - auf der VM belegt durch
"qsv: not available on this system" bei gleichzeitig fehlendem qsv_* in --help.
Jetzt ist HandBrakes Liste die einzige Auskunft.
Dazu nach FAMILIE unterschieden (nvenc/qsv/vce/vaapi) statt alles in "vaapi" zu
werfen - eine AMD-Karte lief unter dem Intel-Namen. Hardware-AV1 bekommt eine
eigene Kennung, weil es die beste Kombination aus Tempo und Groesse ist und
sonst unsichtbar bliebe.
## 3. Vektorbefehle unter Windows - gemessen, nicht "unbekannt"
Es gibt dort kein /proc/cpuinfo, also meldete der Windows-Worker
"Vektorbefehle unbekannt" - gerade auf der Maschine, die encodieren soll.
Jetzt ueber IsProcessorFeaturePresent (kernel32, winnt.h dokumentiert) plus
CPU-Name aus der Registry. Auf dem Commander-PC gegengeprueft:
vorher: AMD64 Family 26 Model 68 Stepping 0 / Vektorbefehle unbekannt
jetzt: AMD Ryzen 7 9700X 8-Core Processor / avx512f / 16 Kerne
Damit verschwindet die AVX2-Warnung fuer diesen Worker von selbst - genau das
hatte der Commander gefordert.
## 4. Ehrliche Fehlermeldung statt "Keine Roh-MKVs gefunden"
Neues _erreichbarkeit_pruefen() unterscheidet jetzt drei Faelle statt einem:
Pfad nicht erreichbar UND kein Mapping gesetzt (nennt RIPPY_PATH_MAP samt
Beispiel), Mapping gesetzt aber greift nicht, oder Pfad einfach nicht da. Und
es prueft BEIDE Pfade - im Fall des Commanders lag die Quelle auf der
erreichbaren NAS, das ZIEL aber auf der VM-Platte ohne Samba; das waere erst
beim Schreiben nach Stunden Rechenzeit aufgefallen.
Jede Meldung sagt jetzt ausdruecklich, dass die Rohdaten NICHT verloren sind
und "Neu komprimieren" genuegt.
## 5. Persoenliche Werte raus
Vier Platzhalter trugen die Umgebung des Commanders (192.168.178.20,
TOBIS-PC, seine Jellyfin- und Rippy-IP). In einem Repo, das weitergegeben
wird, hat das nichts verloren.
Nebenbei dreimal in die eigene Falle getappt: deutsche Anfuehrungszeichen in
DOPPELT gequoteten Python-Strings beenden den String vorzeitig. Der Bestand
nutzt dafuer einfach gequotete f-Strings - jetzt auch meine.
NOCH OFFEN und wichtig: RIPPY_PATH_MAP wird von niemandem GESETZT (Installer,
UI, Compose). Ein Windows-Worker kann damit grundsaetzlich nicht transcodieren.
Das ist der naechste Schritt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -378,7 +378,7 @@ export default function StorageMounts() {
|
||||
label="Rechner (dein PC oder NAS — Name oder IP)"
|
||||
value={host}
|
||||
onChange={e => setHost(e.target.value)}
|
||||
placeholder="192.168.178.20 oder TOBIS-PC"
|
||||
placeholder="z. B. 192.168.1.20 oder MEIN-NAS"
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
|
||||
@@ -204,7 +204,7 @@ export default function WorkerVerwaltung() {
|
||||
label="LAN-IP der Rippy-Maschine (Docker-Host)"
|
||||
value={rippyHost}
|
||||
onChange={e => setRippyHost(e.target.value.trim())}
|
||||
placeholder="z. B. 192.168.178.162"
|
||||
placeholder="z. B. 192.168.1.10"
|
||||
/>
|
||||
<p className="text-xs mt-2 text-slate-500 dark:text-slate-400">
|
||||
Die IP der Maschine, auf der <strong>Rippy selbst</strong> (Docker) läuft — meist deine
|
||||
@@ -216,7 +216,8 @@ export default function WorkerVerwaltung() {
|
||||
{siehtOeffentlichAus && (
|
||||
<p className="text-xs mt-2 p-3 rounded-xl bg-amber-500/10 border border-amber-500/20 text-amber-700 dark:text-amber-300">
|
||||
⚠️ Das sieht nach einer externen Domain aus (Reverse-Proxy) — die geht nicht. Bitte die
|
||||
<strong> LAN-IP</strong> der Rippy-Maschine eintragen, z. B. 192.168.178.162.
|
||||
<strong> LAN-IP</strong> der Rippy-Maschine eintragen — die beginnt im Heimnetz
|
||||
fast immer mit 192.168., 10. oder 172.16.–172.31.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -77,10 +77,20 @@ export const LOG_LEVEL_STYLES = {
|
||||
},
|
||||
} as const
|
||||
|
||||
// Encoder-Backends, wie worker/caps.py sie meldet. Hardware wird seit
|
||||
// 25.07.2026 nach FAMILIE unterschieden (nvenc/qsv/vce/vaapi) — vorher landete
|
||||
// eine AMD-Karte unter dem Intel-Namen „vaapi", und AV1 in Hardware war gar
|
||||
// nicht sichtbar, obwohl es die beste Kombination aus Tempo und Größe ist.
|
||||
export const ENCODER_BADGES: Record<string, { label: string; highlight: boolean }> = {
|
||||
'cpu-x264': { label: 'H.264 (CPU)', highlight: false },
|
||||
'cpu-x265': { label: 'H.265 (CPU)', highlight: false },
|
||||
'cpu-av1': { label: 'AV1 (CPU)', highlight: false },
|
||||
'nvenc': { label: 'NVENC ⚡ (NVIDIA)', highlight: true },
|
||||
'nvenc-av1': { label: 'AV1 · NVENC ⚡', highlight: true },
|
||||
'qsv': { label: 'QuickSync ⚡ (Intel)', highlight: true },
|
||||
'qsv-av1': { label: 'AV1 · QuickSync ⚡', highlight: true },
|
||||
'vce': { label: 'VCE ⚡ (AMD)', highlight: true },
|
||||
'vce-av1': { label: 'AV1 · VCE ⚡', highlight: true },
|
||||
'vaapi': { label: 'VAAPI ⚡', highlight: true },
|
||||
'nvenc': { label: 'NVENC ⚡', highlight: true },
|
||||
'vaapi-av1': { label: 'AV1 · VAAPI ⚡', highlight: true },
|
||||
}
|
||||
|
||||
@@ -498,7 +498,7 @@ export default function SettingsPage() {
|
||||
label="Server-URL"
|
||||
value={settings.jellyfinUrl}
|
||||
onChange={(e) => handleChange('jellyfinUrl', e.target.value)}
|
||||
placeholder="http://192.168.178.50:8096"
|
||||
placeholder="z. B. http://192.168.1.50:8096"
|
||||
/>
|
||||
<div className="flex gap-2 items-end">
|
||||
<div className="flex-1">
|
||||
|
||||
Reference in New Issue
Block a user