Signatur
Beschreibung
Das error-Ereignis gehört zu den Media Source Extensions (MSE). Es wird an einem SourceBuffer ausgelöst, wenn der Browser die mit appendBuffer() übergebenen Daten nicht verarbeiten kann. Typische Ursachen sind kaputte oder abgeschnittene Segmente, ein fehlendes Initialisierungssegment, ein Codec, der nicht zum MIME-Typ aus addSourceBuffer() passt, oder Daten, die der Demuxer nicht versteht.
Das Ereignis ist ein schlichtes Event ohne Fehlerdetails. Es blubbert nicht und lässt sich nicht abbrechen. Die Reihenfolge ist festgelegt: Zuerst wird updating auf false gesetzt, dann folgen error und anschließend updateend. Das Ereignis update kommt in diesem Fall nicht. Bei Fehlern im Parser (dem sogenannten „append error algorithm“) ruft der Browser außerdem mediaSource.endOfStream("decode") auf. Die MediaSource wechselt dadurch in den Zustand "ended", und am Medienelement wird ein MediaError mit dem Code MEDIA_ERR_DECODE gesetzt.
Einen Handler meldest du mit addEventListener("error", handler) an oder weist ihn der Eigenschaft sourceBuffer.onerror zu. Das Ereignis eignet sich vor allem dazu, Fehler zu protokollieren, eine Anzeige für den Nutzer zu zeigen oder die Wiedergabe mit einer neuen MediaSource bzw. einer anderen Qualitätsstufe neu aufzubauen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, hier immer "error". |
|
| $handler Pflicht | (event: Event) => void | Callback, das ein einfaches Event erhält. event.target ist der betroffene SourceBuffer. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once oder signal, um den Listener automatisch wieder zu entfernen. |
Rückgabewert
addEventListener() gibt nichts zurück. Der Handler erhält ein Event, das keine Fehlerdetails enthält.Beispiele
Fehler beim Anhängen mit addEventListener erkennen
const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', async () => {
const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if (!MediaSource.isTypeSupported(mime)) {
console.warn('Codec nicht unterstützt');
return;
}
const sb = mediaSource.addSourceBuffer(mime);
sb.addEventListener('error', (e) => {
console.error('SourceBuffer-Fehler:', e.type);
console.log('MediaSource-Zustand:', mediaSource.readyState);
console.log('MediaError-Code:', video.error?.code);
});
// Absichtlich ungültige Daten anhängen
sb.appendBuffer(new Uint8Array([0, 1, 2, 3, 4, 5]));
});
appendBuffer als Promise mit Fehlerbehandlung
const appendAsync = (sourceBuffer, data) =>
new Promise((resolve, reject) => {
const controller = new AbortController();
const { signal } = controller;
sourceBuffer.addEventListener('updateend', () => {
controller.abort(); // alle Listener entfernen
resolve();
}, { signal });
sourceBuffer.addEventListener('error', () => {
controller.abort();
reject(new Error('appendBuffer fehlgeschlagen'));
}, { signal });
sourceBuffer.appendBuffer(data);
});
// Verwendung innerhalb eines sourceopen-Handlers:
const loadSegments = async (sb, urls) => {
for (const url of urls) {
const data = await (await fetch(url)).arrayBuffer();
try {
await appendAsync(sb, data);
console.log('Segment angehängt:', url);
} catch (err) {
console.error(err.message, url);
break; // weitere Appends wären sinnlos
}
}
};
on-Property verwenden und wieder entfernen
const mediaSource = new MediaSource();
const video = document.querySelector('video');
video.src = URL.createObjectURL(mediaSource);
mediaSource.onsourceopen = () => {
const sb = mediaSource.addSourceBuffer('video/webm; codecs="vp9"');
sb.onerror = () => {
document.querySelector('#status').textContent =
'Das Video konnte nicht dekodiert werden.';
sb.onerror = null; // Handler entfernen
};
fetch('/video/clip.webm')
.then((res) => res.arrayBuffer())
.then((buf) => sb.appendBuffer(buf));
};
// Wichtig · Fallstricke
- Keine Fehlerdetails: Das Ereignis sagt nicht, was schiefging. Genauere Hinweise liefern
video.error.code,video.error.messageund die Konsole der Entwicklerwerkzeuge (in Chrome z. B. im „Media“-Panel). - Nicht jeder Fehler löst
erroraus: Wenn duappendBuffer()aufrufst, währendupdatingnochtrueist, der Buffer entfernt wurde oderreadyStateauf"closed"steht, wird sofort synchron eineInvalidStateError-DOMExceptiongeworfen. Ist der Speicher voll, kommt eineQuotaExceededError. Beides fängst du mittry/catchab. - Nach
errorfolgt immerupdateend. Wer Appends nur überupdateendin eine Warteschlange einreiht, muss den Fehlerfall selbst erkennen. Sonst läuft die Schleife weiter und scheitert erneut, weil dieMediaSourcedann bereits im Zustand"ended"ist. - Ein Aufruf von
abort()löstabortundupdateendaus, aber keinerror. - Mit
MediaSource.isTypeSupported()prüfst du den MIME-Typ vorab. Das schließt fehlerhafte Daten aber nicht aus. - Kompatibilität: MSE wird in allen modernen Desktop-Browsern unterstützt. Auf dem iPhone gibt es erst ab iOS 17.1
ManagedMediaSource, dessenSourceBufferdasselbe Ereignis auslöst. In Dedicated Workers ist MSE nur in einigen Browsern verfügbar (z. B. Chrome 108+).