Start · Sprachen · JavaScript · Referenz · RTCRtpReceiver.track

RTCRtpReceiver.track

Eigenschaft

Schreibgeschützte Eigenschaft, die den <code>MediaStreamTrack</code> liefert, über den ein <code>RTCRtpReceiver</code> eingehende Audio- oder Videodaten bereitstellt.

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

Signatur

RTCRtpReceiver.track

Beschreibung

Die Eigenschaft track eines RTCRtpReceiver gibt den MediaStreamTrack zurück, über den die vom entfernten Teilnehmer empfangenen Medien in deiner Anwendung ankommen. Diesen Track kannst du in einen MediaStream packen und in einem <video>- oder <audio>-Element abspielen, mit der Web Audio API verarbeiten oder für Statistiken und die Qualitätsüberwachung auswerten.

Der Track wird zusammen mit dem Empfänger angelegt, also sobald ein RTCRtpTransceiver entsteht, etwa durch addTransceiver() oder beim Anwenden einer entfernten Beschreibung mit setRemoteDescription(). Er ist nie null, bleibt über die ganze Lebensdauer des Empfängers dasselbe Objekt und ist anfangs stummgeschaltet (muted === true). Sobald RTP-Pakete eintreffen, wechselt er zu muted === false und löst das Ereignis unmute aus.

In der Praxis bekommst du den Track meistens über das Ereignis track von RTCPeerConnection (event.track entspricht event.receiver.track). Direkt über receiver.track greifst du vor allem dann zu, wenn du über pc.getReceivers() oder pc.getTransceivers() gehst, zum Beispiel um alle eingehenden Tracks aufzulisten oder gezielt Audio- und Videoempfänger zu unterscheiden.

Rückgabewert

Typ
MediaStreamTrack
Beschreibung
Der mit dem Empfänger verknüpfte eingehende MediaStreamTrack. Seine Eigenschaft kind ist "audio" oder "video". Die Eigenschaft ist schreibgeschützt, eine Zuweisung hat keine Wirkung.

Beispiele

Eingehendes Video im track-Ereignis anzeigen

const pc = new RTCPeerConnection();
const remoteVideo = document.querySelector('#remote');

pc.addEventListener('track', ({ receiver, streams }) => {
  // receiver.track ist identisch mit event.track
  const track = receiver.track;
  console.log(`Neuer ${track.kind}-Track, stumm: ${track.muted}`);

  if (track.kind === 'video') {
    remoteVideo.srcObject = streams[0] ?? new MediaStream([track]);
  }
});
Neuer video-Track, stumm: true

Alle eingehenden Tracks über getReceivers() auflisten

const listIncomingTracks = (pc) =>
  pc.getReceivers().map(({ track }) => ({
    id: track.id,
    kind: track.kind,
    readyState: track.readyState,
    muted: track.muted
  }));

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

console.table(listIncomingTracks(pc));
Tabelle mit zwei Einträgen: kind "audio" und "video", readyState "live", muted true

Auf eintreffende Medien warten (unmute)

const waitForMedia = (receiver) =>
  new Promise((resolve) => {
    const { track } = receiver;
    if (!track.muted) return resolve(track);
    track.addEventListener('unmute', () => resolve(track), { once: true });
  });

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

waitForMedia(receiver).then((track) => {
  console.log('Erste Videodaten empfangen:', track.id);
});
Erste Videodaten empfangen: <Track-ID> (sobald RTP-Pakete eintreffen)

Eingehendes Audio mit der Web Audio API pegeln

const monitorLevel = (receiver) => {
  const ctx = new AudioContext();
  const source = ctx.createMediaStreamSource(new MediaStream([receiver.track]));
  const analyser = ctx.createAnalyser();
  source.connect(analyser);

  const data = new Uint8Array(analyser.frequencyBinCount);
  setInterval(() => {
    analyser.getByteFrequencyData(data);
    const avg = data.reduce((a, b) => a + b, 0) / data.length;
    console.log('Pegel:', avg.toFixed(1));
  }, 1000);
};

const pc = new RTCPeerConnection();
const audioReceiver = pc.getReceivers().find((r) => r.track.kind === 'audio');
if (audioReceiver) monitorLevel(audioReceiver);
Pegel: 0.0 … (ab Medienempfang steigende Werte)

// Wichtig · Fallstricke

  • Stumm am Anfang: Der Track ist sofort vorhanden, aber stummgeschaltet (muted), bis Daten ankommen. Wenn du auf unmute hörst, weißt du, ab wann wirklich Medien fließen.
  • Kein Ersetzen: Anders als bei RTCRtpSender gibt es kein replaceTrack(). Der Empfänger-Track bleibt immer dasselbe Objekt.
  • Beenden: Wird der Transceiver gestoppt (transceiver.stop()) oder die Verbindung geschlossen (pc.close()), wechselt der Track auf readyState === "ended". Ändert die Gegenseite nur die Richtung (z. B. auf inactive), wird der Track stummgeschaltet, aber nicht beendet. Den Track selbst mit track.stop() zu stoppen beendet nur die lokale Wiedergabe, die Gegenseite sendet weiter.
  • Autoplay: Browser können die Wiedergabe von eingehendem Audio ohne vorherige Nutzerinteraktion blockieren. Rufe play() am Medienelement auf und fange ein abgelehntes Promise ab.
  • Kompatibilität: In allen modernen Browsern verfügbar. In älteren Implementierungen (vor Unified Plan, z. B. Chrome mit Plan B) konnten sich die Zuordnung von Empfängern zu Tracks und der Zeitpunkt ihres Entstehens anders verhalten.