Signatur
Beschreibung
Die schreibgeschützte Eigenschaft sender eines RTCRtpTransceiver verweist auf das RTCRtpSender-Objekt, das für den ausgehenden Teil des Transceivers zuständig ist. Es kodiert die Mediendaten des zugewiesenen MediaStreamTrack und überträgt sie als RTP-Pakete an die Gegenstelle.
Jeder Transceiver besteht aus einem festen Paar aus sender und receiver. Das Sender-Objekt bleibt über die gesamte Lebensdauer des Transceivers gleich und wird nicht ausgetauscht. Ausgetauscht wird nur der Track, den es sendet, und zwar mit sender.replaceTrack(). Dafür ist keine neue SDP-Aushandlung nötig.
In der Praxis greift man über transceiver.sender vor allem auf diese Funktionen zu:
- Track wechseln, z. B. von der Kamera zur Bildschirmfreigabe (
replaceTrack()) - Kodierparameter anpassen, z. B. Bitrate, Auflösungsskalierung oder Simulcast-Schichten (
getParameters()/setParameters()) - Statistiken abrufen (
getStats()) - DTMF-Töne senden bei Audio (
dtmf)
Hat der Sender noch keinen Track, ist sender.track gleich null. Das kommt z. B. vor, wenn ein Transceiver mit addTransceiver("video") ohne Track angelegt wurde oder wenn die Richtung "recvonly" ist.
Rückgabewert
RTCRtpSender-Objekt, das die ausgehenden Medien des Transceivers kodiert und sendet. Die Eigenschaft ist nie null, der zugehörige track kann aber null sein.Beispiele
Sender eines neuen Transceivers auslesen
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [videoTrack] = stream.getVideoTracks();
const transceiver = pc.addTransceiver(videoTrack, { direction: 'sendrecv' });
const { sender } = transceiver;
console.log(sender instanceof RTCRtpSender);
console.log(sender.track === videoTrack);
Von Kamera auf Bildschirmfreigabe umschalten
const switchToScreen = async (pc) => {
const screen = await navigator.mediaDevices.getDisplayMedia({ video: true });
const [screenTrack] = screen.getVideoTracks();
// Video-Transceiver suchen
const transceiver = pc.getTransceivers()
.find((t) => t.receiver.track.kind === 'video');
// Track tauschen, ohne neue Aushandlung
await transceiver.sender.replaceTrack(screenTrack);
console.log('Sende jetzt:', transceiver.sender.track.label);
};
Maximale Bitrate über den Sender begrenzen
const limitBitrate = async (transceiver, maxBitrate) => {
const { sender } = transceiver;
const params = sender.getParameters();
if (!params.encodings || params.encodings.length === 0) {
params.encodings = [{}];
}
params.encodings[0].maxBitrate = maxBitrate;
await sender.setParameters(params);
console.log('Neue Bitrate:', sender.getParameters().encodings[0].maxBitrate);
};
// Aufruf nach erfolgreicher Aushandlung
await limitBitrate(pc.getTransceivers()[0], 500_000);
Ausgehende Statistiken abfragen
const logOutbound = async (transceiver) => {
const report = await transceiver.sender.getStats();
report.forEach((stat) => {
if (stat.type === 'outbound-rtp') {
console.log(`${stat.kind}: ${stat.bytesSent} Bytes gesendet`);
}
});
};
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
transceiver.senderwird still ignoriert (im Strict Mode gibt es einenTypeError). Einen Track wechselt man mitsender.replaceTrack(). - Track kann
nullsein: Vor dem Zugriff aufsender.track.kindimmer prüfen, z. B. mitsender.track?.kind. Die Medienart ermittelt man zuverlässiger übertransceiver.receiver.track.kind, denn der Receiver hat immer einen Track. - Richtung beachten: Bei
direction"recvonly"oder"inactive"sendet der Sender nichts, auch wenn ein Track zugewiesen ist. - Gestoppte Transceiver: Nach
transceiver.stop()bleibt das Sender-Objekt erreichbar, sendet aber nichts mehr. Aufrufe wiereplaceTrack()werden dann abgelehnt (InvalidStateError). setParameters(): Vorher immergetParameters()aufrufen und das zurückgegebene Objekt ändern. Selbst gebaute Objekte führen wegen der fehlendentransactionIdzu einemInvalidModificationError.- Kompatibilität: Wird in Chrome, Edge, Firefox und Safari unterstützt (Unified Plan). Ältere Browser mit „Plan B“ kannten keine Transceiver. Dort gab es nur
pc.getSenders(). - Nur in einem sicheren Kontext (HTTPS) sinnvoll nutzbar, weil
getUserMedia()undgetDisplayMedia()HTTPS voraussetzen.