Signatur
Beschreibung
RTCInboundRtpStreamStats ist ein Wörterbuch (Dictionary) der WebRTC-API. Es beschreibt die Empfangsseite eines RTP-Streams an der lokalen RTCPeerConnection. Solche Objekte erhältst du nicht über einen Konstruktor. Sie stecken im RTCStatsReport, den RTCPeerConnection.getStats() oder RTCRtpReceiver.getStats() zurückgibt, und haben dort den Wert type === "inbound-rtp".
Die Einträge eignen sich für Qualitätsüberwachung (Paketverlust, Jitter, Bitrate), Diagnose (eingefrorene Videos, Decoder-Probleme) und adaptive Oberflächen, zum Beispiel eine Anzeige der Verbindungsqualität. Wichtige Felder sind:
kind(„audio“ oder „video“),ssrc,trackIdentifier,mid,codecId,transportIdpacketsReceived,packetsLost,bytesReceived,headerBytesReceived,jitter,lastPacketReceivedTimestamp- nur Video:
framesDecoded,framesDropped,framesReceived,keyFramesDecoded,frameWidth,frameHeight,framesPerSecond,freezeCount,totalFreezesDuration,pliCount,firCount,nackCount,decoderImplementation,qpSum - nur Audio:
audioLevel,totalAudioEnergy,totalSamplesReceived,concealedSamples,concealmentEvents - Jitter-Puffer:
jitterBufferDelay,jitterBufferEmittedCount,jitterBufferTargetDelay - Verweis auf die Gegenseite:
remoteIdzeigt auf den zugehörigenremote-outbound-rtp-Eintrag
Fast alle Zähler sind kumulativ, zählen also seit Beginn des Streams hoch. Raten wie die Bitrate in kbit/s oder den Paketverlust in Prozent berechnest du selbst: Du vergleichst zwei Messungen und teilst die Differenz der Werte durch die Differenz der timestamp-Werte (in Millisekunden).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $id Pflicht | string | — | Eindeutige ID des Statistik-Objekts innerhalb des Berichts. |
| $type Pflicht | "inbound-rtp" | — | Typ-Kennung; bei diesem Wörterbuch immer "inbound-rtp". |
| $timestamp Pflicht | DOMHighResTimeStamp | — | Zeitpunkt der Messung in Millisekunden. |
| $kind Pflicht | "audio" | "video" | — | Medienart des Streams. |
| $ssrc Pflicht | number | — | RTP-Synchronisationsquelle (SSRC) des Streams. |
| $packetsReceived | number | — | Anzahl der bisher empfangenen RTP-Pakete. |
| $packetsLost | number | — | Anzahl verlorener Pakete. Der Wert kann durch Duplikate negativ werden. |
| $bytesReceived | number | — | Empfangene Nutzdaten-Bytes, ohne Header und Padding. |
| $jitter | number | — | Paket-Jitter in Sekunden. |
| $framesDecoded | number | — | Nur Video: Anzahl erfolgreich dekodierter Frames. |
| $framesPerSecond | number | — | Nur Video: dekodierte Frames pro Sekunde in der letzten Sekunde. |
| $frameWidth / frameHeight | number | — | Nur Video: Auflösung des zuletzt dekodierten Frames. |
| $jitterBufferDelay | number | — | Summe der Verweilzeiten im Jitter-Puffer in Sekunden. Für einen Mittelwert durch jitterBufferEmittedCount teilen. |
| $audioLevel | number | — | Nur Audio: aktueller Pegel zwischen 0 und 1. |
| $trackIdentifier | string | — | id des zugehörigen MediaStreamTrack. |
| $remoteId | string | — | ID des passenden remote-outbound-rtp-Eintrags. |
Rückgabewert
RTCStatsReport-Map. Es wird über getStats() geliefert und nicht selbst erzeugt.Beispiele
Eingehende Streams aus getStats() auslesen
// pc ist eine bestehende, verbundene RTCPeerConnection
const logInbound = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type !== 'inbound-rtp') return;
console.log(`${stats.kind}: ${stats.packetsReceived} Pakete, ${stats.packetsLost} verloren, Jitter ${(stats.jitter * 1000).toFixed(1)} ms`);
});
};
await logInbound(pc);
Bitrate und Paketverlust periodisch berechnen
const monitorVideo = (pc, intervalMs = 1000) => {
let prev = null;
return setInterval(async () => {
const report = await pc.getStats();
const cur = [...report.values()].find(
(s) => s.type === 'inbound-rtp' && s.kind === 'video'
);
if (!cur) return;
if (prev) {
const seconds = (cur.timestamp - prev.timestamp) / 1000;
const kbps = ((cur.bytesReceived - prev.bytesReceived) * 8) / seconds / 1000;
const lost = cur.packetsLost - prev.packetsLost;
const recv = cur.packetsReceived - prev.packetsReceived;
const lossPct = recv + lost > 0 ? (lost / (recv + lost)) * 100 : 0;
console.log(`Video: ${kbps.toFixed(0)} kbit/s, Verlust ${lossPct.toFixed(2)} %, ${cur.frameWidth}x${cur.frameHeight} @ ${cur.framesPerSecond ?? '?'} fps`);
}
prev = cur;
}, intervalMs);
};
const timer = monitorVideo(pc);
// später: clearInterval(timer);
Statistik für einen einzelnen Empfänger samt Codec
const [receiver] = pc.getReceivers().filter((r) => r.track.kind === 'audio');
const report = await receiver.getStats();
for (const stats of report.values()) {
if (stats.type === 'inbound-rtp') {
const codec = report.get(stats.codecId);
const avgBufferMs = stats.jitterBufferEmittedCount
? (stats.jitterBufferDelay / stats.jitterBufferEmittedCount) * 1000
: 0;
console.log(codec?.mimeType, `Pegel ${stats.audioLevel}`, `Puffer ${avgBufferMs.toFixed(0)} ms`);
}
}