Start · Sprachen · JavaScript · Referenz · MediaKeyStatusMap

MediaKeyStatusMap

Schnittstelle

Schreibgeschützte Zuordnung von Schlüssel-IDs zum aktuellen Status der zugehörigen Medienschlüssel einer <code>MediaKeySession</code> (Encrypted Media Extensions).

seit JavaScript Baseline: alle modernen Browser (Chrome, Edge, Fir Kategorie: webapi

Signatur

interface MediaKeyStatusMap

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üssel
  • has(keyId) – prüft, ob eine Schlüssel-ID vorhanden ist
  • get(keyId) – liefert den Status oder undefined
  • forEach(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

Typ
MediaKeyStatusMap
Beschreibung
Wird über 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}`);
  }
});
Anzahl Schlüssel: 1 0123456789abcdef0123456789abcdef → usable

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;
    }
  });
});
HDCP-Einschränkung – niedrigere Auflösung wählen.

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');
}
Status: usable Abspielbar: true

// 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 mit for...of über entries() ([keyId, status]) ist daher eindeutiger.
  • Schlüssel-IDs sind Binärdaten: Für Ausgaben oder Vergleiche mit Manifest-Werten (z. B. default_KID in 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, nachdem update() eine Lizenz übernommen hat. Statusänderungen immer über das Event keystatuseschange verfolgen, 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).