Signatur
Beschreibung
Ein RTCRtpSender gehört zu genau einer RTCPeerConnection und ist für das Senden eines einzelnen Medien-Tracks (Audio oder Video) als RTP-Strom zuständig. Du erhältst ihn als Rückgabewert von RTCPeerConnection.addTrack(), über RTCRtpTransceiver.sender oder über RTCPeerConnection.getSenders(). Mit new selbst erzeugen kannst du ihn nicht.
Wichtige Mitglieder:
track: der gerade gesendeteMediaStreamTrackodernull.transport: der zugehörigeRTCDtlsTransport.dtmf: einRTCDTMFSenderfür Tonwahl (nur bei Audio, sonstnull).getParameters()/setParameters(): lesen und ändern Enkodierungsparameter wiemaxBitrate,maxFramerate,scaleResolutionDownBy,activeoderpriority.replaceTrack(track): tauscht den gesendeten Track ohne neue SDP-Aushandlung aus, z. B. beim Wechsel von Kamera zu Bildschirmfreigabe.setStreams(...streams): legt fest, zu welchenMediaStreams der Track auf der Gegenseite gehört.getStats(): liefert einenRTCStatsReportnur für diesen Sender.RTCRtpSender.getCapabilities(kind)(statisch): meldet die Codecs und Header-Erweiterungen, die der Browser senden kann.
Typische Anwendungen sind Bandbreitenbegrenzung, Simulcast-Steuerung, das Stummschalten eines Videos ohne neue Aushandlung (replaceTrack(null) oder encodings[i].active = false) und das Auswerten der Sendestatistik für die Qualitätsüberwachung.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $track (replaceTrack) Pflicht | MediaStreamTrack | null | Neuer Track mit derselben kind (audio/video), oder null, um das Senden zu pausieren. |
|
| $parameters (setParameters) Pflicht | RTCRtpSendParameters | Das Objekt, das zuvor mit getParameters() gelesen und dann verändert wurde (enthält transactionId, encodings und weitere Felder). |
|
| $kind (getCapabilities) Pflicht | "audio" | "video" | Medienart, für die die Sendefähigkeiten abgefragt werden. | |
| $...streams (setStreams) | MediaStream[] | Streams, denen der Track beim Empfänger zugeordnet wird. |
Rückgabewert
addTrack(), getSenders() oder transceiver.sender. replaceTrack(), setParameters() und getStats() liefern jeweils ein Promise.Beispiele
Sender über addTrack erhalten und Bitrate begrenzen
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const videoTrack = stream.getVideoTracks()[0];
const sender = pc.addTrack(videoTrack, stream);
// Parameter lesen, ändern, zurückschreiben
const params = sender.getParameters();
if (!params.encodings || params.encodings.length === 0) {
params.encodings = [{}];
}
params.encodings[0].maxBitrate = 500_000; // 500 kbit/s
params.encodings[0].maxFramerate = 24;
await sender.setParameters(params);
console.log('Max. Bitrate:', sender.getParameters().encodings[0].maxBitrate);
Zwischen Kamera und Bildschirmfreigabe wechseln (replaceTrack)
const switchToScreen = async (pc) => {
const screen = await navigator.mediaDevices.getDisplayMedia({ video: true });
const screenTrack = screen.getVideoTracks()[0];
const sender = pc.getSenders().find((s) => s.track?.kind === 'video');
if (!sender) throw new Error('Kein Video-Sender gefunden');
const cameraTrack = sender.track;
await sender.replaceTrack(screenTrack); // keine neue Aushandlung nötig
// Wenn die Freigabe beendet wird, zurück zur Kamera
screenTrack.addEventListener('ended', () => sender.replaceTrack(cameraTrack));
};
Sendestatistik und Codec-Fähigkeiten auslesen
const logOutboundStats = async (sender) => {
const report = await sender.getStats();
report.forEach((stat) => {
if (stat.type === 'outbound-rtp') {
console.log(`${stat.kind}: ${stat.bytesSent} Bytes, ${stat.packetsSent} Pakete`);
}
});
};
const caps = RTCRtpSender.getCapabilities('video');
console.log(caps.codecs.map((c) => c.mimeType));
Video pausieren, ohne den Track zu stoppen
const setVideoActive = async (sender, active) => {
const params = sender.getParameters();
params.encodings.forEach((enc) => { enc.active = active; });
await sender.setParameters(params);
};
// Beispiel: Video kurz aussetzen
const videoSender = pc.getSenders().find((s) => s.track?.kind === 'video');
await setVideoActive(videoSender, false);
// Wichtig · Fallstricke
- Ablauf bei
setParameters(): Übergib immer das Objekt, das du unmittelbar vorher mitgetParameters()gelesen hast. Ein selbst gebautes Objekt oder eine veraltetetransactionIdführt zu einemInvalidModificationError. Die Anzahl derencodingsund ihrerids lassen sich nachträglich nicht ändern; Simulcast-Schichten legst du überaddTransceiver(track, { sendEncodings })fest. - Leere
encodings: Vor Abschluss der Aushandlung (setLocalDescription) kannencodingsin manchen Browsern leer sein. Setze Parameter deshalb am besten nach der Aushandlung. replaceTrack()funktioniert nur mit einem Track derselben Art. Weicht der neue Track stark ab (z. B. anderer Codec nötig), wird das Promise abgelehnt. Der alte Track wird dabei nicht gestoppt; rufe bei Bedarf selbsttrack.stop()auf, damit die Kamera-LED ausgeht.removeTrack(sender)an derRTCPeerConnectionerfordert eine neue Aushandlung.replaceTrack(null)dagegen nicht.- Kompatibilität: Grundfunktionen gibt es in Chrome, Edge, Firefox und Safari.
setStreams(),priority/networkPriority,scalabilityModeund Encoded Transforms (sender.transform) werden unterschiedlich unterstützt. Prüfe diese Features vorher, z. B. mit'setStreams' in RTCRtpSender.prototype. - Datenschutz:
getCapabilities()kann zum Fingerprinting beitragen. Aus Mediengeräten erzeugte Tracks gibt es ohnehin nur in sicheren Kontexten (HTTPS).