Signatur
Beschreibung
Mit close() teilt die Anwendung mit, dass sie eine Sitzung der Encrypted Media Extensions (EME) nicht mehr braucht. Das Content Decryption Module (CDM) gibt danach alle Schlüssel und internen Ressourcen der Sitzung frei. Ab diesem Moment lassen sich damit keine Medien mehr entschlüsseln.
Die Methode gibt ein Promise zurück. Es wird erfüllt, sobald die Sitzung geschlossen ist. Gleichzeitig wird das Promise in MediaKeySession.closed erfüllt. Dort sollte die Aufräumlogik stehen, denn eine Sitzung kann auch ohne Zutun der Anwendung enden, zum Beispiel wenn das CDM abstürzt oder Hardware-Ressourcen entzogen werden.
Setze close() ein, wenn du die Wiedergabe beendest, zu einem anderen Inhalt wechselst oder eine Sitzung nach einem Fehler neu aufbauen musst. Bei dauerhaften Sitzungen ("persistent-license") bleiben gespeicherte Lizenzdaten nach close() erhalten. Sollen sie gelöscht werden, rufe vorher remove() auf.
Rückgabewert
Promise, das mit undefined erfüllt wird, sobald die Sitzung geschlossen ist. Ist die Sitzung bereits geschlossen, wird es sofort erfüllt. Wurde die Sitzung noch nicht initialisiert (weder generateRequest() noch load() aufgerufen), wird es mit einem InvalidStateError abgelehnt.Beispiele
Sitzung beim Beenden der Wiedergabe schließen
const video = document.querySelector('video');
let session = null;
video.addEventListener('encrypted', async (event) => {
const mediaKeys = video.mediaKeys;
session = mediaKeys.createSession();
session.addEventListener('message', async (msg) => {
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('ended', async () => {
if (session) {
await session.close();
console.log('Sitzung geschlossen:', session.sessionId);
session = null;
}
});
Aufräumen über das closed-Promise
const watchSession = (session) => {
session.closed.then((reason) => {
// reason ist in neueren Browsern z. B. 'closed-by-application' oder 'internal-error'
console.log('Sitzung beendet, Grund:', reason ?? 'unbekannt');
});
};
// irgendwo später:
// watchSession(session);
// await session.close();
Alle Sitzungen beim Inhaltswechsel sicher schließen
const sessions = new Set();
const closeAllSessions = async () => {
const results = await Promise.allSettled(
[...sessions].map((s) => s.close())
);
results.forEach((r, i) => {
if (r.status === 'rejected') {
console.warn(`Sitzung ${i} konnte nicht geschlossen werden:`, r.reason.name);
}
});
sessions.clear();
console.log('Alle Sitzungen freigegeben');
};
const switchSource = async (video, url) => {
await closeAllSessions();
video.src = url;
};
// Wichtig · Fallstricke
- Nicht initialisierte Sitzung: Ruft man
close()auf, bevorgenerateRequest()oderload()gelaufen ist, wird das Promise mitInvalidStateErrorabgelehnt. Fehler deshalb immer mittry/catchoderPromise.allSettled()abfangen. - close() ist nicht remove(): Bei
"persistent-license"-Sitzungen bleiben gespeicherte Lizenzdaten nachclose()erhalten. Zum Löschen vorherremove()aufrufen. - Speicherlecks vermeiden: Nicht geschlossene Sitzungen belegen CDM-Ressourcen. Manche Hardware-CDMs erlauben nur wenige gleichzeitige Sitzungen, deshalb bei jedem Inhaltswechsel aufräumen.
- Der Grund für das Schließen (
MediaKeySessionClosedReason) imclosed-Promise wird noch nicht von allen Browsern geliefert. Mitundefinedrechnen. - Kompatibilität: EME gibt es nur in sicheren Kontexten (HTTPS). Welche Schlüsselsysteme verfügbar sind, hängt vom Browser ab (Widevine, PlayReady, FairPlay, Clear Key).