Start · Sprachen · JavaScript · Referenz · HTMLMediaElement.setMediaKeys()

HTMLMediaElement.setMediaKeys()

Methode

Verknüpft ein <code>MediaKeys</code>-Objekt mit einem Audio- oder Video-Element, damit verschlüsselte Medien (DRM) während der Wiedergabe entschlüsselt werden können.

seit JavaScript Encrypted Media Extensions (EME) – Baseline: alle Kategorie: webapi

Signatur

HTMLMediaElement.prototype.setMediaKeys(mediaKeys)

Beschreibung

setMediaKeys() gehört zu den Encrypted Media Extensions (EME). Damit hängen Sie ein zuvor über navigator.requestMediaKeySystemAccess() und MediaKeySystemAccess.createMediaKeys() erzeugtes MediaKeys-Objekt an ein <video>- oder <audio>-Element. Dessen Content Decryption Module (CDM), etwa Widevine, PlayReady oder FairPlay, entschlüsselt dann die Medien während der Wiedergabe.

Die Methode arbeitet asynchron und gibt ein Promise zurück. Erst wenn es erfüllt ist, steht das Objekt in HTMLMediaElement.mediaKeys bereit. Mit null als Argument lösen Sie die Verknüpfung wieder. Das klappt aber nur, wenn das CDM das Entfernen während der Wiedergabe erlaubt.

Üblicherweise setzen Sie die MediaKeys vor dem Zuweisen der Quelle (src oder MediaSource) oder als Reaktion auf das encrypted-Ereignis. Danach erzeugen Sie mit mediaKeys.createSession() eine MediaKeySession, schicken die Lizenzanfrage an Ihren Lizenzserver und übergeben die Antwort mit session.update().

Parameter

Name Typ Default Beschreibung
$mediaKeys Pflicht MediaKeys | null Das MediaKeys-Objekt, das zum Entschlüsseln verwendet werden soll, oder null, um eine bestehende Verknüpfung zu lösen.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das ohne Wert erfüllt wird, sobald die MediaKeys verknüpft sind. Scheitert der Vorgang, wird es mit einer DOMException abgelehnt: InvalidStateError (z. B. wenn schon eine andere Zuweisung läuft), QuotaExceededError (die MediaKeys sind schon an ein anderes Element gebunden) oder NotSupportedError (bestehende Keys dürfen nicht entfernt werden).

Beispiele

MediaKeys erzeugen und an ein Video binden (Clear Key)

const video = document.querySelector('video');

const config = [{
  initDataTypes: ['cenc'],
  videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }]
}];

const setupDrm = async () => {
  const access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', config);
  const mediaKeys = await access.createMediaKeys();
  await video.setMediaKeys(mediaKeys);
  console.log('MediaKeys gesetzt:', video.mediaKeys === mediaKeys);
  video.src = '/media/encrypted.mp4';
};

setupDrm().catch((err) => console.error('DRM-Setup fehlgeschlagen:', err.name, err.message));
MediaKeys gesetzt: true

Auf das encrypted-Ereignis reagieren und eine Lizenz anfordern

const video = document.querySelector('video');

video.addEventListener('encrypted', async (event) => {
  if (!video.mediaKeys) {
    const access = await navigator.requestMediaKeySystemAccess('com.widevine.alpha', [{
      initDataTypes: [event.initDataType],
      videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.640028"' }]
    }]);
    await video.setMediaKeys(await access.createMediaKeys());
  }

  const session = video.mediaKeys.createSession();
  session.addEventListener('message', async (msgEvent) => {
    const res = await fetch('https://license.example.com/widevine', {
      method: 'POST',
      body: msgEvent.message
    });
    await session.update(await res.arrayBuffer());
  });

  await session.generateRequest(event.initDataType, event.initData);
});

MediaKeys beim Abbau des Players wieder lösen

const teardownPlayer = async (video) => {
  video.pause();
  video.removeAttribute('src');
  video.load();
  try {
    await video.setMediaKeys(null);
    console.log('MediaKeys entfernt:', video.mediaKeys);
  } catch (err) {
    // z. B. NotSupportedError, wenn das CDM das Entfernen nicht erlaubt
    console.warn('Entfernen nicht möglich:', err.name);
  }
};

teardownPlayer(document.querySelector('video'));
MediaKeys entfernt: null

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: EME steht nur unter HTTPS bzw. localhost zur Verfügung. In iframes kann die Permissions-Policy encrypted-media nötig sein (<iframe allow="encrypted-media">).
  • Nicht parallel aufrufen: Läuft noch ein früherer setMediaKeys()-Aufruf, wird der zweite mit InvalidStateError abgelehnt. Warten Sie also immer mit await auf das Promise.
  • Ein MediaKeys-Objekt pro Element: Ein MediaKeys-Objekt lässt sich nicht an mehrere Medienelemente zugleich binden (QuotaExceededError).
  • Die Browser unterstützen unterschiedliche Schlüsselsysteme: Chrome, Edge und Firefox nutzen Widevine, Edge zusätzlich PlayReady, Safari nur FairPlay (com.apple.fps). org.w3.clearkey eignet sich nur zum Testen und bietet keinen echten Schutz.
  • Ältere Safari-Versionen hatten ein Präfix (webkitSetMediaKeys) mit abweichender API. Für produktive Player lohnen sich deshalb Bibliotheken wie Shaka Player oder dash.js.
  • Ob das Entfernen oder Austauschen während der Wiedergabe klappt, entscheidet das CDM. Fangen Sie Fehler deshalb immer ab.