Start · Sprachen · JavaScript · Referenz · SourceBuffer: error

SourceBuffer: error

Ereignis

Wird am <code>SourceBuffer</code> ausgelöst, wenn beim Verarbeiten der Daten aus <code>appendBuffer()</code> ein Fehler auftritt, z. B. bei ungültigen oder nicht unterstützten Mediendaten.

seit JavaScript Media Source Extensions – Baseline: Chrome, Edge, Kategorie: webapi

Signatur

sourceBuffer.addEventListener("error", handler)

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

Typ
void
Beschreibung
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]));
});
SourceBuffer-Fehler: error MediaSource-Zustand: ended MediaError-Code: 3

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
    }
  }
};
Segment angehängt: /video/init.mp4 appendBuffer fehlgeschlagen /video/seg-1.m4s

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.message und die Konsole der Entwicklerwerkzeuge (in Chrome z. B. im „Media“-Panel).
  • Nicht jeder Fehler löst error aus: Wenn du appendBuffer() aufrufst, während updating noch true ist, der Buffer entfernt wurde oder readyState auf "closed" steht, wird sofort synchron eine InvalidStateError-DOMException geworfen. Ist der Speicher voll, kommt eine QuotaExceededError. Beides fängst du mit try/catch ab.
  • Nach error folgt immer updateend. Wer Appends nur über updateend in eine Warteschlange einreiht, muss den Fehlerfall selbst erkennen. Sonst läuft die Schleife weiter und scheitert erneut, weil die MediaSource dann bereits im Zustand "ended" ist.
  • Ein Aufruf von abort() löst abort und updateend aus, aber kein error.
  • 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, dessen SourceBuffer dasselbe Ereignis auslöst. In Dedicated Workers ist MSE nur in einigen Browsern verfügbar (z. B. Chrome 108+).