Signatur
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:
|
Rückgabewert
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);
}
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);
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));
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');
// Wichtig · Fallstricke
- Ist die Verbindung bereits geschlossen (
signalingState === "closed"), wird einInvalidStateErrorgeworfen. Ein ungültiger String alskindführt zu einemTypeError, ungültigesendEncodings(z. B. doppelterid-Werte oderscaleResolutionDownBy< 1) zu einemRangeErroroderTypeError. - Jeder Aufruf erzeugt eine neue m-Section. Rufen Sie
addTransceiver()nicht bei jeder Neuverbindung erneut auf, sondern verwenden Sie vorhandene Transceiver mitreplaceTrack()unddirectionweiter. Sonst wächst die SDP unnötig. - Anders als
addTrack()verwendetaddTransceiver()keine ungenutzten Transceiver wieder, sondern legt immer einen neuen an. - Simulcast über
sendEncodingswird in Safari erst ab Version 15.4 zuverlässig unterstützt. Ältere Firefox-Versionen hatten Einschränkungen beiscaleResolutionDownBy. - Ä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()mittransceiver.setCodecPreferences()fest.