@webex/plugin-meetings 3.0.0-beta.22 → 3.0.0-beta.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +0 -3
- package/dist/constants.js.map +1 -1
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +505 -493
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/index.js +1 -4
- package/dist/meeting/index.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +4 -2
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/statsAnalyzer/global.js +1 -93
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +297 -299
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +84 -47
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/breakouts/breakout.d.ts +8 -0
- package/dist/types/breakouts/collection.d.ts +5 -0
- package/dist/types/breakouts/index.d.ts +5 -0
- package/dist/types/common/browser-detection.d.ts +9 -0
- package/dist/types/common/collection.d.ts +48 -0
- package/dist/types/common/config.d.ts +2 -0
- package/dist/types/common/errors/captcha-error.d.ts +15 -0
- package/dist/types/common/errors/intent-to-join.d.ts +16 -0
- package/dist/types/common/errors/join-meeting.d.ts +17 -0
- package/dist/types/common/errors/media.d.ts +15 -0
- package/dist/types/common/errors/parameter.d.ts +15 -0
- package/dist/types/common/errors/password-error.d.ts +15 -0
- package/dist/types/common/errors/permission.d.ts +14 -0
- package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
- package/dist/types/common/errors/reconnection.d.ts +15 -0
- package/dist/types/common/errors/stats.d.ts +15 -0
- package/dist/types/common/errors/webex-errors.d.ts +69 -0
- package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/types/common/events/events-scope.d.ts +17 -0
- package/dist/types/common/events/events.d.ts +12 -0
- package/dist/types/common/events/trigger-proxy.d.ts +2 -0
- package/dist/types/common/events/util.d.ts +2 -0
- package/dist/types/common/logs/logger-config.d.ts +2 -0
- package/dist/types/common/logs/logger-proxy.d.ts +2 -0
- package/dist/types/common/logs/request.d.ts +34 -0
- package/dist/types/common/queue.d.ts +32 -0
- package/dist/types/config.d.ts +77 -0
- package/dist/types/constants.d.ts +895 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/locus-info/controlsUtils.d.ts +2 -0
- package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/types/locus-info/fullState.d.ts +2 -0
- package/dist/types/locus-info/hostUtils.d.ts +2 -0
- package/dist/types/locus-info/index.d.ts +269 -0
- package/dist/types/locus-info/infoUtils.d.ts +2 -0
- package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/types/locus-info/parser.d.ts +212 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/index.d.ts +32 -0
- package/dist/types/media/properties.d.ts +107 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
- package/dist/types/meeting/effectsState.d.ts +42 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +75 -0
- package/dist/types/meeting/index.d.ts +1706 -0
- package/dist/types/meeting/muteState.d.ts +108 -0
- package/dist/types/meeting/request.d.ts +261 -0
- package/dist/types/meeting/request.type.d.ts +11 -0
- package/dist/types/meeting/state.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +2 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +57 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +93 -0
- package/dist/types/meeting-info/request.d.ts +22 -0
- package/dist/types/meeting-info/util.d.ts +2 -0
- package/dist/types/meeting-info/utilv2.d.ts +2 -0
- package/dist/types/meetings/collection.d.ts +23 -0
- package/dist/types/meetings/index.d.ts +297 -0
- package/dist/types/meetings/request.d.ts +27 -0
- package/dist/types/meetings/util.d.ts +18 -0
- package/dist/types/member/index.d.ts +146 -0
- package/dist/types/member/util.d.ts +2 -0
- package/dist/types/members/collection.d.ts +24 -0
- package/dist/types/members/index.d.ts +320 -0
- package/dist/types/members/request.d.ts +50 -0
- package/dist/types/members/util.d.ts +2 -0
- package/dist/types/metrics/config.d.ts +178 -0
- package/dist/types/metrics/constants.d.ts +57 -0
- package/dist/types/metrics/index.d.ts +160 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +50 -0
- package/dist/types/multistream/receiveSlot.d.ts +64 -0
- package/dist/types/multistream/receiveSlotManager.d.ts +41 -0
- package/dist/types/multistream/remoteMedia.d.ts +93 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +56 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +241 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/types/personal-meeting-room/index.d.ts +47 -0
- package/dist/types/personal-meeting-room/request.d.ts +14 -0
- package/dist/types/personal-meeting-room/util.d.ts +2 -0
- package/dist/types/reachability/index.d.ts +140 -0
- package/dist/types/reachability/request.d.ts +35 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +117 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +193 -0
- package/dist/types/recording-controller/util.d.ts +13 -0
- package/dist/types/roap/index.d.ts +77 -0
- package/dist/types/roap/request.d.ts +35 -0
- package/dist/types/roap/turnDiscovery.d.ts +74 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +195 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
- package/dist/types/transcription/index.d.ts +64 -0
- package/package.json +19 -19
- package/src/constants.ts +0 -3
- package/src/media/properties.ts +1 -3
- package/src/mediaQualityMetrics/config.ts +379 -377
- package/src/meeting/index.ts +1 -4
- package/src/networkQualityMonitor/index.ts +6 -6
- package/src/statsAnalyzer/global.ts +1 -94
- package/src/statsAnalyzer/index.ts +325 -373
- package/src/statsAnalyzer/mqaUtil.ts +92 -89
- package/test/integration/spec/space-meeting.js +1 -1
- package/test/unit/spec/networkQualityMonitor/index.js +4 -4
- package/test/unit/spec/stats-analyzer/index.js +63 -39
|
@@ -1,30 +1,41 @@
|
|
|
1
|
-
/* eslint-disable prefer-destructuring */
|
|
1
|
+
/* eslint-disable no-param-reassign, prefer-destructuring */
|
|
2
2
|
|
|
3
3
|
import {mean, max} from 'lodash';
|
|
4
4
|
|
|
5
5
|
import {STATS} from '../constants';
|
|
6
6
|
|
|
7
|
-
export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSent}) => {
|
|
8
|
-
const mediaType = STATS.AUDIO_CORRELATE;
|
|
7
|
+
export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSent, mediaType}) => {
|
|
9
8
|
const sendrecvType = STATS.RECEIVE_DIRECTION;
|
|
10
9
|
|
|
10
|
+
const lastPacketsReceived = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsReceived || 0;
|
|
11
|
+
const lastPacketsLost = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsLost || 0;
|
|
12
|
+
const lastPacketsDecoded = lastMqaDataSent[mediaType]?.[sendrecvType].totalSamplesDecoded || 0;
|
|
13
|
+
const lastSamplesReceived = lastMqaDataSent[mediaType]?.[sendrecvType].totalSamplesReceived || 0;
|
|
14
|
+
const lastConcealedSamples = lastMqaDataSent[mediaType]?.[sendrecvType].concealedSamples || 0;
|
|
15
|
+
const lastBytesReceived = lastMqaDataSent[mediaType]?.[sendrecvType].totalBytesReceived || 0;
|
|
16
|
+
const lastFecPacketsReceived = lastMqaDataSent[mediaType]?.[sendrecvType].fecPacketsReceived || 0;
|
|
17
|
+
const lastFecPacketsDiscarded =
|
|
18
|
+
lastMqaDataSent[mediaType]?.[sendrecvType].fecPacketsDiscarded || 0;
|
|
19
|
+
|
|
20
|
+
const {csi} = statsResults[mediaType];
|
|
21
|
+
if (csi && !audioReceiver.streams[0].common.csi.includes(csi)) {
|
|
22
|
+
audioReceiver.streams[0].common.csi.push(csi);
|
|
23
|
+
}
|
|
24
|
+
|
|
11
25
|
audioReceiver.common.common.direction = statsResults[mediaType].direction;
|
|
12
26
|
audioReceiver.common.transportType = statsResults.connectionType.remote.transport[0];
|
|
27
|
+
|
|
13
28
|
// add rtpPacket info inside common as also for call analyzer
|
|
14
29
|
audioReceiver.common.rtpPackets =
|
|
15
|
-
statsResults[mediaType][sendrecvType].totalPacketsReceived -
|
|
16
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsReceived || 0;
|
|
30
|
+
statsResults[mediaType][sendrecvType].totalPacketsReceived - lastPacketsReceived || 0;
|
|
17
31
|
// Hop by hop are numbers and not percentage so we compare on what we sent the last min
|
|
18
32
|
// collect the packets received for the last min
|
|
19
33
|
audioReceiver.streams[0].common.rtpPackets = audioReceiver.common.rtpPackets;
|
|
20
34
|
audioReceiver.common.mediaHopByHopLost =
|
|
21
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost -
|
|
22
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost || 0;
|
|
35
|
+
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
23
36
|
audioReceiver.common.rtpHopByHopLost =
|
|
24
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost -
|
|
25
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost || 0;
|
|
37
|
+
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
26
38
|
|
|
27
|
-
// @ts-ignore
|
|
28
39
|
audioReceiver.streams[0].common.maxRtpJitter =
|
|
29
40
|
// @ts-ignore
|
|
30
41
|
max(statsResults[mediaType][sendrecvType].meanRtpJitter) * 1000 || 0;
|
|
@@ -35,43 +46,45 @@ export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSen
|
|
|
35
46
|
// Fec packets do come in as part of the FEC only for audio
|
|
36
47
|
const fecRecovered =
|
|
37
48
|
statsResults[mediaType][sendrecvType].fecPacketsReceived -
|
|
38
|
-
|
|
39
|
-
(statsResults[mediaType][sendrecvType].fecPacketsDiscarded -
|
|
40
|
-
lastMqaDataSent[mediaType][sendrecvType].fecPacketsDiscarded);
|
|
49
|
+
lastFecPacketsReceived -
|
|
50
|
+
(statsResults[mediaType][sendrecvType].fecPacketsDiscarded - lastFecPacketsDiscarded);
|
|
41
51
|
|
|
42
52
|
audioReceiver.streams[0].common.rtpEndToEndLost =
|
|
43
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost -
|
|
44
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost -
|
|
45
|
-
fecRecovered || 0;
|
|
53
|
+
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost - fecRecovered || 0;
|
|
46
54
|
|
|
47
55
|
audioReceiver.streams[0].common.framesDropped =
|
|
48
|
-
statsResults[mediaType][sendrecvType].totalSamplesDecoded -
|
|
49
|
-
lastMqaDataSent[mediaType][sendrecvType].totalSamplesDecoded || 0;
|
|
56
|
+
statsResults[mediaType][sendrecvType].totalSamplesDecoded - lastPacketsDecoded || 0;
|
|
50
57
|
audioReceiver.streams[0].common.renderedFrameRate =
|
|
51
58
|
(audioReceiver.streams[0].common.framesDropped * 100) / 60 || 0;
|
|
59
|
+
|
|
52
60
|
audioReceiver.streams[0].common.framesReceived =
|
|
53
|
-
statsResults[mediaType][sendrecvType].totalSamplesReceived -
|
|
54
|
-
lastMqaDataSent[mediaType][sendrecvType].totalSamplesReceived || 0;
|
|
61
|
+
statsResults[mediaType][sendrecvType].totalSamplesReceived - lastSamplesReceived || 0;
|
|
55
62
|
audioReceiver.streams[0].common.concealedFrames =
|
|
56
|
-
statsResults[mediaType][sendrecvType].concealedSamples -
|
|
57
|
-
lastMqaDataSent[mediaType][sendrecvType].concealedSamples || 0;
|
|
63
|
+
statsResults[mediaType][sendrecvType].concealedSamples - lastConcealedSamples || 0;
|
|
58
64
|
audioReceiver.streams[0].common.receivedBitrate =
|
|
59
|
-
((statsResults[mediaType][sendrecvType].totalBytesReceived -
|
|
60
|
-
lastMqaDataSent[mediaType][sendrecvType].totalBytesReceived) *
|
|
61
|
-
8) /
|
|
62
|
-
60 || 0;
|
|
65
|
+
((statsResults[mediaType][sendrecvType].totalBytesReceived - lastBytesReceived) * 8) / 60 || 0;
|
|
63
66
|
|
|
64
67
|
audioReceiver.common.rtpBitrate = audioReceiver.streams[0].common.receivedBitrate;
|
|
65
68
|
};
|
|
66
69
|
|
|
67
|
-
export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent}) => {
|
|
68
|
-
const mediaType = STATS.AUDIO_CORRELATE;
|
|
70
|
+
export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent, mediaType}) => {
|
|
69
71
|
const sendrecvType = STATS.SEND_DIRECTION;
|
|
70
72
|
|
|
73
|
+
const lastPacketsSent = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsSent || 0;
|
|
74
|
+
const lastPacketsLost =
|
|
75
|
+
lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsLostOnReceiver || 0;
|
|
76
|
+
const lastBytesSent = lastMqaDataSent[mediaType]?.[sendrecvType].totalBytesSent || 0;
|
|
77
|
+
const lastFramesEncoded = lastMqaDataSent[mediaType]?.[sendrecvType].totalKeyFramesEncoded || 0;
|
|
78
|
+
const lastFirCount = lastMqaDataSent[mediaType]?.[sendrecvType].totalFirCount || 0;
|
|
79
|
+
|
|
80
|
+
const {csi} = statsResults[mediaType];
|
|
81
|
+
if (csi && !audioSender.streams[0].common.csi.includes(csi)) {
|
|
82
|
+
audioSender.streams[0].common.csi.push(csi);
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
audioSender.common.common.direction = statsResults[mediaType].direction;
|
|
72
86
|
audioSender.common.transportType = statsResults.connectionType.local.transport[0];
|
|
73
87
|
|
|
74
|
-
// @ts-ignore
|
|
75
88
|
audioSender.common.maxRemoteJitter =
|
|
76
89
|
// @ts-ignore
|
|
77
90
|
max(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
|
|
@@ -79,8 +92,7 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
|
|
|
79
92
|
mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
|
|
80
93
|
|
|
81
94
|
audioSender.common.rtpPackets =
|
|
82
|
-
statsResults[mediaType][sendrecvType].totalPacketsSent -
|
|
83
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsSent || 0;
|
|
95
|
+
statsResults[mediaType][sendrecvType].totalPacketsSent - lastPacketsSent || 0;
|
|
84
96
|
audioSender.streams[0].common.rtpPackets = audioSender.common.rtpPackets;
|
|
85
97
|
// From candidate-pair
|
|
86
98
|
audioSender.common.availableBitrate =
|
|
@@ -88,15 +100,13 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
|
|
|
88
100
|
// Calculate based on how much packets lost of received compated to how to the client sent
|
|
89
101
|
|
|
90
102
|
const totalpacketsLostForaMin =
|
|
91
|
-
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver -
|
|
92
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLostOnReceiver;
|
|
103
|
+
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver - lastPacketsLost;
|
|
93
104
|
|
|
94
105
|
audioSender.common.remoteLossRate =
|
|
95
106
|
totalpacketsLostForaMin > 0
|
|
96
107
|
? (totalpacketsLostForaMin * 100) / audioSender.common.rtpPackets
|
|
97
108
|
: 0; // This is the packets sent with in last min || 0;
|
|
98
109
|
|
|
99
|
-
// @ts-ignore
|
|
100
110
|
audioSender.common.maxRoundTripTime =
|
|
101
111
|
// @ts-ignore
|
|
102
112
|
max(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
|
|
@@ -105,9 +115,7 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
|
|
|
105
115
|
audioSender.common.roundTripTime = audioSender.common.maxRoundTripTime;
|
|
106
116
|
|
|
107
117
|
// Calculate the outgoing bitrate
|
|
108
|
-
const totalBytesSentInaMin =
|
|
109
|
-
statsResults[mediaType][sendrecvType].totalBytesSent -
|
|
110
|
-
lastMqaDataSent[mediaType][sendrecvType].totalBytesSent;
|
|
118
|
+
const totalBytesSentInaMin = statsResults[mediaType][sendrecvType].totalBytesSent - lastBytesSent;
|
|
111
119
|
|
|
112
120
|
audioSender.streams[0].common.transmittedBitrate = totalBytesSentInaMin
|
|
113
121
|
? (totalBytesSentInaMin * 8) / 60
|
|
@@ -115,33 +123,37 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
|
|
|
115
123
|
audioSender.common.rtpBitrate = audioSender.streams[0].common.transmittedBitrate;
|
|
116
124
|
|
|
117
125
|
audioSender.streams[0].transmittedKeyFrames =
|
|
118
|
-
statsResults[mediaType][sendrecvType].totalKeyFramesEncoded -
|
|
119
|
-
lastMqaDataSent[mediaType][sendrecvType].totalKeyFramesEncoded || 0;
|
|
126
|
+
statsResults[mediaType][sendrecvType].totalKeyFramesEncoded - lastFramesEncoded || 0;
|
|
120
127
|
audioSender.streams[0].requestedKeyFrames =
|
|
121
|
-
statsResults[mediaType][sendrecvType].totalFirCount -
|
|
122
|
-
lastMqaDataSent[mediaType][sendrecvType].totalFirCount || 0;
|
|
128
|
+
statsResults[mediaType][sendrecvType].totalFirCount - lastFirCount || 0;
|
|
123
129
|
};
|
|
124
130
|
|
|
125
|
-
export const getVideoReceiverMqa = ({
|
|
126
|
-
videoReceiver,
|
|
127
|
-
statsResults,
|
|
128
|
-
lastMqaDataSent,
|
|
129
|
-
isShareStream = false,
|
|
130
|
-
}) => {
|
|
131
|
-
const mediaType = isShareStream ? STATS.SHARE_CORRELATE : STATS.VIDEO_CORRELATE;
|
|
131
|
+
export const getVideoReceiverMqa = ({videoReceiver, statsResults, lastMqaDataSent, mediaType}) => {
|
|
132
132
|
const sendrecvType = STATS.RECEIVE_DIRECTION;
|
|
133
133
|
|
|
134
|
+
const lastPacketsReceived = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsReceived || 0;
|
|
135
|
+
const lastPacketsLost = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsLost || 0;
|
|
136
|
+
const lastBytesReceived = lastMqaDataSent[mediaType]?.[sendrecvType].totalBytesReceived || 0;
|
|
137
|
+
const lastFramesReceived = lastMqaDataSent[mediaType]?.[sendrecvType].framesReceived || 0;
|
|
138
|
+
const lastFramesDecoded = lastMqaDataSent[mediaType]?.[sendrecvType].framesDecoded || 0;
|
|
139
|
+
const lastFramesDropped = lastMqaDataSent[mediaType]?.[sendrecvType].framesDropped || 0;
|
|
140
|
+
const lastKeyFramesDecoded = lastMqaDataSent[mediaType]?.[sendrecvType].keyFramesDecoded || 0;
|
|
141
|
+
const lastPliCount = lastMqaDataSent[mediaType]?.[sendrecvType].totalPliCount || 0;
|
|
142
|
+
|
|
143
|
+
const {csi} = statsResults[mediaType];
|
|
144
|
+
if (csi && !videoReceiver.streams[0].common.csi.includes(csi)) {
|
|
145
|
+
videoReceiver.streams[0].common.csi.push(csi);
|
|
146
|
+
}
|
|
147
|
+
|
|
134
148
|
videoReceiver.common.common.direction = statsResults[mediaType].direction;
|
|
135
149
|
videoReceiver.common.transportType = statsResults.connectionType.remote.transport[0];
|
|
136
150
|
// collect the packets received for the last min
|
|
137
151
|
videoReceiver.common.rtpPackets =
|
|
138
|
-
statsResults[mediaType][sendrecvType].totalPacketsReceived -
|
|
139
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsReceived || 0;
|
|
152
|
+
statsResults[mediaType][sendrecvType].totalPacketsReceived - lastPacketsReceived || 0;
|
|
140
153
|
videoReceiver.streams[0].common.rtpPackets = videoReceiver.common.rtpPackets;
|
|
141
154
|
|
|
142
155
|
const totalPacketLoss =
|
|
143
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost -
|
|
144
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost || 0;
|
|
156
|
+
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
145
157
|
|
|
146
158
|
// Hope by hop are numbers and not percentage so we compare on what we sent the last min
|
|
147
159
|
// this is including packet lost
|
|
@@ -153,7 +165,6 @@ export const getVideoReceiverMqa = ({
|
|
|
153
165
|
|
|
154
166
|
// calculate this values
|
|
155
167
|
|
|
156
|
-
// @ts-ignore
|
|
157
168
|
videoReceiver.common.maxRemoteJitter =
|
|
158
169
|
// @ts-ignore
|
|
159
170
|
max(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
|
|
@@ -161,12 +172,11 @@ export const getVideoReceiverMqa = ({
|
|
|
161
172
|
mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
|
|
162
173
|
|
|
163
174
|
videoReceiver.streams[0].common.rtpJitter = videoReceiver.common.maxRemoteJitter;
|
|
164
|
-
// videoReceiver.streams[0].common.rtpJitter = (statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay - lastMqaDataSent.resolutions[mediaType][sendrecvType].jitterBufferDelay) / (statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount - lastMqaDataSent.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount) * 1000 || 0;
|
|
175
|
+
// videoReceiver.streams[0].common.rtpJitter = (statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay - lastMqaDataSent.resolutions[mediaType]?.[sendrecvType].jitterBufferDelay) / (statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount - lastMqaDataSent.resolutions[mediaType]?.[sendrecvType].jitterBufferEmittedCount) * 1000 || 0;
|
|
165
176
|
|
|
166
177
|
// Calculate the outgoing bitrate
|
|
167
178
|
const totalBytesReceivedInaMin =
|
|
168
|
-
statsResults[mediaType][sendrecvType].totalBytesReceived -
|
|
169
|
-
lastMqaDataSent[mediaType][sendrecvType].totalBytesReceived;
|
|
179
|
+
statsResults[mediaType][sendrecvType].totalBytesReceived - lastBytesReceived;
|
|
170
180
|
|
|
171
181
|
videoReceiver.streams[0].common.receivedBitrate = totalBytesReceivedInaMin
|
|
172
182
|
? (totalBytesReceivedInaMin * 8) / 60
|
|
@@ -175,11 +185,9 @@ export const getVideoReceiverMqa = ({
|
|
|
175
185
|
|
|
176
186
|
// From tracks //TODO: calculate a proper one
|
|
177
187
|
const totalFrameReceivedInaMin =
|
|
178
|
-
statsResults.resolutions[mediaType][sendrecvType].framesReceived -
|
|
179
|
-
lastMqaDataSent.resolutions[mediaType][sendrecvType].framesReceived;
|
|
188
|
+
statsResults.resolutions[mediaType][sendrecvType].framesReceived - lastFramesReceived;
|
|
180
189
|
const totalFrameDecodedInaMin =
|
|
181
|
-
statsResults.resolutions[mediaType][sendrecvType].framesDecoded -
|
|
182
|
-
lastMqaDataSent.resolutions[mediaType][sendrecvType].framesDecoded;
|
|
190
|
+
statsResults.resolutions[mediaType][sendrecvType].framesDecoded - lastFramesDecoded;
|
|
183
191
|
|
|
184
192
|
videoReceiver.streams[0].common.receivedFrameRate = totalFrameReceivedInaMin
|
|
185
193
|
? (totalFrameReceivedInaMin * 100) / 60
|
|
@@ -189,8 +197,7 @@ export const getVideoReceiverMqa = ({
|
|
|
189
197
|
: 0;
|
|
190
198
|
|
|
191
199
|
videoReceiver.streams[0].common.framesDropped =
|
|
192
|
-
statsResults.resolutions[mediaType][sendrecvType].framesDropped -
|
|
193
|
-
lastMqaDataSent.resolutions[mediaType][sendrecvType].framesDropped;
|
|
200
|
+
statsResults.resolutions[mediaType][sendrecvType].framesDropped - lastFramesDropped;
|
|
194
201
|
videoReceiver.streams[0].receivedHeight =
|
|
195
202
|
statsResults.resolutions[mediaType][sendrecvType].height;
|
|
196
203
|
videoReceiver.streams[0].receivedWidth = statsResults.resolutions[mediaType][sendrecvType].width;
|
|
@@ -200,22 +207,27 @@ export const getVideoReceiverMqa = ({
|
|
|
200
207
|
256;
|
|
201
208
|
|
|
202
209
|
videoReceiver.streams[0].receivedKeyFrames =
|
|
203
|
-
statsResults[mediaType][sendrecvType].keyFramesDecoded -
|
|
204
|
-
lastMqaDataSent[mediaType][sendrecvType].keyFramesDecoded || 0;
|
|
210
|
+
statsResults[mediaType][sendrecvType].keyFramesDecoded - lastKeyFramesDecoded || 0;
|
|
205
211
|
videoReceiver.streams[0].requestedKeyFrames =
|
|
206
|
-
statsResults[mediaType][sendrecvType].totalPliCount -
|
|
207
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPliCount || 0;
|
|
212
|
+
statsResults[mediaType][sendrecvType].totalPliCount - lastPliCount || 0;
|
|
208
213
|
};
|
|
209
214
|
|
|
210
|
-
export const getVideoSenderMqa = ({
|
|
211
|
-
videoSender,
|
|
212
|
-
statsResults,
|
|
213
|
-
lastMqaDataSent,
|
|
214
|
-
isShareStream = false,
|
|
215
|
-
}) => {
|
|
216
|
-
const mediaType = isShareStream ? STATS.SHARE_CORRELATE : STATS.VIDEO_CORRELATE;
|
|
215
|
+
export const getVideoSenderMqa = ({videoSender, statsResults, lastMqaDataSent, mediaType}) => {
|
|
217
216
|
const sendrecvType = STATS.SEND_DIRECTION;
|
|
218
217
|
|
|
218
|
+
const lastPacketsSent = lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsSent || 0;
|
|
219
|
+
const lastPacketsLost =
|
|
220
|
+
lastMqaDataSent[mediaType]?.[sendrecvType].totalPacketsLostOnReceiver || 0;
|
|
221
|
+
const lastBytesSent = lastMqaDataSent[mediaType]?.[sendrecvType].totalBytesSent || 0;
|
|
222
|
+
const lastKeyFramesEncoded =
|
|
223
|
+
lastMqaDataSent[mediaType]?.[sendrecvType].totalKeyFramesEncoded || 0;
|
|
224
|
+
const lastFirCount = lastMqaDataSent[mediaType]?.[sendrecvType].totalFirCount || 0;
|
|
225
|
+
const lastFramesSent = lastMqaDataSent[mediaType]?.[sendrecvType].framesSent || 0;
|
|
226
|
+
const {csi} = statsResults[mediaType];
|
|
227
|
+
if (csi && !videoSender.streams[0].common.csi.includes(csi)) {
|
|
228
|
+
videoSender.streams[0].common.csi.push(csi);
|
|
229
|
+
}
|
|
230
|
+
|
|
219
231
|
videoSender.common.common.direction = statsResults[mediaType].direction;
|
|
220
232
|
videoSender.common.transportType = statsResults.connectionType.local.transport[0];
|
|
221
233
|
|
|
@@ -227,22 +239,19 @@ export const getVideoSenderMqa = ({
|
|
|
227
239
|
mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
|
|
228
240
|
|
|
229
241
|
videoSender.common.rtpPackets =
|
|
230
|
-
statsResults[mediaType][sendrecvType].totalPacketsSent -
|
|
231
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsSent || 0;
|
|
242
|
+
statsResults[mediaType][sendrecvType].totalPacketsSent - lastPacketsSent || 0;
|
|
232
243
|
videoSender.common.availableBitrate =
|
|
233
244
|
statsResults[mediaType][sendrecvType].availableOutgoingBitrate || 0;
|
|
234
245
|
// Calculate based on how much packets lost of received compated to how to the client sent
|
|
235
246
|
|
|
236
247
|
const totalpacketsLostForaMin =
|
|
237
|
-
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver -
|
|
238
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsLostOnReceiver;
|
|
248
|
+
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver - lastPacketsLost;
|
|
239
249
|
|
|
240
250
|
videoSender.common.remoteLossRate =
|
|
241
251
|
totalpacketsLostForaMin > 0
|
|
242
252
|
? (totalpacketsLostForaMin * 100) / (videoSender.common.rtpPackets + totalpacketsLostForaMin)
|
|
243
253
|
: 0; // This is the packets sent with in last min || 0;
|
|
244
254
|
|
|
245
|
-
// @ts-ignore
|
|
246
255
|
videoSender.common.maxRoundTripTime =
|
|
247
256
|
// @ts-ignore
|
|
248
257
|
max(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
|
|
@@ -251,13 +260,10 @@ export const getVideoSenderMqa = ({
|
|
|
251
260
|
videoSender.common.roundTripTime = videoSender.common.maxRoundTripTime;
|
|
252
261
|
|
|
253
262
|
videoSender.streams[0].common.rtpPackets =
|
|
254
|
-
statsResults[mediaType][sendrecvType].totalPacketsSent -
|
|
255
|
-
lastMqaDataSent[mediaType][sendrecvType].totalPacketsSent || 0;
|
|
263
|
+
statsResults[mediaType][sendrecvType].totalPacketsSent - lastPacketsSent || 0;
|
|
256
264
|
|
|
257
265
|
// Calculate the outgoing bitrate
|
|
258
|
-
const totalBytesSentInaMin =
|
|
259
|
-
statsResults[mediaType][sendrecvType].totalBytesSent -
|
|
260
|
-
lastMqaDataSent[mediaType][sendrecvType].totalBytesSent;
|
|
266
|
+
const totalBytesSentInaMin = statsResults[mediaType][sendrecvType].totalBytesSent - lastBytesSent;
|
|
261
267
|
|
|
262
268
|
videoSender.streams[0].common.transmittedBitrate = totalBytesSentInaMin
|
|
263
269
|
? (totalBytesSentInaMin * 8) / 60
|
|
@@ -266,16 +272,13 @@ export const getVideoSenderMqa = ({
|
|
|
266
272
|
videoSender.common.rtpBitrate = videoSender.streams[0].common.transmittedBitrate;
|
|
267
273
|
|
|
268
274
|
videoSender.streams[0].transmittedKeyFrames =
|
|
269
|
-
statsResults[mediaType][sendrecvType].totalKeyFramesEncoded -
|
|
270
|
-
lastMqaDataSent[mediaType][sendrecvType].totalKeyFramesEncoded || 0;
|
|
275
|
+
statsResults[mediaType][sendrecvType].totalKeyFramesEncoded - lastKeyFramesEncoded || 0;
|
|
271
276
|
videoSender.streams[0].requestedKeyFrames =
|
|
272
|
-
statsResults[mediaType][sendrecvType].totalFirCount -
|
|
273
|
-
lastMqaDataSent[mediaType][sendrecvType].totalFirCount || 0;
|
|
277
|
+
statsResults[mediaType][sendrecvType].totalFirCount - lastFirCount || 0;
|
|
274
278
|
|
|
275
279
|
// From tracks //TODO: calculate a proper one
|
|
276
280
|
const totalFrameSentInaMin =
|
|
277
|
-
statsResults.resolutions[mediaType][sendrecvType].framesSent -
|
|
278
|
-
(lastMqaDataSent.resolutions[mediaType][sendrecvType].framesSent || 0);
|
|
281
|
+
statsResults.resolutions[mediaType][sendrecvType].framesSent - (lastFramesSent || 0);
|
|
279
282
|
|
|
280
283
|
videoSender.streams[0].common.transmittedFrameRate = totalFrameSentInaMin
|
|
281
284
|
? (totalFrameSentInaMin * 100) / 60
|
|
@@ -141,7 +141,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
141
141
|
it('Bob has flowing streams on reconnect', () => {
|
|
142
142
|
const retrieveStats = () => {
|
|
143
143
|
assert.isAbove(
|
|
144
|
-
bob.meeting.statsAnalyzer.statsResults
|
|
144
|
+
bob.meeting.statsAnalyzer.statsResults['audio-recv-0'].recv.totalPacketsReceived,
|
|
145
145
|
0,
|
|
146
146
|
'total packets received greater than 0'
|
|
147
147
|
);
|
|
@@ -24,7 +24,7 @@ describe('plugin-meetings', () => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const configObject = {
|
|
27
|
-
mediaType: 'video',
|
|
27
|
+
mediaType: 'video-send',
|
|
28
28
|
remoteRtpResults: {
|
|
29
29
|
id: 'RTCRemoteInboundRtpVideoStream_2411086660',
|
|
30
30
|
timestamp: 1624472676193.79,
|
|
@@ -42,12 +42,12 @@ describe('plugin-meetings', () => {
|
|
|
42
42
|
roundTripTimeMeasurements: 14,
|
|
43
43
|
},
|
|
44
44
|
statsAnalyzerCurrentStats: {
|
|
45
|
-
audio: {
|
|
45
|
+
'audio-send': {
|
|
46
46
|
send: {
|
|
47
47
|
currentPacketLossRatio: 8,
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
|
-
video: {
|
|
50
|
+
'video-send': {
|
|
51
51
|
send: {
|
|
52
52
|
currentPacketLossRatio: 10,
|
|
53
53
|
},
|
|
@@ -83,7 +83,7 @@ describe('plugin-meetings', () => {
|
|
|
83
83
|
}),
|
|
84
84
|
sinon.match(EVENT_TRIGGERS.NETWORK_QUALITY),
|
|
85
85
|
sinon.match({
|
|
86
|
-
mediaType: 'video',
|
|
86
|
+
mediaType: 'video-send',
|
|
87
87
|
networkQualityScore: 0,
|
|
88
88
|
})
|
|
89
89
|
)
|
|
@@ -24,14 +24,15 @@ describe('plugin-meetings', () => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const defaultStats = {
|
|
27
|
+
resolutions: {},
|
|
27
28
|
internal: {
|
|
28
|
-
video: {
|
|
29
|
+
'video-send-1': {
|
|
29
30
|
send: {
|
|
30
31
|
totalPacketsLostOnReceiver: 10,
|
|
31
32
|
},
|
|
32
33
|
},
|
|
33
34
|
},
|
|
34
|
-
video: {
|
|
35
|
+
'video-send-1': {
|
|
35
36
|
send: {
|
|
36
37
|
packetsSent: 2,
|
|
37
38
|
meanRemoteJitter: [],
|
|
@@ -65,12 +66,12 @@ describe('plugin-meetings', () => {
|
|
|
65
66
|
});
|
|
66
67
|
|
|
67
68
|
it('should trigger determineUplinkNetworkQuality with specific arguments', async () => {
|
|
68
|
-
await statsAnalyzer.parseGetStatsResult(statusResult, 'video');
|
|
69
|
+
await statsAnalyzer.parseGetStatsResult(statusResult, 'video-send-1', true);
|
|
69
70
|
|
|
70
71
|
assert.calledOnce(statsAnalyzer.networkQualityMonitor.determineUplinkNetworkQuality);
|
|
71
72
|
assert(
|
|
72
73
|
sandBoxSpy.calledWith({
|
|
73
|
-
mediaType: 'video',
|
|
74
|
+
mediaType: 'video-send-1',
|
|
74
75
|
remoteRtpResults: statusResult,
|
|
75
76
|
statsAnalyzerCurrentStats: statsAnalyzer.statsResults,
|
|
76
77
|
})
|
|
@@ -110,28 +111,52 @@ describe('plugin-meetings', () => {
|
|
|
110
111
|
// bytesReceived and bytesSent need to be non-zero in order for StatsAnalyzer to parse any other values
|
|
111
112
|
fakeStats = {
|
|
112
113
|
audio: {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
senders: [
|
|
115
|
+
{
|
|
116
|
+
report: [
|
|
117
|
+
{
|
|
118
|
+
type: 'outbound-rtp',
|
|
119
|
+
packetsSent: 0,
|
|
120
|
+
bytesSent: 1,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
receivers: [
|
|
126
|
+
{
|
|
127
|
+
report: [
|
|
128
|
+
{
|
|
129
|
+
type: 'inbound-rtp',
|
|
130
|
+
packetsReceived: 0,
|
|
131
|
+
bytesReceived: 1,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
],
|
|
123
136
|
},
|
|
124
137
|
video: {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
senders: [
|
|
139
|
+
{
|
|
140
|
+
report: [
|
|
141
|
+
{
|
|
142
|
+
type: 'outbound-rtp',
|
|
143
|
+
framesSent: 0,
|
|
144
|
+
bytesSent: 1,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
receivers: [
|
|
150
|
+
{
|
|
151
|
+
report: [
|
|
152
|
+
{
|
|
153
|
+
type: 'inbound-rtp',
|
|
154
|
+
framesDecoded: 0,
|
|
155
|
+
bytesReceived: 1,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
135
160
|
},
|
|
136
161
|
};
|
|
137
162
|
|
|
@@ -139,21 +164,20 @@ describe('plugin-meetings', () => {
|
|
|
139
164
|
getConnectionState: sinon.stub().returns(ConnectionState.Connected),
|
|
140
165
|
getTransceiverStats: sinon.stub().resolves({
|
|
141
166
|
audio: {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
currentDirection: 'sendrecv',
|
|
145
|
-
localTrackLabel: 'fake mic',
|
|
167
|
+
senders: [fakeStats.audio.senders[0]],
|
|
168
|
+
receivers: [fakeStats.audio.receivers[0]],
|
|
146
169
|
},
|
|
147
170
|
video: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
171
|
+
senders: [fakeStats.video.senders[0]],
|
|
172
|
+
receivers: [fakeStats.video.receivers[0]],
|
|
173
|
+
},
|
|
174
|
+
screenShareAudio: {
|
|
175
|
+
senders: [],
|
|
176
|
+
receivers: [],
|
|
152
177
|
},
|
|
153
178
|
screenShareVideo: {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
currentDirection: 'sendrecv',
|
|
179
|
+
senders: [],
|
|
180
|
+
receivers: [],
|
|
157
181
|
},
|
|
158
182
|
}),
|
|
159
183
|
};
|
|
@@ -207,7 +231,7 @@ describe('plugin-meetings', () => {
|
|
|
207
231
|
checkReceivedEvent({expected: {}});
|
|
208
232
|
|
|
209
233
|
// setup a mock to return some values higher the previous ones
|
|
210
|
-
fakeStats.audio.
|
|
234
|
+
fakeStats.audio.senders[0].report[0].packetsSent += 10;
|
|
211
235
|
|
|
212
236
|
await progressTime();
|
|
213
237
|
|
|
@@ -227,7 +251,7 @@ describe('plugin-meetings', () => {
|
|
|
227
251
|
checkReceivedEvent({expected: {}});
|
|
228
252
|
|
|
229
253
|
// setup a mock to return some values higher the previous ones
|
|
230
|
-
fakeStats.video.
|
|
254
|
+
fakeStats.video.senders[0].report[0].framesSent += 1;
|
|
231
255
|
|
|
232
256
|
await progressTime();
|
|
233
257
|
|
|
@@ -247,7 +271,7 @@ describe('plugin-meetings', () => {
|
|
|
247
271
|
checkReceivedEvent({expected: {}});
|
|
248
272
|
|
|
249
273
|
// setup a mock to return some values higher the previous ones
|
|
250
|
-
fakeStats.audio.
|
|
274
|
+
fakeStats.audio.receivers[0].report[0].packetsReceived += 5;
|
|
251
275
|
|
|
252
276
|
await progressTime();
|
|
253
277
|
// check that we got the REMOTE_MEDIA_STARTED event for audio
|
|
@@ -267,7 +291,7 @@ describe('plugin-meetings', () => {
|
|
|
267
291
|
checkReceivedEvent({expected: {}});
|
|
268
292
|
|
|
269
293
|
// setup a mock to return some values higher the previous ones
|
|
270
|
-
fakeStats.video.
|
|
294
|
+
fakeStats.video.receivers[0].report[0].framesDecoded += 1;
|
|
271
295
|
|
|
272
296
|
await progressTime();
|
|
273
297
|
// check that we got the REMOTE_MEDIA_STARTED event for video
|