Signatur
Beschreibung
Das Ereignis waitingforkey gehört zu den Encrypted Media Extensions (EME). Es wird an einem <video>- oder <audio>-Element ausgelöst, wenn das Element auf verschlüsselte Daten stößt, für die das Content Decryption Module (CDM) noch keinen passenden Schlüssel hat. Die Wiedergabe hält dann an, bis ein gültiger Schlüssel vorliegt.
Das Ereignis wird einmal pro Blockade ausgelöst, also beim ersten Mal, wenn die Wiedergabe wegen eines fehlenden Schlüssels stehen bleibt. Kommt der Schlüssel später an (z. B. über MediaKeySession.update()), läuft die Wiedergabe automatisch weiter. Fehlt danach wieder ein Schlüssel, kann das Ereignis erneut feuern.
Typische Anwendungsfälle:
- Einen Ladehinweis wie „Lizenz wird geladen…“ anzeigen, solange der Player auf den Schlüssel wartet.
- Diagnose und Telemetrie in DRM-Playern, etwa um langsame Lizenzserver zu erkennen.
- Einen Zeitgeber starten, der einen Fehler meldet, wenn der Schlüssel zu lange ausbleibt.
Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften. Es blubbert nicht (bubbles) und lässt sich nicht abbrechen. Du kannst es mit addEventListener() oder über die Eigenschaft onwaitingforkey registrieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "waitingforkey". |
|
| $handler Pflicht | (event: Event) => void | Callback-Funktion, die ein einfaches Event-Objekt bekommt. event.target ist das betroffene Medien-Element. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. |
Rückgabewert
addEventListener() gibt nichts zurück.Beispiele
Lizenz-Hinweis mit addEventListener anzeigen
const video = document.querySelector('video');
const hint = document.querySelector('#license-hint');
video.addEventListener('waitingforkey', () => {
hint.hidden = false;
hint.textContent = 'Lizenz wird geladen …';
console.log('Wiedergabe blockiert: Schlüssel fehlt');
});
// Sobald die Wiedergabe wieder läuft, Hinweis ausblenden
video.addEventListener('playing', () => {
hint.hidden = true;
});
Über die on-Property registrieren und wieder entfernen
const video = document.querySelector('video');
video.onwaitingforkey = (event) => {
console.log(`${event.target.currentSrc} wartet auf einen Schlüssel`);
};
// Später: Handler wieder entfernen
video.onwaitingforkey = null;
Timeout mit removeEventListener, falls der Schlüssel ausbleibt
const video = document.querySelector('video');
let timer;
const onWaitingForKey = () => {
clearTimeout(timer);
timer = setTimeout(() => {
console.error('Lizenzserver antwortet nicht – Wiedergabe abgebrochen');
video.pause();
}, 10_000);
};
const onPlaying = () => clearTimeout(timer);
video.addEventListener('waitingforkey', onWaitingForKey);
video.addEventListener('playing', onPlaying);
// Aufräumen, z. B. beim Zerstören des Players
const destroyPlayer = () => {
clearTimeout(timer);
video.removeEventListener('waitingforkey', onWaitingForKey);
video.removeEventListener('playing', onPlaying);
};
Zusammenspiel mit dem encrypted-Ereignis (EME-Grundgerüst)
const video = document.querySelector('video');
const config = [{
initDataTypes: ['cenc'],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }]
}];
const setupEme = async () => {
const access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', config);
const mediaKeys = await access.createMediaKeys();
await video.setMediaKeys(mediaKeys);
video.addEventListener('encrypted', async (event) => {
const session = mediaKeys.createSession();
session.addEventListener('message', async (msg) => {
// Lizenz beim Server anfordern (URL ist ein Platzhalter)
const res = await fetch('/license', { method: 'POST', body: msg.message });
await session.update(await res.arrayBuffer());
});
await session.generateRequest(event.initDataType, event.initData);
});
video.addEventListener('waitingforkey', () => {
console.log('Warte auf Schlüssel aus der MediaKeySession …');
});
};
setupEme().catch(console.error);
// Wichtig · Fallstricke
- Nur bei verschlüsselten Medien: Das Ereignis feuert nur, wenn EME aktiv ist, also wenn verschlüsselte Inhalte (z. B. über Media Source Extensions) abgespielt werden. Bei normalen Videos kommt es nie vor.
- Nicht mit
waitingverwechseln:waitingsteht für fehlende Daten (Pufferung),waitingforkeyfür einen fehlenden Schlüssel. Bei einer Schlüssel-Blockade kann zusätzlichwaitingausgelöst werden. - Kein Ereignis, wenn der Schlüssel ankommt: Ob die Wiedergabe weiterläuft, erkennst du an
playingodertimeupdatebzw. ankeystatuseschangederMediaKeySession. - Kompatibilität: Wird in aktuellen Chromium-Browsern, Firefox (ab 69) und Safari unterstützt. Welche Schlüsselsysteme verfügbar sind (Widevine, FairPlay, PlayReady, ClearKey), hängt vom Browser und von der Plattform ab.
- Sicherheit: EME funktioniert nur in einem sicheren Kontext (HTTPS). In iframes kann die Permissions Policy
encrypted-medianötig sein.