@webex/plugin-meetings 2.60.1-next.13 → 2.60.1-next.15

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.
Files changed (63) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/interpretation/index.js +1 -1
  4. package/dist/interpretation/siLanguage.js +1 -1
  5. package/dist/mediaQualityMetrics/config.d.ts +103 -99
  6. package/dist/mediaQualityMetrics/config.js +133 -129
  7. package/dist/mediaQualityMetrics/config.js.map +1 -1
  8. package/dist/meeting/index.d.ts +0 -1
  9. package/dist/meeting/index.js +7 -15
  10. package/dist/meeting/index.js.map +1 -1
  11. package/dist/meeting/request.d.ts +2 -0
  12. package/dist/meeting/request.js +4 -0
  13. package/dist/meeting/request.js.map +1 -1
  14. package/dist/meeting/voicea-meeting.d.ts +0 -4
  15. package/dist/meeting/voicea-meeting.js +26 -58
  16. package/dist/meeting/voicea-meeting.js.map +1 -1
  17. package/dist/meetings/index.js +19 -0
  18. package/dist/meetings/index.js.map +1 -1
  19. package/dist/meetings/util.js +1 -1
  20. package/dist/meetings/util.js.map +1 -1
  21. package/dist/metrics/constants.d.ts +2 -0
  22. package/dist/metrics/constants.js +3 -1
  23. package/dist/metrics/constants.js.map +1 -1
  24. package/dist/reachability/index.js +14 -20
  25. package/dist/reachability/index.js.map +1 -1
  26. package/dist/reconnection-manager/index.js +63 -43
  27. package/dist/reconnection-manager/index.js.map +1 -1
  28. package/dist/roap/turnDiscovery.d.ts +18 -2
  29. package/dist/roap/turnDiscovery.js +163 -69
  30. package/dist/roap/turnDiscovery.js.map +1 -1
  31. package/dist/rtcMetrics/index.d.ts +7 -0
  32. package/dist/rtcMetrics/index.js +38 -1
  33. package/dist/rtcMetrics/index.js.map +1 -1
  34. package/dist/statsAnalyzer/index.js +135 -23
  35. package/dist/statsAnalyzer/index.js.map +1 -1
  36. package/dist/statsAnalyzer/mqaUtil.d.ts +28 -4
  37. package/dist/statsAnalyzer/mqaUtil.js +278 -148
  38. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  39. package/dist/webinar/index.js +1 -1
  40. package/package.json +21 -21
  41. package/src/mediaQualityMetrics/config.ts +107 -107
  42. package/src/meeting/index.ts +5 -18
  43. package/src/meeting/request.ts +6 -0
  44. package/src/meeting/voicea-meeting.ts +26 -65
  45. package/src/meetings/index.ts +22 -0
  46. package/src/meetings/util.ts +1 -1
  47. package/src/metrics/constants.ts +2 -0
  48. package/src/reachability/index.ts +0 -6
  49. package/src/reconnection-manager/index.ts +18 -7
  50. package/src/roap/turnDiscovery.ts +100 -24
  51. package/src/rtcMetrics/index.ts +43 -1
  52. package/src/statsAnalyzer/index.ts +158 -24
  53. package/src/statsAnalyzer/mqaUtil.ts +302 -154
  54. package/test/unit/spec/meeting/index.js +195 -4
  55. package/test/unit/spec/meeting/request.js +2 -0
  56. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  57. package/test/unit/spec/meetings/utils.js +35 -8
  58. package/test/unit/spec/reachability/index.ts +74 -0
  59. package/test/unit/spec/reconnection-manager/index.js +36 -1
  60. package/test/unit/spec/roap/turnDiscovery.ts +326 -76
  61. package/test/unit/spec/rtcMetrics/index.ts +32 -3
  62. package/test/unit/spec/stats-analyzer/index.js +439 -1
  63. package/test/utils/webex-test-users.js +12 -4
