Signatur
Beschreibung
Der Konstruktor RTCEncodedVideoFrame() gehört zur API WebRTC Encoded Transform. Diese API gibt Ihnen Zugriff auf die bereits kodierten Videoframes einer WebRTC-Verbindung. Der Zugriff liegt zwischen Encoder und Paketierer (Sender) bzw. zwischen Depaketierer und Decoder (Empfänger). Der Konstruktor nimmt einen bestehenden Frame und legt daraus ein neues Objekt an. Dieses Objekt ist vollständig unabhängig: Der Puffer in data ist eine tiefe Kopie, und auch Typ ("key", "delta" oder "empty") sowie Metadaten werden übernommen.
Wichtig ist das immer dann, wenn Sie einen Frame mehrfach verwenden wollen, etwa um ihn an mehrere Ziele weiterzugeben, ihn zwischenzuspeichern oder ihn neu einzureihen, ohne das Original zu verändern. Mit dem optionalen Parameter options.metadata können Sie beim Kopieren gezielt Metadaten ändern, zum Beispiel rtpTimestamp. So müssen Sie den Frame nicht umständlich von Hand nachbauen.
Normalerweise verwenden Sie den Konstruktor im Handler des Events rtctransform eines Dedicated Workers. Dort liest ein TransformStream die Frames aus event.transformer.readable und schreibt sie nach event.transformer.writable. Auf der Hauptseite wird der Worker über new RTCRtpScriptTransform(worker, options) an einen RTCRtpSender oder RTCRtpReceiver gebunden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $originalFrame Pflicht | RTCEncodedVideoFrame | Der Frame, der kopiert werden soll. Kopiert werden die Nutzdaten (data), der Typ und die Metadaten. |
|
| $options | object | {} | Optionales Objekt mit folgender Eigenschaft:
|
Rückgabewert
RTCEncodedVideoFrame mit kopierten Daten und den übernommenen oder überschriebenen Metadaten.Beispiele
Frames im Worker kopieren und weiterreichen
// worker.js – wird per RTCRtpScriptTransform eingebunden
self.addEventListener("rtctransform", (event) => {
const { readable, writable } = event.transformer;
const copyTransform = new TransformStream({
transform(frame, controller) {
// Unabhängige Kopie erzeugen, das Original bleibt unverändert
const copy = new RTCEncodedVideoFrame(frame);
controller.enqueue(copy);
},
});
readable.pipeThrough(copyTransform).pipeTo(writable);
});
Worker auf der Hauptseite an einen Sender binden
// main.js
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const sender = pc.addTrack(track, stream);
const worker = new Worker("worker.js");
sender.transform = new RTCRtpScriptTransform(worker, { role: "sender" });
console.log("Encoded Transform aktiv:", sender.transform instanceof RTCRtpScriptTransform);
Kopie mit geänderten Metadaten (rtpTimestamp)
// worker.js
let offset = 0;
self.onrtctransform = (event) => {
const { readable, writable } = event.transformer;
readable
.pipeThrough(new TransformStream({
transform(frame, controller) {
const metadata = frame.getMetadata();
const copy = new RTCEncodedVideoFrame(frame, {
metadata: { ...metadata, rtpTimestamp: metadata.rtpTimestamp + offset },
});
console.log(frame.type, copy.getMetadata().rtpTimestamp);
controller.enqueue(copy);
},
}))
.pipeTo(writable);
};
Unabhängigkeit der Daten prüfen
// worker.js, innerhalb von transform(frame, controller)
const copy = new RTCEncodedVideoFrame(frame);
const view = new Uint8Array(copy.data);
view[0] ^= 0xff; // nur die Kopie verändern
const original = new Uint8Array(frame.data);
console.log(original[0] === view[0]); // false – getrennte Puffer
controller.enqueue(frame);
// Wichtig · Fallstricke
- Nur im Worker:
RTCEncodedVideoFrameist nur in Dedicated Workers verfügbar, die überRTCRtpScriptTransformeingebunden sind. Im Fenster-Kontext gibt es den Konstruktor nicht. - Browser-Unterstützung: Der Konstruktor ist relativ neu und wird nicht überall unterstützt. Prüfen Sie im Worker vorher mit
typeof RTCEncodedVideoFrame === "function". Ältere Chromium-Versionen kennen nur die proprietäre APIcreateEncodedStreams(), ohne diesen Konstruktor. - Speicher und Leistung: Jede Kopie dupliziert den gesamten Puffer. Bei hohen Bildraten und Auflösungen erhöht das den Speicherbedarf und die GC-Last deutlich. Kopieren Sie daher nur, wenn Sie das Original wirklich weiterverwenden.
- Metadaten: Metadaten, die nicht zusammenpassen oder nicht geändert werden dürfen, lösen eine Ausnahme aus. Übernehmen Sie am besten zuerst alle Metadaten mit
{ ...frame.getMetadata() }und ändern Sie danach gezielt einzelne Felder. - Bei Ende-zu-Ende-Verschlüsselung (z. B. SFrame-ähnliche Verfahren) dürfen Sie die Header-Bytes des Codecs nicht beschädigen. Sonst kann die Gegenseite die Frames nicht mehr dekodieren.