Signatur
Beschreibung
Die schreibgeschützte Eigenschaft headerBytesSent eines RTCOutboundRtpStreamStats-Objekts (Statistiktyp "outbound-rtp") zählt alle Bytes, die bisher als RTP-Header oder Padding für die jeweilige Synchronisationsquelle (SSRC) gesendet wurden. Dazu gehören auch RTP-Header-Erweiterungen. Nutzdaten zählen nicht dazu, sie stehen in bytesSent. Header von Transportprotokollen wie IP, UDP, DTLS oder TURN werden ebenfalls nicht mitgezählt.
Zusammen mit bytesSent ergibt sich die gesamte RTP-Bandbreite eines Streams. So lässt sich der Protokoll-Overhead berechnen. Das ist nützlich bei niedrigen Bitraten, etwa bei Audio mit Opus, wo Header einen großen Anteil haben. Auch Padding-Bytes, die die Bandbreitenschätzung (z. B. beim Probing) erzeugt, sind hier sichtbar.
Der Wert ist ein kumulativer Zähler, der seit Beginn des Streams nur wächst. Um eine Rate in Bit pro Sekunde zu erhalten, vergleichst du zwei Messungen und teilst die Differenz durch die Differenz der timestamp-Werte in Millisekunden.
Rückgabewert
unsigned long long) mit der Gesamtzahl der bisher gesendeten RTP-Header- und Padding-Bytes für diese SSRC.Beispiele
Header-Bytes aller ausgehenden Streams auslesen
// pc ist eine verbundene RTCPeerConnection
const logHeaderBytes = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'outbound-rtp') {
console.log(`${stats.kind} (SSRC ${stats.ssrc}): ` +
`${stats.headerBytesSent} Header-Bytes, ${stats.bytesSent} Nutzdaten-Bytes`);
}
});
};
await logHeaderBytes(pc);
Header-Overhead in Prozent berechnen
const overheadPercent = async (sender) => {
const report = await sender.getStats();
for (const stats of report.values()) {
if (stats.type === 'outbound-rtp' && stats.headerBytesSent !== undefined) {
const total = stats.headerBytesSent + stats.bytesSent;
return total === 0 ? 0 : (stats.headerBytesSent / total) * 100;
}
}
return null; // Wert nicht verfügbar
};
const [audioSender] = pc.getSenders().filter((s) => s.track?.kind === 'audio');
const pct = await overheadPercent(audioSender);
console.log(`RTP-Header-Overhead: ${pct?.toFixed(1)} %`);
Header-Bitrate periodisch messen
const monitorHeaderBitrate = (sender, intervalMs = 1000) => {
let last = null;
return setInterval(async () => {
const report = await sender.getStats();
const current = [...report.values()].find((s) => s.type === 'outbound-rtp');
if (!current) return;
if (last) {
const deltaBytes = current.headerBytesSent - last.headerBytesSent;
const deltaMs = current.timestamp - last.timestamp;
const kbps = (deltaBytes * 8) / deltaMs; // Bit pro ms = kbit/s
console.log(`Header-Bitrate: ${kbps.toFixed(1)} kbit/s`);
}
last = current;
}, intervalMs);
};
const timerId = monitorHeaderBitrate(pc.getSenders()[0]);
// Später: clearInterval(timerId);
// Wichtig · Fallstricke
- Kein Transport-Overhead: IP-, UDP-, SRTP-Auth-Tag- und TURN-Header sind nicht enthalten. Die tatsächliche Netzlast ist also höher als
headerBytesSent + bytesSent. Für die Transportebene gibt esRTCTransportStats.bytesSentbzw.RTCIceCandidatePairStats.bytesSent. - Retransmissionen: Mit RTX und Simulcast hat jede Schicht einen eigenen
outbound-rtp-Eintrag. Für die Summe musst du über alle Einträge addieren. Retransmittierte Bytes stehen zusätzlich inretransmittedBytesSent. - Browser-Unterstützung: Chromium-Browser und Firefox liefern den Wert. In Safari fehlt er je nach Version. Prüfe deshalb vor dem Rechnen auf
undefined. - Der Zähler ist kumulativ. Wird ein Sender über
replaceTrack()neu belegt, bleibt der Zähler meist erhalten. Bei einer neuen SSRC beginnt er wieder bei 0.