@@ -18,6 +18,10 @@ import {
18
18
  emptyMqaInterval,
19
19
  emptyVideoReceive,
20
20
  emptyVideoTransmit,
21
+ emptyAudioReceiveStream,
22
+ emptyAudioTransmitStream,
23
+ emptyVideoReceiveStream,
24
+ emptyVideoTransmitStream,
21
25
  } from '../mediaQualityMetrics/config';
22
26
  import LoggerProxy from '../common/logs/logger-proxy';
23
27
 
@@ -27,6 +31,10 @@ import {
27
31
  getAudioReceiverMqa,
28
32
  getVideoSenderMqa,
29
33
  getVideoReceiverMqa,
34
+ getAudioSenderStreamMqa,
35
+ getAudioReceiverStreamMqa,
36
+ getVideoSenderStreamMqa,
37
+ getVideoReceiverStreamMqa,
30
38
  } from './mqaUtil';
31
39
  import {ReceiveSlot} from '../multistream/receiveSlot';
32
40
 
@@ -153,6 +161,7 @@ export class StatsAnalyzer extends EventsScope {
153
161
  sendMqaData() {
154
162
  const newMqa = cloneDeep(emptyMqaInterval);
155
163
 
164
+ // Fill in empty stats items for lastMqaDataSent
156
165
  Object.keys(this.statsResults).forEach((mediaType) => {
157
166
  if (!this.lastMqaDataSent[mediaType]) {
158
167
  this.lastMqaDataSent[mediaType] = {};
@@ -165,53 +174,178 @@ export class StatsAnalyzer extends EventsScope {
165
174
  if (!this.lastMqaDataSent[mediaType].recv && mediaType.includes('-recv')) {
166
175
  this.lastMqaDataSent[mediaType].recv = {};
167
176
  }
177
+ });
178
+
179
+ // Create stats the first level, totals for senders and receivers
180
+ const audioSender = cloneDeep(emptyAudioTransmit);
181
+ const audioShareSender = cloneDeep(emptyAudioTransmit);
182
+ const audioReceiver = cloneDeep(emptyAudioReceive);
183
+ const audioShareReceiver = cloneDeep(emptyAudioReceive);
184
+ const videoSender = cloneDeep(emptyVideoTransmit);
185
+ const videoShareSender = cloneDeep(emptyVideoTransmit);
186
+ const videoReceiver = cloneDeep(emptyVideoReceive);
187
+ const videoShareReceiver = cloneDeep(emptyVideoReceive);
188
+
189
+ getAudioSenderMqa({
190
+ audioSender,
191
+ statsResults: this.statsResults,
192
+ lastMqaDataSent: this.lastMqaDataSent,
193
+ baseMediaType: 'audio-send',
194
+ });
195
+ newMqa.audioTransmit.push(audioSender);
196
+
197
+ getAudioSenderMqa({
198
+ audioSender: audioShareSender,
199
+ statsResults: this.statsResults,
200
+ lastMqaDataSent: this.lastMqaDataSent,
201
+ baseMediaType: 'audio-share-send',
202
+ });
203
+ newMqa.audioTransmit.push(audioShareSender);
204
+
205
+ getAudioReceiverMqa({
206
+ audioReceiver,
207
+ statsResults: this.statsResults,
208
+ lastMqaDataSent: this.lastMqaDataSent,
209
+ baseMediaType: 'audio-recv',
210
+ });
211
+ newMqa.audioReceive.push(audioReceiver);
212
+
213
+ getAudioReceiverMqa({
214
+ audioReceiver: audioShareReceiver,
215
+ statsResults: this.statsResults,
216
+ lastMqaDataSent: this.lastMqaDataSent,
217
+ baseMediaType: 'audio-share-recv',
218
+ });
219
+ newMqa.audioReceive.push(audioShareReceiver);
220
+
221
+ getVideoSenderMqa({
222
+ videoSender,
223
+ statsResults: this.statsResults,
224
+ lastMqaDataSent: this.lastMqaDataSent,
225
+ baseMediaType: 'video-send',
226
+ });
227
+ newMqa.videoTransmit.push(videoSender);
228
+
229
+ getVideoSenderMqa({
230
+ videoSender: videoShareSender,
231
+ statsResults: this.statsResults,
232
+ lastMqaDataSent: this.lastMqaDataSent,
233
+ baseMediaType: 'video-share-send',
234
+ });
235
+ newMqa.videoTransmit.push(videoShareSender);
236
+
237
+ getVideoReceiverMqa({
238
+ videoReceiver,
239
+ statsResults: this.statsResults,
240
+ lastMqaDataSent: this.lastMqaDataSent,
241
+ baseMediaType: 'video-recv',
242
+ });
243
+ newMqa.videoReceive.push(videoReceiver);
244
+
245
+ getVideoReceiverMqa({
246
+ videoReceiver: videoShareReceiver,
247
+ statsResults: this.statsResults,
248
+ lastMqaDataSent: this.lastMqaDataSent,
249
+ baseMediaType: 'video-share-recv',
250
+ });
251
+ newMqa.videoReceive.push(videoShareReceiver);
252
+
253
+ // Add stats for individual streams
254
+ Object.keys(this.statsResults).forEach((mediaType) => {
255
+ if (mediaType.includes('audio-send')) {
256
+ const audioSenderStream = cloneDeep(emptyAudioTransmitStream);
257
+
258
+ getAudioSenderStreamMqa({
259
+ audioSenderStream,
260
+ statsResults: this.statsResults,
261
+ lastMqaDataSent: this.lastMqaDataSent,
262
+ mediaType,
263
+ });
264
+ newMqa.audioTransmit[0].streams.push(audioSenderStream);
168
265
 
169
- if (mediaType.includes('audio-send') || mediaType.includes('audio-share-send')) {
170
- const audioSender = cloneDeep(emptyAudioTransmit);
266
+ this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
267
+ } else if (mediaType.includes('audio-share-send')) {
268
+ const audioSenderStream = cloneDeep(emptyAudioTransmitStream);
171
269
 
172
- getAudioSenderMqa({
173
- audioSender,
270
+ getAudioSenderStreamMqa({
271
+ audioSenderStream,
174
272
  statsResults: this.statsResults,
175
273
  lastMqaDataSent: this.lastMqaDataSent,
176
274
  mediaType,
177
275
  });
178
- newMqa.audioTransmit.push(audioSender);
276
+ newMqa.audioTransmit[1].streams.push(audioSenderStream);
179
277
 
180
278
  this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
181
- } else if (mediaType.includes('audio-recv') || mediaType.includes('audio-share-recv')) {
182
- const audioReceiver = cloneDeep(emptyAudioReceive);
279
+ } else if (mediaType.includes('audio-recv')) {
280
+ const audioReceiverStream = cloneDeep(emptyAudioReceiveStream);
281
+
282
+ getAudioReceiverStreamMqa({
283
+ audioReceiverStream,
284
+ statsResults: this.statsResults,
285
+ lastMqaDataSent: this.lastMqaDataSent,
286
+ mediaType,
287
+ });
288
+ newMqa.audioReceive[0].streams.push(audioReceiverStream);
183
289
 
184
- getAudioReceiverMqa({
185
- audioReceiver,
290
+ this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
291
+ } else if (mediaType.includes('audio-share-recv')) {
292
+ const audioReceiverStream = cloneDeep(emptyAudioReceiveStream);
293
+
294
+ getAudioReceiverStreamMqa({
295
+ audioReceiverStream,
186
296
  statsResults: this.statsResults,
187
297
  lastMqaDataSent: this.lastMqaDataSent,
188
298
  mediaType,
189
299
  });
190
- newMqa.audioReceive.push(audioReceiver);
300
+ newMqa.audioReceive[1].streams.push(audioReceiverStream);
191
301
 
192
302
  this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
193
- } else if (mediaType.includes('video-send') || mediaType.includes('video-share-send')) {
194
- const videoSender = cloneDeep(emptyVideoTransmit);
303
+ } else if (mediaType.includes('video-send')) {
304
+ const videoSenderStream = cloneDeep(emptyVideoTransmitStream);
305
+
306
+ getVideoSenderStreamMqa({
307
+ videoSenderStream,
308
+ statsResults: this.statsResults,
309
+ lastMqaDataSent: this.lastMqaDataSent,
310
+ mediaType,
311
+ });
312
+ newMqa.videoTransmit[0].streams.push(videoSenderStream);
313
+
314
+ this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
315
+ } else if (mediaType.includes('video-share-send')) {
316
+ const videoSenderStream = cloneDeep(emptyVideoTransmitStream);
195
317
 
196
- getVideoSenderMqa({
197
- videoSender,
318
+ getVideoSenderStreamMqa({
319
+ videoSenderStream,
198
320
  statsResults: this.statsResults,
199
321
  lastMqaDataSent: this.lastMqaDataSent,
200
322
  mediaType,
201
323
  });
202
- newMqa.videoTransmit.push(videoSender);
324
+ newMqa.videoTransmit[1].streams.push(videoSenderStream);
203
325
 
204
326
  this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
205
- } else if (mediaType.includes('video-recv') || mediaType.includes('video-share-recv')) {
206
- const videoReceiver = cloneDeep(emptyVideoReceive);
327
+ } else if (mediaType.includes('video-recv')) {
328
+ const videoReceiverStream = cloneDeep(emptyVideoReceiveStream);
329
+
330
+ getVideoReceiverStreamMqa({
331
+ videoReceiverStream,
332
+ statsResults: this.statsResults,
333
+ lastMqaDataSent: this.lastMqaDataSent,
334
+ mediaType,
335
+ });
336
+ newMqa.videoReceive[0].streams.push(videoReceiverStream);
337
+
338
+ this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
339
+ } else if (mediaType.includes('video-share-recv')) {
340
+ const videoReceiverStream = cloneDeep(emptyVideoReceiveStream);
207
341
 
208
- getVideoReceiverMqa({
209
- videoReceiver,
342
+ getVideoReceiverStreamMqa({
343
+ videoReceiverStream,
210
344
  statsResults: this.statsResults,
211
345
  lastMqaDataSent: this.lastMqaDataSent,
212
346
  mediaType,
213
347
  });
214
- newMqa.videoReceive.push(videoReceiver);
348
+ newMqa.videoReceive[1].streams.push(videoReceiverStream);
215
349
 
216
350
  this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
217
351
  }
@@ -381,7 +515,6 @@ export class StatsAnalyzer extends EventsScope {
381
515
  this.parseCandidate(getStatsResult, type, isSender, false);
382
516
  break;
383
517
  case 'media-source':
384
- // @ts-ignore
385
518
  this.parseAudioSource(getStatsResult, type);
386
519
  break;
387
520
  default:
@@ -911,6 +1044,7 @@ export class StatsAnalyzer extends EventsScope {
911
1044
  if (result.bytesReceived) {
912
1045
  let kilobytes = 0;
913
1046
  const receiveSlot = this.receiveSlotCallback(result.ssrc);
1047
+ const sourceState = receiveSlot?.sourceState;
914
1048
  const idAndCsi = receiveSlot
915
1049
  ? `id: "${receiveSlot.id || ''}"${receiveSlot.csi ? ` and csi: ${receiveSlot.csi}` : ''}`
916
1050
  : '';
@@ -938,10 +1072,10 @@ export class StatsAnalyzer extends EventsScope {
938
1072
  this.statsResults[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
939
1073
 
940
1074
  if (currentPacketsReceived === 0) {
941
- if (receiveSlot) {
1075
+ if (receiveSlot && sourceState === 'live') {
942
1076
  LoggerProxy.logger.info(
943
- `StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot ${idAndCsi}`,
944
- currentPacketsReceived
1077
+ `StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot ${idAndCsi}. Total packets received on slot: `,
1078
+ result.packetsReceived
945
1079
  );
946
1080
  }
947
1081
  }