Signatur
Beschreibung
Die Eigenschaft transformer des RTCTransformEvent-Interfaces liefert das RTCRtpScriptTransformer-Objekt, das beim Erzeugen eines RTCRtpScriptTransform im Hauptthread automatisch im zugehörigen Worker angelegt wird. Das Ereignis rtctransform wird im Worker-Global-Scope ausgelöst, sobald eine Transformation einem RTCRtpSender oder RTCRtpReceiver zugewiesen wird (bzw. beim Erstellen des Transforms).
Über den Transformer erhält man Zugriff auf einen readable-Stream mit kodierten Audio- oder Video-Frames (RTCEncodedVideoFrame / RTCEncodedAudioFrame) und einen writable-Stream, in den die veränderten Frames zurückgeschrieben werden. Typische Einsatzfälle sind Ende-zu-Ende-Verschlüsselung (E2EE) in SFU-basierten Videokonferenzen, das Einfügen von Metadaten oder die Analyse von Frames.
Außerdem stellt der Transformer die Eigenschaft options bereit – das Objekt, das im Hauptthread als zweites Argument an new RTCRtpScriptTransform(worker, options) übergeben wurde. Damit lässt sich etwa unterscheiden, ob es sich um eine Sende- oder Empfangsrichtung handelt. Methoden wie generateKeyFrame() und sendKeyFrameRequest() ermöglichen die Steuerung von Keyframes.
Rückgabewert
RTCRtpScriptTransformer-Objekt mit readable, writable und options.Beispiele
Hauptthread: Transform an Sender und Empfänger binden
// main.js
const worker = new Worker('e2ee-worker.js');
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const sender = pc.addTrack(track, stream);
// Löst im Worker ein rtctransform-Ereignis aus
sender.transform = new RTCRtpScriptTransform(worker, { side: 'send', keyId: 1 });
pc.addEventListener('track', ({ receiver }) => {
receiver.transform = new RTCRtpScriptTransform(worker, { side: 'receive' });
});
Worker: Frames über event.transformer durchleiten
// e2ee-worker.js
addEventListener('rtctransform', (event) => {
const { transformer } = event;
console.log('Richtung:', transformer.options.side);
const passThrough = new TransformStream({
transform(frame, controller) {
// Frame unverändert weiterreichen
controller.enqueue(frame);
},
});
transformer.readable
.pipeThrough(passThrough)
.pipeTo(transformer.writable);
});
Worker: einfache XOR-"Verschlüsselung" der Nutzdaten
// e2ee-worker.js — nur Demonstration, keine echte Kryptografie!
const KEY = 0x5a;
const xorFrame = (frame, controller) => {
const data = new Uint8Array(frame.data);
// Die ersten 10 Bytes (Header bei VP8-Keyframes) unverändert lassen
for (let i = 10; i < data.length; i++) data[i] ^= KEY;
frame.data = data.buffer;
controller.enqueue(frame);
};
onrtctransform = ({ transformer }) => {
transformer.readable
.pipeThrough(new TransformStream({ transform: xorFrame }))
.pipeTo(transformer.writable)
.catch((err) => console.error('Pipeline-Fehler:', err));
};
// Wichtig · Fallstricke
- Nur im Worker:
RTCTransformEventund damittransformerexistieren ausschließlich imDedicatedWorkerGlobalScope. Im Hauptthread gibt es das Ereignis nicht. - Schreibgeschützt: Eine Zuweisung an
event.transformerwird ignoriert (im Strict ModeTypeError). - Pro Transform ein Ereignis: Wird derselbe Worker für mehrere
RTCRtpScriptTransform-Instanzen genutzt, feuertrtctransformmehrfach – übertransformer.optionsunterscheiden, welcher Transformer gerade vorliegt. - Pipeline nicht vergessen: Wird
readablenicht anwritableweitergeleitet, kommen keine Medien beim Gegenüber an bzw. werden nicht wiedergegeben. - Browser-Kompatibilität: Safari und Firefox unterstützen die API seit Längerem; Chromium hat lange nur die ältere, nicht standardisierte Variante
RTCRtpSender.createEncodedStreams()(Insertable Streams) angeboten. Feature-Erkennung per'RTCRtpScriptTransform' in window. - Sicherheit: Für echte E2EE WebCrypto (z. B. AES-GCM) verwenden, Codec-Header unverschlüsselt lassen, damit Paketierung und SFU weiter funktionieren; Schlüssel sicher per
postMessagean den Worker übergeben.