Start · Sprachen · JavaScript · Referenz · MediaSource.handle

MediaSource.handle

Eigenschaft

Liefert ein <code>MediaSourceHandle</code>, einen übertragbaren Proxy für ein im Dedicated Worker erzeugtes <code>MediaSource</code>, der im Haupt-Thread an <code>HTMLMediaElement.srcObject</code> gebunden wird.

seit JavaScript Chrome 108+, Edge 108+; Safari 17.1+ (via ManagedM Kategorie: webapi

Signatur

get MediaSource.prototype.handle

Beschreibung

Die schreibgeschützte Eigenschaft handle gibt ein MediaSourceHandle-Objekt zurück. Es ist ein Stellvertreter (Proxy) für das zugehörige MediaSource-Objekt und lässt sich per postMessage() als übertragbares Objekt (Transferable) von einem Dedicated Worker an den Haupt-Thread schicken.

Das ist der Kern von MSE-in-Workers: Das rechenintensive Abrufen, Demuxen und Anhängen von Mediensegmenten per SourceBuffer.appendBuffer() läuft vollständig im Worker, der Haupt-Thread bleibt frei für die UI. Im Haupt-Thread wird das empfangene Handle anschließend mit videoElement.srcObject = handle an ein <video>- oder <audio>-Element gebunden. Ein Objekt-URL über URL.createObjectURL() ist für Worker-MediaSources nicht verfügbar.

Die Eigenschaft ist nur im Kontext eines Dedicated Workers verfügbar. Bei jedem Zugriff wird dasselbe MediaSourceHandle-Objekt zurückgegeben. Ob der Browser MSE im Worker unterstützt, prüft man mit der statischen Eigenschaft MediaSource.canConstructInDedicatedWorker.

Rückgabewert

Typ
MediaSourceHandle
Beschreibung
Ein übertragbares MediaSourceHandle, das auf das MediaSource-Objekt des Workers verweist. Wiederholte Zugriffe liefern dieselbe Instanz.

Beispiele

Worker: MediaSource erzeugen und Handle übertragen

// worker.js
const mediaSource = new MediaSource();
const handle = mediaSource.handle;

// Handle als Transferable an den Haupt-Thread senden
postMessage({ handle }, [handle]);

mediaSource.addEventListener('sourceopen', async () => {
  const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
  const sourceBuffer = mediaSource.addSourceBuffer(mime);

  const response = await fetch('/media/clip-fragmented.mp4');
  const data = await response.arrayBuffer();

  sourceBuffer.addEventListener('updateend', () => {
    if (mediaSource.readyState === 'open') mediaSource.endOfStream();
  }, { once: true });

  sourceBuffer.appendBuffer(data);
});

Haupt-Thread: Handle an das Video-Element binden

// main.js
const video = document.querySelector('video');

if ('MediaSource' in window && MediaSource.canConstructInDedicatedWorker) {
  const worker = new Worker('worker.js');
  worker.addEventListener('message', ({ data }) => {
    if (data.handle) {
      // srcObject statt src – Objekt-URLs gehen hier nicht
      video.srcObject = data.handle;
      console.log(data.handle instanceof MediaSourceHandle);
    }
  });
} else {
  console.warn('MSE im Worker nicht verfügbar – Fallback auf Haupt-Thread-MSE');
}
true

Gleiche Instanz bei mehrfachem Zugriff

// worker.js
const ms = new MediaSource();
console.log(ms.handle === ms.handle);
true

// Wichtig · Fallstricke

  • Nur im Dedicated Worker: Im Haupt-Thread, in Shared oder Service Workern steht handle nicht zur Verfügung.
  • Einmal übertragbar: Ein MediaSourceHandle kann nur ein einziges Mal übertragen werden. Ein zweiter postMessage()-Transfer wirft einen DataCloneError. Außerdem muss es in der Transfer-Liste stehen – bloßes Klonen ohne Transfer schlägt fehl.
  • Nur srcObject: Das Handle muss über HTMLMediaElement.srcObject zugewiesen werden, URL.createObjectURL() ist für Worker-MediaSources nicht erlaubt.
  • Kompatibilität: Unterstützt in Chromium-Browsern ab Version 108. Safari unterstützt MSE im Worker über ManagedMediaSource (ab 17.1), Firefox bisher nicht. Immer per MediaSource.canConstructInDedicatedWorker prüfen und einen Fallback im Haupt-Thread vorsehen.