|
|
@@ -38,6 +38,7 @@ KEYS_BY_BROWSER_TYPE[browsers.CHROME] = {
|
|
38
|
38
|
'packetsLost': 'packetsLost',
|
|
39
|
39
|
'bytesReceived': 'bytesReceived',
|
|
40
|
40
|
'bytesSent': 'bytesSent',
|
|
|
41
|
+ 'googCodecName': 'googCodecName',
|
|
41
|
42
|
'googFrameHeightReceived': 'googFrameHeightReceived',
|
|
42
|
43
|
'googFrameWidthReceived': 'googFrameWidthReceived',
|
|
43
|
44
|
'googFrameHeightSent': 'googFrameHeightSent',
|
|
|
@@ -92,6 +93,7 @@ function SsrcStats() {
|
|
92
|
93
|
};
|
|
93
|
94
|
this.resolution = {};
|
|
94
|
95
|
this.framerate = 0;
|
|
|
96
|
+ this.codec = '';
|
|
95
|
97
|
}
|
|
96
|
98
|
|
|
97
|
99
|
/**
|
|
|
@@ -137,6 +139,10 @@ SsrcStats.prototype.setFramerate = function(framerate) {
|
|
137
|
139
|
this.framerate = framerate || 0;
|
|
138
|
140
|
};
|
|
139
|
141
|
|
|
|
142
|
+SsrcStats.prototype.setCodec = function(codec) {
|
|
|
143
|
+ this.codec = codec || '';
|
|
|
144
|
+};
|
|
|
145
|
+
|
|
140
|
146
|
/**
|
|
141
|
147
|
*
|
|
142
|
148
|
*/
|
|
|
@@ -693,8 +699,18 @@ StatsCollector.prototype.processStatsReport = function() {
|
|
693
|
699
|
} else {
|
|
694
|
700
|
ssrcStats.setResolution(null);
|
|
695
|
701
|
}
|
|
|
702
|
+
|
|
|
703
|
+ let codec;
|
|
|
704
|
+
|
|
|
705
|
+ // Try to get the codec for later reporting.
|
|
|
706
|
+ try {
|
|
|
707
|
+ codec = getStatValue(now, 'googCodecName') || '';
|
|
|
708
|
+ } catch (e) { /* not supported*/ }
|
|
|
709
|
+
|
|
|
710
|
+ ssrcStats.setCodec(codec);
|
|
696
|
711
|
}
|
|
697
|
712
|
|
|
|
713
|
+
|
|
698
|
714
|
this.eventEmitter.emit(
|
|
699
|
715
|
StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);
|
|
700
|
716
|
|
|
|
@@ -718,10 +734,13 @@ StatsCollector.prototype._processAndEmitReport = function() {
|
|
718
|
734
|
let bitrateUpload = 0;
|
|
719
|
735
|
const resolutions = {};
|
|
720
|
736
|
const framerates = {};
|
|
|
737
|
+ const codecs = {};
|
|
721
|
738
|
let audioBitrateDownload = 0;
|
|
722
|
739
|
let audioBitrateUpload = 0;
|
|
|
740
|
+ let audioCodec = '';
|
|
723
|
741
|
let videoBitrateDownload = 0;
|
|
724
|
742
|
let videoBitrateUpload = 0;
|
|
|
743
|
+ let videoCodec = '';
|
|
725
|
744
|
|
|
726
|
745
|
for (const [ ssrc, ssrcStats ] of this.ssrc2stats) {
|
|
727
|
746
|
// process packet loss stats
|
|
|
@@ -742,9 +761,11 @@ StatsCollector.prototype._processAndEmitReport = function() {
|
|
742
|
761
|
if (track.isAudioTrack()) {
|
|
743
|
762
|
audioBitrateDownload += ssrcStats.bitrate.download;
|
|
744
|
763
|
audioBitrateUpload += ssrcStats.bitrate.upload;
|
|
|
764
|
+ audioCodec = ssrcStats.codec;
|
|
745
|
765
|
} else {
|
|
746
|
766
|
videoBitrateDownload += ssrcStats.bitrate.download;
|
|
747
|
767
|
videoBitrateUpload += ssrcStats.bitrate.upload;
|
|
|
768
|
+ videoCodec = ssrcStats.codec;
|
|
748
|
769
|
}
|
|
749
|
770
|
|
|
750
|
771
|
const participantId = track.getParticipantId();
|
|
|
@@ -767,6 +788,18 @@ StatsCollector.prototype._processAndEmitReport = function() {
|
|
767
|
788
|
userFramerates[ssrc] = ssrcStats.framerate;
|
|
768
|
789
|
framerates[participantId] = userFramerates;
|
|
769
|
790
|
}
|
|
|
791
|
+ if (audioCodec.length && videoCodec.length) {
|
|
|
792
|
+ const codecDesc = {
|
|
|
793
|
+ 'audio': audioCodec,
|
|
|
794
|
+ 'video': videoCodec
|
|
|
795
|
+ };
|
|
|
796
|
+
|
|
|
797
|
+ // Is there a reason this can't be done more directly?
|
|
|
798
|
+ const userCodecs = codecs[participantId] || {};
|
|
|
799
|
+
|
|
|
800
|
+ userCodecs[ssrc] = codecDesc;
|
|
|
801
|
+ codecs[participantId] = userCodecs;
|
|
|
802
|
+ }
|
|
770
|
803
|
} else {
|
|
771
|
804
|
logger.error(`No participant ID returned by ${track}`);
|
|
772
|
805
|
}
|
|
|
@@ -833,6 +866,7 @@ StatsCollector.prototype._processAndEmitReport = function() {
|
|
833
|
866
|
'packetLoss': this.conferenceStats.packetLoss,
|
|
834
|
867
|
'resolution': resolutions,
|
|
835
|
868
|
'framerate': framerates,
|
|
|
869
|
+ 'codec': codecs,
|
|
836
|
870
|
'transport': this.conferenceStats.transport,
|
|
837
|
871
|
localAvgAudioLevels,
|
|
838
|
872
|
avgAudioLevels
|