Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: waitingforkey

HTMLMediaElement: waitingforkey

Ereignis

Wird an einem Medien-Element ausgelöst, wenn die Wiedergabe stoppt, weil zum Entschlüsseln der nächsten Daten ein Schlüssel fehlt.

seit JavaScript Encrypted Media Extensions (EME); Chrome 63+, Edge Kategorie: webapi

Signatur

element.addEventListener("waitingforkey", handler)

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

Typ
void
Beschreibung
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;
});
Wiedergabe blockiert: Schlüssel fehlt

Ü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);
};
Lizenzserver antwortet nicht – Wiedergabe abgebrochen (nur wenn nach 10 s noch kein Schlüssel vorliegt)

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);
Warte auf Schlüssel aus der MediaKeySession …

// 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 waiting verwechseln: waiting steht für fehlende Daten (Pufferung), waitingforkey für einen fehlenden Schlüssel. Bei einer Schlüssel-Blockade kann zusätzlich waiting ausgelöst werden.
  • Kein Ereignis, wenn der Schlüssel ankommt: Ob die Wiedergabe weiterläuft, erkennst du an playing oder timeupdate bzw. an keystatuseschange der MediaKeySession.
  • 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-media nötig sein.