mirror of
https://github.com/owncast/owncast.git
synced 2024-12-19 15:56:47 +03:00
112 lines
2.8 KiB
JavaScript
112 lines
2.8 KiB
JavaScript
import { URL_PLAYBACK_METRICS } from '../utils/constants.js';
|
|
const METRICS_SEND_INTERVAL = 10000;
|
|
|
|
class PlaybackMetrics {
|
|
constructor() {
|
|
this.hasPerformedInitialVariantChange = false;
|
|
|
|
this.segmentDownloadTime = [];
|
|
this.bandwidthTracking = [];
|
|
this.latencyTracking = [];
|
|
this.errors = 0;
|
|
this.qualityVariantChanges = 0;
|
|
this.isBuffering = false;
|
|
this.bufferingDurationTimer = 0;
|
|
|
|
setInterval(() => {
|
|
this.send();
|
|
}, METRICS_SEND_INTERVAL);
|
|
}
|
|
|
|
incrementErrorCount(count) {
|
|
this.errors += count;
|
|
}
|
|
|
|
incrementQualityVariantChanges() {
|
|
// We always start the player at the lowest quality, so let's just not
|
|
// count the first change.
|
|
if (!this.hasPerformedInitialVariantChange) {
|
|
this.hasPerformedInitialVariantChange = true;
|
|
return;
|
|
}
|
|
this.qualityVariantChanges++;
|
|
}
|
|
|
|
setIsBuffering(isBuffering) {
|
|
this.isBuffering = isBuffering;
|
|
|
|
if (!isBuffering) {
|
|
clearTimeout(this.bufferingDurationTimer);
|
|
return;
|
|
}
|
|
|
|
this.bufferingDurationTimer = setTimeout(() => {
|
|
this.incrementErrorCount(1);
|
|
}, 500);
|
|
}
|
|
|
|
trackSegmentDownloadTime(seconds) {
|
|
this.segmentDownloadTime.push(seconds);
|
|
}
|
|
|
|
trackBandwidth(bps) {
|
|
this.bandwidthTracking.push(bps);
|
|
}
|
|
|
|
trackLatency(latency) {
|
|
this.latencyTracking.push(latency);
|
|
}
|
|
|
|
async send() {
|
|
if (
|
|
this.segmentDownloadTime.length < 4 ||
|
|
this.bandwidthTracking.length < 4
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const errorCount = this.errors;
|
|
const average = (arr) => arr.reduce((p, c) => p + c, 0) / arr.length;
|
|
|
|
const averageDownloadDuration = average(this.segmentDownloadTime) / 1000;
|
|
const roundedAverageDownloadDuration =
|
|
Math.round(averageDownloadDuration * 1000) / 1000;
|
|
|
|
const averageBandwidth = average(this.bandwidthTracking) / 1000;
|
|
const roundedAverageBandwidth = Math.round(averageBandwidth * 1000) / 1000;
|
|
|
|
const averageLatency = average(this.latencyTracking) / 1000;
|
|
const roundedAverageLatency = Math.round(averageLatency * 1000) / 1000;
|
|
|
|
const data = {
|
|
bandwidth: roundedAverageBandwidth,
|
|
latency: roundedAverageLatency,
|
|
downloadDuration: roundedAverageDownloadDuration,
|
|
errors: errorCount + this.isBuffering ? 1 : 0,
|
|
qualityVariantChanges: this.qualityVariantChanges,
|
|
};
|
|
this.errors = 0;
|
|
this.qualityVariantChanges = 0;
|
|
this.segmentDownloadTime = [];
|
|
this.bandwidthTracking = [];
|
|
this.latencyTracking = [];
|
|
|
|
const options = {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(data),
|
|
};
|
|
|
|
try {
|
|
fetch(URL_PLAYBACK_METRICS, options);
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
|
|
// console.log(data);
|
|
}
|
|
}
|
|
|
|
export default PlaybackMetrics;
|