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

new MediaStreamTrackGenerator()

Methode

Erzeugt einen <code>MediaStreamTrackGenerator</code>, also einen <code>MediaStreamTrack</code>, der über einen <code>WritableStream</code> mit <code>VideoFrame</code>- bzw. <code>AudioData</code>-Objekten gefüttert wird.

seit JavaScript Chrome/Edge 94+ (nicht standardisiert, experimente Kategorie: webapi

Signatur

new MediaStreamTrackGenerator(options)

Beschreibung

Der Konstruktor MediaStreamTrackGenerator() gehört zur sogenannten Insertable Streams for MediaStreamTrack-API („Breakout Box“). Er erzeugt einen Track, der sich wie jeder andere MediaStreamTrack verhält. Er kann also in einem <video>-Element angezeigt, an eine RTCPeerConnection übergeben oder mit MediaRecorder aufgenommen werden. Seine Medieninhalte stammen aber nicht von Kamera oder Mikrofon, sondern von Ihrem eigenen JavaScript-Code.

Die Daten schreiben Sie über die Eigenschaft writable ein, einen WritableStream. Bei einem Video-Track sind das VideoFrame-Objekte, bei einem Audio-Track AudioData-Objekte. Meist wird der Generator zusammen mit MediaStreamTrackProcessor verwendet: Der Processor liefert die Frames eines echten Tracks als ReadableStream, ein TransformStream verändert sie (zum Beispiel für Hintergrundunschärfe, Filter oder Wasserzeichen), und der Generator macht daraus wieder einen Track.

Typische Einsatzgebiete sind Videokonferenz-Effekte, das Einblenden von Overlays, synthetisch erzeugte Testbilder oder das Einspeisen von Frames aus WebCodecs-Decodern in eine WebRTC-Verbindung.

Parameter

Name Typ Default Beschreibung
$options Pflicht object Konfigurationsobjekt für den zu erzeugenden Track.
$options.kind Pflicht "audio" | "video" Art des Tracks. Bei "video" nimmt writable VideoFrame-Objekte an, bei "audio" AudioData-Objekte. Andere Werte lösen einen TypeError aus.

Rückgabewert

Typ
MediaStreamTrackGenerator
Beschreibung
Ein neues MediaStreamTrackGenerator-Objekt. Es erbt von MediaStreamTrack und besitzt zusätzlich die Eigenschaft writable (WritableStream).

Beispiele

Kamerabild in Graustufen umwandeln (Breakout Box)

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();

const processor = new MediaStreamTrackProcessor({ track });
const generator = new MediaStreamTrackGenerator({ kind: 'video' });

const canvas = new OffscreenCanvas(1, 1);
const ctx = canvas.getContext('2d');

const transformer = new TransformStream({
  async transform(frame, controller) {
    canvas.width = frame.displayWidth;
    canvas.height = frame.displayHeight;
    ctx.filter = 'grayscale(1)';
    ctx.drawImage(frame, 0, 0);
    const newFrame = new VideoFrame(canvas, { timestamp: frame.timestamp });
    frame.close(); // Original-Frame freigeben!
    controller.enqueue(newFrame);
  }
});

processor.readable.pipeThrough(transformer).pipeTo(generator.writable);

// Der Generator ist selbst ein MediaStreamTrack
document.querySelector('video').srcObject = new MediaStream([generator]);

Synthetisches Testbild erzeugen

const generator = new MediaStreamTrackGenerator({ kind: 'video' });
const writer = generator.writable.getWriter();

const canvas = new OffscreenCanvas(640, 360);
const ctx = canvas.getContext('2d');
let n = 0;

const tick = async () => {
  ctx.fillStyle = `hsl(${n % 360}, 80%, 50%)`;
  ctx.fillRect(0, 0, 640, 360);
  ctx.fillStyle = '#fff';
  ctx.font = '48px sans-serif';
  ctx.fillText(`Frame ${n}`, 40, 80);

  const frame = new VideoFrame(canvas, { timestamp: n * 33333 }); // µs
  await writer.write(frame);
  frame.close();
  n++;
  if (generator.readyState === 'live') setTimeout(tick, 33);
};
tick();

console.log(generator.kind, generator.readyState);
video live

Unterstützung prüfen und Fehler bei ungültigem kind

if (!('MediaStreamTrackGenerator' in globalThis)) {
  console.log('Nicht unterstützt – Fallback z. B. canvas.captureStream()');
} else {
  try {
    new MediaStreamTrackGenerator({ kind: 'text' });
  } catch (err) {
    console.log(err.name);
  }
}
TypeError

// Wichtig · Fallstricke

  • Kompatibilität: Die API ist nicht standardisiert und nur in Chromium-Browsern (Chrome, Edge, Opera) verfügbar. Die W3C-Spezifikation ersetzt sie durch VideoTrackGenerator, das nur in Workern verfügbar ist. Prüfen Sie die Unterstützung immer per Feature-Detection und sehen Sie einen Fallback vor, etwa HTMLCanvasElement.captureStream().
  • Speicher: VideoFrame- und AudioData-Objekte belegen oft GPU- oder Hardware-Puffer. Rufen Sie nach der Verarbeitung immer close() auf. Sonst kommt der Stream ins Stocken, oder der Speicher läuft voll.
  • Der kind muss zu den geschriebenen Daten passen. Wer ein AudioData in einen Video-Generator schreibt, bekommt einen Fehler und der Stream bricht ab.
  • Verwenden Sie für die Zeitstempel (timestamp, in Mikrosekunden) monoton steigende Werte. Sonst kann es bei der Wiedergabe oder in WebRTC zu Rucklern kommen.
  • Rufen Sie auf dem Generator stop() auf, wird der Track beendet (readyState = \"ended\"), und weitere Schreibzugriffe schlagen fehl.
  • Rechenintensive Transformationen verlegen Sie am besten in einen Worker, damit der Hauptthread nicht blockiert.