Start · Sprachen · JavaScript · Referenz · SourceBuffer.removeAsync()

SourceBuffer.removeAsync()

Methode

Entfernt asynchron alle Mediensegmente im Zeitbereich <code>start</code> bis <code>end</code> aus dem <code>SourceBuffer</code> und liefert ein Promise, das nach dem Entfernen erfüllt wird.

seit JavaScript Nicht standardisiert, experimentell – nur Firefox Kategorie: webapi

Signatur

SourceBuffer.prototype.removeAsync(start, end)

Beschreibung

removeAsync() ist die Promise-basierte Variante von SourceBuffer.remove() aus der Media Source Extensions API (MSE). Die Methode startet das Entfernen gepufferter Mediendaten zwischen zwei Zeitpunkten (in Sekunden) und gibt ein Promise zurück. Du musst also nicht mehr auf das Ereignis updateend warten, sondern kannst direkt mit await arbeiten.

Gebraucht wird das vor allem bei Streaming-Playern, die ihren Puffer selbst verwalten: Bei langen Live-Streams oder auf Geräten mit wenig Speicher entfernst du schon abgespielte Bereiche, damit beim nächsten appendBuffer() kein QuotaExceededError auftritt. Auch beim Wechsel der Qualitätsstufe oder beim Springen im Video kann es sinnvoll sein, veraltete Segmente zu löschen.

Während das Entfernen läuft, ist sourceBuffer.updating auf true gesetzt. In dieser Zeit darfst du weder etwas anhängen noch etwas anderes entfernen. Die Methode war nie Teil der Spezifikation und nur in Firefox hinter einer Einstellung verfügbar. Für echten Produktivcode solltest du daher remove() zusammen mit dem Ereignis updateend verwenden oder dir selbst eine Promise-Hülle schreiben.

Parameter

Name Typ Default Beschreibung
$start Pflicht number Beginn des zu entfernenden Bereichs in Sekunden. Der Wert muss ≥ 0 und ≤ mediaSource.duration sein.
$end Pflicht number Ende des zu entfernenden Bereichs in Sekunden. Muss größer als start sein; Infinity ist erlaubt, um alles bis zum Ende zu entfernen.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald die Daten entfernt sind. Es wird abgelehnt, wenn die Argumente ungültig sind (TypeError) oder der Puffer gerade in Benutzung bzw. nicht mehr an die MediaSource gebunden ist (InvalidStateError).

Beispiele

Bereits abgespielten Puffer entfernen

const video = document.querySelector('video');

// sourceBuffer stammt aus mediaSource.addSourceBuffer(...)
const trimBuffer = async (sourceBuffer) => {
  // Bei 30 Sekunden oder weniger gibt es nichts zu entfernen
  const keepFrom = video.currentTime - 30; // 30 s Rückpuffer behalten
  if (keepFrom <= 0 || sourceBuffer.updating) return;

  await sourceBuffer.removeAsync(0, keepFrom);
  console.log('Puffer gekürzt bis', keepFrom.toFixed(1), 's');
};
Puffer gekürzt bis 42.3 s

Promise-Hülle mit Rückfall auf remove()

const removeRange = (sourceBuffer, start, end) => {
  // Die experimentelle Methode nutzen, wenn vorhanden
  if (typeof sourceBuffer.removeAsync === 'function') {
    return sourceBuffer.removeAsync(start, end);
  }
  // Sonst remove() mit den Ereignissen updateend/error
  return new Promise((resolve, reject) => {
    const onEnd = () => { cleanup(); resolve(); };
    const onError = () => { cleanup(); reject(new Error('Entfernen fehlgeschlagen')); };
    const cleanup = () => {
      sourceBuffer.removeEventListener('updateend', onEnd);
      sourceBuffer.removeEventListener('error', onError);
    };
    sourceBuffer.addEventListener('updateend', onEnd);
    sourceBuffer.addEventListener('error', onError);
    sourceBuffer.remove(start, end);
  });
};

// Verwendung
await removeRange(sourceBuffer, 0, 10);
console.log(sourceBuffer.buffered.length ? sourceBuffer.buffered.start(0) : 'leer');
10

QuotaExceededError abfangen und neu anhängen

const appendWithEviction = async (sourceBuffer, video, chunk) => {
  try {
    sourceBuffer.appendBuffer(chunk);
  } catch (err) {
    if (err.name !== 'QuotaExceededError') throw err;
    // Puffer voll: alles bis 10 s vor der aktuellen Position entfernen
    await sourceBuffer.removeAsync(0, Math.max(0.1, video.currentTime - 10));
    sourceBuffer.appendBuffer(chunk);
  }
};

// Wichtig · Fallstricke

  • Nicht standardisiert: removeAsync() war nur in Firefox verfügbar, und zwar hinter der Einstellung media.mediasource.experimental.enabled. Chrome und Safari haben sie nie unterstützt. Prüfe die Methode deshalb immer mit typeof sb.removeAsync === 'function' und nutze sonst remove() als Rückfall.
  • Während sourceBuffer.updating === true ist, darfst du nicht erneut remove(), removeAsync() oder appendBuffer() aufrufen. Sonst gibt es einen InvalidStateError.
  • end muss größer als start sein. Ist mediaSource.duration NaN (also noch nicht gesetzt), schlägt der Aufruf fehl.
  • Entfernt wird ab Keyframe-Grenzen. Im Attribut buffered können daher etwas andere Bereiche übrig bleiben als angefragt.
  • Entferne nie den Bereich um video.currentTime, sonst stockt die Wiedergabe.