Start · Sprachen · JavaScript · Referenz · MediaKeySystemAccess

MediaKeySystemAccess

Schnittstelle

Stellt den Zugriff auf ein Key System der Encrypted Media Extensions (EME) dar und erzeugt <code>MediaKeys</code> für die Wiedergabe verschlüsselter Medien.

seit JavaScript Baseline: alle modernen Browser (seit 2019); nur i Kategorie: webapi

Signatur

interface MediaKeySystemAccess

Beschreibung

MediaKeySystemAccess gehört zur Encrypted Media Extensions API (EME). Man erzeugt ein solches Objekt nicht selbst. Es ist der Erfüllungswert des Promises von navigator.requestMediaKeySystemAccess(keySystem, configs). Das Objekt bestätigt, dass der Browser das angefragte Key System (z. B. "com.widevine.alpha", "com.microsoft.playready", "com.apple.fps" oder "org.w3.clearkey") mit mindestens einer der übergebenen Konfigurationen unterstützt.

Das Interface hat drei Mitglieder:

  • keySystem (nur lesbar, string): der Name des ausgewählten Key Systems.
  • getConfiguration(): gibt ein MediaKeySystemConfiguration-Objekt zurück, also die Konfiguration, die der Browser tatsächlich ausgewählt hat. Sie enthält z. B. die unterstützten Codecs, persistentState, distinctiveIdentifier und sessionTypes.
  • createMediaKeys(): gibt ein Promise<MediaKeys> zurück. Das MediaKeys-Objekt hängt man mit HTMLMediaElement.setMediaKeys() an ein <video>- oder <audio>-Element an.

Der typische Ablauf bei DRM-geschützter Wiedergabe sieht so aus: Unterstützung abfragen → MediaKeySystemAccess erhalten → createMediaKeys() aufrufen → setMediaKeys() aufrufen → beim encrypted-Event eine MediaKeySession erzeugen → die Lizenz vom Lizenzserver holen und mit session.update() übergeben. In der Praxis übernehmen Player-Bibliotheken wie Shaka Player, dash.js oder hls.js diesen Ablauf meist. Direkt nutzt man das Interface vor allem, um Fähigkeiten zu prüfen oder eigene Player zu bauen.

Parameter

Name Typ Default Beschreibung
$keySystem Pflicht string Parameter von navigator.requestMediaKeySystemAccess(): der Name des Key Systems, z. B. "org.w3.clearkey" oder "com.widevine.alpha".
$supportedConfigurations Pflicht MediaKeySystemConfiguration[] Parameter von navigator.requestMediaKeySystemAccess(): eine nicht leere Liste von Konfigurationen, geordnet nach Priorität. Mögliche Felder sind initDataTypes, audioCapabilities, videoCapabilities, distinctiveIdentifier, persistentState und sessionTypes. Der Browser wählt die erste unterstützte Konfiguration.

Rückgabewert

Typ
MediaKeySystemAccess
Beschreibung
Kommt als Erfüllungswert von navigator.requestMediaKeySystemAccess(). Bietet keySystem, getConfiguration() (Rückgabetyp MediaKeySystemConfiguration) und createMediaKeys() (Rückgabetyp Promise<MediaKeys>).

Beispiele

Unterstützung eines Key Systems prüfen

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

const isSupported = async (keySystem) => {
  try {
    const access = await navigator.requestMediaKeySystemAccess(keySystem, config);
    console.log(`${access.keySystem} wird unterstützt`);
    return true;
  } catch (err) {
    console.log(`${keySystem} nicht verfügbar: ${err.name}`);
    return false;
  }
};

for (const ks of ['com.widevine.alpha', 'com.microsoft.playready', 'org.w3.clearkey']) {
  await isSupported(ks);
}
com.widevine.alpha wird unterstützt com.microsoft.playready nicht verfügbar: NotSupportedError org.w3.clearkey wird unterstützt

Tatsächlich gewählte Konfiguration auslesen

const access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{
  initDataTypes: ['keyids', 'webm'],
  videoCapabilities: [
    { contentType: 'video/webm; codecs="vp9"' },
    { contentType: 'video/mp4; codecs="hev1.1.6.L93.B0"' }
  ],
  persistentState: 'optional'
}]);

const chosen = access.getConfiguration();
console.log(chosen.initDataTypes);
console.log(chosen.videoCapabilities.map((c) => c.contentType));
console.log(chosen.persistentState);
["keyids", "webm"] ["video/webm; codecs=\"vp9\""] "not-allowed"

MediaKeys erzeugen und an ein Video hängen (Clear Key)

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

const access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{
  initDataTypes: ['keyids'],
  videoCapabilities: [{ contentType: 'video/webm; codecs="vp8"' }]
}]);

const mediaKeys = await access.createMediaKeys();
await video.setMediaKeys(mediaKeys);

video.addEventListener('encrypted', async (event) => {
  const session = mediaKeys.createSession();
  session.addEventListener('message', async (msg) => {
    // Lizenzanfrage an den Server senden
    const res = await fetch('/license', { method: 'POST', body: msg.message });
    await session.update(await res.arrayBuffer());
  });
  await session.generateRequest(event.initDataType, event.initData);
});

video.src = '/media/encrypted.webm';

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: navigator.requestMediaKeySystemAccess() steht nur über HTTPS oder localhost zur Verfügung. In iframes muss die Permissions Policy encrypted-media erlaubt sein, etwa mit <iframe allow="encrypted-media">.
  • Ablehnung mit NotSupportedError: Das Promise wird abgelehnt, wenn das Key System oder keine der Konfigurationen unterstützt wird. Fehlen audioCapabilities und videoCapabilities, geben Chrome und andere Browser eine Konsolenwarnung aus. Zukünftig kann das zu einer Ablehnung führen. Deshalb immer konkrete contentType-Angaben mit Codecs machen und robustness setzen, wo nötig.
  • Die zurückgegebene Konfiguration kann abweichen: getConfiguration() gibt nur die tatsächlich unterstützte Teilmenge zurück. Nicht angenommene Codecs fehlen darin. Prüfe also diese Konfiguration statt deiner eigenen Anfrage.
  • Browser-Unterschiede: Welche Key Systems es gibt, hängt vom Browser ab. Chrome, Edge und Firefox bieten Widevine, Edge zusätzlich PlayReady, Safari FairPlay (com.apple.fps). Clear Key ist fast überall vorhanden, bietet aber keinen echten Kopierschutz. Unter Linux oder in Headless-Umgebungen fehlt Widevine oft.
  • Datenschutz: distinctiveIdentifier: "required" und persistentState: "required" können eine Nutzerabfrage auslösen oder im Inkognito-Modus scheitern. Fordere sie nur an, wenn sie wirklich nötig sind.