Start · Sprachen · JavaScript · Referenz · RTCPeerConnection.addTransceiver()

RTCPeerConnection.addTransceiver()

Methode

Erstellt einen neuen <code>RTCRtpTransceiver</code> für einen Track oder eine Medienart (<code>"audio"</code>/<code>"video"</code>) und fügt ihn der <code>RTCPeerConnection</code> hinzu.

seit JavaScript Baseline: alle modernen Browser (Chrome 69+, Firef Kategorie: webapi

Signatur

RTCPeerConnection.prototype.addTransceiver(trackOrKind, init)

Beschreibung

addTransceiver() legt einen neuen RTCRtpTransceiver an. Er besteht aus einem RTCRtpSender und einem RTCRtpReceiver und entspricht in der SDP-Aushandlung genau einer Media-Section (m=-Zeile). Anders als bei addTrack() haben Sie hier die volle Kontrolle über Richtung, Streams und Encodings, etwa für Simulcast.

Als erstes Argument übergeben Sie entweder einen MediaStreamTrack oder nur die Medienart als String ("audio" oder "video"). Die zweite Variante ist nützlich, wenn Sie nur empfangen wollen (direction: "recvonly") oder den Track erst später mit sender.replaceTrack() nachreichen möchten, ohne neu verhandeln zu müssen.

Nach dem Aufruf feuert die Verbindung ein negotiationneeded-Ereignis, denn ein neuer Transceiver erfordert ein neues Offer/Answer. Den Transceiver erreichen Sie später über getTransceivers(). Zum Beenden rufen Sie transceiver.stop() auf.

Parameter

Name Typ Default Beschreibung
$trackOrKind Pflicht MediaStreamTrack | "audio" | "video" Ein Track, der dem Sender zugeordnet wird, oder die Medienart als String. Bei einem String wird ein Transceiver ohne Track angelegt (sender.track === null).
$init RTCRtpTransceiverInit {} Optionales Objekt mit folgenden Feldern:
  • direction: "sendrecv" (Standard), "sendonly", "recvonly" oder "inactive"
  • streams: Array von MediaStream-Objekten, denen der Track auf der Gegenseite zugeordnet wird
  • sendEncodings: Array von RTCRtpEncodingParameters, z. B. rid, maxBitrate, scaleResolutionDownBy für Simulcast

Rückgabewert

Typ
RTCRtpTransceiver
Beschreibung
Der neu erstellte Transceiver mit den Eigenschaften sender, receiver, direction und mid. mid bleibt bis zur Aushandlung null.

Beispiele

Kamera-Track senden und empfangen

const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });

for (const track of stream.getTracks()) {
  const transceiver = pc.addTransceiver(track, {
    direction: 'sendrecv',
    streams: [stream]
  });
  console.log(transceiver.sender.track.kind, transceiver.direction);
}
audio sendrecv video sendrecv

Nur empfangen (z. B. Zuschauer eines Streams)

const pc = new RTCPeerConnection();

pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });

pc.addEventListener('track', ({ track, streams }) => {
  console.log('Empfange', track.kind);
  document.querySelector('video').srcObject = streams[0] ?? new MediaStream([track]);
});

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
console.log(pc.getTransceivers().length);
2

Simulcast mit drei Qualitätsstufen

const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } });
const [videoTrack] = stream.getVideoTracks();

const transceiver = pc.addTransceiver(videoTrack, {
  direction: 'sendonly',
  streams: [stream],
  sendEncodings: [
    { rid: 'q', scaleResolutionDownBy: 4, maxBitrate: 150_000 },
    { rid: 'h', scaleResolutionDownBy: 2, maxBitrate: 500_000 },
    { rid: 'f', maxBitrate: 1_500_000 }
  ]
});

console.log(transceiver.sender.getParameters().encodings.map(e => e.rid));
["q", "h", "f"]

Platzhalter anlegen und Track später einsetzen

const pc = new RTCPeerConnection();
const transceiver = pc.addTransceiver('video', { direction: 'sendrecv' });

// ... Aushandlung erfolgt ...

const screen = await navigator.mediaDevices.getDisplayMedia({ video: true });
await transceiver.sender.replaceTrack(screen.getVideoTracks()[0]);
console.log('Bildschirmfreigabe aktiv, keine Neuverhandlung nötig');
Bildschirmfreigabe aktiv, keine Neuverhandlung nötig

// Wichtig · Fallstricke

  • Ist die Verbindung bereits geschlossen (signalingState === "closed"), wird ein InvalidStateError geworfen. Ein ungültiger String als kind führt zu einem TypeError, ungültige sendEncodings (z. B. doppelte rid-Werte oder scaleResolutionDownBy < 1) zu einem RangeError oder TypeError.
  • Jeder Aufruf erzeugt eine neue m-Section. Rufen Sie addTransceiver() nicht bei jeder Neuverbindung erneut auf, sondern verwenden Sie vorhandene Transceiver mit replaceTrack() und direction weiter. Sonst wächst die SDP unnötig.
  • Anders als addTrack() verwendet addTransceiver() keine ungenutzten Transceiver wieder, sondern legt immer einen neuen an.
  • Simulcast über sendEncodings wird in Safari erst ab Version 15.4 zuverlässig unterstützt. Ältere Firefox-Versionen hatten Einschränkungen bei scaleResolutionDownBy.
  • Ältere Safari-Versionen mit „Plan B“-SDP unterstützen keine Transceiver. Aktuelle Browser nutzen ausschließlich „Unified Plan“.
  • Die Codec-Reihenfolge legen Sie vor createOffer() mit transceiver.setCodecPreferences() fest.