Signatur
Beschreibung
Die Eigenschaft remoteTimestamp gehört zu Statistik-Objekten vom Typ "remote-outbound-rtp", die du über RTCPeerConnection.getStats() oder RTCRtpReceiver.getStats() erhältst. Sie beschreibt, wann der entfernte Peer die Statistiken zu seinem ausgehenden RTP-Strom verschickt hat. Der Wert stammt aus dem NTP-Zeitstempel des RTCP-Sender Reports (SR) und wird in einen DOMHighResTimeStamp (Millisekunden seit dem 1. Januar 1970 UTC) umgerechnet.
Im Unterschied dazu gibt die geerbte Eigenschaft timestamp an, wann die Statistiken lokal erzeugt bzw. empfangen wurden. Die Differenz timestamp - remoteTimestamp setzt sich also aus der Übertragungsverzögerung (einseitige Latenz) und dem Uhrenversatz zwischen beiden Rechnern zusammen.
Typische Einsatzzwecke sind die Diagnose von Verbindungsqualität, das Erkennen veralteter Berichte (z. B. wenn keine neuen Sender Reports mehr eintreffen) und die grobe Abschätzung von Uhrenabweichungen zwischen den Peers. Für eine verlässliche Latenzmessung eignet sich dagegen eher roundTripTime aus "remote-inbound-rtp"-Statistiken, da diese nicht von synchronisierten Uhren abhängt.
Rückgabewert
undefined), solange noch kein RTCP Sender Report empfangen wurde.Beispiele
remoteTimestamp aus den Empfangsstatistiken auslesen
// pc ist eine bestehende, verbundene RTCPeerConnection
const logRemoteTimestamps = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'remote-outbound-rtp') {
const remote = new Date(stats.remoteTimestamp);
console.log(`${stats.kind}: SR gesendet um ${remote.toISOString()}`);
}
});
};
await logRemoteTimestamps(pc);
Alter des Berichts und Uhrenversatz abschätzen
const analyzeSenderReports = async (receiver) => {
const report = await receiver.getStats();
for (const stats of report.values()) {
if (stats.type !== 'remote-outbound-rtp' || stats.remoteTimestamp === undefined) continue;
// lokale Zeit minus entfernte Zeit = Latenz + Uhrenversatz
const delta = stats.timestamp - stats.remoteTimestamp;
console.log(`Delta lokal/entfernt: ${delta.toFixed(1)} ms`);
// Wie alt ist der Bericht aus lokaler Sicht?
const age = (performance.timeOrigin + performance.now()) - stats.timestamp;
console.log(`Bericht ist ${age.toFixed(0)} ms alt`);
}
};
const [receiver] = pc.getReceivers();
await analyzeSenderReports(receiver);
Ausbleibende Sender Reports überwachen
const watchSenderReports = (pc, timeoutMs = 10000) => {
const lastSeen = new Map();
return setInterval(async () => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type !== 'remote-outbound-rtp') return;
const prev = lastSeen.get(stats.id);
if (prev && prev.remoteTimestamp === stats.remoteTimestamp) {
if (Date.now() - prev.seenAt > timeoutMs) {
console.warn(`Keine neuen Sender Reports für ${stats.kind}`);
}
return;
}
lastSeen.set(stats.id, { remoteTimestamp: stats.remoteTimestamp, seenAt: Date.now() });
});
}, 2000);
};
const timer = watchSenderReports(pc);
// später: clearInterval(timer);
// Wichtig · Fallstricke
- Uhren nicht synchron: Der Wert basiert auf der Systemuhr des entfernten Peers. Weicht diese ab, kann
timestamp - remoteTimestampsogar negativ werden. Nutze die Differenz nicht als exakte Latenz, sondern verwenderoundTripTimeaus"remote-inbound-rtp". - Kann fehlen: Bevor der erste RTCP Sender Report eintrifft, gibt es entweder kein
"remote-outbound-rtp"-Objekt oderremoteTimestampistundefined. Immer prüfen, bevor du rechnest. - Bezugspunkt: Anders als
performance.now()ist der Wert relativ zur Unix-Epoche und kann direkt annew Date()übergeben werden. - Aktualisierungsrate: Sender Reports kommen typischerweise nur alle paar Sekunden; mehrere
getStats()-Aufrufe hintereinander liefern daher oft denselben Wert. - Kompatibilität: Unterstützt in aktuellen Versionen von Chrome, Edge, Firefox und Safari; ältere Browser liefern
"remote-outbound-rtp"-Statistiken teilweise gar nicht.