Signatur
Beschreibung
MediaKeyStatusMap gehört zur Encrypted Media Extensions API (EME). Eine Instanz bekommt man nur über die Eigenschaft MediaKeySession.keyStatuses. Die Map ordnet jeder Schlüssel-ID (ArrayBuffer bzw. ArrayBufferView) den aktuellen Status des Schlüssels als Zeichenkette zu, z. B. "usable", "expired", "released", "output-restricted", "output-downscaled", "usable-in-future", "status-pending" oder "internal-error".
Die Schnittstelle verhält sich wie eine schreibgeschützte Map. Sie bietet:
size– Anzahl der bekannten Schlüsselhas(keyId)– prüft, ob eine Schlüssel-ID vorhanden istget(keyId)– liefert den Status oderundefinedforEach(callback, thisArg),entries(),keys(),values()und[Symbol.iterator]()zum Durchlaufen
Typischerweise wertet man die Map im Handler des Events keystatuseschange an der MediaKeySession aus. So erkennt ein Player, ob ein Schlüssel abgelaufen ist, ob HDCP-Vorgaben die Ausgabe beschränken ("output-restricted") oder ob die Wiedergabe mit einer anderen Qualitätsstufe fortgesetzt werden sollte.
Die Map lässt sich nicht verändern: Es gibt kein set(), delete() oder clear(). Den Inhalt bestimmt allein das Content Decryption Module (CDM), nachdem der Lizenzserver geantwortet und session.update() die Lizenz übernommen hat.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $keyId Pflicht | ArrayBuffer|ArrayBufferView | Schlüssel-ID, die an has() bzw. get() übergeben wird. Verglichen wird der Byte-Inhalt, nicht die Objektidentität. |
|
| $callback Pflicht | (status: string, keyId: ArrayBuffer, map: MediaKeyStatusMap) => void | Funktion für forEach(). Achtung: Wie bei Map ist das erste Argument der Wert (Status), das zweite der Schlüssel (Schlüssel-ID). |
|
| $thisArg | any | undefined | Optionaler this-Wert für den Callback von forEach(). |
Rückgabewert
MediaKeySession.keyStatuses bereitgestellt. get() gibt einen Status als string oder undefined zurück, has() einen boolean, size eine number, die Iteratoren liefern Paare der Form [ArrayBuffer, string].Beispiele
Schlüsselstatus bei keystatuseschange auswerten
// Voraussetzung: mediaKeys wurde über navigator.requestMediaKeySystemAccess() erzeugt
const toHex = (buf) =>
[...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, '0')).join('');
const session = mediaKeys.createSession();
session.addEventListener('keystatuseschange', () => {
console.log(`Anzahl Schlüssel: ${session.keyStatuses.size}`);
for (const [keyId, status] of session.keyStatuses) {
console.log(`${toHex(keyId)} → ${status}`);
}
});
Auf abgelaufene oder eingeschränkte Schlüssel reagieren
session.addEventListener('keystatuseschange', async () => {
session.keyStatuses.forEach((status, keyId) => {
switch (status) {
case 'expired':
console.warn('Lizenz abgelaufen – Sitzung wird geschlossen.');
session.close();
break;
case 'output-restricted':
console.warn('HDCP-Einschränkung – niedrigere Auflösung wählen.');
// z. B. player.selectMaxHeight(480);
break;
case 'internal-error':
console.error('CDM-Fehler für Schlüssel', new Uint8Array(keyId));
break;
}
});
});
Bestimmte Schlüssel-ID gezielt abfragen
// Schlüssel-ID als Hex-String, z. B. aus dem Manifest (default_KID)
const hexToBytes = (hex) =>
new Uint8Array(hex.match(/../g).map((h) => parseInt(h, 16)));
const kid = hexToBytes('0123456789abcdef0123456789abcdef');
if (session.keyStatuses.has(kid)) {
const status = session.keyStatuses.get(kid);
console.log(`Status: ${status}`);
console.log(`Abspielbar: ${status === 'usable'}`);
} else {
console.log('Schlüssel (noch) nicht bekannt');
}
// Wichtig · Fallstricke
- Reihenfolge der Argumente in
forEach(): Zuerst kommt der Status, dann die Schlüssel-ID. In älteren Chrome-Versionen war die Reihenfolge vertauscht. Die Iteration mitfor...ofüberentries()([keyId, status]) ist daher eindeutiger. - Schlüssel-IDs sind Binärdaten: Für Ausgaben oder Vergleiche mit Manifest-Werten (z. B.
default_KIDin DASH) in Hex umwandeln. Auf Byte-Reihenfolge und Bindestriche in UUID-Schreibweise achten, besonders bei PlayReady (Little-Endian-GUID). - Die Map ist direkt nach
createSession()leer. Einträge erscheinen erst, nachdemupdate()eine Lizenz übernommen hat. Statusänderungen immer über das Eventkeystatuseschangeverfolgen, nicht per Polling. - Die Werte
"usable-in-future"und"status-pending"kamen erst in neueren Fassungen der Spezifikation hinzu und werden nicht überall gemeldet. Unbekannte Statuswerte sollte der Code deshalb tolerant behandeln. - EME steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Welche Statuswerte tatsächlich auftreten, hängt vom Browser und vom CDM ab (Widevine, PlayReady, FairPlay).