Signatur
Beschreibung
Mit navigator.requestMediaKeySystemAccess() beginnt jede Wiedergabe verschlüsselter Medien über die Encrypted Media Extensions (EME). Die Methode prüft, ob der Browser ein bestimmtes Schlüsselsystem (Content Decryption Module, CDM) unterstützt, und zwar mit mindestens einer der übergebenen Konfigurationen (Container, Codecs, Robustheit, Sitzungstypen usw.).
Wird eine passende Konfiguration gefunden, wird das Promise mit einem MediaKeySystemAccess-Objekt erfüllt. Über dessen Methode createMediaKeys() erzeugt man ein MediaKeys-Objekt, das per HTMLMediaElement.setMediaKeys() an ein <video>- oder <audio>-Element gebunden wird. Mit getConfiguration() sieht man, welche Konfiguration der Browser tatsächlich gewählt hat.
Die Konfigurationen werden in der angegebenen Reihenfolge geprüft; die erste, die unterstützt wird, gewinnt. Man ordnet sie deshalb nach Präferenz (z. B. zuerst hohe Robustheit, dann Software-Fallback). Wird keine Konfiguration unterstützt oder ist das Schlüsselsystem unbekannt, wird das Promise mit einer NotSupportedError-DOMException abgelehnt.
In der Praxis wird die Methode meist von Playern wie Shaka Player, dash.js oder hls.js aufgerufen. Direkte Nutzung ist sinnvoll für Feature-Erkennung („Welches DRM kann dieser Browser?“) oder eigene, schlanke Player.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $keySystem Pflicht | string | Kennung des Schlüsselsystems, z. B. "com.widevine.alpha", "com.microsoft.playready", "com.apple.fps" oder "org.w3.clearkey". |
|
| $supportedConfigurations Pflicht | MediaKeySystemConfiguration[] | Nicht-leeres Array von Konfigurationsobjekten mit u. a. initDataTypes (z. B. ["cenc"]), audioCapabilities und videoCapabilities (je { contentType, robustness }), distinctiveIdentifier und persistentState ("required", "optional", "not-allowed") sowie sessionTypes (z. B. ["temporary"], ["persistent-license"]). Ein leeres Array führt zu einem TypeError. |
Rückgabewert
MediaKeySystemAccess-Objekt erfüllt wird, wenn eine Konfiguration unterstützt wird. Andernfalls Ablehnung mit NotSupportedError (nicht unterstützt), TypeError (leerer keySystem oder leeres Konfigurations-Array) oder SecurityError (unsicherer Kontext / Permissions-Policy).Beispiele
Unterstützte DRM-Systeme erkennen
const keySystems = [
'com.widevine.alpha',
'com.microsoft.playready',
'com.apple.fps',
'org.w3.clearkey'
];
const config = [{
initDataTypes: ['cenc'],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }],
audioCapabilities: [{ contentType: 'audio/mp4; codecs="mp4a.40.2"' }]
}];
const detectDrm = async () => {
const result = {};
for (const ks of keySystems) {
try {
await navigator.requestMediaKeySystemAccess(ks, config);
result[ks] = true;
} catch {
result[ks] = false;
}
}
return result;
};
detectDrm().then(console.log);
MediaKeys erzeugen und an ein Video binden
const video = document.querySelector('video');
const setupDrm = async () => {
const access = await navigator.requestMediaKeySystemAccess('com.widevine.alpha', [{
initDataTypes: ['cenc'],
videoCapabilities: [{
contentType: 'video/mp4; codecs="avc1.640028"',
robustness: 'SW_SECURE_DECODE'
}],
audioCapabilities: [{
contentType: 'audio/mp4; codecs="mp4a.40.2"',
robustness: 'SW_SECURE_CRYPTO'
}],
sessionTypes: ['temporary']
}]);
console.log('Gewählte Konfiguration:', access.getConfiguration());
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 eigenen Lizenzserver
const res = await fetch('/license', { method: 'POST', body: msg.message });
await session.update(await res.arrayBuffer());
});
await session.generateRequest(event.initDataType, event.initData);
});
};
setupDrm().catch((err) => console.error('DRM nicht verfügbar:', err.name));
Konfigurationen nach Präferenz mit Fallback
const getBestAccess = async () => {
const video = (robustness) => [{
contentType: 'video/mp4; codecs="avc1.640028"',
robustness
}];
// Erst Hardware-DRM (HW_SECURE_ALL), dann Software-Fallback
const access = await navigator.requestMediaKeySystemAccess('com.widevine.alpha', [
{ initDataTypes: ['cenc'], videoCapabilities: video('HW_SECURE_ALL') },
{ initDataTypes: ['cenc'], videoCapabilities: video('SW_SECURE_CRYPTO') }
]);
const { robustness } = access.getConfiguration().videoCapabilities[0];
console.log(`Robustheit: ${robustness}`);
return access;
};
getBestAccess();
// Wichtig · Fallstricke
- Nur in sicheren Kontexten (HTTPS bzw.
localhost) verfügbar. In iframes muss die Permissions-Policyencrypted-mediaerlaubt sein (<iframe allow="encrypted-media">), sonst gibt es einenSecurityError. - Immer Codecs angeben: Fehlt
contentTypebzw. die Codec-Angabe invideoCapabilities/audioCapabilities, geben Chrome und andere eine Konsolenwarnung aus und das Verhalten kann sich künftig ändern.robustnesssollte ebenfalls gesetzt werden. - Browserabhängige Schlüsselsysteme: Chrome/Firefox/Edge unterstützen i. d. R. Widevine (Edge zusätzlich PlayReady), Safari FairPlay (
com.apple.fps, teils mitinitDataTypes: ['sinf']oder['skd']). ClearKey ist nur für Tests gedacht und bietet keinen echten Schutz. - Auf manchen Linux-Distributionen oder in Chromium-Builds ohne Widevine-CDM schlägt der Aufruf fehl; in Firefox muss DRM vom Nutzer ggf. erst aktiviert werden (erstes Aufrufen löst einen Download des CDM aus, der Aufruf kann dann länger dauern).
- Datenschutz:
distinctiveIdentifier: "required"oderpersistentState: "required"kann Nutzer-Rückfragen auslösen oder abgelehnt werden. Nur anfordern, wenn wirklich nötig (z. B. für Offline-Lizenzen). - Das Ergebnis nicht dauerhaft cachen – Unterstützung kann sich durch Updates oder Einstellungen ändern. Wiederholte Aufrufe zur Erkennung sind unbedenklich, können aber einige hundert Millisekunden dauern.