fix(caps,ui): Encoder werden gemessen statt behauptet
Der Modulkopf von caps.py verspricht "ehrlich erkannt, nicht behauptet" -
erkenne_encoder() tat aber drei Mal das Gegenteil:
1. cpu-x264 und cpu-x265 standen fest verdrahtet in der Liste ("immer
dabei"). Ein Rip-Worker OHNE HandBrake behauptete damit, komprimieren zu
koennen; jeder Transcode dort endete sofort mit "nicht installiert".
2. 'vaapi' wurde allein wegen /dev/dri gemeldet, ohne zu pruefen, ob
HandBrake das ueberhaupt kann. Auf der VM gemessen: das Worker-Image
kennt svt_av1/x264/x265/mpeg4/mpeg2/VP8/VP9/theora und KEINEN einzigen
Hardware-Encoder. Rippy haette VAAPI versprochen und dann versagt.
3. Ueber die Rechenleistung sagte es gar nichts. Genau deshalb war nicht zu
sehen, dass ein 4K-Encode auf dieser Maschine Tage braucht: CPU-Modell
ist das generische "QEMU Virtual CPU version 2.5+", grep -c avx2
/proc/cpuinfo = 0, nur bis sse4_2. x265 lebt von AVX2. Gemessen an der
Leseposition des Quellstroms: 28-55 h fuer einen Film, 3,84 von 4 Kernen
gesaettigt. Abhilfe waere der CPU-Typ 'host' in Proxmox.
Jetzt wird die Encoder-Liste aus `HandBrakeCLI --help` geparst (Abschnitt
-e/--encoder, Formatstrings im Worker-Image gemessen - AGENTS Regel D), und
Hardware zaehlt nur, wenn Geraet UND HandBrake-Unterstuetzung da sind. Neu
gemeldet: cpu-av1 (svt_av1 ist wirklich verfuegbar) sowie CPU-Modell,
Kernzahl und Vektorbefehlsstufe je Worker.
UI: Kerne/Vektorbefehle stehen bei jedem Worker (Worker-Tab und
Einstellungen -> System), dazu die ungefilterte HandBrake-Auskunft und eine
sichtbare Warnung, wenn AVX2 fehlt - inklusive des Hinweises auf den
VM-CPU-Typ. Der Warntext liegt in lib/encoder.ts, damit er nicht doppelt
im Code steht.
Mit im gleichen Zug (dieselbe Datei): der Schalter "Alle Tracks rippen" ist
entfallen. Er war ein Placebo - abcde bekommt keine Track-Auswahl und es gab
auch keine Oberflaeche, um eine Teilmenge zu waehlen. Eine Audio-CD wurde
also immer vollstaendig gerippt, egal wie der Schalter stand. An seiner
Stelle steht jetzt die Wahrheit.
7 Tests, Testdaten sind echte HandBrake-Ausgaben von der VM. Der Parser ist
zusaetzlich gegen die vollen 697 Zeilen der echten --help gegengeprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { Button } from '../components/ui/Button'
|
||||
import { Input, Select, Toggle } from '../components/ui/Input'
|
||||
import { MEDIA_SERVER_OPTIONEN } from '../lib/mediaServer'
|
||||
import { ENCODER_BADGES } from '../lib/design'
|
||||
import { simdWarnung } from '../lib/encoder'
|
||||
|
||||
interface SettingsState {
|
||||
tmdbApiKey: string
|
||||
@@ -19,7 +20,6 @@ interface SettingsState {
|
||||
movieDir: string
|
||||
seriesDir: string
|
||||
musicDir: string
|
||||
ripAllTracks: boolean
|
||||
mainFeatureOnly: boolean
|
||||
autoEject: boolean
|
||||
autoRipStart: boolean
|
||||
@@ -48,7 +48,6 @@ const defaultSettings: SettingsState = {
|
||||
movieDir: 'movies',
|
||||
seriesDir: 'series',
|
||||
musicDir: 'music',
|
||||
ripAllTracks: true,
|
||||
mainFeatureOnly: false,
|
||||
autoEject: true,
|
||||
autoRipStart: false,
|
||||
@@ -74,7 +73,15 @@ interface WorkerInfo {
|
||||
// keydb: "ja" | "nein" | "unbekannt" — sagt, ob DIESER Worker eine KEYDB.cfg
|
||||
// in seinem MakeMKV-Datenverzeichnis sieht. Nur der Worker, der wirklich
|
||||
// rippt, zaehlt, deshalb steht die Angabe pro Worker und nicht global.
|
||||
info?: { makemkv?: string, handbrake?: string, makemkv_key?: string, keydb?: string }
|
||||
// cpu_kerne/cpu_simd: Rechenleistung fuers Software-Encodieren. Ohne diese
|
||||
// Angaben war am 25.07.2026 nicht zu sehen, dass ein 4K-Encode auf der
|
||||
// Rippy-VM Tage statt Stunden braucht (kein AVX2, 4 Kerne).
|
||||
// handbrake_encoder: die ungefilterte Encoder-Auskunft von HandBrake selbst.
|
||||
info?: {
|
||||
makemkv?: string, handbrake?: string, makemkv_key?: string, keydb?: string,
|
||||
cpu_modell?: string, cpu_kerne?: string, cpu_simd?: string,
|
||||
handbrake_encoder?: string,
|
||||
}
|
||||
}
|
||||
|
||||
// Antwort von GET/POST/DELETE /system/keydb (Feldnamen exakt wie die API sie liefert).
|
||||
@@ -427,14 +434,16 @@ export default function SettingsPage() {
|
||||
🎵 Audio-CD
|
||||
</p>
|
||||
|
||||
<div className="p-4 rounded-xl border border-slate-200/80 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-950/80">
|
||||
<Toggle
|
||||
label="Alle Tracks rippen"
|
||||
description="Rippe alle Tracks einer CD (FLAC + MusicBrainz-Tags)."
|
||||
checked={settings.ripAllTracks}
|
||||
onChange={(v) => handleChange('ripAllTracks', v)}
|
||||
/>
|
||||
</div>
|
||||
{/* Der Schalter „Alle Tracks rippen" ist am 25.07.2026 entfallen.
|
||||
Er war ein Placebo: abcde bekommt keine Track-Auswahl (siehe
|
||||
build_abcde_cmd) und es gibt auch keine Oberflaeche, um eine
|
||||
Teilmenge zu waehlen — eine Audio-CD wurde also immer
|
||||
vollstaendig gerippt, egal wie der Schalter stand. Statt einer
|
||||
Wahl, die nichts bewirkt, steht hier jetzt die Wahrheit. */}
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400 px-1">
|
||||
💿 Eine Audio-CD wird immer vollständig gerippt — alle Tracks als
|
||||
FLAC, mit MusicBrainz-Tags.
|
||||
</p>
|
||||
|
||||
<p className="text-xs font-bold uppercase tracking-wider pt-2 text-slate-400 dark:text-slate-500">
|
||||
Allgemein
|
||||
@@ -555,6 +564,24 @@ export default function SettingsPage() {
|
||||
{ENCODER_BADGES[e]?.label || e}
|
||||
</span>
|
||||
))}
|
||||
{(w.info?.cpu_kerne || w.info?.cpu_simd) && (
|
||||
<p className="mt-1 text-xs text-slate-500 dark:text-slate-400" title={w.info?.cpu_modell || ''}>
|
||||
{w.info?.cpu_modell ? `${w.info.cpu_modell} · ` : ''}
|
||||
{w.info?.cpu_kerne ? `${w.info.cpu_kerne} Kerne` : ''}
|
||||
{w.info?.cpu_kerne && w.info?.cpu_simd ? ' · ' : ''}
|
||||
{w.info?.cpu_simd ? `Vektorbefehle ${w.info.cpu_simd}` : ''}
|
||||
</p>
|
||||
)}
|
||||
{simdWarnung(w.info?.cpu_simd) && (
|
||||
<p className="mt-1 text-xs text-amber-600 dark:text-amber-400">
|
||||
{simdWarnung(w.info?.cpu_simd)}
|
||||
</p>
|
||||
)}
|
||||
{w.info?.handbrake_encoder && (
|
||||
<p className="mt-1 text-xs text-slate-400 dark:text-slate-500 font-mono break-all">
|
||||
HandBrake meldet: {w.info.handbrake_encoder}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user