Signatur
Beschreibung
Die Methode forEach() der Schnittstelle MediaKeyStatusMap geht alle Einträge der Statusliste einer MediaKeySession durch. Für jeden Eintrag wird die übergebene Funktion mit dem Status (Wert), der Schlüssel-ID (Schlüssel) und der Map selbst aufgerufen, ähnlich wie bei Map.prototype.forEach().
Man erreicht die Map über MediaKeySession.keyStatuses. Typischerweise wird sie im Handler des Ereignisses keystatuseschange ausgewertet. Dort prüft man etwa, ob Lizenzschlüssel abgelaufen ("expired") sind, ob die Ausgabe eingeschränkt ist ("output-restricted", z. B. wegen fehlendem HDCP) oder ob alle Schlüssel nutzbar ("usable") sind.
Die Schlüssel-IDs sind Binärdaten (ArrayBuffer bzw. BufferSource) und keine Zeichenketten. Für Protokolle oder Vergleiche muss man sie daher selbst umwandeln, z. B. in einen Hex-String.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callbackFn Pflicht | (value: MediaKeyStatus, key: ArrayBuffer, map: MediaKeyStatusMap) => void | Wird für jeden Eintrag aufgerufen. value ist der Status als String ("usable", "expired", "released", "output-restricted", "output-downscaled", "usable-in-future", "status-pending", "internal-error"), key ist die Schlüssel-ID und map die durchlaufene MediaKeyStatusMap. |
|
| $thisArg | any | undefined | Wert, der beim Aufruf von callbackFn als this gesetzt wird. Bei Pfeilfunktionen wirkungslos. |
Rückgabewert
entries() bzw. den Iterator.Beispiele
Schlüsselstatus bei keystatuseschange protokollieren
// Schlüssel-ID (ArrayBuffer) in Hex-String umwandeln
const toHex = (buf) =>
[...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, '0')).join('');
const watchSession = (session) => {
session.addEventListener('keystatuseschange', () => {
session.keyStatuses.forEach((status, keyId) => {
console.log(`Schlüssel ${toHex(keyId)}: ${status}`);
});
});
};
Auf abgelaufene oder eingeschränkte Schlüssel reagieren
const checkKeys = async (session, video) => {
let problem = null;
session.keyStatuses.forEach((status) => {
if (status === 'expired') problem = 'Lizenz abgelaufen';
if (status === 'output-restricted') problem ??= 'Ausgabe eingeschränkt (z. B. HDCP)';
if (status === 'internal-error') problem ??= 'Interner CDM-Fehler';
});
if (problem) {
video.pause();
console.warn('Wiedergabe gestoppt:', problem);
if (problem === 'Lizenz abgelaufen') await session.close();
}
};
Status zählen mit thisArg
const counter = { usable: 0, other: 0 };
function count(status) {
status === 'usable' ? this.usable++ : this.other++;
}
// session ist eine bestehende MediaKeySession
session.keyStatuses.forEach(count, counter);
console.log(counter);
// Wichtig · Fallstricke
- Reihenfolge der Argumente: Zuerst kommt der Status (Wert), danach die Schlüssel-ID. Das ist dieselbe Reihenfolge wie bei
Map.prototype.forEach()und wird oft verwechselt. - Binäre Schlüssel:
keyIdist einArrayBuffer. Ein Vergleich mit===vergleicht nur Referenzen und nicht den Inhalt. Wandle die IDs deshalb vorher um, zum Beispiel in einen Hex-String. - Vor der ersten Lizenzantwort (
session.update()) ist die Map normalerweise leer. Werte sie am besten erst im Ereigniskeystatuseschangeaus. - Die Map ist eine Momentaufnahme. Ändern sich Status später, wird wieder
keystatuseschangeausgelöst. - EME ist nur in sicheren Kontexten (HTTPS) verfügbar. Welche Statuswerte tatsächlich vorkommen (z. B.
\"usable-in-future\"), hängt vom CDM ab (Widevine, FairPlay, PlayReady). Ältere Browser liefern teilweise nicht alle Werte. breakgeht inforEach()nicht. Wer früh abbrechen will, nutztfor...ofübersession.keyStatuses.