Start · Sprachen · JavaScript · Referenz · RTCTrackEvent.streams

RTCTrackEvent.streams

Eigenschaft

Schreibgeschütztes Array der <code>MediaStream</code>-Objekte, denen der im <code>track</code>-Event empfangene Remote-Track angehört.

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

Signatur

RTCTrackEvent.streams

Beschreibung

Die Eigenschaft streams des RTCTrackEvent liefert ein schreibgeschütztes Array von MediaStream-Objekten. Jeder Eintrag steht für einen Stream, zu dem der neu empfangene Track (event.track) gehört. Das Event wird am RTCPeerConnection ausgelöst, sobald die Gegenstelle per SDP-Aushandlung einen neuen Track ankündigt.

Hauptzweck ist es, Remote-Tracks einfach in einem <video>- oder <audio>-Element darzustellen: Da Audio- und Video-Track desselben Streams jeweils ein eigenes track-Event auslösen, aber auf dasselbe MediaStream-Objekt verweisen, genügt meist video.srcObject = event.streams[0]. So bleiben Audio und Video synchron (Lip-Sync), weil sie derselben Stream-ID zugeordnet sind.

Welche Streams im Array landen, bestimmt der Sender: Beim Aufruf von pc.addTrack(track, ...streams) auf der Gegenseite werden die angegebenen Streams über die a=msid-Zeilen im SDP übertragen. Wurde addTrack() ohne Stream-Argument aufgerufen, ist streams ein leeres Array. Ein Track kann auch mehreren Streams gleichzeitig angehören.

Rückgabewert

Typ
ReadonlyArray<MediaStream>
Beschreibung
Ein eingefrorenes Array von MediaStream-Objekten, die den empfangenen Track enthalten. Kann leer sein, wenn der Sender keinem Stream zugeordnet hat.

Beispiele

Remote-Stream an ein Video-Element binden

const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const remoteVideo = document.querySelector('#remoteVideo');

pc.addEventListener('track', (event) => {
  const [remoteStream] = event.streams;
  // Audio- und Video-Track teilen sich denselben Stream – nur einmal zuweisen
  if (remoteStream && remoteVideo.srcObject !== remoteStream) {
    remoteVideo.srcObject = remoteStream;
    console.log('Remote-Stream verbunden:', remoteStream.id);
  }
});
Remote-Stream verbunden: 3f1c9a2e-7b4d-4c1e-9f0a-12ab34cd56ef

Fallback bei leerem streams-Array

const pc = new RTCPeerConnection();
const remoteVideo = document.querySelector('#remoteVideo');
let fallbackStream = null;

pc.ontrack = ({ track, streams }) => {
  if (streams.length > 0) {
    remoteVideo.srcObject = streams[0];
    return;
  }
  // Sender hat addTrack() ohne Stream aufgerufen – eigenen Stream aufbauen
  fallbackStream ??= new MediaStream();
  fallbackStream.addTrack(track);
  remoteVideo.srcObject = fallbackStream;
  console.log(`Track ${track.kind} ohne Stream empfangen – Fallback genutzt`);
};
Track video ohne Stream empfangen – Fallback genutzt

Mehrere Teilnehmer anhand der Stream-ID verwalten

const pc = new RTCPeerConnection();
const container = document.querySelector('#participants');
const videos = new Map(); // stream.id -> HTMLVideoElement

pc.addEventListener('track', (event) => {
  for (const stream of event.streams) {
    if (videos.has(stream.id)) continue;

    const video = document.createElement('video');
    video.autoplay = true;
    video.playsInline = true;
    video.srcObject = stream;
    container.append(video);
    videos.set(stream.id, video);

    // Aufräumen, wenn der Stream seinen letzten Track verliert
    stream.addEventListener('removetrack', () => {
      if (stream.getTracks().length === 0) {
        video.remove();
        videos.delete(stream.id);
      }
    });
  }
  console.log('Aktive Teilnehmer:', videos.size);
});
Aktive Teilnehmer: 2

// Wichtig · Fallstricke

  • Leeres Array möglich: Ruft die Gegenseite addTrack(track) ohne Stream auf, ist event.streams leer – event.streams[0] ist dann undefined. Immer prüfen oder mit event.track einen eigenen MediaStream aufbauen.
  • Mehrfache Events: Für jeden Track (Audio, Video) wird ein eigenes track-Event ausgelöst. Wer srcObject jedes Mal neu setzt, kann Ruckler oder abgebrochene play()-Promises verursachen – vorher auf Gleichheit prüfen.
  • Stream-IDs: Die id des Remote-Streams entspricht der vom Sender gewählten msid, nicht zwingend der lokalen Stream-ID auf der Senderseite in allen älteren Implementierungen.
  • Schreibgeschützt: Das Array ist eingefroren; push() o. Ä. wirft im Strict Mode einen TypeError.
  • Kompatibilität: In allen modernen Browsern verfügbar. Das veraltete addstream-Event bzw. onaddstream sollte nicht mehr verwendet werden; ältere Safari-Versionen vor 11 unterstützen ontrack nicht.
  • Autoplay-Richtlinien beachten: Für Video mit Ton ist oft eine Nutzerinteraktion nötig; muted und playsInline helfen besonders auf iOS.