Start · Sprachen · JavaScript · Referenz · new ManagedMediaSource()

new ManagedMediaSource()

Methode

Erzeugt eine neue, noch leere <code>ManagedMediaSource</code>-Instanz ohne Quellpuffer. Sie dient als stromsparende, vom Browser verwaltete Alternative zu <code>MediaSource</code>.

seit JavaScript Safari 17 (macOS), Safari 17.1 (iOS/iPadOS); in Ch Kategorie: webapi

Signatur

new ManagedMediaSource()

Beschreibung

Der Konstruktor ManagedMediaSource() erzeugt ein neues ManagedMediaSource-Objekt. Anfangs hat es keine zugeordneten Quellpuffer, und sein readyState ist "closed". ManagedMediaSource erbt von MediaSource und bietet damit dieselbe API für Media Source Extensions (MSE): Man hängt es an ein <video>- oder <audio>-Element, legt nach dem Ereignis sourceopen mit addSourceBuffer() Puffer an und füllt sie mit Mediensegmenten, etwa bei adaptivem Streaming (HLS/DASH mit fMP4).

Anders als bei MediaSource hat der Browser bei ManagedMediaSource mehr Kontrolle. Er darf gepufferte Daten selbst entfernen, zum Beispiel wenn der Speicher knapp wird. Außerdem sagt er der Anwendung über die Eigenschaft streaming und die Ereignisse startstreaming und endstreaming, wann sie neue Daten laden soll. So kann das Gerät das Funkmodul länger schlafen lassen, was auf Mobilgeräten Akku spart. Deshalb ist ManagedMediaSource auf dem iPhone die einzige MSE-Variante. Das klassische MediaSource gibt es dort nicht.

In der Praxis prüft man zuerst, ob window.ManagedMediaSource existiert, und greift sonst auf MediaSource zurück. Die Anwendung sollte nur Daten anhängen, solange streaming den Wert true hat. Außerdem sollte sie das Ereignis bufferedchange der ManagedSourceBuffer-Objekte beobachten, weil der Browser gepufferte Bereiche auch ohne Zutun der Anwendung entfernen kann.

Rückgabewert

Typ
ManagedMediaSource
Beschreibung
Eine neue ManagedMediaSource-Instanz mit readyState === "closed" und leerer sourceBuffers-Liste.

Beispiele

Funktionserkennung mit Rückfall auf MediaSource

const MSClass = window.ManagedMediaSource ?? window.MediaSource;

if (!MSClass) {
  console.log('Kein MSE-Support – native Wiedergabe verwenden');
} else {
  const source = new MSClass();
  console.log(source.constructor.name, source.readyState);
}
ManagedMediaSource closed

An ein Video-Element anhängen und Puffer anlegen

const video = document.querySelector('video');
const source = new ManagedMediaSource();

// Ohne AirPlay-Alternative Pflicht, sonst feuert 'sourceopen' nicht
video.disableRemotePlayback = true;
video.src = URL.createObjectURL(source);

source.addEventListener('sourceopen', async () => {
  const mime = 'video/mp4; codecs="avc1.64001f, mp4a.40.2"';
  if (!ManagedMediaSource.isTypeSupported(mime)) return;

  const buffer = source.addSourceBuffer(mime);
  const init = await fetch('/media/init.mp4').then(r => r.arrayBuffer());
  buffer.appendBuffer(init);
  console.log('Init-Segment angehängt');
}, { once: true });
Init-Segment angehängt

Nur nachladen, wenn der Browser es wünscht

const source = new ManagedMediaSource();
const video = document.querySelector('video');
video.disableRemotePlayback = true;
video.src = URL.createObjectURL(source);

const segments = ['/media/seg1.m4s', '/media/seg2.m4s', '/media/seg3.m4s'];
let buffer;

const loadNext = async () => {
  if (!source.streaming || !segments.length || buffer.updating) return;
  const data = await fetch(segments.shift()).then(r => r.arrayBuffer());
  buffer.appendBuffer(data);
};

source.addEventListener('sourceopen', () => {
  buffer = source.addSourceBuffer('video/mp4; codecs="avc1.64001f"');
  buffer.addEventListener('updateend', loadNext);
  buffer.addEventListener('bufferedchange', (e) => {
    console.log('Entfernte Bereiche:', e.removedRanges.length);
  });
  loadNext();
});

source.addEventListener('startstreaming', () => {
  console.log('Browser fordert Daten an');
  loadNext();
});
source.addEventListener('endstreaming', () => console.log('Nachladen pausieren'));
Browser fordert Daten an

// Wichtig · Fallstricke

  • Browser-Unterstützung: ManagedMediaSource gibt es in Safari ab Version 17 (macOS) bzw. 17.1 (iOS/iPadOS). Chrome und Firefox unterstützen die Schnittstelle derzeit nicht. Deshalb immer die Funktion erkennen und auf MediaSource zurückfallen.
  • AirPlay/Remote Playback: Unter Safari feuert sourceopen nur, wenn man entweder video.disableRemotePlayback = true setzt oder über <source> eine Alternative für AirPlay angibt, etwa einen HLS-Stream. Das wird am häufigsten übersehen.
  • Daten können verschwinden: Der Browser darf gepufferte Bereiche selbst entfernen. Man sollte sich also nicht darauf verlassen, dass bereits angehängte Segmente erhalten bleiben. Stattdessen bufferedchange auswerten und entfernte Bereiche bei Bedarf neu laden.
  • streaming beachten: Wer auch bei streaming === false weiter Daten anhängt, verschenkt den Energiespareffekt. Der Browser kann solche Daten außerdem wieder verwerfen.
  • Der Konstruktor erwartet keine Argumente. Ohne new aufgerufen, wirft er einen TypeError.
  • Nicht mehr benötigte Objekt-URLs mit URL.revokeObjectURL() freigeben.