FUND 1 — 'Key korrekt, aber als ungueltig angezeigt': Stimmt beides. Live gemessen: Der aktuelle Forum-Key ist in Ordnung, aber MakeMKV 1.18.4 ist ZU ALT fuer ihn — makemkvcon meldet 5020 UND 5021 zusammen, und die alte Pruefung brach beim ersten Code ab und beschuldigte den Schluessel. urteilAusAusgabe sammelt jetzt ALLE Codes (5021 schlaegt 5020, MakeMKV-Version aus MSG 1005 wird mitgelesen) und die Kachel sagt den wahren Satz: 'Der Key ist in Ordnung — MakeMKV 1.18.4 ist zu alt. Rippy hat ihn entfernt, damit der Beta-Modus weiterlaeuft (Rips klappen trotzdem). Abhilfe: MakeMKV aktualisieren.' Neues Feld weiterBetrieb: Beta-Modus ist GELB (Warnung), nicht rot. Test mit der echten Ausgabe als Fixture. FUND 2 — 'Komprimieren auf CPU statt GPU': Der Default 'H.265 MKV 1080p30' ist ein CPU-Preset. Neue GEMESSENE Empfehlung (gemeinsam/preset-empfehlung.ts): aus den echten Backends und der echten Preset-Liste des eigenen HandBrake — VCN vor NVENC vor QSV vor CPU, nur Namen die WIRKLICH in der Liste stehen, HandBrake-Presets deckeln die Aufloesung nur (DVD bleibt SD). Kette: eigene Wahl > allgemeines Preset > Empfehlung > CPU-Default. Auf dem Commander-PC: bluray/dvd -> 'H.265 VCN 1080p', uhd -> 'H.265 VCN 2160p 4K'. Die Preset-Auswahl zeigt 'automatisch: <Empfehlung>' als Leer-Option. FUND 3 — 'keine Alternative waehlbar': 'Aendern …'-Dialog an der Laufwerks-Kachel (§ 5 Schritt 4): TMDb-Suche (Film + Serie, mit Postern), Klick uebernimmt — Nutzer-Wahl gilt als 100 % und steuert Ablage-Ordner, NFO und Poster. Neue Nachrichten metadaten-suchen / zuordnung-setzen / metadaten-vorschlaege. Dazu: Poster in der Laufwerks-Kachel (CSP um image.tmdb.org erweitert), Restzeit-Schaetzung am Fortschritt. 192 Tests gruen, Smoke gruen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
0e1c927e7b
commit
c5dd90cc18
@@ -91,15 +91,24 @@ export interface KeyUrteil {
|
||||
ok: boolean
|
||||
code: number | null
|
||||
grund: string
|
||||
/** Die MakeMKV-Version aus MSG 1005 („MakeMKV v1.18.4 …") — '' wenn
|
||||
* nicht erkennbar. */
|
||||
version: string
|
||||
}
|
||||
|
||||
/** Nimmt MakeMKV den hinterlegten Schlüssel an? — es selbst gefragt:
|
||||
* `info disc:9999` braucht keinen Datenträger, die Freischaltungs-Meldung
|
||||
* kommt trotzdem (makemkv_aufruf.py, 29.08.2026). */
|
||||
* kommt trotzdem (makemkv_aufruf.py, 29.08.2026).
|
||||
*
|
||||
* ⚠ ALLE Codes einsammeln, dann urteilen: Beim Commander kamen 5020 UND
|
||||
* 5021 zusammen (30.08.2026 live gemessen) — 5020 allein klingt nach
|
||||
* „Schlüssel kaputt", die URSACHE steht aber in 5021: MakeMKV ist zu alt
|
||||
* für den aktuellen Beta-Key. Wer beim ersten Code abbricht, beschuldigt
|
||||
* den falschen. */
|
||||
export function keyPruefen(programm: string, timeoutMs = 120_000): Promise<KeyUrteil> {
|
||||
return new Promise((fertig) => {
|
||||
if (programm.length === 0) {
|
||||
fertig({ ok: false, code: null, grund: 'MakeMKV nicht gefunden' })
|
||||
fertig({ ok: false, code: null, grund: 'MakeMKV nicht gefunden', version: '' })
|
||||
return
|
||||
}
|
||||
const kind = spawn(programm, ['-r', '--noscan', 'info', 'disc:9999'], {
|
||||
@@ -112,28 +121,43 @@ export function keyPruefen(programm: string, timeoutMs = 120_000): Promise<KeyUr
|
||||
const zeiger = setTimeout(() => kind.kill(), timeoutMs)
|
||||
kind.on('error', (fehler) => {
|
||||
clearTimeout(zeiger)
|
||||
fertig({ ok: false, code: null, grund: `MakeMKV nicht befragbar (${String(fehler)})` })
|
||||
fertig({ ok: false, code: null, grund: `MakeMKV nicht befragbar (${String(fehler)})`, version: '' })
|
||||
})
|
||||
kind.on('close', () => {
|
||||
clearTimeout(zeiger)
|
||||
for (const zeile of textVon(Buffer.concat(stuecke)).split(/\r?\n/)) {
|
||||
if (!zeile.startsWith('MSG:')) continue
|
||||
const code = Number(zeile.slice(4).split(',', 1)[0])
|
||||
if (!Number.isInteger(code)) continue
|
||||
if (KEY_ABGELEHNT.includes(code) || code === 5051) {
|
||||
fertig({ ok: false, code, grund: KRITISCHE_CODES[code] ?? `MSG ${code}` })
|
||||
return
|
||||
}
|
||||
}
|
||||
fertig({ ok: true, code: null, grund: '' })
|
||||
fertig(urteilAusAusgabe(textVon(Buffer.concat(stuecke))))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/** Die Ausgabe eines info-Laufs → Urteil (pur, testbar). */
|
||||
export function urteilAusAusgabe(ausgabe: string): KeyUrteil {
|
||||
const codes: number[] = []
|
||||
let version = ''
|
||||
for (const zeile of ausgabe.split(/\r?\n/)) {
|
||||
if (!zeile.startsWith('MSG:')) continue
|
||||
const code = Number(zeile.slice(4).split(',', 1)[0])
|
||||
if (!Number.isInteger(code)) continue
|
||||
if (code === 1005) {
|
||||
const treffer = /MakeMKV v([0-9][0-9.]*)/.exec(zeile)
|
||||
if (treffer !== null) version = treffer[1]
|
||||
}
|
||||
if (KEY_ABGELEHNT.includes(code) || code === 5051) codes.push(code)
|
||||
}
|
||||
if (codes.length === 0) return { ok: true, code: null, grund: '', version }
|
||||
// 5021 schlägt alles: Es benennt die URSACHE (Version zu alt) — 5020
|
||||
// ist dann nur die Folge und würde den Schlüssel zu Unrecht beschuldigen.
|
||||
const code = codes.includes(5021) ? 5021 : codes[0]
|
||||
return { ok: false, code, grund: KRITISCHE_CODES[code] ?? `MSG ${code}`, version }
|
||||
}
|
||||
|
||||
export interface SchluesselStand {
|
||||
/** 'dauerlizenz' | 'forum' | 'keiner' */
|
||||
quelle: string
|
||||
angenommen: boolean | null
|
||||
/** Laufen Rips trotzdem? (Beta-Modus ohne Key = ja — das ist eine
|
||||
* WARNUNG mit Handlungsempfehlung, kein Ausfall.) */
|
||||
weiterBetrieb: boolean
|
||||
gueltigBis: string
|
||||
geholtAm: string
|
||||
text: string
|
||||
@@ -155,9 +179,12 @@ export async function schluesselKette(
|
||||
return {
|
||||
quelle: 'dauerlizenz',
|
||||
angenommen: urteil.ok,
|
||||
weiterBetrieb: urteil.ok,
|
||||
gueltigBis: '',
|
||||
geholtAm: jetztIso,
|
||||
text: urteil.ok ? 'Eigener Schlüssel hinterlegt und angenommen.' : `Eigener Schlüssel abgelehnt: ${urteil.grund}`,
|
||||
text: urteil.ok
|
||||
? `Eigener Schlüssel hinterlegt und von MakeMKV${urteil.version.length > 0 ? ` ${urteil.version}` : ''} angenommen.`
|
||||
: `Eigener Schlüssel abgelehnt: ${urteil.grund}`,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +196,7 @@ export async function schluesselKette(
|
||||
return {
|
||||
quelle: 'keiner',
|
||||
angenommen: urteil.ok,
|
||||
weiterBetrieb: true,
|
||||
gueltigBis: '',
|
||||
geholtAm: jetztIso,
|
||||
text: urteil.ok
|
||||
@@ -181,15 +209,25 @@ export async function schluesselKette(
|
||||
const urteil = await keyPruefen(makemkvcon)
|
||||
if (!urteil.ok) {
|
||||
// Ein abgelehnter Schlüssel ist schlimmer als keiner — zurücknehmen.
|
||||
// (Live gemessen 30.08.2026: MIT abgelehntem Key verweigert MakeMKV
|
||||
// alles; OHNE läuft es im Beta-Modus weiter und rippt.)
|
||||
keyZuruecknehmen()
|
||||
}
|
||||
const versionsText = urteil.version.length > 0 ? ` ${urteil.version}` : ''
|
||||
return {
|
||||
quelle: 'forum',
|
||||
angenommen: urteil.ok,
|
||||
// Der Zurücknahme-Weg lässt MakeMKV im Beta-Modus weiterlaufen —
|
||||
// Rips gehen, nur eben ohne Freischaltungs-Komfort.
|
||||
weiterBetrieb: true,
|
||||
gueltigBis: forum.gueltigBis,
|
||||
geholtAm: jetztIso,
|
||||
text: urteil.ok
|
||||
? `Beta-Key aus dem Forum hinterlegt${forum.gueltigBis.length > 0 ? ` — gültig bis ${forum.gueltigBis}` : ''}.`
|
||||
: `Beta-Key abgelehnt (${urteil.grund}) — wieder entfernt. Vermutlich ist MakeMKV zu alt.`,
|
||||
? `Beta-Key aus dem Forum hinterlegt und von MakeMKV${versionsText} angenommen${forum.gueltigBis.length > 0 ? ` — gültig bis ${forum.gueltigBis}` : ''}.`
|
||||
: urteil.code === 5021
|
||||
? `Der aktuelle Beta-Key ist in Ordnung — aber MakeMKV${versionsText} ist ZU ALT für ihn. ` +
|
||||
'Rippy hat ihn wieder entfernt, damit MakeMKV im Beta-Modus weiterläuft (so klappen Rips trotzdem). ' +
|
||||
'Abhilfe: MakeMKV von makemkv.com aktualisieren — danach hinterlegt Rippy den Key automatisch neu.'
|
||||
: `Beta-Key abgelehnt (${urteil.grund}) — wieder entfernt, damit MakeMKV im Beta-Modus weiterläuft.`,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user