Signatur
Beschreibung
MediaSource.canConstructInDedicatedWorker ist eine statische Eigenschaft der Schnittstelle MediaSource aus den Media Source Extensions (MSE). Sie ist schreibgeschützt und liefert true, wenn der Browser MSE in Workern unterstützt. Damit lässt sich also im Code prüfen, ob man new MediaSource() innerhalb eines DedicatedWorkerGlobalScope aufrufen kann.
Nützlich ist das, wenn Videodaten aufwendig abgerufen, zerlegt, umgepackt (Transmuxing) und an SourceBuffer angehängt werden müssen. Übernimmt ein Worker diese Arbeit, bleibt der Haupt-Thread frei für Oberfläche und Interaktion, und die Wiedergabe stockt nicht so leicht, wenn die Seite gerade stark beschäftigt ist.
Der Ablauf sieht so aus: Der Worker erzeugt die MediaSource und holt sich über mediaSource.handle ein MediaSourceHandle. Dieses Handle schickt er per postMessage() als übertragbares Objekt an den Haupt-Thread. Dort wird es dem Element <video> bzw. <audio> über srcObject zugewiesen. Meldet die Eigenschaft false oder fehlt sie ganz, sollte man zum klassischen Weg zurückfallen, also MediaSource im Haupt-Thread mit URL.createObjectURL().
Rückgabewert
true, wenn MediaSource in einem Dedicated Worker erzeugt werden kann, sonst false. In Browsern ohne diese Funktion ist die Eigenschaft undefined.Beispiele
Einfache Funktionserkennung
// Funktioniert im Haupt-Thread und im Worker
const workerMseSupported =
'MediaSource' in globalThis &&
MediaSource.canConstructInDedicatedWorker === true;
console.log(`MSE im Worker: ${workerMseSupported}`);
Haupt-Thread: Worker starten oder zum klassischen Weg zurückfallen
const video = document.querySelector('video');
if (window.MediaSource?.canConstructInDedicatedWorker) {
const worker = new Worker('mse-worker.js');
worker.addEventListener('message', ({ data }) => {
if (data.type === 'handle') {
// MediaSourceHandle direkt als srcObject setzen
video.srcObject = data.handle;
video.play().catch(console.error);
}
});
} else {
// Klassischer Weg im Haupt-Thread
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
console.log('MediaSource im Haupt-Thread geöffnet');
// SourceBuffer anlegen und Segmente anhängen ...
}, { once: true });
}
Worker (mse-worker.js): MediaSource erzeugen und Handle übertragen
// mse-worker.js
if (!MediaSource.canConstructInDedicatedWorker) {
throw new Error('MSE im Worker wird nicht unterstützt');
}
const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
const mediaSource = new MediaSource();
const handle = mediaSource.handle;
// Handle als übertragbares Objekt an den Haupt-Thread senden
postMessage({ type: 'handle', handle }, [handle]);
mediaSource.addEventListener('sourceopen', async () => {
const sourceBuffer = mediaSource.addSourceBuffer(mime);
const response = await fetch('/media/video-segment.mp4');
const data = await response.arrayBuffer();
sourceBuffer.addEventListener('updateend', () => {
mediaSource.endOfStream();
console.log('Segment angehängt, Stream beendet');
}, { once: true });
sourceBuffer.appendBuffer(data);
}, { once: true });
// Wichtig · Fallstricke
- Browser-Kompatibilität: Unterstützt in Chromium-basierten Browsern ab Version 108 (Chrome, Edge, Opera). In Firefox und Safari fehlt die Eigenschaft je nach Version ganz und ist dann
undefined. Deshalb optional chaining (?.) verwenden oder hart mit=== truevergleichen. - Statische Eigenschaft: Sie steht am Konstruktor, also
MediaSource.canConstructInDedicatedWorker, und nicht an einer Instanz.new MediaSource().canConstructInDedicatedWorkerergibtundefined. - Nur Dedicated Worker: In Shared Workern und Service Workern ist
MediaSourcenicht verfügbar. - Kein Objekt-URL im Worker: Eine im Worker erzeugte
MediaSourcewird perMediaSourceHandleundsrcObjectangebunden.URL.createObjectURL()ist dafür nicht vorgesehen. - Handle nur einmal übertragbar: Ein
MediaSourceHandlemuss in der Transfer-Liste vonpostMessage()stehen und lässt sich nur einmal übertragen. Ein zweiter Versuch wirft eineDataCloneError-DOMException. - Ereignisse wie
sourceopenkommen im Worker an, nicht im Haupt-Thread. Die Wiedergabe steuert man trotzdem weiter über das Medien-Element im Haupt-Thread.