Start · Sprachen · JavaScript · Referenz · RTCEncodedAudioFrame.getMetadata()

RTCEncodedAudioFrame.getMetadata()

Methode

Gibt ein Objekt mit den Metadaten eines codierten Audio-Frames zurück, z. B. SSRC, CSRCs, Payload-Typ, Sequenznummer und MIME-Typ.

seit JavaScript WebRTC Encoded Transform – Firefox 117+, Safari 15 Kategorie: webapi

Signatur

RTCEncodedAudioFrame.prototype.getMetadata()

Beschreibung

Die Methode getMetadata() eines RTCEncodedAudioFrame liefert ein einfaches Objekt (RTCEncodedAudioFrameMetadata) mit Informationen zum RTP-Kontext des Frames. Dazu gehören die Synchronisationsquelle (synchronizationSource, SSRC), die beitragenden Quellen (contributingSources, CSRCs), der RTP-payloadType, die sequenceNumber und – in neueren Implementierungen – der mimeType des Codecs (z. B. "audio/opus") und der rtpTimestamp.

Einsatz findet die Methode in WebRTC Encoded Transforms (früher „Insertable Streams“). Dort bekommt man in einem Worker über das Ereignis rtctransform einen lesbaren und einen schreibbaren Stream mit codierten Frames. Mit getMetadata() kann man pro Frame entscheiden, wie er verarbeitet wird, z. B. für Ende-zu-Ende-Verschlüsselung Schlüssel pro SSRC auswählen, Frames nach Codec filtern oder Diagnosedaten protokollieren.

Das zurückgegebene Objekt ist eine Momentaufnahme: Änderungen daran wirken sich nicht auf den Frame aus. Die eigentlichen Nutzdaten stehen weiterhin in frame.data (ein ArrayBuffer).

Rückgabewert

Typ
RTCEncodedAudioFrameMetadata (Object)
Beschreibung
Objekt mit den Eigenschaften synchronizationSource (number), contributingSources (Array<number>), payloadType (number), sequenceNumber (number) sowie je nach Browser mimeType (string) und rtpTimestamp (number).

Beispiele

Metadaten im Worker protokollieren (RTCRtpScriptTransform)

// worker.js
self.addEventListener('rtctransform', (event) => {
  const { readable, writable } = event.transformer;

  const transform = new TransformStream({
    transform(frame, controller) {
      const meta = frame.getMetadata();
      console.log(
        `SSRC=${meta.synchronizationSource} PT=${meta.payloadType} ` +
        `Seq=${meta.sequenceNumber} Codec=${meta.mimeType ?? 'unbekannt'}`
      );
      controller.enqueue(frame); // Frame unverändert weiterreichen
    }
  });

  readable.pipeThrough(transform).pipeTo(writable);
});
SSRC=1234567890 PT=111 Seq=4711 Codec=audio/opus

Transform auf der Hauptseite an einen Receiver hängen

// main.js
const worker = new Worker('worker.js');
const pc = new RTCPeerConnection();

pc.addEventListener('track', (event) => {
  if (event.track.kind === 'audio') {
    event.receiver.transform = new RTCRtpScriptTransform(worker, { side: 'receive' });
  }
});

Schlüssel pro Sender (SSRC) für E2E-Verschlüsselung wählen

// worker.js – vereinfachte XOR-"Verschlüsselung" nur zur Demonstration
const keys = new Map([[1234567890, 0x5a]]);

const decrypt = new TransformStream({
  transform(frame, controller) {
    const { synchronizationSource, contributingSources } = frame.getMetadata();
    const key = keys.get(synchronizationSource);
    if (key === undefined) return; // unbekannter Sender: Frame verwerfen

    const bytes = new Uint8Array(frame.data);
    for (let i = 0; i < bytes.length; i++) bytes[i] ^= key;
    frame.data = bytes.buffer;

    if (contributingSources.length) {
      console.log('Gemischter Stream, CSRCs:', contributingSources);
    }
    controller.enqueue(frame);
  }
});

self.onrtctransform = ({ transformer }) =>
  transformer.readable.pipeThrough(decrypt).pipeTo(transformer.writable);

// Wichtig · Fallstricke

  • Kompatibilität: Firefox und Safari unterstützen den standardisierten Weg über RTCRtpScriptTransform. Chrome unterstützt dies erst in neueren Versionen (ab ca. 141) und bot vorher nur die proprietäre API RTCRtpSender.createEncodedStreams() bzw. RTCRtpReceiver.createEncodedStreams() (setzt encodedInsertableStreams: true in der RTCPeerConnection-Konfiguration voraus). Vor dem Einsatz ist Feature-Detection nötig.
  • Felder wie mimeType, rtpTimestamp oder sequenceNumber gibt es nicht in allen Browsern – immer mit ?? oder in absichern.
  • Beim Senden können einige Werte (z. B. sequenceNumber) fehlen, da der RTP-Header erst nach der Transformation erzeugt wird.
  • Das Metadaten-Objekt ist eine Kopie; zum Ändern gibt es in neueren Spezifikationen setMetadata() bzw. den Konstruktor new RTCEncodedAudioFrame(frame, { metadata }) – noch nicht überall verfügbar.
  • Transformationen laufen pro Frame (alle ~20 ms bei Opus) – aufwendige Logik oder console.log in jedem Frame kann die Latenz erhöhen.