Start · Sprachen · JavaScript · Referenz · SourceBuffer.mode

SourceBuffer.mode

Eigenschaft

Legt fest, ob ein <code>SourceBuffer</code> Mediensegmente nach ihren eingebetteten Zeitstempeln (<code>"segments"</code>) oder lückenlos in Anfügereihenfolge (<code>"sequence"</code>) einordnet.

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

Signatur

SourceBuffer.mode

Beschreibung

Die Eigenschaft mode eines SourceBuffer bestimmt, wie Mediendaten, die über appendBuffer() hinzugefügt werden, auf der Zeitachse der Präsentation eingeordnet werden. Es gibt zwei Werte:

  • "segments": Die Zeitstempel in den Mediensegmenten bestimmen die Position. Segmente dürfen in beliebiger Reihenfolge angefügt werden, z. B. beim Springen (Seeking) oder beim adaptiven Wechsel der Qualitätsstufe in DASH/HLS.
  • "sequence": Die Segmente werden unabhängig von ihren eigenen Zeitstempeln direkt hintereinander gelegt. Der Browser passt timestampOffset automatisch an, sodass keine Lücken entstehen. Nützlich zum Aneinanderhängen unabhängiger Clips (z. B. Werbung vor dem Hauptvideo) oder für Formate ohne verlässliche Zeitstempel.

Der Anfangswert hängt vom Byte-Stream-Format ab, das bei MediaSource.addSourceBuffer() angegeben wurde: Für Container mit Zeitstempeln wie MP4 oder WebM ist er "segments"; für Formate, bei denen der Browser Zeitstempel selbst erzeugen muss (etwa audio/mpeg oder audio/aac), ist er "sequence" – und lässt sich dann auch nicht auf "segments" umstellen.

Die Eigenschaft ist les- und schreibbar. Man sollte sie setzen, bevor man Daten anfügt, oder zumindest nur dann, wenn SourceBuffer.updating den Wert false hat.

Parameter

Name Typ Default Beschreibung
$value Pflicht "segments" | "sequence" abhängig vom MIME-Typ (meist "segments") Neuer Modus beim Zuweisen. "segments" ordnet nach den eingebetteten Zeitstempeln ein, "sequence" hängt in Anfügereihenfolge an.

Rückgabewert

Typ
"segments" | "sequence"
Beschreibung
Der aktuelle Anfügemodus des SourceBuffer als Zeichenkette.

Beispiele

Modus nach dem Anlegen des SourceBuffer prüfen

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('Standardmodus:', sb.mode);
});
Standardmodus: segments

Unabhängige Clips lückenlos aneinanderhängen (sequence)

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

// Wartet, bis der SourceBuffer mit dem Anfügen fertig ist
const appendAsync = (sb, data) => new Promise((resolve, reject) => {
  sb.addEventListener('updateend', resolve, { once: true });
  sb.addEventListener('error', reject, { once: true });
  sb.appendBuffer(data);
});

mediaSource.addEventListener('sourceopen', async () => {
  const sb = mediaSource.addSourceBuffer('video/webm; codecs="vp9, opus"');
  sb.mode = 'sequence'; // Clips beginnen jeweils bei 0 s -> trotzdem hintereinander

  for (const url of ['/clips/werbung.webm', '/clips/hauptfilm.webm']) {
    const data = await (await fetch(url)).arrayBuffer();
    await appendAsync(sb, data);
    console.log(`${url} angefügt, Ende bei ${sb.buffered.end(0).toFixed(1)} s`);
  }
  mediaSource.endOfStream();
});
/clips/werbung.webm angefügt, Ende bei 15.0 s /clips/hauptfilm.webm angefügt, Ende bei 615.0 s

Modus sicher umschalten (Fehlerbehandlung)

const setModeSafely = (sb, mode) => {
  if (sb.updating) {
    // Erst nach Abschluss des laufenden Anfügevorgangs umstellen
    sb.addEventListener('updateend', () => setModeSafely(sb, mode), { once: true });
    return;
  }
  try {
    sb.mode = mode;
    console.log('Neuer Modus:', sb.mode);
  } catch (err) {
    // TypeError: z. B. "segments" bei audio/mpeg nicht erlaubt
    // InvalidStateError: Buffer entfernt oder mitten im Segment
    console.warn(`Modus "${mode}" nicht setzbar:`, err.name);
  }
};

// Beispiel: MP3-Stream erzwingt "sequence"
const ms = new MediaSource();
document.querySelector('audio').src = URL.createObjectURL(ms);
ms.addEventListener('sourceopen', () => {
  const sb = ms.addSourceBuffer('audio/mpeg');
  console.log('Start:', sb.mode);
  setModeSafely(sb, 'segments');
});
Start: sequence Modus "segments" nicht setzbar: TypeError

// Wichtig · Fallstricke

  • Ausnahmen beim Setzen: InvalidStateError, wenn der SourceBuffer bereits aus MediaSource.sourceBuffers entfernt wurde, wenn updating den Wert true hat oder wenn gerade ein Mediensegment nur teilweise angefügt wurde. TypeError, wenn man bei Formaten mit browsergenerierten Zeitstempeln (z. B. audio/mpeg, audio/aac) "segments" setzt.
  • Ist MediaSource.readyState "ended", setzt das Zuweisen von mode den Zustand wieder auf "open" und löst sourceopen erneut aus.
  • Im Modus "sequence" überschreibt der Browser timestampOffset automatisch. Wer timestampOffset manuell steuern will (z. B. beim Seeking in adaptiven Streams), sollte "segments" verwenden – "sequence" eignet sich schlecht für Streams, bei denen Segmente außer der Reihe geladen werden.
  • Umschalten auf "sequence" beginnt eine neue kodierte Frame-Gruppe am aktuellen Ende; nachfolgende Daten landen dort, nicht an ihrem ursprünglichen Zeitstempel.
  • Kompatibilität: In allen aktuellen Desktop-Browsern und Android verfügbar. Auf dem iPhone steht MSE erst ab iOS 17.1 über ManagedMediaSource zur Verfügung; dort gilt mode analog. In Dedicated Workers ist MSE nur in neueren Chromium-Versionen nutzbar.