97 lines
3.2 KiB
JavaScript
97 lines
3.2 KiB
JavaScript
|
|
function createStatsSummary() {
|
||
|
|
return {
|
||
|
|
video: {
|
||
|
|
packetsLost: 0,
|
||
|
|
packetsReceived: 0,
|
||
|
|
bytesReceived: 0,
|
||
|
|
jitter: 0,
|
||
|
|
roundTripTime: 0,
|
||
|
|
fps: 0,
|
||
|
|
bitrate: 0
|
||
|
|
},
|
||
|
|
audio: {
|
||
|
|
packetsLost: 0,
|
||
|
|
packetsReceived: 0,
|
||
|
|
bytesReceived: 0,
|
||
|
|
jitter: 0
|
||
|
|
},
|
||
|
|
network: {
|
||
|
|
totalPacketsLost: 0,
|
||
|
|
totalPacketsReceived: 0,
|
||
|
|
inboundRtpCount: 0,
|
||
|
|
jitter: 0,
|
||
|
|
roundTripTime: 0
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function summarizeInboundStats(stats) {
|
||
|
|
const summary = createStatsSummary();
|
||
|
|
|
||
|
|
stats.forEach((report) => {
|
||
|
|
if (report.type === 'inbound-rtp' && report.mediaType === 'video') {
|
||
|
|
summary.network.inboundRtpCount++;
|
||
|
|
|
||
|
|
if (report.packetsLost !== undefined && report.packetsReceived !== undefined) {
|
||
|
|
summary.network.totalPacketsLost += report.packetsLost;
|
||
|
|
summary.network.totalPacketsReceived += report.packetsReceived;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (report.jitter !== undefined) {
|
||
|
|
summary.network.jitter = Math.max(summary.network.jitter, report.jitter);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (report.roundTripTime !== undefined) {
|
||
|
|
summary.network.roundTripTime = Math.max(summary.network.roundTripTime, report.roundTripTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
summary.video.packetsLost = report.packetsLost || 0;
|
||
|
|
summary.video.packetsReceived = report.packetsReceived || 0;
|
||
|
|
summary.video.bytesReceived = report.bytesReceived || 0;
|
||
|
|
summary.video.jitter = report.jitter || 0;
|
||
|
|
summary.video.roundTripTime = report.roundTripTime || 0;
|
||
|
|
summary.video.fps = report.framesPerSecond || 0;
|
||
|
|
|
||
|
|
if (report.bytesReceived && report.timestamp) {
|
||
|
|
const duration = report.timestamp / 1000;
|
||
|
|
summary.video.bitrate = duration > 0
|
||
|
|
? Math.round((report.bytesReceived * 8) / (duration * 1000))
|
||
|
|
: 0;
|
||
|
|
}
|
||
|
|
} else if (report.type === 'inbound-rtp' && report.mediaType === 'audio') {
|
||
|
|
summary.audio.packetsLost = report.packetsLost || 0;
|
||
|
|
summary.audio.packetsReceived = report.packetsReceived || 0;
|
||
|
|
summary.audio.bytesReceived = report.bytesReceived || 0;
|
||
|
|
summary.audio.jitter = report.jitter || 0;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return summary;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getNetworkQualityFromSummary(summary) {
|
||
|
|
const { totalPacketsLost, totalPacketsReceived, inboundRtpCount, jitter, roundTripTime } = summary.network;
|
||
|
|
|
||
|
|
if (inboundRtpCount === 0) {
|
||
|
|
return 'no_signal';
|
||
|
|
}
|
||
|
|
|
||
|
|
const packetLossRate = totalPacketsReceived > 0
|
||
|
|
? totalPacketsLost / (totalPacketsLost + totalPacketsReceived)
|
||
|
|
: 0;
|
||
|
|
const jitterMs = jitter * 1000;
|
||
|
|
const rttMs = roundTripTime * 1000;
|
||
|
|
|
||
|
|
if (packetLossRate > 0.05 || jitterMs > 100 || rttMs > 300) {
|
||
|
|
return 'poor';
|
||
|
|
}
|
||
|
|
if (packetLossRate > 0.02 || jitterMs > 50 || rttMs > 150) {
|
||
|
|
return 'fair';
|
||
|
|
}
|
||
|
|
if (packetLossRate > 0.01 || jitterMs > 30 || rttMs > 100) {
|
||
|
|
return 'good';
|
||
|
|
}
|
||
|
|
|
||
|
|
return 'excellent';
|
||
|
|
}
|