Start · Sprachen · JavaScript · Referenz · MediaSource.removeSourceBuffer()

MediaSource.removeSourceBuffer()

Methode

Entfernt einen <code>SourceBuffer</code> aus der <code>sourceBuffers</code>-Liste eines <code>MediaSource</code>-Objekts und bricht dabei laufende Anhänge- oder Entfernvorgänge ab.

seit JavaScript Baseline: alle modernen Browser (Media Source Exte Kategorie: webapi

Signatur

MediaSource.prototype.removeSourceBuffer(sourceBuffer)

Beschreibung

Mit removeSourceBuffer() löst man einen zuvor per addSourceBuffer() erzeugten SourceBuffer wieder von seiner MediaSource. Der Puffer verschwindet aus mediaSource.sourceBuffers und, falls er aktiv war, auch aus mediaSource.activeSourceBuffers. Danach lässt er sich nicht mehr verwenden. Jeder weitere Aufruf von appendBuffer() o. Ä. wirft einen Fehler.

Typische Einsatzfälle:

  • Beim Wechsel des Codecs oder der Spur (z. B. andere Audiosprache, anderes Containerformat), wenn SourceBuffer.changeType() nicht verfügbar ist oder nicht ausreicht.
  • Beim Aufräumen eines Players, bevor eine neue Quelle geladen wird.
  • Beim Entfernen einer Spur während der Wiedergabe, etwa wenn ein Stream ab einem Zeitpunkt nur noch Video liefert.

Läuft auf dem Puffer gerade ein Vorgang (updating === true), bricht der Browser ihn ab und feuert auf dem SourceBuffer die Ereignisse abort und updateend. Außerdem feuert die SourceBufferList das Ereignis removesourcebuffer. Wenn sich dadurch die aktiven Spuren ändern, kommt noch change auf den zugehörigen Track-Listen hinzu.

Parameter

Name Typ Default Beschreibung
$sourceBuffer Pflicht SourceBuffer Der zu entfernende SourceBuffer. Er muss zu genau dieser MediaSource gehören, also in mediaSource.sourceBuffers enthalten sein.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Die Wirkung zeigt sich an mediaSource.sourceBuffers und am Ereignis removesourcebuffer.

Beispiele

SourceBuffer beim Aufräumen des Players entfernen

const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', () => {
  const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
  const sb = mediaSource.addSourceBuffer(mime);
  console.log('Puffer vorher:', mediaSource.sourceBuffers.length);

  // ... Segmente anhängen ...

  // Später: Puffer wieder entfernen
  mediaSource.removeSourceBuffer(sb);
  console.log('Puffer nachher:', mediaSource.sourceBuffers.length);
});
Puffer vorher: 1 Puffer nachher: 0

Sicher entfernen: Zugehörigkeit prüfen und auf laufende Updates reagieren

const safeRemove = (mediaSource, sb) => {
  // Nur entfernen, wenn der Puffer wirklich zu dieser MediaSource gehört
  const owned = Array.from(mediaSource.sourceBuffers).includes(sb);
  if (!owned) {
    console.warn('SourceBuffer gehört nicht (mehr) zu dieser MediaSource');
    return false;
  }
  if (sb.updating) {
    // Laufender append/remove wird abgebrochen -> 'abort' + 'updateend'
    sb.addEventListener('abort', () => console.log('Laufender Vorgang abgebrochen'), { once: true });
  }
  mediaSource.removeSourceBuffer(sb);
  return true;
};

// Nutzung:
// safeRemove(mediaSource, audioBuffer);
Laufender Vorgang abgebrochen (nur wenn updating === true war)

Codec-Wechsel: alten Puffer entfernen, neuen anlegen

const switchCodec = async (mediaSource, oldSb, newMime, initSegmentUrl) => {
  if (!MediaSource.isTypeSupported(newMime)) {
    throw new Error(`Nicht unterstützt: ${newMime}`);
  }
  mediaSource.sourceBuffers.addEventListener(
    'removesourcebuffer',
    () => console.log('Alter Puffer entfernt'),
    { once: true }
  );
  mediaSource.removeSourceBuffer(oldSb);

  const newSb = mediaSource.addSourceBuffer(newMime);
  const data = await (await fetch(initSegmentUrl)).arrayBuffer();

  await new Promise((resolve, reject) => {
    newSb.addEventListener('updateend', resolve, { once: true });
    newSb.addEventListener('error', reject, { once: true });
    newSb.appendBuffer(data);
  });
  console.log('Neuer Puffer bereit:', newMime);
  return newSb;
};
Alter Puffer entfernt Neuer Puffer bereit: video/webm; codecs="vp9"

// Wichtig · Fallstricke

  • NotFoundError (DOMException): Wird geworfen, wenn der übergebene Puffer nicht in mediaSource.sourceBuffers steht, etwa weil er bereits entfernt wurde oder zu einer anderen MediaSource gehört. Ein doppelter Aufruf ist daher ein häufiger Fehler.
  • Laufende Vorgänge werden abgebrochen: Hat der Puffer updating === true, gehen die gerade angehängten Daten verloren. Wer das nicht will, wartet vorher auf updateend.
  • Referenz ist danach unbrauchbar: Jeder Methodenaufruf auf dem entfernten SourceBuffer wirft einen InvalidStateError. Verweise auf den Puffer im eigenen Code sollte man deshalb löschen.
  • Anders als addSourceBuffer() verlangt removeSourceBuffer() nicht, dass readyState auf "open" steht. Die Methode funktioniert also auch nach endOfStream().
  • Alternative changeType(): Für einen reinen Codec- oder Containerwechsel ist SourceBuffer.changeType() meist die bessere Wahl. Sie vermeidet das Entfernen und neu Anlegen, das in manchen Browsern die Wiedergabe unterbricht.
  • Kompatibilität: Chrome, Edge, Firefox und Safari (Desktop) unterstützen die Methode. Auf dem iPhone steht MSE erst ab iOS 17.1 als ManagedMediaSource zur Verfügung, mit derselben Methode. In Dedicated Workers ist MediaSource nur in neueren Chromium-Versionen verfügbar.