Signatur
Beschreibung
generateRequest() gehört zu den Encrypted Media Extensions (EME) und startet den Lizenzaustausch für verschlüsselte Medieninhalte. Die Methode übergibt die Initialisierungsdaten (z. B. einen PSSH-Block aus einer MP4-Datei) an das Content Decryption Module (CDM). Das CDM erzeugt daraus eine Lizenzanfrage.
Wichtig: Das zurückgegebene Promise enthält nicht die Lizenzanfrage selbst. Das CDM löst stattdessen auf der Sitzung ein message-Event aus (messageType: "license-request"). Dessen message-Eigenschaft (ein ArrayBuffer) schickt man an den Lizenzserver. Die Antwort des Servers gibt man anschließend mit MediaKeySession.update() an die Sitzung zurück.
Typischerweise ruft man die Methode im Handler des encrypted-Events eines HTMLMediaElement auf. Das Event liefert initDataType und initData direkt mit. Vorher müssen die Schlüssel über navigator.requestMediaKeySystemAccess(), createMediaKeys() und video.setMediaKeys() eingerichtet sein. Die Sitzung selbst erzeugt man mit mediaKeys.createSession().
Pro Sitzung darf generateRequest() nur einmal aufgerufen werden. Für weitere Initialisierungsdaten legt man eine neue Sitzung an.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $initDataType Pflicht | string | Format der Initialisierungsdaten, z. B. "cenc" (Common Encryption, PSSH), "keyids" (JSON-Liste von Key-IDs) oder "webm". Das Format muss vom Schlüsselsystem unterstützt werden. |
|
| $initData Pflicht | ArrayBuffer|TypedArray|DataView | Die eigentlichen Initialisierungsdaten, meist event.initData aus dem encrypted-Event. |
Rückgabewert
message-Event der Sitzung. Bei ungültigen Daten wird das Promise abgelehnt, z. B. mit TypeError, NotSupportedError oder InvalidStateError.Beispiele
Lizenzanfrage im encrypted-Event erzeugen (Clear Key)
const video = document.querySelector('video');
const config = [{
initDataTypes: ['cenc'],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }]
}];
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 (msgEvent) => {
// Lizenzanfrage an den Server senden
const response = await fetch('https://license.example.com/clearkey', {
method: 'POST',
body: msgEvent.message
});
const license = await response.arrayBuffer();
await session.update(license);
console.log('Lizenz übernommen');
});
await session.generateRequest(event.initDataType, event.initData);
console.log('Lizenzanfrage erzeugt:', event.initDataType);
});
Anfrage mit bekannten Key-IDs (keyids-Format)
const toBase64Url = (bytes) =>
btoa(String.fromCharCode(...bytes))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const keyId = new Uint8Array([0x10,0x77,0xef,0xec,0xc0,0xb2,0x4d,0x02,
0xac,0xe3,0x3c,0x1e,0x52,0xe2,0xfb,0x4b]);
const initData = new TextEncoder().encode(
JSON.stringify({ kids: [toBase64Url(keyId)] })
);
const access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{
initDataTypes: ['keyids'],
videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"' }]
}]);
const mediaKeys = await access.createMediaKeys();
const session = mediaKeys.createSession('temporary');
session.addEventListener('message', (e) => {
console.log('Nachrichtentyp:', e.messageType);
});
await session.generateRequest('keyids', initData);
Fehlerbehandlung bei nicht unterstütztem Format
const handleEncrypted = async (mediaKeys, event) => {
const session = mediaKeys.createSession();
try {
await session.generateRequest(event.initDataType, event.initData);
} catch (err) {
// z. B. NotSupportedError, wenn das CDM das Format nicht kennt
console.error(`generateRequest fehlgeschlagen: ${err.name}`);
await session.close();
}
};
// Wichtig · Fallstricke
- Nur einmal pro Sitzung: Ein zweiter Aufruf auf derselben
MediaKeySessionführt zu einemInvalidStateError. Das gilt auch für eine bereits geschlossene Sitzung. - Listener zuerst registrieren: Den
message-Listener vorgenerateRequest()anhängen, sonst kann die Lizenzanfrage verloren gehen. - Leere Initialisierungsdaten führen zu einem
TypeError. Ein von der Konfiguration nicht unterstütztesinitDataTypeführt zu einemNotSupportedError. - Doppelte encrypted-Events: Browser lösen
encryptedoft mehrfach aus, etwa für Audio und Video oder mehrere PSSH-Boxen. Bereits verarbeiteteinitDatasollte man erkennen und ignorieren, um überflüssige Sitzungen und Lizenzanfragen zu vermeiden. - Sicherer Kontext: EME ist nur über HTTPS verfügbar. Welche Schlüsselsysteme es gibt, hängt vom Browser ab: Widevine in Chrome, Firefox und Edge, FairPlay in Safari, PlayReady in Edge. Nur
org.w3.clearkeyist weitgehend überall vorhanden. Safari/FairPlay verwendet teils das eigeneinitDataType"sinf"bzw."skd". - In iframes kann die Permissions-Policy
encrypted-mediadie Nutzung blockieren.