Start · Sprachen · JavaScript · Referenz · RTCRtpSender

RTCRtpSender

Schnittstelle

Steuert Enkodierung und Versand eines <code>MediaStreamTrack</code> über eine <code>RTCPeerConnection</code> an einen Remote-Peer und liefert Informationen dazu.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2020) Kategorie: webapi

Signatur

interface RTCRtpSender

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 gesendete MediaStreamTrack oder null.
  • transport: der zugehörige RTCDtlsTransport.
  • dtmf: ein RTCDTMFSender für Tonwahl (nur bei Audio, sonst null).
  • getParameters() / setParameters(): lesen und ändern Enkodierungsparameter wie maxBitrate, maxFramerate, scaleResolutionDownBy, active oder priority.
  • replaceTrack(track): tauscht den gesendeten Track ohne neue SDP-Aushandlung aus, z. B. beim Wechsel von Kamera zu Bildschirmfreigabe.
  • setStreams(...streams): legt fest, zu welchen MediaStreams der Track auf der Gegenseite gehört.
  • getStats(): liefert einen RTCStatsReport nur 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

Typ
RTCRtpSender
Beschreibung
Das Interface selbst wird nicht zurückgegeben. Instanzen bekommst du von 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);
Max. Bitrate: 500000

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/VP8", "video/rtx", "video/VP9", "video/H264", "video/AV1", ...] video: 1843200 Bytes, 1620 Pakete

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 mit getParameters() gelesen hast. Ein selbst gebautes Objekt oder eine veraltete transactionId führt zu einem InvalidModificationError. Die Anzahl der encodings und ihre rids lassen sich nachträglich nicht ändern; Simulcast-Schichten legst du über addTransceiver(track, { sendEncodings }) fest.
  • Leere encodings: Vor Abschluss der Aushandlung (setLocalDescription) kann encodings in 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 selbst track.stop() auf, damit die Kamera-LED ausgeht.
  • removeTrack(sender) an der RTCPeerConnection erfordert eine neue Aushandlung. replaceTrack(null) dagegen nicht.
  • Kompatibilität: Grundfunktionen gibt es in Chrome, Edge, Firefox und Safari. setStreams(), priority/networkPriority, scalabilityMode und 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).