Signatur
Beschreibung
RTCTrackEvent ist das Ereignisobjekt des track-Ereignisses einer RTCPeerConnection. Es wird ausgelöst, wenn während der SDP-Aushandlung (meist nach setRemoteDescription()) ein neuer eingehender Medienkanal entsteht und dem zugehörigen RTCRtpReceiver ein MediaStreamTrack zugeordnet wird. Über dieses Ereignis kommt man bei einer WebRTC-Verbindung also an das Audio- und Videomaterial der Gegenseite.
Das Ereignis hat vier schreibgeschützte Eigenschaften:
track– der neue eingehendeMediaStreamTrackstreams– ein Array mit denMediaStream-Objekten, denen die Gegenseite den Track zugeordnet hat (kann leer sein)receiver– derRTCRtpReceiver, der den Track empfängttransceiver– der zugehörigeRTCRtpTransceiver
Meist hängt man event.streams[0] direkt an ein <video>-Element (über srcObject). Sendet die Gegenseite ihre Tracks ohne Stream-Zuordnung (addTrack(track) ohne Stream-Argument), ist streams leer. Dann muss man selbst einen MediaStream anlegen und die Tracks hinzufügen.
Wie jedes Ereignis kann man es mit pc.addEventListener("track", handler) oder über die Eigenschaft pc.ontrack abfangen. Den Konstruktor new RTCTrackEvent(type, init) braucht man in der Praxis kaum, höchstens für Tests oder eigene Ereignisse.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, normalerweise "track". |
|
| $eventInitDict Pflicht | object | Initialisierungsobjekt (RTCTrackEventInit). Pflichtfelder sind receiver (RTCRtpReceiver), track (MediaStreamTrack) und transceiver (RTCRtpTransceiver). Optional sind streams (MediaStream[], Standard []) sowie die üblichen Event-Optionen bubbles, cancelable und composed. |
Rückgabewert
RTCTrackEvent-Objekt mit den Eigenschaften track, streams, receiver und transceiver, die alle schreibgeschützt sind.Beispiele
Entfernten Stream mit addEventListener im Video-Element anzeigen
const pc = new RTCPeerConnection({
iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});
const remoteVideo = document.querySelector("#remote");
pc.addEventListener("track", (event) => {
console.log(`Neuer ${event.track.kind}-Track:`, event.track.id);
// Nur einmal zuweisen, da das Ereignis für Audio UND Video ausgelöst wird
if (remoteVideo.srcObject !== event.streams[0]) {
remoteVideo.srcObject = event.streams[0];
}
});
ontrack mit Rückfall bei leerem streams-Array
const pc = new RTCPeerConnection();
const remoteVideo = document.querySelector("#remote");
let inboundStream = null;
pc.ontrack = ({ track, streams }) => {
if (streams.length > 0) {
remoteVideo.srcObject = streams[0];
return;
}
// Gegenseite hat addTrack() ohne Stream aufgerufen
if (!inboundStream) {
inboundStream = new MediaStream();
remoteVideo.srcObject = inboundStream;
}
inboundStream.addTrack(track);
};
Transceiver und Receiver auswerten, Track-Ende erkennen
const pc = new RTCPeerConnection();
pc.addEventListener("track", (event) => {
const { track, receiver, transceiver } = event;
console.log("mid:", transceiver.mid, "Richtung:", transceiver.currentDirection);
track.addEventListener("unmute", () => console.log(`${track.kind} liefert Daten`));
track.addEventListener("ended", () => console.log(`${track.kind} beendet`));
// Empfangsstatistiken gezielt für diesen Track abfragen
setTimeout(async () => {
const stats = await receiver.getStats();
stats.forEach((r) => {
if (r.type === "inbound-rtp") console.log("Pakete empfangen:", r.packetsReceived);
});
}, 5000);
});
Wieder abmelden: removeEventListener bzw. ontrack = null
const pc = new RTCPeerConnection();
const onTrack = (e) => console.log("Track:", e.track.kind);
pc.addEventListener("track", onTrack);
// … später, z. B. beim Aufräumen der Komponente
pc.removeEventListener("track", onTrack);
pc.ontrack = null;
pc.close();
// Wichtig · Fallstricke
- Mehrfaches Auslösen: Das Ereignis kommt einmal pro Track, bei Audio und Video also zweimal. Wer
srcObjectjedes Mal neu setzt, riskiert Flackern oder abgebrocheneplay()-Aufrufe. Deshalb vorher auf Gleichheit prüfen. - Leeres
streams-Array: Gibt der Absender beiaddTrack()keinen Stream an, bleibtstreamsleer. Dann muss man denMediaStreamselbst anlegen. - Zeitpunkt: Das Ereignis kommt schon während
setRemoteDescription(), also bevor Medien fließen. Anfangs ist der Track oftmuted; erst dasunmute-Ereignis zeigt, dass tatsächlich Daten ankommen. Deshalb den Handler registrieren, bevor man die Remote-Beschreibung setzt. - Entfernen: Wird ein Track auf der Gegenseite entfernt, gibt es kein Gegenstück zu
track. Stattdessen löst derMediaStreamdas Ereignisremovetrackaus bzw. der Track wirdmuted/ended. - Autoplay: Ein Video mit Ton startet ohne vorherige Nutzeraktion oft nicht. Dann
mutedundplaysinlinesetzen (für iOS Safari wichtig) oderplay()nach einer Nutzeraktion aufrufen. - Kompatibilität: Das veraltete Ereignis
addstreambzw.onaddstreamsollte nicht mehr verwendet werden,trackist der Standard. Die Eigenschafttransceivergibt es in Safari erst ab Version 12.1.