Start · Sprachen · JavaScript · Referenz · ManagedMediaSource: startstreaming

ManagedMediaSource: startstreaming

Ereignis

Wird ausgelöst, wenn die <code>streaming</code>-Eigenschaft einer <code>ManagedMediaSource</code> von <code>false</code> auf <code>true</code> wechselt – der Browser möchte jetzt neue Mediendaten.

seit JavaScript Safari 17.1 (iOS 17.1+), Chrome/Edge 142+ (neuere Kategorie: webapi

Signatur

managedMediaSource.addEventListener("startstreaming", handler)

Beschreibung

Das startstreaming-Ereignis gehört zur Schnittstelle ManagedMediaSource, einer energiesparenden Variante von MediaSource. Anders als bei klassischer Media Source Extensions (MSE) entscheidet hier der Browser, wann Daten nachgeladen werden sollen. Er berücksichtigt dabei Pufferstand, Netzwerkart (z. B. Mobilfunk vs. WLAN), Akkustand und Speicherdruck.

Sobald der Browser mehr Daten braucht, setzt er ManagedMediaSource.streaming auf true und löst startstreaming aus. Deine Anwendung sollte dann Segmente per fetch() laden und mit SourceBuffer.appendBuffer() anhängen. Das Gegenstück ist endstreaming: Dann ist genug gepuffert und du solltest das Nachladen anhalten.

Registrieren kannst du den Handler mit addEventListener("startstreaming", handler) oder über die Eigenschaft onstartstreaming. Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften, ist nicht abbrechbar und steigt nicht auf (bubbling).

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "startstreaming".
$handler Pflicht (event: Event) => void Callback, der ein einfaches Event-Objekt erhält. event.target ist die auslösende ManagedMediaSource.
$options boolean | AddEventListenerOptions false Optionen wie once, signal oder passive für addEventListener().

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt nichts zurück. Der Handler bekommt ein Event ohne eigene Zusatzdaten. Den Zustand liest du über source.streaming aus.

Beispiele

Segmente nur bei Bedarf nachladen

const video = document.querySelector('video');
const MS = window.ManagedMediaSource ?? window.MediaSource;
const source = new MS();

// Bei ManagedMediaSource Pflicht, sonst startet keine Wiedergabe über MSE
video.disableRemotePlayback = true;
video.src = URL.createObjectURL(source);

const segmente = ['/video/seg1.mp4', '/video/seg2.mp4', '/video/seg3.mp4'];
let index = 0;
let sb;

const ladeNaechstes = async () => {
  // Weiterladen, solange der Browser Daten möchte
  while (source.streaming && index < segmente.length) {
    if (sb.updating) {
      await new Promise((r) => sb.addEventListener('updateend', r, { once: true }));
    }
    const res = await fetch(segmente[index++]);
    sb.appendBuffer(await res.arrayBuffer());
    await new Promise((r) => sb.addEventListener('updateend', r, { once: true }));
  }
  if (index >= segmente.length && !sb.updating) source.endOfStream();
};

source.addEventListener('sourceopen', () => {
  sb = source.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
  source.addEventListener('startstreaming', () => {
    console.log('startstreaming – lade Daten');
    ladeNaechstes();
  });
  source.addEventListener('endstreaming', () => {
    console.log('endstreaming – Puffer voll, Pause');
  });
});
startstreaming – lade Daten endstreaming – Puffer voll, Pause

Über die on-Eigenschaft onstartstreaming

if ('ManagedMediaSource' in window) {
  const source = new ManagedMediaSource();
  source.onstartstreaming = (event) => {
    console.log('Streaming aktiv:', event.target.streaming);
  };
  source.onendstreaming = () => console.log('Streaming pausiert');

  const video = document.createElement('video');
  video.disableRemotePlayback = true;
  video.src = URL.createObjectURL(source);
  document.body.append(video);
}
Streaming aktiv: true

Listener per AbortController wieder entfernen

const source = new ManagedMediaSource();
const controller = new AbortController();

const onStart = () => console.log('Browser fordert Daten an');
source.addEventListener('startstreaming', onStart, { signal: controller.signal });

// Später, z. B. beim Wechsel auf ein anderes Video:
controller.abort(); // entfernt den Listener
// alternativ: source.removeEventListener('startstreaming', onStart);

// Wichtig · Fallstricke

  • Browser-Kompatibilität: ManagedMediaSource gibt es seit Safari 17.1 (auf dem iPhone ab iOS 17.1, dort ohne klassisches MediaSource). Chromium-Browser unterstützen es erst in neuen Versionen, Firefox bisher nicht. Prüfe per Feature-Erkennung ('ManagedMediaSource' in window) und nutze sonst MediaSource als Ausweichlösung.
  • Ohne video.disableRemotePlayback = true (oder eine AirPlay-Alternativquelle über <source>) startet Safari die Wiedergabe über ManagedMediaSource nicht.
  • startstreaming kann während einer Wiedergabe mehrfach kommen. Die Ladelogik muss also neu starten und fortsetzen können, statt nur einmal zu laufen.
  • Das Ereignis ist ein Hinweis, keine Pflicht: Anhängen ist auch bei streaming === false möglich. Das kostet aber mehr Energie, und der Browser kann Puffer wieder freigeben (siehe bufferedchange auf ManagedSourceBuffer).
  • Vor jedem appendBuffer() sourceBuffer.updating prüfen, sonst droht ein InvalidStateError.