Signatur
Beschreibung
Das Ereignis updateend gehört zur Schnittstelle SourceBuffer aus den Media Source Extensions (MSE). Es wird ausgelöst, wenn eine asynchrone Pufferoperation, also appendBuffer() oder remove(), fertig ist. Zu diesem Zeitpunkt steht sourceBuffer.updating wieder auf false. Erst jetzt dürfen Sie die nächste Operation am selben Puffer starten.
Die Reihenfolge der Ereignisse ist festgelegt: Zuerst kommt updatestart. Danach folgt genau eines der Ereignisse update (Erfolg), error (Fehler) oder abort (Abbruch durch abort()). Ganz am Ende kommt immer updateend. Deshalb eignet sich updateend gut als zentrale Stelle für die Warteschlangen-Logik: nächstes Segment anhängen, alte Bereiche entfernen oder mediaSource.endOfStream() aufrufen.
Registrieren können Sie den Handler mit addEventListener("updateend", handler) oder über die Eigenschaft sourceBuffer.onupdateend. Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften. Es blubbert nicht (bubbles) und lässt sich nicht abbrechen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "updateend". |
|
| $handler Pflicht | (event: Event) => void | Callback, das nach Abschluss der Pufferoperation aufgerufen wird. event.target ist der betroffene SourceBuffer. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { once: true }, praktisch für einmalige Aktionen nach einem bestimmten Append. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein Event-Objekt.Beispiele
Segmente nacheinander anhängen (Warteschlange)
const video = document.querySelector('video');
const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
const segmente = ['init.mp4', 'seg1.m4s', 'seg2.m4s', 'seg3.m4s'];
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', async () => {
const sb = mediaSource.addSourceBuffer(mime);
const puffer = await Promise.all(
segmente.map(async (url) => (await fetch(url)).arrayBuffer())
);
const naechstes = () => {
if (puffer.length > 0) {
sb.appendBuffer(puffer.shift());
} else if (mediaSource.readyState === 'open') {
mediaSource.endOfStream();
console.log('Alle Segmente angehängt');
}
};
sb.addEventListener('updateend', naechstes);
naechstes(); // erstes Segment starten
});
Erfolg und Fehler unterscheiden
const beobachte = (sb) => {
let fehler = false;
sb.addEventListener('updatestart', () => { fehler = false; });
sb.addEventListener('error', () => { fehler = true; });
sb.addEventListener('updateend', () => {
console.log(fehler ? 'Operation fehlgeschlagen' : 'Operation erfolgreich',
'| gepuffert bis:', sb.buffered.length ? sb.buffered.end(sb.buffered.length - 1) : 0);
});
};
Promise-Hilfsfunktion mit onupdateend bzw. once
// Wartet, bis der SourceBuffer frei ist
const warteAufUpdate = (sb) => new Promise((resolve) => {
if (!sb.updating) return resolve();
sb.addEventListener('updateend', () => resolve(), { once: true });
});
const altesEntfernen = async (sb, video) => {
await warteAufUpdate(sb);
const bis = video.currentTime - 30;
if (bis > 0) {
sb.remove(0, bis);
await warteAufUpdate(sb);
console.log('Puffer bereinigt bis', bis.toFixed(1));
}
};
// Alternative per Property (ersetzt vorherigen Handler!)
// sb.onupdateend = () => console.log('fertig');
// sb.onupdateend = null; // Handler wieder entfernen
// Wichtig · Fallstricke
updateendheißt nicht „erfolgreich“: Das Ereignis kommt auch nacherrorundabort. Für den Erfolgsfall hören Sie aufupdate.- InvalidStateError: Rufen Sie
appendBuffer()oderremove()auf, solangeupdating === trueist, wird einInvalidStateErrorgeworfen. Warten Sie deshalb immer aufupdateend. - QuotaExceededError: Ist der Puffer voll, wirft
appendBuffer()synchron einen Fehler, undupdateendwird nicht ausgelöst. Entfernen Sie alte Bereiche mitremove()und versuchen Sie es danach erneut. endOfStream()darf nur aufgerufen werden, wenn kein SourceBuffer mehrupdatingist. Der richtige Zeitpunkt dafür ist also einupdateend-Handler.- Eine Zuweisung an
onupdateendüberschreibt einen vorher gesetzten Handler. Mehrere Listener registrieren Sie mitaddEventListener. - Kompatibilität: MSE wird von Chrome, Edge, Firefox und Safari (Desktop) unterstützt. Auf dem iPhone steht es erst ab iOS 17.1 als
ManagedMediaSourcezur Verfügung. Prüfen Sie Codecs vorab mitMediaSource.isTypeSupported().