fix(uhd): 4K-UHD geloest - makemkvcon holt Schluessel unter Linux nie
Ampel / ampel (push) Successful in 28s
Ampel / ampel (push) Successful in 28s
Richtigstellung des Vortags-Befunds. Dort stand, MakeMKVs Schluessel-Kanal
sei abgeschaltet. Das war FALSCH: die Herleitung stuetzte sich auf zwei
Hostnamen aus alten Forumsbeitraegen (hkdata.fairuse.org,
hkdata.crabdance.com), die zwar wirklich nicht mehr aufloesen, von MakeMKV
aber laengst nicht mehr benutzt werden. Aufgedeckt durch den Einwand des
Commanders, unter Windows ginge es sofort.
Gegenprobe mit demselben Laufwerk und derselben Disc (Akira UHD, MKB v76):
Linux (Worker) Windows
Verbindungen KEINE EINZIGE 185.84.108.20:443
Meldung 3338 nie "Downloading latest HK"
_private_data.tar 2048 B, 0 Keys 6,4 MB, 604 Keys
Disc volume key unknown TCOUNT:5, geht auf
Gegengeprueft mit leerem UND gefuelltem Speicher, mit und ohne --noscan,
mit dev:/dev/sr0 und disc:0, mit geloeschter update.conf. Linux fragt nie.
Die Meldungsvorlage "Downloading latest %1 to %2 ..." steckt sehr wohl im
Linux-Binary - sie loest nur nicht aus. Gleiches Symptom im MakeMKV-Forum,
seit Jahren offen (t=25782, t=34022). Der Dienst lebt; der Worker erreicht
185.84.108.20:443 sogar problemlos.
BEWIESEN: Nach Uebernahme des Windows-Schluesselspeichers oeffnet
makemkvcon auf der VM die Akira-UHD - "Operation successfully completed",
TCOUNT:5, fuenf Titel, identisch zum Windows-Ergebnis. Erster belegter
UHD-Disc-Zugriff auf der Rippy-Maschine.
- makemkv_daten.py (beide Zwillinge): zaehle_schluessel,
private_data_pruefen, schluesselspeicher_status, private_data_schreiben.
Die Pruefung lehnt einen Speicher OHNE hkd_*.bin ab - sonst laedt jemand
den leeren Vorrat einer frischen Installation hoch, nichts aendert sich,
und niemand versteht warum. Modulkopf komplett neu, inkl. der
Fehldiagnose als Warnung fuer spaeter.
- API: GET/POST /system/keystore. Der Rohkoerper der Anfrage IST die Datei
(binaer - JSON/Base64 waere Ballast, Multipart kann die API nicht).
Groessengrenze 64 MB = client_max_body_size in nginx.conf.
- UI: neuer Block "Disc-Schluessel fuer 4K-UHD" UEBER dem KEYDB-Block, mit
Schluessel-Anzahl, Upload und Anleitung fuer den Windows-Weg. KEYDB.cfg
ist jetzt als Notnagel beschriftet. Worker-Plakette zeigt die Anzahl;
0 heisst sichtbar "4K-UHD scheitert".
- tasks.py: UHD-Fehlertext sagt den Windows-Weg an und nennt die Anzahl
bekannter Schluessel dieses Workers.
- caps.py meldet schluessel je Worker.
- Alle Falschaussagen korrigiert: UI (3), Anleitung (2), README (3),
KONZEPT §8 + §10, Worker-Dockerfile, makemkv_key.py (dort stand "Den
AACS-Schluessel zieht MakeMKV via LibreDrive ohnehin selbst aus dem
Laufwerk" - gilt fuer Blu-ray, NICHT fuer UHD).
- SAVEPOINT v3.11, ROADMAP Etappe 18 (Etappe 17 mit Nachtrag), AGENTS.
Offen: voller UHD-Rip inkl. Transcode-E2E; und ob sich der Abruf unter
Linux doch anstossen laesst.
Quellen (AGENTS Regel D):
- Linux laedt keine Hashed Keys, gleiches Symptom:
https://forum.makemkv.com/forum/viewtopic.php?t=25782
https://forum.makemkv.com/forum/viewtopic.php?t=34022
- Schluessel als hkd_*.bin in _private_data.tar:
https://forum.makemkv.com/forum/viewtopic.php?t=32675
- Meldungsformat: https://www.makemkv.com/developers/usage.txt
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,15 @@ interface KeydbStatus {
|
||||
geaendert: string
|
||||
}
|
||||
|
||||
// Antwort von GET/POST /system/keystore — MakeMKVs eigener Schluesselvorrat.
|
||||
interface KeystoreStatus {
|
||||
vorhanden: boolean
|
||||
pfad: string
|
||||
groesse_bytes: number
|
||||
schluessel: number
|
||||
geaendert: string
|
||||
}
|
||||
|
||||
// Ein AACS-Dump aus GET /system/aacs-dumps.
|
||||
interface AacsDump {
|
||||
name: string
|
||||
@@ -130,6 +139,9 @@ export default function SettingsPage() {
|
||||
const [keydbBusy, setKeydbBusy] = useState(false)
|
||||
const [dumps, setDumps] = useState<AacsDump[]>([])
|
||||
const keydbInput = useRef<HTMLInputElement>(null)
|
||||
const [keystore, setKeystore] = useState<KeystoreStatus | null>(null)
|
||||
const [keystoreBusy, setKeystoreBusy] = useState(false)
|
||||
const keystoreInput = useRef<HTMLInputElement>(null)
|
||||
|
||||
const { toast } = useToast()
|
||||
|
||||
@@ -155,6 +167,7 @@ export default function SettingsPage() {
|
||||
// nicht das, was wir gerade hochgeschickt haben.
|
||||
const keydbLaden = () => {
|
||||
api.get('/system/keydb').then(r => setKeydb(r.data)).catch(() => setKeydb(null))
|
||||
api.get('/system/keystore').then(r => setKeystore(r.data)).catch(() => setKeystore(null))
|
||||
api.get('/system/aacs-dumps').then(r => setDumps(r.data?.dumps || [])).catch(() => setDumps([]))
|
||||
// Die Worker-Plaketten oben kommen aus /capabilities und stammen aus dem
|
||||
// letzten Herzschlag des Workers (minuetlich) — ohne dieses Nachladen
|
||||
@@ -180,6 +193,25 @@ export default function SettingsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const keystoreHochladen = async (datei: File) => {
|
||||
setKeystoreBusy(true)
|
||||
try {
|
||||
// Die Datei wandert als roher Anfrage-Körper zur API — _private_data.tar
|
||||
// ist binär, JSON oder Base64 wäre nur unnötiger Ballast, und Multipart
|
||||
// kann die API nicht (kein python-multipart).
|
||||
await api.post('/system/keystore', datei, {
|
||||
headers: { 'Content-Type': 'application/octet-stream' },
|
||||
})
|
||||
keydbLaden()
|
||||
toast('success', 'Schlüsselspeicher übernommen — wirkt ab dem nächsten Rip.')
|
||||
} catch (e: any) {
|
||||
toast('error', e?.response?.data?.detail
|
||||
|| 'Übernahme fehlgeschlagen — ist das wirklich die Datei _private_data.tar, und läuft die API?')
|
||||
} finally {
|
||||
setKeystoreBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
const keydbEntfernen = async () => {
|
||||
setKeydbBusy(true)
|
||||
try {
|
||||
@@ -221,6 +253,9 @@ export default function SettingsPage() {
|
||||
api.get('/system/keydb')
|
||||
.then(r => setKeydb(r.data))
|
||||
.catch(() => setKeydb(null))
|
||||
api.get('/system/keystore')
|
||||
.then(r => setKeystore(r.data))
|
||||
.catch(() => setKeystore(null))
|
||||
api.get('/system/aacs-dumps')
|
||||
.then(r => setDumps(r.data?.dumps || []))
|
||||
.catch(() => setDumps([]))
|
||||
@@ -726,20 +761,24 @@ export default function SettingsPage() {
|
||||
HandBrake {w.info.handbrake}
|
||||
</span>
|
||||
)}
|
||||
{/* Nur das Verzeichnis des rippenden Workers zaehlt — deshalb je Worker. */}
|
||||
{w.info?.keydb === 'ja' && (
|
||||
{/*
|
||||
Nur das Verzeichnis des rippenden Workers zaehlt — deshalb je Worker.
|
||||
Die Zahl der Disc-Schluessel ist die entscheidende Angabe fuer 4K-UHD:
|
||||
0 heisst, dass JEDE unbekannte UHD-Disc scheitert.
|
||||
*/}
|
||||
{w.info?.schluessel && w.info.schluessel !== '0' && w.info.schluessel !== 'unbekannt' && (
|
||||
<span className="text-xs px-2.5 py-0.5 rounded-md font-medium bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border border-emerald-500/30">
|
||||
KEYDB.cfg vorhanden
|
||||
{w.info.schluessel} Disc-Schlüssel
|
||||
</span>
|
||||
)}
|
||||
{w.info?.keydb === 'nein' && (
|
||||
{w.info?.schluessel === '0' && (
|
||||
<span className="text-xs px-2.5 py-0.5 rounded-md font-medium bg-amber-500/15 text-amber-600 dark:text-amber-400 border border-amber-500/30">
|
||||
keine KEYDB.cfg
|
||||
keine Disc-Schlüssel — 4K-UHD scheitert
|
||||
</span>
|
||||
)}
|
||||
{w.info?.keydb === 'unbekannt' && (
|
||||
{w.info?.keydb === 'ja' && (
|
||||
<span className="text-xs px-2.5 py-0.5 rounded-md font-medium bg-slate-200 dark:bg-slate-800 text-slate-500 dark:text-slate-400 border border-slate-300 dark:border-slate-700">
|
||||
KEYDB.cfg unbekannt
|
||||
+ KEYDB.cfg
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -747,19 +786,17 @@ export default function SettingsPage() {
|
||||
)}
|
||||
{/*
|
||||
Bis 25.07.2026 stand hier, MakeMKV-Updates braechten die neueste
|
||||
Disc-Schluessel-Datenbank mit. Auf der Rippy-VM nachgemessen: falsch.
|
||||
MakeMKV hat gar keine mitgelieferte Schluessel-Datenbank, und der
|
||||
Online-Kanal liefert nichts mehr (die Server hkdata.fairuse.org und
|
||||
hkdata.crabdance.com loesen weltweit nicht mehr auf). Updates bringen
|
||||
Laufwerks-Firmware-Unterstuetzung und Fehlerbehebungen — Schluessel
|
||||
fuer neue UHD-Pressungen kommen ausschliesslich aus der KEYDB.cfg.
|
||||
Disc-Schluessel-Datenbank mit. Nachgemessen: falsch — MakeMKV liefert
|
||||
gar keine Schluessel mit, es holt sie zur Laufzeit. Und die
|
||||
Linux-Version holt sie nie (kein einziger Verbindungsversuch, auf
|
||||
beiden Maschinen verglichen). Deshalb der Schluesselspeicher unten.
|
||||
*/}
|
||||
<p className="text-xs mt-3 pt-3 border-t border-slate-200/60 dark:border-slate-800 text-slate-500 dark:text-slate-400">
|
||||
<strong className="text-slate-700 dark:text-slate-300">MakeMKV</strong> lässt sich aktuell halten
|
||||
(Update-Check unten; Version über <code>MAKEMKV_VERSION</code> + Rebuild) — neue Versionen bringen
|
||||
vor allem Laufwerks-Unterstützung und Fehlerbehebungen. <strong>Disc-Schlüssel für neue
|
||||
4K-UHD-Pressungen kommen dagegen NICHT aus einem Update</strong>, sondern nur aus der KEYDB.cfg
|
||||
im Block darunter.
|
||||
vor allem Laufwerks-Unterstützung und Fehlerbehebungen. <strong>Disc-Schlüssel für 4K-UHD kommen
|
||||
NICHT aus einem Update</strong> — die holt MakeMKV zur Laufzeit, und die Linux-Version tut das
|
||||
nie. Deshalb der Block „Disc-Schlüssel für 4K-UHD" weiter unten.
|
||||
{' '}<strong className="text-slate-700 dark:text-slate-300">HandBrake</strong> im eingebauten
|
||||
Docker-Worker ist bewusst die stabile <strong>Debian-Version</strong> — für die Kompression völlig
|
||||
ausreichend und wird <strong>nicht separat aktualisiert</strong>. Native Worker (Windows) holen
|
||||
@@ -776,18 +813,91 @@ export default function SettingsPage() {
|
||||
/>
|
||||
|
||||
{/*
|
||||
MakeMKV-Schluessel (KEYDB.cfg) — Befund vom 25.07.2026 auf der Rippy-VM:
|
||||
MakeMKV versucht bei einer unbekannten UHD-Pressung gar nicht mehr, online
|
||||
einen Schluessel zu holen, und die dokumentierten Schluessel-Server sind tot.
|
||||
Der einzige heute funktionierende Weg ist eine Datei KEYDB.cfg (GROSS
|
||||
geschrieben, unter Linux case-sensitiv) im MakeMKV-Datenverzeichnis.
|
||||
Rippy stellt nur den Platz dafuer bereit — mitgeliefert wird nichts.
|
||||
Schluesselspeicher — der Hauptweg fuer 4K-UHD (Befund 25.07.2026,
|
||||
auf beiden Maschinen gemessen): makemkvcon holt Disc-Schluessel
|
||||
unter Linux NIE selbst, die Windows-Version tut es (Meldung 3338,
|
||||
Verbindung nach 185.84.108.20:443). Deshalb wird der Vorrat hier
|
||||
von Hand hereingereicht. Frueher stand an dieser Stelle die These,
|
||||
MakeMKVs Schluessel-Kanal sei abgeschaltet — das war falsch.
|
||||
*/}
|
||||
<div className="p-4 rounded-xl border border-slate-200/80 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-950/80 space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-semibold text-slate-900 dark:text-slate-200 flex items-center gap-2">
|
||||
<Database size={16} className="text-amber-500" />
|
||||
Disc-Schlüssel für 4K-UHD
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="file"
|
||||
className="hidden"
|
||||
ref={keystoreInput}
|
||||
accept=".tar"
|
||||
onChange={(e) => {
|
||||
const datei = e.target.files?.[0]
|
||||
e.target.value = ''
|
||||
if (datei) keystoreHochladen(datei)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="amber"
|
||||
size="sm"
|
||||
onClick={() => keystoreInput.current?.click()}
|
||||
disabled={keystoreBusy}
|
||||
>
|
||||
<Upload size={14} />
|
||||
{keystoreBusy ? 'Übernehme…' : '_private_data.tar übernehmen'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{keystore?.vorhanden && keystore.schluessel > 0 ? (
|
||||
<div className="p-3 rounded-lg text-sm bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border border-emerald-500/30">
|
||||
<p className="font-semibold">{keystore.schluessel} Disc-Schlüssel vorhanden.</p>
|
||||
<p className="text-xs mt-1">
|
||||
{bytesLesbar(keystore.groesse_bytes)} · zuletzt geändert {zeitLesbar(keystore.geaendert)}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-3 rounded-lg text-sm bg-amber-500/15 text-amber-600 dark:text-amber-400 border border-amber-500/30">
|
||||
<p className="font-semibold">Kein einziger Disc-Schlüssel vorhanden.</p>
|
||||
<p className="text-xs mt-1">
|
||||
DVDs und normale Blu-rays laufen trotzdem. 4K-UHD-Discs scheitern dagegen mit
|
||||
„The volume key is unknown for this disc" — solange hier nichts liegt, jede einzelne.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
<strong className="text-slate-700 dark:text-slate-300">Warum das nötig ist:</strong> MakeMKV
|
||||
holt sich diese Schlüssel eigentlich selbst aus dem Netz. Die <strong>Linux-Version tut das
|
||||
nicht</strong> — am 25.07.2026 nachgemessen: sie baut dabei nicht eine einzige Verbindung auf.
|
||||
Die Windows-Version schon. Ein MakeMKV-Update ändert daran nichts, es ist kein Fehler in Rippy.
|
||||
</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
<strong className="text-slate-700 dark:text-slate-300">So füllst du den Vorrat:</strong> MakeMKV
|
||||
auf einem Windows-PC installieren (gleicher Beta-Key), das Laufwerk dort anstecken und die Disc
|
||||
einmal öffnen. MakeMKV lädt die Schlüssel dabei nach. Danach unter <em>Preferences → General</em>
|
||||
das „MakeMKV data directory" nachschlagen, die Datei <code>_private_data.tar</code> daraus hier
|
||||
hochladen — fertig. Für neue Discs von Zeit zu Zeit wiederholen.
|
||||
</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
Das ist der Zwischenspeicher <strong className="text-slate-700 dark:text-slate-300">deiner
|
||||
eigenen</strong> MakeMKV-Installation, über MakeMKVs offiziellen Weg mit deiner eigenen Lizenz
|
||||
geholt. Rippy liefert keine Schlüssel mit und lädt keine herunter.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
KEYDB.cfg — der NOTNAGEL, nicht der Hauptweg. Sie hilft bei Pressungen,
|
||||
die auch MakeMKV selbst nicht kennt. Der Regelfall laeuft ueber den
|
||||
Schluesselspeicher im Block darueber. Dateiname GROSS geschrieben, unter
|
||||
Linux case-sensitiv. Rippy stellt nur den Platz bereit.
|
||||
*/}
|
||||
<div className="p-4 rounded-xl border border-slate-200/80 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-950/80 space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-semibold text-slate-900 dark:text-slate-200 flex items-center gap-2">
|
||||
<KeyRound size={16} className="text-amber-500" />
|
||||
MakeMKV-Schlüssel (KEYDB.cfg)
|
||||
KEYDB.cfg (Notnagel)
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
{/*
|
||||
@@ -834,20 +944,20 @@ export default function SettingsPage() {
|
||||
<p className="text-xs mt-1 font-mono opacity-80">{keydb.pfad}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-3 rounded-lg text-sm bg-amber-500/15 text-amber-600 dark:text-amber-400 border border-amber-500/30">
|
||||
<p className="font-semibold">Es liegt keine KEYDB.cfg bereit.</p>
|
||||
<div className="p-3 rounded-lg text-sm bg-slate-200 dark:bg-slate-800 text-slate-500 dark:text-slate-400 border border-slate-300 dark:border-slate-700">
|
||||
<p className="font-semibold">Keine KEYDB.cfg hinterlegt.</p>
|
||||
<p className="text-xs mt-1">
|
||||
DVDs und normale Blu-rays laufen trotzdem. Nur bei 4K-UHD-Discs, deren Schlüssel MakeMKV
|
||||
nicht kennt, bricht der Rip mit „The volume key is unknown for this disc" ab.
|
||||
Das ist normal und meistens auch nicht nötig — der Regelfall läuft über den
|
||||
Schlüsselspeicher oben.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
Die <strong className="text-slate-700 dark:text-slate-300">KEYDB.cfg</strong> ist eine reine
|
||||
Textdatei mit Disc-Schlüsseln für 4K-UHD-Blu-rays. MakeMKV holte solche Schlüssel früher selbst
|
||||
aus dem Netz — das funktioniert heute nicht mehr, die alten Schlüssel-Server sind abgeschaltet.
|
||||
Ein MakeMKV-Update hilft dagegen nicht.
|
||||
Textdatei mit Disc-Schlüsseln. Sie ist der <strong className="text-slate-700 dark:text-slate-300">
|
||||
Notnagel</strong> für den Fall, dass eine Pressung selbst über den Schlüsselspeicher nicht
|
||||
aufgeht — also auch MakeMKV sie nicht kennt. Zuerst immer den Weg darüber versuchen.
|
||||
</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
<strong className="text-slate-700 dark:text-slate-300">Wichtig:</strong> Rippy liefert keine
|
||||
@@ -926,9 +1036,9 @@ export default function SettingsPage() {
|
||||
<p className="text-xs mt-1">
|
||||
⚠️ Update verfügbar — in der .env <code>MAKEMKV_VERSION={updates.makemkv.verfuegbar}</code> setzen,
|
||||
dann auf der Rippy-Maschine <code>docker compose build worker && docker compose up -d worker</code>.
|
||||
{/* 25.07.2026 richtiggestellt: ein Update bringt KEINE Schluessel — die kommen nur aus der KEYDB.cfg. */}
|
||||
{/* 25.07.2026 richtiggestellt: ein Update bringt KEINE Disc-Schluessel mit. */}
|
||||
Neue Versionen bringen Laufwerks-Unterstützung und Fehlerbehebungen — aber
|
||||
<strong> keine Disc-Schlüssel</strong>: die kommen ausschließlich aus deiner KEYDB.cfg.
|
||||
<strong> keine Disc-Schlüssel</strong>: die kommen aus dem Schlüsselspeicher.
|
||||
</p>
|
||||
)
|
||||
: <span className="text-xs ml-1 text-emerald-600 dark:text-emerald-400">✓ aktuell</span>}
|
||||
|
||||
Reference in New Issue
Block a user