Signatur
Beschreibung
Die schreibgeschützte Eigenschaft timestamp eines RTCAudioSourceStats-Wörterbuchs (Statistiktyp "media-source" mit kind === "audio") enthält einen DOMHighResTimeStamp. Er gibt an, wann die Statistikdaten der lokalen Audioquelle – etwa audioLevel, totalAudioEnergy oder totalSamplesDuration – erfasst wurden.
Der Wert ist eine Zahl in Millisekunden, gemessen seit der Performance-Zeitbasis (performance.timeOrigin). Er hat also dieselbe Zeitbasis wie performance.now(). Um ihn in eine absolute Uhrzeit umzurechnen, addiert man performance.timeOrigin.
In der Praxis braucht man timestamp vor allem, um Raten zu berechnen: Die Differenz zweier kumulativer Werte (z. B. totalAudioEnergy) wird durch die Zeitdifferenz zweier Abfragen über RTCPeerConnection.getStats() geteilt. So erhält man z. B. die durchschnittliche Lautstärke über ein Intervall, auch wenn die Abfragen nicht exakt gleichmäßig erfolgen.
Rückgabewert
performance.timeOrigin, gegebenenfalls mit Nachkommastellen.Beispiele
Zeitstempel der Audioquellen-Statistik auslesen
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const pc = new RTCPeerConnection();
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'media-source' && stats.kind === 'audio') {
console.log('Erfasst bei (ms):', stats.timestamp);
console.log('Uhrzeit:', new Date(performance.timeOrigin + stats.timestamp).toISOString());
}
});
Durchschnittlichen Pegel über ein Intervall berechnen
const getAudioSource = async (pc) => {
const report = await pc.getStats();
return [...report.values()].find(
(s) => s.type === 'media-source' && s.kind === 'audio'
);
};
const measureLevel = async (pc, intervalMs = 1000) => {
const a = await getAudioSource(pc);
await new Promise((r) => setTimeout(r, intervalMs));
const b = await getAudioSource(pc);
if (!a || !b) return null;
const energyDelta = b.totalAudioEnergy - a.totalAudioEnergy;
const durationDelta = b.totalSamplesDuration - a.totalSamplesDuration;
const elapsedMs = b.timestamp - a.timestamp;
// RMS-Pegel (0..1) aus der Energie über die Dauer
const rms = durationDelta > 0 ? Math.sqrt(energyDelta / durationDelta) : 0;
console.log(`Messfenster: ${elapsedMs.toFixed(1)} ms, RMS-Pegel: ${rms.toFixed(3)}`);
return rms;
};
await measureLevel(pc);
Veraltete Statistiken erkennen
const isStale = (stats, maxAgeMs = 2000) =>
performance.now() - stats.timestamp > maxAgeMs;
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type === 'media-source' && stats.kind === 'audio') {
console.log(isStale(stats) ? 'Daten veraltet' : 'Daten aktuell');
}
}
// Wichtig · Fallstricke
- Keine Unix-Zeit:
timestampist relativ zuperformance.timeOrigin, nicht zu 1970. FürDatemuss manperformance.timeOriginaddieren. Direkt mitDate.now()vergleichen ergibt Unsinn. - Zwischengespeicherte Werte: Browser können Statistiken kurz zwischenspeichern. Zwei schnell hintereinander ausgeführte
getStats()-Aufrufe liefern dann eventuell denselbentimestamp. Vor dem Teilen durch die Zeitdifferenz immer auf0prüfen. - Präzision: Aus Sicherheitsgründen (Timing-Angriffe) kann die Auflösung vergröbert sein, besonders ohne Cross-Origin-Isolation.
- Kompatibilität: Audio-spezifische
media-source-Statistiken werden in Chromium und Safari unterstützt. Firefox liefert sie nicht oder nur teilweise. Deshalb vorher prüfen, obstats.kind === "audio"gesetzt ist. - Die Eigenschaft ist von
RTCStatsgeerbt und bei allen Statistiktypen gleich aufgebaut.