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

SourceBuffer.abort()

Methode

Bricht das Anhängen des aktuellen Segments an einen <code>SourceBuffer</code> ab und setzt den Segmentparser zurück.

seit JavaScript Media Source Extensions – Baseline: alle modernen Kategorie: webapi

Signatur

SourceBuffer.prototype.abort()

Beschreibung

abort() gehört zu den Media Source Extensions (MSE). Die Methode stoppt eine laufende Operation von appendBuffer() und versetzt den Segmentparser des SourceBuffer in seinen Ausgangszustand. Teilweise gelesene Mediensegmente werden verworfen. Danach erwartet der Parser als Nächstes wieder den Anfang eines Initialisierungs- oder Mediensegments.

Gebraucht wird das vor allem in adaptiven Streaming-Playern (DASH/HLS über MSE):

  • Beim Springen im Video (Seeking): Ein Segment wird gerade angehängt, gehört aber nicht mehr zur neuen Abspielposition. Mit abort() wird es sofort verworfen, statt dass man auf das Ende wartet.
  • Beim Wechsel von Qualität oder Quelle: Bevor Sie timestampOffset neu setzen oder ein anderes Initialisierungssegment anhängen, muss der Parser in einem sauberen Zustand sein. Im Modus "segments" ist das Setzen von timestampOffset während eines halb gelesenen Mediensegments nicht erlaubt.
  • Beim Zurücksetzen des Anhängefensters: abort() setzt appendWindowStart auf den Präsentationsbeginn (in der Regel 0) und appendWindowEnd auf +Infinity zurück.

Wenn gerade ein Anhängevorgang läuft (updating === true), wird er beendet: updating wird auf false gesetzt, danach werden die Ereignisse abort und updateend am SourceBuffer ausgelöst. Läuft kein Anhängevorgang, setzt die Methode nur den Parser und das Anhängefenster zurück.

Rückgabewert

Typ
undefined
Beschreibung
Die Methode gibt nichts zurück. Das Ergebnis erkennen Sie am Zustand des Puffers (updating ist false) und an den Ereignissen abort und updateend.

Beispiele

Laufendes Anhängen beim Springen im Video abbrechen

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"';
  const sourceBuffer = mediaSource.addSourceBuffer(mime);

  sourceBuffer.addEventListener('abort', () => {
    console.log('Anhängen abgebrochen');
  });

  video.addEventListener('seeking', () => {
    // Nur abbrechen, wenn die MediaSource offen ist und gerade angehängt wird
    if (mediaSource.readyState === 'open' && sourceBuffer.updating) {
      sourceBuffer.abort();
    }
    // Danach passendes Segment für video.currentTime laden …
  });

  const init = await fetch('/media/init.mp4').then((r) => r.arrayBuffer());
  sourceBuffer.appendBuffer(init);
});
Anhängen abgebrochen // nur wenn während eines appendBuffer() gesprungen wurde

Parser vor dem Setzen von timestampOffset zurücksetzen

// Wechsel auf eine andere Qualitätsstufe mit eigenem Initialisierungssegment
const switchRendition = async (sourceBuffer, initUrl, offsetSeconds) => {
  // Halb gelesenes Segment verwerfen, Parser zurücksetzen
  sourceBuffer.abort();

  // Jetzt ist das Setzen von timestampOffset erlaubt
  sourceBuffer.timestampOffset = offsetSeconds;

  const init = await fetch(initUrl).then((r) => r.arrayBuffer());

  await new Promise((resolve, reject) => {
    sourceBuffer.addEventListener('updateend', resolve, { once: true });
    sourceBuffer.addEventListener('error', reject, { once: true });
    sourceBuffer.appendBuffer(init);
  });

  console.log('Neue Qualitätsstufe initialisiert');
};
Neue Qualitätsstufe initialisiert

Abbruch sicher kapseln und auf updateend warten

const safeAbort = (mediaSource, sourceBuffer) =>
  new Promise((resolve) => {
    // Außerhalb von "open" würde abort() einen InvalidStateError werfen
    if (mediaSource.readyState !== 'open') return resolve(false);

    if (sourceBuffer.updating) {
      // Nach abort() feuern nacheinander "abort" und "updateend"
      sourceBuffer.addEventListener('updateend', () => resolve(true), { once: true });
      sourceBuffer.abort();
    } else {
      sourceBuffer.abort(); // setzt nur Parser und Anhängefenster zurück
      resolve(true);
    }
  });

// Verwendung
// const ok = await safeAbort(mediaSource, sourceBuffer);
// console.log(sourceBuffer.appendWindowEnd);
Infinity

// Wichtig · Fallstricke

  • InvalidStateError: Diesen Fehler wirft abort(), wenn der SourceBuffer nicht mehr in mediaSource.sourceBuffers steht oder wenn mediaSource.readyState nicht "open" ist (zum Beispiel nach endOfStream(), dann ist er "ended"). Prüfen Sie den Zustand vorher.
  • Kein Abbruch von remove(): Läuft gerade ein Löschvorgang über remove(), wirft abort() ebenfalls einen InvalidStateError. Warten Sie in diesem Fall auf updateend.
  • Nebeneffekt auf das Anhängefenster: appendWindowStart und appendWindowEnd werden zurückgesetzt. Wenn Sie ein eigenes Anhängefenster verwenden, müssen Sie es nach abort() neu setzen.
  • Bereits gepufferte Daten bleiben erhalten: Verworfen wird nur das unvollständige Segment. Schon vollständig gelesene Bereiche stehen weiter in buffered. Zum Entfernen dient remove().
  • Wechsel des Initialisierungssegments: Nach abort() kann ein neues Initialisierungssegment nötig sein, wenn die Qualitätsstufe gewechselt wird. Ein neues Mediensegment muss an einer vollständigen Segmentgrenze beginnen.
  • Kompatibilität: Alle aktuellen Desktop-Browser und Android unterstützen MSE. Auf dem iPhone gibt es MSE erst ab iOS 17.1, und dort über ManagedMediaSource. Prüfen Sie die Unterstützung vorab mit 'MediaSource' in window bzw. MediaSource.isTypeSupported().