|
|
@@ -231,8 +231,11 @@ export default function StatsCollector(
|
|
231
|
231
|
this.statsIntervalId = null;
|
|
232
|
232
|
this.statsIntervalMilis = statsInterval;
|
|
233
|
233
|
|
|
234
|
|
- // Map of ssrcs to SsrcStats
|
|
235
|
|
- this.ssrc2stats = {};
|
|
|
234
|
+ /**
|
|
|
235
|
+ * Maps SSRC numbers to {@link SsrcStats}.
|
|
|
236
|
+ * @type {Map<number,SsrcStats}
|
|
|
237
|
+ */
|
|
|
238
|
+ this.ssrc2stats = new Map();
|
|
236
|
239
|
}
|
|
237
|
240
|
|
|
238
|
241
|
/* eslint-enable max-params */
|
|
|
@@ -401,6 +404,28 @@ StatsCollector.prototype._defineGetStatValueMethod = function(keys) {
|
|
401
|
404
|
return (item, name) => itemStatByKey(item, keyFromName(name));
|
|
402
|
405
|
};
|
|
403
|
406
|
|
|
|
407
|
+/**
|
|
|
408
|
+ * Obtains a stat value from given stat and converts it to a non-negative
|
|
|
409
|
+ * number. If the value is either invalid or negative then 0 will be returned.
|
|
|
410
|
+ * @param report
|
|
|
411
|
+ * @param {string} name
|
|
|
412
|
+ * @return {number}
|
|
|
413
|
+ * @private
|
|
|
414
|
+ */
|
|
|
415
|
+StatsCollector.prototype.getNonNegativeStat = function(report, name) {
|
|
|
416
|
+ let value = this._getStatValue(report, name);
|
|
|
417
|
+
|
|
|
418
|
+ if (typeof value !== 'number') {
|
|
|
419
|
+ value = Number(value);
|
|
|
420
|
+ }
|
|
|
421
|
+
|
|
|
422
|
+ if (isNaN(value)) {
|
|
|
423
|
+ return 0;
|
|
|
424
|
+ }
|
|
|
425
|
+
|
|
|
426
|
+ return Math.max(0, value);
|
|
|
427
|
+};
|
|
|
428
|
+
|
|
404
|
429
|
/* eslint-disable no-continue */
|
|
405
|
430
|
|
|
406
|
431
|
/**
|
|
|
@@ -412,25 +437,6 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
412
|
437
|
}
|
|
413
|
438
|
|
|
414
|
439
|
const getStatValue = this._getStatValue;
|
|
415
|
|
-
|
|
416
|
|
- /**
|
|
417
|
|
- *
|
|
418
|
|
- * @param report
|
|
419
|
|
- * @param name
|
|
420
|
|
- */
|
|
421
|
|
- function getNonNegativeStat(report, name) {
|
|
422
|
|
- let value = getStatValue(report, name);
|
|
423
|
|
-
|
|
424
|
|
- if (typeof value !== 'number') {
|
|
425
|
|
- value = Number(value);
|
|
426
|
|
- }
|
|
427
|
|
-
|
|
428
|
|
- if (isNaN(value)) {
|
|
429
|
|
- return 0;
|
|
430
|
|
- }
|
|
431
|
|
-
|
|
432
|
|
- return Math.max(0, value);
|
|
433
|
|
- }
|
|
434
|
440
|
const byteSentStats = {};
|
|
435
|
441
|
|
|
436
|
442
|
for (const idx in this.currentStatsReport) {
|
|
|
@@ -464,7 +470,7 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
464
|
470
|
type = getStatValue(now, 'transportType');
|
|
465
|
471
|
localip = getStatValue(now, 'localAddress');
|
|
466
|
472
|
active = getStatValue(now, 'activeConnection');
|
|
467
|
|
- rtt = getNonNegativeStat(now, 'currentRoundTripTime');
|
|
|
473
|
+ rtt = this.getNonNegativeStat(now, 'currentRoundTripTime');
|
|
468
|
474
|
} catch (e) { /* not supported*/ }
|
|
469
|
475
|
if (!ip || !type || !localip || active !== 'true') {
|
|
470
|
476
|
continue;
|
|
|
@@ -512,7 +518,7 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
512
|
518
|
}
|
|
513
|
519
|
|
|
514
|
520
|
const before = this.previousStatsReport[idx];
|
|
515
|
|
- const ssrc = getStatValue(now, 'ssrc');
|
|
|
521
|
+ const ssrc = this.getNonNegativeStat(now, 'ssrc');
|
|
516
|
522
|
|
|
517
|
523
|
if (!before || !ssrc) {
|
|
518
|
524
|
continue;
|
|
|
@@ -529,8 +535,12 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
529
|
535
|
continue;
|
|
530
|
536
|
}
|
|
531
|
537
|
|
|
532
|
|
- const ssrcStats
|
|
533
|
|
- = this.ssrc2stats[ssrc] || (this.ssrc2stats[ssrc] = new SsrcStats());
|
|
|
538
|
+ let ssrcStats = this.ssrc2stats.get(ssrc);
|
|
|
539
|
+
|
|
|
540
|
+ if (!ssrcStats) {
|
|
|
541
|
+ ssrcStats = new SsrcStats();
|
|
|
542
|
+ this.ssrc2stats.set(ssrc, ssrcStats);
|
|
|
543
|
+ }
|
|
534
|
544
|
|
|
535
|
545
|
let isDownloadStream = true;
|
|
536
|
546
|
let key = 'packetsReceived';
|
|
|
@@ -550,11 +560,13 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
550
|
560
|
packetsNow = 0;
|
|
551
|
561
|
}
|
|
552
|
562
|
|
|
553
|
|
- const packetsBefore = getNonNegativeStat(before, key);
|
|
|
563
|
+ const packetsBefore = this.getNonNegativeStat(before, key);
|
|
554
|
564
|
const packetsDiff = Math.max(0, packetsNow - packetsBefore);
|
|
555
|
565
|
|
|
556
|
|
- const packetsLostNow = getNonNegativeStat(now, 'packetsLost');
|
|
557
|
|
- const packetsLostBefore = getNonNegativeStat(before, 'packetsLost');
|
|
|
566
|
+ const packetsLostNow
|
|
|
567
|
+ = this.getNonNegativeStat(now, 'packetsLost');
|
|
|
568
|
+ const packetsLostBefore
|
|
|
569
|
+ = this.getNonNegativeStat(before, 'packetsLost');
|
|
558
|
570
|
const packetsLostDiff = Math.max(0, packetsLostNow - packetsLostBefore);
|
|
559
|
571
|
|
|
560
|
572
|
ssrcStats.setLoss({
|
|
|
@@ -563,8 +575,10 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
563
|
575
|
isDownloadStream
|
|
564
|
576
|
});
|
|
565
|
577
|
|
|
566
|
|
- const bytesReceivedNow = getNonNegativeStat(now, 'bytesReceived');
|
|
567
|
|
- const bytesReceivedBefore = getNonNegativeStat(before, 'bytesReceived');
|
|
|
578
|
+ const bytesReceivedNow
|
|
|
579
|
+ = this.getNonNegativeStat(now, 'bytesReceived');
|
|
|
580
|
+ const bytesReceivedBefore
|
|
|
581
|
+ = this.getNonNegativeStat(before, 'bytesReceived');
|
|
568
|
582
|
const bytesReceived
|
|
569
|
583
|
= Math.max(0, bytesReceivedNow - bytesReceivedBefore);
|
|
570
|
584
|
|
|
|
@@ -628,7 +642,7 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
628
|
642
|
// let's try with another one (FF)
|
|
629
|
643
|
try {
|
|
630
|
644
|
ssrcStats.setFramerate(Math.round(
|
|
631
|
|
- getNonNegativeStat(now, 'framerateMean')));
|
|
|
645
|
+ this.getNonNegativeStat(now, 'framerateMean')));
|
|
632
|
646
|
} catch (err) { /* not supported*/ }
|
|
633
|
647
|
}
|
|
634
|
648
|
|
|
|
@@ -650,34 +664,29 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
650
|
664
|
};
|
|
651
|
665
|
let bitrateDownload = 0;
|
|
652
|
666
|
let bitrateUpload = 0;
|
|
653
|
|
- const resolutions = {};
|
|
654
|
|
- const framerates = {};
|
|
655
|
|
-
|
|
656
|
|
- Object.keys(this.ssrc2stats).forEach(
|
|
657
|
|
- function(ssrc) {
|
|
658
|
|
- const ssrcStats = this.ssrc2stats[ssrc];
|
|
|
667
|
+ const resolutions = new Map();
|
|
|
668
|
+ const framerates = new Map();
|
|
659
|
669
|
|
|
660
|
|
- // process packet loss stats
|
|
661
|
|
- const loss = ssrcStats.loss;
|
|
662
|
|
- const type = loss.isDownloadStream ? 'download' : 'upload';
|
|
|
670
|
+ for (const [ ssrc, ssrcStats ] of this.ssrc2stats) {
|
|
|
671
|
+ // process packet loss stats
|
|
|
672
|
+ const loss = ssrcStats.loss;
|
|
|
673
|
+ const type = loss.isDownloadStream ? 'download' : 'upload';
|
|
663
|
674
|
|
|
664
|
|
- totalPackets[type] += loss.packetsTotal;
|
|
665
|
|
- lostPackets[type] += loss.packetsLost;
|
|
|
675
|
+ totalPackets[type] += loss.packetsTotal;
|
|
|
676
|
+ lostPackets[type] += loss.packetsLost;
|
|
666
|
677
|
|
|
667
|
|
- // process bitrate stats
|
|
668
|
|
- bitrateDownload += ssrcStats.bitrate.download;
|
|
669
|
|
- bitrateUpload += ssrcStats.bitrate.upload;
|
|
|
678
|
+ // process bitrate stats
|
|
|
679
|
+ bitrateDownload += ssrcStats.bitrate.download;
|
|
|
680
|
+ bitrateUpload += ssrcStats.bitrate.upload;
|
|
670
|
681
|
|
|
671
|
|
- ssrcStats.resetBitrate();
|
|
|
682
|
+ ssrcStats.resetBitrate();
|
|
672
|
683
|
|
|
673
|
|
- // collect resolutions
|
|
674
|
|
- resolutions[ssrc] = ssrcStats.resolution;
|
|
|
684
|
+ // collect resolutions
|
|
|
685
|
+ resolutions.set(ssrc, ssrcStats.resolution);
|
|
675
|
686
|
|
|
676
|
|
- // collect framerates
|
|
677
|
|
- framerates[ssrc] = ssrcStats.framerate;
|
|
678
|
|
- },
|
|
679
|
|
- this
|
|
680
|
|
- );
|
|
|
687
|
+ // collect framerates
|
|
|
688
|
+ framerates.set(ssrc, ssrcStats.framerate);
|
|
|
689
|
+ }
|
|
681
|
690
|
|
|
682
|
691
|
this.eventEmitter.emit(
|
|
683
|
692
|
StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);
|
|
|
@@ -728,7 +737,7 @@ StatsCollector.prototype.processAudioLevelReport = function() {
|
|
728
|
737
|
}
|
|
729
|
738
|
|
|
730
|
739
|
const before = this.baselineAudioLevelsReport[idx];
|
|
731
|
|
- const ssrc = getStatValue(now, 'ssrc');
|
|
|
740
|
+ const ssrc = this.getNonNegativeStat(now, 'ssrc');
|
|
732
|
741
|
|
|
733
|
742
|
if (!before) {
|
|
734
|
743
|
logger.warn(`${ssrc} not enough data`);
|