@webex/plugin-meetings 2.60.1-next.16 → 2.60.1-next.18

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 (35) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.d.ts +1 -0
  4. package/dist/constants.js +1 -0
  5. package/dist/constants.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/locus-info/index.js +4 -1
  9. package/dist/locus-info/index.js.map +1 -1
  10. package/dist/meeting/index.js +27 -8
  11. package/dist/meeting/index.js.map +1 -1
  12. package/dist/meetings/index.d.ts +1 -1
  13. package/dist/meetings/index.js +6 -20
  14. package/dist/meetings/index.js.map +1 -1
  15. package/dist/reconnection-manager/index.js +22 -26
  16. package/dist/reconnection-manager/index.js.map +1 -1
  17. package/dist/statsAnalyzer/index.d.ts +5 -1
  18. package/dist/statsAnalyzer/index.js +75 -88
  19. package/dist/statsAnalyzer/index.js.map +1 -1
  20. package/dist/webinar/index.js +1 -1
  21. package/package.json +22 -23
  22. package/src/constants.ts +1 -0
  23. package/src/locus-info/index.ts +4 -1
  24. package/src/meeting/index.ts +25 -1
  25. package/src/meetings/index.ts +10 -23
  26. package/src/reconnection-manager/index.ts +11 -13
  27. package/src/statsAnalyzer/index.ts +131 -153
  28. package/test/integration/spec/journey.js +2 -2
  29. package/test/integration/spec/space-meeting.js +1 -1
  30. package/test/unit/spec/locus-info/index.js +13 -6
  31. package/test/unit/spec/meeting/index.js +49 -1
  32. package/test/unit/spec/meetings/index.js +21 -0
  33. package/test/unit/spec/metrics/index.js +1 -2
  34. package/test/unit/spec/reconnection-manager/index.js +1 -11
  35. package/test/unit/spec/stats-analyzer/index.js +686 -493
@@ -42,126 +42,156 @@ describe('plugin-meetings', () => {
42
42
 
43
43
  it('should call processOutboundRTPResult', () => {
44
44
  const calledSpy = sandbox.spy(statsAnalyzer, 'processOutboundRTPResult');
45
- statsAnalyzer.parseGetStatsResult({ type: 'outbound-rtp' }, 'video-send');
45
+ statsAnalyzer.parseGetStatsResult({type: 'outbound-rtp'}, 'video-send');
46
46
  assert(calledSpy.calledOnce);
47
47
  });
48
48
 
49
49
  it('should call processInboundRTPResult', () => {
50
50
  const calledSpy = sandbox.spy(statsAnalyzer, 'processInboundRTPResult');
51
- statsAnalyzer.parseGetStatsResult({ type: 'inbound-rtp' }, 'video-recv');
51
+ statsAnalyzer.parseGetStatsResult({type: 'inbound-rtp'}, 'video-recv');
52
52
  assert(calledSpy.calledOnce);
53
53
  });
54
54
 
55
55
  it('should call compareSentAndReceived', () => {
56
56
  const calledSpy = sandbox.spy(statsAnalyzer, 'compareSentAndReceived');
57
- statsAnalyzer.parseGetStatsResult({ type: 'remote-outbound-rtp' }, 'video-send');
57
+ statsAnalyzer.parseGetStatsResult({type: 'remote-outbound-rtp'}, 'video-send');
58
58
  assert(calledSpy.calledOnce);
59
59
  });
60
60
 
61
61
  it('should call parseCandidate', () => {
62
62
  const calledSpy = sandbox.spy(statsAnalyzer, 'parseCandidate');
63
- statsAnalyzer.parseGetStatsResult({ type: 'local-candidate' }, 'video-send');
63
+ statsAnalyzer.parseGetStatsResult({type: 'local-candidate'}, 'video-send');
64
64
  assert(calledSpy.calledOnce);
65
65
  });
66
66
 
67
67
  it('processOutboundRTPResult should create the correct stats results', () => {
68
68
  // establish the `statsResults` object.
69
- statsAnalyzer.parseGetStatsResult({ type: 'none' }, 'audio-send', true);
70
-
71
- statsAnalyzer.processOutboundRTPResult({
72
- bytesSent: 50000,
73
- codecId: "RTCCodec_1_Outbound_111",
74
- headerBytesSent: 25000,
75
- id: "RTCOutboundRTPAudioStream_123456789",
76
- kind: "audio",
77
- mediaSourceId: "RTCAudioSource_2",
78
- mediaType: "audio",
79
- nackCount: 1,
80
- packetsSent: 3600,
81
- remoteId: "RTCRemoteInboundRtpAudioStream_123456789",
82
- retransmittedBytesSent: 100,
83
- retransmittedPacketsSent: 2,
84
- ssrc: 123456789,
85
- targetBitrate: 256000,
86
- timestamp: 1707341489336,
87
- trackId: "RTCMediaStreamTrack_sender_2",
88
- transportId: "RTCTransport_0_1",
89
- type: "outbound-rtp",
90
- }, 'audio-send', true);
69
+ statsAnalyzer.parseGetStatsResult({type: 'none'}, 'audio-send', true);
70
+
71
+ statsAnalyzer.processOutboundRTPResult(
72
+ {
73
+ bytesSent: 50000,
74
+ codecId: 'RTCCodec_1_Outbound_111',
75
+ headerBytesSent: 25000,
76
+ id: 'RTCOutboundRTPAudioStream_123456789',
77
+ kind: 'audio',
78
+ mediaSourceId: 'RTCAudioSource_2',
79
+ mediaType: 'audio',
80
+ nackCount: 1,
81
+ packetsSent: 3600,
82
+ remoteId: 'RTCRemoteInboundRtpAudioStream_123456789',
83
+ retransmittedBytesSent: 100,
84
+ retransmittedPacketsSent: 2,
85
+ ssrc: 123456789,
86
+ targetBitrate: 256000,
87
+ timestamp: 1707341489336,
88
+ trackId: 'RTCMediaStreamTrack_sender_2',
89
+ transportId: 'RTCTransport_0_1',
90
+ type: 'outbound-rtp',
91
+ },
92
+ 'audio-send',
93
+ true
94
+ );
91
95
 
92
96
  assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.headerBytesSent, 25000);
93
97
  assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.totalBytesSent, 50000);
94
98
  assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.totalNackCount, 1);
95
- assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.totalPacketsSent, 3600)
96
- assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.retransmittedPacketsSent, 2);
97
- assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.retransmittedBytesSent, 100);
99
+ assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.totalPacketsSent, 3600);
100
+ assert.strictEqual(
101
+ statsAnalyzer.statsResults['audio-send'].send.retransmittedPacketsSent,
102
+ 2
103
+ );
104
+ assert.strictEqual(
105
+ statsAnalyzer.statsResults['audio-send'].send.retransmittedBytesSent,
106
+ 100
107
+ );
98
108
  });
99
109
 
100
110
  it('processInboundRTPResult should create the correct stats results', () => {
101
111
  // establish the `statsResults` object.
102
- statsAnalyzer.parseGetStatsResult({ type: 'none' }, 'audio-recv-1', false);
103
-
104
- statsAnalyzer.processInboundRTPResult({
105
- audioLevel: 0,
106
- bytesReceived: 509,
107
- codecId: "RTCCodec_6_Inbound_111",
108
- concealedSamples: 200000,
109
- concealmentEvents: 13,
110
- fecPacketsDiscarded: 1,
111
- fecPacketsReceived: 1,
112
- headerBytesReceived: 250,
113
- id: "RTCInboundRTPAudioStream_123456789",
114
- insertedSamplesForDeceleration: 0,
115
- jitter: 0.012,
116
- jitterBufferDelay: 1000,
117
- jitterBufferEmittedCount: 10000,
118
- kind: "audio",
119
- lastPacketReceivedTimestamp: 1707341488529,
120
- mediaType: "audio",
121
- packetsDiscarded: 0,
122
- packetsLost: 0,
123
- packetsReceived: 12,
124
- remoteId: "RTCRemoteOutboundRTPAudioStream_123456789",
125
- removedSamplesForAcceleration: 0,
126
- silentConcealedSamples: 200000,
127
- ssrc: 123456789,
128
- timestamp: 1707341489419,
129
- totalAudioEnergy: 133,
130
- totalSamplesDuration: 7,
131
- totalSamplesReceived: 300000,
132
- trackId: "RTCMediaStreamTrack_receiver_76",
133
- transportId: "RTCTransport_0_1",
134
- type: "inbound-rtp",
135
- }, 'audio-recv-1', false);
136
-
137
- assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.totalPacketsReceived, 12);
112
+ statsAnalyzer.parseGetStatsResult({type: 'none'}, 'audio-recv-1', false);
113
+
114
+ statsAnalyzer.processInboundRTPResult(
115
+ {
116
+ audioLevel: 0,
117
+ bytesReceived: 509,
118
+ codecId: 'RTCCodec_6_Inbound_111',
119
+ concealedSamples: 200000,
120
+ concealmentEvents: 13,
121
+ fecPacketsDiscarded: 1,
122
+ fecPacketsReceived: 1,
123
+ headerBytesReceived: 250,
124
+ id: 'RTCInboundRTPAudioStream_123456789',
125
+ insertedSamplesForDeceleration: 0,
126
+ jitter: 0.012,
127
+ jitterBufferDelay: 1000,
128
+ jitterBufferEmittedCount: 10000,
129
+ kind: 'audio',
130
+ lastPacketReceivedTimestamp: 1707341488529,
131
+ mediaType: 'audio',
132
+ packetsDiscarded: 0,
133
+ packetsLost: 0,
134
+ packetsReceived: 12,
135
+ remoteId: 'RTCRemoteOutboundRTPAudioStream_123456789',
136
+ removedSamplesForAcceleration: 0,
137
+ silentConcealedSamples: 200000,
138
+ ssrc: 123456789,
139
+ timestamp: 1707341489419,
140
+ totalAudioEnergy: 133,
141
+ totalSamplesDuration: 7,
142
+ totalSamplesReceived: 300000,
143
+ trackId: 'RTCMediaStreamTrack_receiver_76',
144
+ transportId: 'RTCTransport_0_1',
145
+ type: 'inbound-rtp',
146
+ },
147
+ 'audio-recv-1',
148
+ false
149
+ );
150
+
151
+ assert.strictEqual(
152
+ statsAnalyzer.statsResults['audio-recv-1'].recv.totalPacketsReceived,
153
+ 12
154
+ );
138
155
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.fecPacketsDiscarded, 1);
139
156
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.fecPacketsReceived, 1);
140
157
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.totalBytesReceived, 509);
141
- assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.headerBytesReceived, 250);
158
+ assert.strictEqual(
159
+ statsAnalyzer.statsResults['audio-recv-1'].recv.headerBytesReceived,
160
+ 250
161
+ );
142
162
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.audioLevel, 0);
143
163
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.totalAudioEnergy, 133);
144
- assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.totalSamplesReceived, 300000);
164
+ assert.strictEqual(
165
+ statsAnalyzer.statsResults['audio-recv-1'].recv.totalSamplesReceived,
166
+ 300000
167
+ );
145
168
  assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.totalSamplesDecoded, 0);
146
- assert.strictEqual(statsAnalyzer.statsResults['audio-recv-1'].recv.concealedSamples, 200000);
169
+ assert.strictEqual(
170
+ statsAnalyzer.statsResults['audio-recv-1'].recv.concealedSamples,
171
+ 200000
172
+ );
147
173
  });
148
174
 
149
175
  it('parseAudioSource should create the correct stats results', () => {
150
176
  // establish the `statsResults` object.
151
- statsAnalyzer.parseGetStatsResult({ type: 'none' }, 'audio-send', true);
152
-
153
- statsAnalyzer.parseAudioSource({
154
- audioLevel: 0.03,
155
- echoReturnLoss: -30,
156
- echoReturnLossEnhancement: 0.17,
157
- id: "RTCAudioSource_2",
158
- kind: "audio",
159
- timestamp: 1707341488160.012,
160
- totalAudioEnergy: 0.001,
161
- totalSamplesDuration: 4.5,
162
- trackIdentifier: "2207e5bf-c595-4301-93f7-283994d8143f",
163
- type: "media-source",
164
- }, 'audio-send', true);
177
+ statsAnalyzer.parseGetStatsResult({type: 'none'}, 'audio-send', true);
178
+
179
+ statsAnalyzer.parseAudioSource(
180
+ {
181
+ audioLevel: 0.03,
182
+ echoReturnLoss: -30,
183
+ echoReturnLossEnhancement: 0.17,
184
+ id: 'RTCAudioSource_2',
185
+ kind: 'audio',
186
+ timestamp: 1707341488160.012,
187
+ totalAudioEnergy: 0.001,
188
+ totalSamplesDuration: 4.5,
189
+ trackIdentifier: '2207e5bf-c595-4301-93f7-283994d8143f',
190
+ type: 'media-source',
191
+ },
192
+ 'audio-send',
193
+ true
194
+ );
165
195
 
166
196
  assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.audioLevel, 0.03);
167
197
  assert.strictEqual(statsAnalyzer.statsResults['audio-send'].send.totalAudioEnergy, 0.001);
@@ -267,7 +297,7 @@ describe('plugin-meetings', () => {
267
297
  };
268
298
 
269
299
  before(() => {
270
- LoggerConfig.set({ enable: false });
300
+ LoggerConfig.set({enable: false});
271
301
  LoggerProxy.set();
272
302
  loggerSpy = sandbox.spy(LoggerProxy.logger, 'info');
273
303
  });
@@ -413,6 +443,74 @@ describe('plugin-meetings', () => {
413
443
  },
414
444
  ],
415
445
  },
446
+ share: {
447
+ senders: [
448
+ {
449
+ localTrackLabel: 'fake-share',
450
+ report: [
451
+ {
452
+ type: 'outbound-rtp',
453
+ bytesSent: 1,
454
+ framesSent: 0,
455
+ packetsSent: 0,
456
+ },
457
+ {
458
+ type: 'remote-inbound-rtp',
459
+ packetsLost: 0,
460
+ },
461
+ {
462
+ type: 'candidate-pair',
463
+ state: 'succeeded',
464
+ localCandidateId: 'fake-candidate-id',
465
+ },
466
+ {
467
+ type: 'candidate-pair',
468
+ state: 'failed',
469
+ localCandidateId: 'bad-candidate-id',
470
+ },
471
+ {
472
+ type: 'local-candidate',
473
+ id: 'fake-candidate-id',
474
+ protocol: 'tcp',
475
+ },
476
+ ],
477
+ },
478
+ ],
479
+ receivers: [
480
+ {
481
+ report: [
482
+ {
483
+ type: 'inbound-rtp',
484
+ bytesReceived: 1,
485
+ frameHeight: 720,
486
+ frameWidth: 1280,
487
+ framesDecoded: 0,
488
+ framesReceived: 0,
489
+ packetsLost: 0,
490
+ packetsReceived: 0,
491
+ },
492
+ {
493
+ type: 'remote-outbound-rtp',
494
+ },
495
+ {
496
+ type: 'candidate-pair',
497
+ state: 'succeeded',
498
+ localCandidateId: 'fake-candidate-id',
499
+ },
500
+ {
501
+ type: 'candidate-pair',
502
+ state: 'failed',
503
+ localCandidateId: 'bad-candidate-id',
504
+ },
505
+ {
506
+ type: 'local-candidate',
507
+ id: 'fake-candidate-id',
508
+ protocol: 'tcp',
509
+ },
510
+ ],
511
+ },
512
+ ],
513
+ },
416
514
  };
417
515
 
418
516
  pc = {
@@ -431,15 +529,15 @@ describe('plugin-meetings', () => {
431
529
  receivers: [fakeStats.audio.receivers[0]],
432
530
  },
433
531
  screenShareVideo: {
434
- senders: [fakeStats.video.senders[0]],
435
- receivers: [fakeStats.video.receivers[0]],
532
+ senders: [fakeStats.share.senders[0]],
533
+ receivers: [fakeStats.share.receivers[0]],
436
534
  },
437
535
  }),
438
536
  };
439
537
 
440
538
  networkQualityMonitor = new NetworkQualityMonitor(initialConfig);
441
539
 
442
- statsAnalyzer = new StatsAnalyzer(initialConfig, () => (receiveSlot), networkQualityMonitor);
540
+ statsAnalyzer = new StatsAnalyzer(initialConfig, () => receiveSlot, networkQualityMonitor);
443
541
 
444
542
  statsAnalyzer.on(EVENTS.LOCAL_MEDIA_STARTED, (data) => {
445
543
  receivedEventsData.local.started = data;
@@ -463,9 +561,10 @@ describe('plugin-meetings', () => {
463
561
  clock.restore();
464
562
  });
465
563
 
466
- const startStatsAnalyzer = async (mediaStatus) => {
564
+ const startStatsAnalyzer = async (mediaStatus, lastEmittedEvents) => {
467
565
  statsAnalyzer.updateMediaStatus(mediaStatus);
468
566
  statsAnalyzer.startAnalyzer(pc);
567
+ statsAnalyzer.lastEmittedStartStopEvent = lastEmittedEvents || {};
469
568
 
470
569
  await testUtils.flushPromises();
471
570
  };
@@ -559,6 +658,26 @@ describe('plugin-meetings', () => {
559
658
  checkReceivedEvent({expected: {local: {stopped: {type: 'video'}}}});
560
659
  });
561
660
 
661
+ it('emits LOCAL_MEDIA_STARTED and LOCAL_MEDIA_STOPPED events for share', async () => {
662
+ await startStatsAnalyzer({expected: {sendShare: true}});
663
+
664
+ // check that we haven't received any events yet
665
+ checkReceivedEvent({expected: {}});
666
+
667
+ // setup a mock to return some values higher the previous ones
668
+ fakeStats.share.senders[0].report[0].framesSent += 1;
669
+
670
+ await progressTime();
671
+
672
+ // check that we got the LOCAL_MEDIA_STARTED event for audio
673
+ checkReceivedEvent({expected: {local: {started: {type: 'share'}}}});
674
+
675
+ // now advance the clock and the mock still returns same values, so only "stopped" event should be triggered
676
+ resetReceivedEvents();
677
+ await progressTime();
678
+ checkReceivedEvent({expected: {local: {stopped: {type: 'share'}}}});
679
+ });
680
+
562
681
  it('emits REMOTE_MEDIA_STARTED and REMOTE_MEDIA_STOPPED events for audio', async () => {
563
682
  await startStatsAnalyzer({expected: {receiveAudio: true}});
564
683
 
@@ -599,6 +718,26 @@ describe('plugin-meetings', () => {
599
718
  checkReceivedEvent({expected: {remote: {stopped: {type: 'video'}}}});
600
719
  });
601
720
 
721
+ it('emits REMOTE_MEDIA_STARTED and REMOTE_MEDIA_STOPPED events for share', async () => {
722
+ await startStatsAnalyzer({expected: {receiveShare: true}});
723
+
724
+ // check that we haven't received any events yet
725
+ checkReceivedEvent({expected: {}});
726
+
727
+ // setup a mock to return some values higher the previous ones
728
+ fakeStats.share.receivers[0].report[0].framesDecoded += 1;
729
+
730
+ await progressTime();
731
+ // check that we got the REMOTE_MEDIA_STARTED event for video
732
+ checkReceivedEvent({expected: {remote: {started: {type: 'share'}}}});
733
+
734
+ // now advance the clock and the mock still returns same values, so only "stopped" event should be triggered
735
+ resetReceivedEvents();
736
+ await progressTime();
737
+
738
+ checkReceivedEvent({expected: {remote: {stopped: {type: 'share'}}}});
739
+ });
740
+
602
741
  it('emits the correct MEDIA_QUALITY events', async () => {
603
742
  await startStatsAnalyzer({expected: {receiveVideo: true}});
604
743
 
@@ -844,107 +983,180 @@ describe('plugin-meetings', () => {
844
983
  });
845
984
 
846
985
  it('logs a message when audio send packets do not increase', async () => {
847
- await startStatsAnalyzer({expected: {sendAudio: true}});
986
+ await startStatsAnalyzer(
987
+ {expected: {sendAudio: true}},
988
+ {audio: {local: EVENTS.LOCAL_MEDIA_STARTED}}
989
+ );
848
990
 
849
991
  // don't increase the packets when time progresses.
850
992
  await progressTime();
851
993
 
852
- assert(loggerSpy.calledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent'));
994
+ assert(
995
+ loggerSpy.calledWith(
996
+ 'StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent'
997
+ )
998
+ );
853
999
  });
854
1000
 
855
1001
  it('does not log a message when audio send packets increase', async () => {
856
- await startStatsAnalyzer({expected: {sendAudio: true}});
1002
+ await startStatsAnalyzer(
1003
+ {expected: {sendAudio: true}},
1004
+ {audio: {local: EVENTS.LOCAL_MEDIA_STOPPED}}
1005
+ );
857
1006
 
858
1007
  fakeStats.audio.senders[0].report[0].packetsSent += 5;
859
1008
  await progressTime();
860
1009
 
861
- assert(loggerSpy.neverCalledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent'));
862
- });
863
-
864
- it('logs a message when audio receive packets do not increase', async () => {
865
- await startStatsAnalyzer({expected: {receiveAudio: true}});
866
-
867
- // don't increase the packets when time progresses.
868
- await progressTime();
869
-
870
- assert(loggerSpy.calledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received'));
871
- });
872
-
873
- it('does not log a message when audio receive packets increase', async () => {
874
- await startStatsAnalyzer({expected: {receiveAudio: true}});
875
-
876
- fakeStats.audio.receivers[0].report[0].packetsReceived += 5;
877
- await progressTime();
878
-
879
- assert(loggerSpy.neverCalledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received'));
1010
+ assert(
1011
+ loggerSpy.neverCalledWith(
1012
+ 'StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent'
1013
+ )
1014
+ );
880
1015
  });
881
1016
 
882
1017
  it('logs a message when video send packets do not increase', async () => {
883
- await startStatsAnalyzer({expected: {sendVideo: true}});
1018
+ await startStatsAnalyzer(
1019
+ {expected: {sendVideo: true}},
1020
+ {video: {local: EVENTS.LOCAL_MEDIA_STARTED}}
1021
+ );
884
1022
 
885
1023
  // don't increase the packets when time progresses.
886
1024
  await progressTime();
887
1025
 
888
- assert(loggerSpy.calledWith('StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent'));
1026
+ assert(
1027
+ loggerSpy.calledWith(
1028
+ 'StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent'
1029
+ )
1030
+ );
889
1031
  });
890
1032
 
891
1033
  it('does not log a message when video send packets increase', async () => {
892
- await startStatsAnalyzer({expected: {sendVideo: true}});
1034
+ await startStatsAnalyzer(
1035
+ {expected: {sendVideo: true}},
1036
+ {video: {local: EVENTS.LOCAL_MEDIA_STOPPED}}
1037
+ );
893
1038
 
894
1039
  fakeStats.video.senders[0].report[0].packetsSent += 5;
895
1040
  await progressTime();
896
1041
 
897
- assert(loggerSpy.neverCalledWith('StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent'));
1042
+ assert(
1043
+ loggerSpy.neverCalledWith(
1044
+ 'StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent'
1045
+ )
1046
+ );
898
1047
  });
899
1048
 
900
- it('logs a message when video receive packets do not increase', async () => {
901
- await startStatsAnalyzer({expected: {receiveVideo: true}});
1049
+ it('logs a message when share send packets do not increase', async () => {
1050
+ await startStatsAnalyzer(
1051
+ {expected: {sendShare: true}},
1052
+ {share: {local: EVENTS.LOCAL_MEDIA_STARTED}}
1053
+ );
902
1054
 
903
1055
  // don't increase the packets when time progresses.
904
1056
  await progressTime();
905
1057
 
906
- assert(loggerSpy.calledWith('StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets received'));
1058
+ assert(
1059
+ loggerSpy.calledWith(
1060
+ 'StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent'
1061
+ )
1062
+ );
907
1063
  });
908
1064
 
909
- it('does not log a message when video receive packets increase', async () => {
910
- await startStatsAnalyzer({expected: {receiveVideo: true}});
1065
+ it('does not log a message when share send packets increase', async () => {
1066
+ await startStatsAnalyzer(
1067
+ {expected: {sendShare: true}},
1068
+ {share: {local: EVENTS.LOCAL_MEDIA_STOPPED}}
1069
+ );
911
1070
 
912
- fakeStats.video.receivers[0].report[0].packetsReceived += 5;
1071
+ fakeStats.share.senders[0].report[0].packetsSent += 5;
913
1072
  await progressTime();
914
1073
 
915
- assert(loggerSpy.neverCalledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received'));
1074
+ assert(
1075
+ loggerSpy.neverCalledWith(
1076
+ 'StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent'
1077
+ )
1078
+ );
916
1079
  });
917
1080
 
918
- it('logs a message when no packets are recieved for a receive slot with sourceState "live"', async () => {
1081
+ ['avatar', 'invalid', 'no source', 'bandwidth limited', 'policy violation'].forEach(
1082
+ (sourceState) => {
1083
+ it(`does not log a message when no packets are recieved for a receive slot with sourceState "${sourceState}"`, async () => {
1084
+ receiveSlot = {
1085
+ sourceState,
1086
+ csi: 2,
1087
+ id: '4',
1088
+ };
1089
+
1090
+ await startStatsAnalyzer();
1091
+
1092
+ // don't increase the packets when time progresses.
1093
+ await progressTime();
1094
+
1095
+ assert.neverCalledWith(
1096
+ loggerSpy,
1097
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot id: "4" and csi: 2. Total packets received on slot: ',
1098
+ 0
1099
+ );
1100
+ });
1101
+ }
1102
+ );
1103
+
1104
+ it(`logs a message if no packets are sent`, async () => {
919
1105
  receiveSlot = {
920
- sourceState: 'live',
1106
+ sourceState: 'live',
921
1107
  csi: 2,
922
- id: "4",
1108
+ id: '4',
923
1109
  };
924
-
925
1110
  await startStatsAnalyzer();
926
1111
 
927
1112
  // don't increase the packets when time progresses.
928
1113
  await progressTime();
929
1114
 
930
- assert.calledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot id: "4" and csi: 2. Total packets received on slot: ', 0);
931
- });
1115
+ assert.calledWith(
1116
+ loggerSpy,
1117
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for mediaType: video-recv-0, receive slot id: "4" and csi: 2. Total packets received on slot: ',
1118
+ 0
1119
+ );
932
1120
 
933
- ["avatar", "invalid", "no source", "bandwidth limited", "policy violation"].forEach((sourceState) => {
934
- it(`does not log a message when no packets are recieved for a receive slot with sourceState "${sourceState}"`, async () => {
935
- receiveSlot = {
936
- sourceState,
937
- csi: 2,
938
- id: "4",
939
- };
940
-
941
- await startStatsAnalyzer();
942
-
943
- // don't increase the packets when time progresses.
944
- await progressTime();
945
-
946
- assert.neverCalledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot id: "4" and csi: 2. Total packets received on slot: ', 0);
947
- });
1121
+ assert.calledWith(
1122
+ loggerSpy,
1123
+ 'StatsAnalyzer:index#processInboundRTPResult --> No frames received for mediaType: video-recv-0, receive slot id: "4" and csi: 2. Total frames received on slot: ',
1124
+ 0
1125
+ );
1126
+
1127
+ assert.calledWith(
1128
+ loggerSpy,
1129
+ 'StatsAnalyzer:index#processInboundRTPResult --> No frames decoded for mediaType: video-recv-0, receive slot id: "4" and csi: 2. Total frames decoded on slot: ',
1130
+ 0
1131
+ );
1132
+
1133
+ assert.calledWith(
1134
+ loggerSpy,
1135
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for mediaType: audio-recv-0, receive slot id: "4" and csi: 2. Total packets received on slot: ',
1136
+ 0
1137
+ );
1138
+
1139
+ assert.calledWith(
1140
+ loggerSpy,
1141
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for mediaType: video-share-recv-0, receive slot id: "4" and csi: 2. Total packets received on slot: ',
1142
+ 0
1143
+ );
1144
+
1145
+ assert.calledWith(
1146
+ loggerSpy,
1147
+ 'StatsAnalyzer:index#processInboundRTPResult --> No frames received for mediaType: video-share-recv-0, receive slot id: "4" and csi: 2. Total frames received on slot: ',
1148
+ 0
1149
+ );
1150
+ assert.calledWith(
1151
+ loggerSpy,
1152
+ 'StatsAnalyzer:index#processInboundRTPResult --> No frames decoded for mediaType: video-share-recv-0, receive slot id: "4" and csi: 2. Total frames decoded on slot: ',
1153
+ 0
1154
+ );
1155
+ assert.calledWith(
1156
+ loggerSpy,
1157
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for mediaType: audio-share-recv-0, receive slot id: "4" and csi: 2. Total packets received on slot: ',
1158
+ 0
1159
+ );
948
1160
  });
949
1161
 
950
1162
  it(`does not log a message if receiveSlot is undefined`, async () => {
@@ -953,7 +1165,11 @@ describe('plugin-meetings', () => {
953
1165
  // don't increase the packets when time progresses.
954
1166
  await progressTime();
955
1167
 
956
- assert.neverCalledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot "". Total packets received on slot: ', 0);
1168
+ assert.neverCalledWith(
1169
+ loggerSpy,
1170
+ 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot "". Total packets received on slot: ',
1171
+ 0
1172
+ );
957
1173
  });
958
1174
 
959
1175
  it('has the correct number of senders and receivers (2)', async () => {
@@ -972,258 +1188,234 @@ describe('plugin-meetings', () => {
972
1188
 
973
1189
  await progressTime();
974
1190
 
975
- assert.deepEqual(
976
- mqeData.audioTransmit[0].streams,
977
- [
978
- {
979
- common: {
980
- codec: 'opus',
981
- csi: [],
982
- requestedBitrate: 0,
983
- requestedFrames: 0,
984
- rtpPackets: 0,
985
- ssci: 0,
986
- transmittedBitrate: 0.13333333333333333,
987
- transmittedFrameRate: 0
988
- },
989
- transmittedKeyFrames: 0,
990
- requestedKeyFrames: 0
991
- }
992
- ]
993
- );
994
- assert.deepEqual(
995
- mqeData.audioTransmit[1].streams,
996
- [
997
- {
998
- common: {
999
- codec: 'opus',
1000
- csi: [],
1001
- requestedBitrate: 0,
1002
- requestedFrames: 0,
1003
- rtpPackets: 0,
1004
- ssci: 0,
1005
- transmittedBitrate: 0.13333333333333333,
1006
- transmittedFrameRate: 0
1007
- },
1008
- transmittedKeyFrames: 0,
1009
- requestedKeyFrames: 0
1010
- }
1011
- ]
1012
- );
1013
- assert.deepEqual(
1014
- mqeData.audioReceive[0].streams,
1015
- [
1016
- {
1017
- common: {
1018
- codec: 'opus',
1019
- concealedFrames: 0,
1020
- csi: [],
1021
- maxConcealRunLength: 0,
1022
- optimalBitrate: 0,
1023
- optimalFrameRate: 0,
1024
- receivedBitrate: 0.13333333333333333,
1025
- receivedFrameRate: 0,
1026
- renderedFrameRate: 0,
1027
- requestedBitrate: 0,
1028
- requestedFrameRate: 0,
1029
- rtpEndToEndLost: 0,
1030
- maxRtpJitter: 0,
1031
- meanRtpJitter: 0,
1032
- rtpPackets: 0,
1033
- ssci: 0,
1034
- rtpJitter: 0,
1035
- framesDropped: 0,
1036
- framesReceived: 0
1037
- }
1038
- }
1039
- ]
1040
- );
1041
- assert.deepEqual(
1042
- mqeData.audioReceive[1].streams,
1043
- [
1044
- {
1045
- common: {
1046
- codec: 'opus',
1047
- concealedFrames: 0,
1048
- csi: [],
1049
- maxConcealRunLength: 0,
1050
- optimalBitrate: 0,
1051
- optimalFrameRate: 0,
1052
- receivedBitrate: 0.13333333333333333,
1053
- receivedFrameRate: 0,
1054
- renderedFrameRate: 0,
1055
- requestedBitrate: 0,
1056
- requestedFrameRate: 0,
1057
- rtpEndToEndLost: 0,
1058
- maxRtpJitter: 0,
1059
- meanRtpJitter: 0,
1060
- rtpPackets: 0,
1061
- ssci: 0,
1062
- rtpJitter: 0,
1063
- framesDropped: 0,
1064
- framesReceived: 0
1065
- }
1066
- }
1067
- ]
1068
- );
1069
- assert.deepEqual(
1070
- mqeData.videoTransmit[0].streams,
1071
- [
1072
- {
1073
- common: {
1074
- codec: 'H264',
1075
- csi: [],
1076
- duplicateSsci: 0,
1077
- requestedBitrate: 0,
1078
- requestedFrames: 0,
1079
- rtpPackets: 0,
1080
- ssci: 0,
1081
- transmittedBitrate: 0.13333333333333333,
1082
- transmittedFrameRate: 0
1083
- },
1084
- h264CodecProfile: 'BP',
1085
- isAvatar: false,
1086
- isHardwareEncoded: false,
1087
- localConfigurationChanges: 2,
1088
- maxFrameQp: 0,
1089
- maxNoiseLevel: 0,
1090
- minRegionQp: 0,
1091
- remoteConfigurationChanges: 0,
1092
- requestedFrameSize: 0,
1093
- requestedKeyFrames: 0,
1094
- transmittedFrameSize: 0,
1095
- transmittedHeight: 0,
1096
- transmittedKeyFrames: 0,
1097
- transmittedKeyFramesClient: 0,
1098
- transmittedKeyFramesConfigurationChange: 0,
1099
- transmittedKeyFramesFeedback: 0,
1100
- transmittedKeyFramesLocalDrop: 0,
1101
- transmittedKeyFramesOtherLayer: 0,
1102
- transmittedKeyFramesPeriodic: 0,
1103
- transmittedKeyFramesSceneChange: 0,
1104
- transmittedKeyFramesStartup: 0,
1105
- transmittedKeyFramesUnknown: 0,
1106
- transmittedWidth: 0
1107
- }
1108
- ]
1109
- );
1110
- assert.deepEqual(
1111
- mqeData.videoTransmit[1].streams,
1112
- [
1113
- {
1114
- common: {
1115
- codec: 'H264',
1116
- csi: [],
1117
- duplicateSsci: 0,
1118
- requestedBitrate: 0,
1119
- requestedFrames: 0,
1120
- rtpPackets: 0,
1121
- ssci: 0,
1122
- transmittedBitrate: 0.13333333333333333,
1123
- transmittedFrameRate: 0
1124
- },
1125
- h264CodecProfile: 'BP',
1126
- isAvatar: false,
1127
- isHardwareEncoded: false,
1128
- localConfigurationChanges: 2,
1129
- maxFrameQp: 0,
1130
- maxNoiseLevel: 0,
1131
- minRegionQp: 0,
1132
- remoteConfigurationChanges: 0,
1133
- requestedFrameSize: 0,
1134
- requestedKeyFrames: 0,
1135
- transmittedFrameSize: 0,
1136
- transmittedHeight: 0,
1137
- transmittedKeyFrames: 0,
1138
- transmittedKeyFramesClient: 0,
1139
- transmittedKeyFramesConfigurationChange: 0,
1140
- transmittedKeyFramesFeedback: 0,
1141
- transmittedKeyFramesLocalDrop: 0,
1142
- transmittedKeyFramesOtherLayer: 0,
1143
- transmittedKeyFramesPeriodic: 0,
1144
- transmittedKeyFramesSceneChange: 0,
1145
- transmittedKeyFramesStartup: 0,
1146
- transmittedKeyFramesUnknown: 0,
1147
- transmittedWidth: 0
1148
- }
1149
- ]
1150
- );
1151
- assert.deepEqual(
1152
- mqeData.videoReceive[0].streams,
1153
- [
1154
- {
1155
- common: {
1156
- codec: 'H264',
1157
- concealedFrames: 0,
1158
- csi: [],
1159
- maxConcealRunLength: 0,
1160
- optimalBitrate: 0,
1161
- optimalFrameRate: 0,
1162
- receivedBitrate: 0.13333333333333333,
1163
- receivedFrameRate: 0,
1164
- renderedFrameRate: 0,
1165
- requestedBitrate: 0,
1166
- requestedFrameRate: 0,
1167
- rtpEndToEndLost: 0,
1168
- rtpJitter: 0,
1169
- rtpPackets: 0,
1170
- ssci: 0,
1171
- framesDropped: 0
1172
- },
1173
- h264CodecProfile: 'BP',
1174
- isActiveSpeaker: true,
1175
- optimalFrameSize: 0,
1176
- receivedFrameSize: 3600,
1177
- receivedHeight: 720,
1178
- receivedKeyFrames: 0,
1179
- receivedKeyFramesForRequest: 0,
1180
- receivedKeyFramesSourceChange: 0,
1181
- receivedKeyFramesUnknown: 0,
1182
- receivedWidth: 1280,
1183
- requestedFrameSize: 0,
1184
- requestedKeyFrames: 0
1185
- }
1186
- ]
1187
- );
1188
- assert.deepEqual(
1189
- mqeData.videoReceive[1].streams,
1190
- [
1191
- {
1192
- common: {
1193
- codec: 'H264',
1194
- concealedFrames: 0,
1195
- csi: [],
1196
- maxConcealRunLength: 0,
1197
- optimalBitrate: 0,
1198
- optimalFrameRate: 0,
1199
- receivedBitrate: 0.13333333333333333,
1200
- receivedFrameRate: 0,
1201
- renderedFrameRate: 0,
1202
- requestedBitrate: 0,
1203
- requestedFrameRate: 0,
1204
- rtpEndToEndLost: 0,
1205
- rtpJitter: 0,
1206
- rtpPackets: 0,
1207
- ssci: 0,
1208
- framesDropped: 0
1209
- },
1210
- h264CodecProfile: 'BP',
1211
- isActiveSpeaker: true,
1212
- optimalFrameSize: 0,
1213
- receivedFrameSize: 3600,
1214
- receivedHeight: 720,
1215
- receivedKeyFrames: 0,
1216
- receivedKeyFramesForRequest: 0,
1217
- receivedKeyFramesSourceChange: 0,
1218
- receivedKeyFramesUnknown: 0,
1219
- receivedWidth: 1280,
1220
- requestedFrameSize: 0,
1221
- requestedKeyFrames: 0
1222
- }
1223
- ]
1224
- );
1191
+ assert.deepEqual(mqeData.audioTransmit[0].streams, [
1192
+ {
1193
+ common: {
1194
+ codec: 'opus',
1195
+ csi: [],
1196
+ requestedBitrate: 0,
1197
+ requestedFrames: 0,
1198
+ rtpPackets: 0,
1199
+ ssci: 0,
1200
+ transmittedBitrate: 0.13333333333333333,
1201
+ transmittedFrameRate: 0,
1202
+ },
1203
+ transmittedKeyFrames: 0,
1204
+ requestedKeyFrames: 0,
1205
+ },
1206
+ ]);
1207
+ assert.deepEqual(mqeData.audioTransmit[1].streams, [
1208
+ {
1209
+ common: {
1210
+ codec: 'opus',
1211
+ csi: [],
1212
+ requestedBitrate: 0,
1213
+ requestedFrames: 0,
1214
+ rtpPackets: 0,
1215
+ ssci: 0,
1216
+ transmittedBitrate: 0.13333333333333333,
1217
+ transmittedFrameRate: 0,
1218
+ },
1219
+ transmittedKeyFrames: 0,
1220
+ requestedKeyFrames: 0,
1221
+ },
1222
+ ]);
1223
+ assert.deepEqual(mqeData.audioReceive[0].streams, [
1224
+ {
1225
+ common: {
1226
+ codec: 'opus',
1227
+ concealedFrames: 0,
1228
+ csi: [],
1229
+ maxConcealRunLength: 0,
1230
+ optimalBitrate: 0,
1231
+ optimalFrameRate: 0,
1232
+ receivedBitrate: 0.13333333333333333,
1233
+ receivedFrameRate: 0,
1234
+ renderedFrameRate: 0,
1235
+ requestedBitrate: 0,
1236
+ requestedFrameRate: 0,
1237
+ rtpEndToEndLost: 0,
1238
+ maxRtpJitter: 0,
1239
+ meanRtpJitter: 0,
1240
+ rtpPackets: 0,
1241
+ ssci: 0,
1242
+ rtpJitter: 0,
1243
+ framesDropped: 0,
1244
+ framesReceived: 0,
1245
+ },
1246
+ },
1247
+ ]);
1248
+ assert.deepEqual(mqeData.audioReceive[1].streams, [
1249
+ {
1250
+ common: {
1251
+ codec: 'opus',
1252
+ concealedFrames: 0,
1253
+ csi: [],
1254
+ maxConcealRunLength: 0,
1255
+ optimalBitrate: 0,
1256
+ optimalFrameRate: 0,
1257
+ receivedBitrate: 0.13333333333333333,
1258
+ receivedFrameRate: 0,
1259
+ renderedFrameRate: 0,
1260
+ requestedBitrate: 0,
1261
+ requestedFrameRate: 0,
1262
+ rtpEndToEndLost: 0,
1263
+ maxRtpJitter: 0,
1264
+ meanRtpJitter: 0,
1265
+ rtpPackets: 0,
1266
+ ssci: 0,
1267
+ rtpJitter: 0,
1268
+ framesDropped: 0,
1269
+ framesReceived: 0,
1270
+ },
1271
+ },
1272
+ ]);
1273
+ assert.deepEqual(mqeData.videoTransmit[0].streams, [
1274
+ {
1275
+ common: {
1276
+ codec: 'H264',
1277
+ csi: [],
1278
+ duplicateSsci: 0,
1279
+ requestedBitrate: 0,
1280
+ requestedFrames: 0,
1281
+ rtpPackets: 0,
1282
+ ssci: 0,
1283
+ transmittedBitrate: 0.13333333333333333,
1284
+ transmittedFrameRate: 0,
1285
+ },
1286
+ h264CodecProfile: 'BP',
1287
+ isAvatar: false,
1288
+ isHardwareEncoded: false,
1289
+ localConfigurationChanges: 2,
1290
+ maxFrameQp: 0,
1291
+ maxNoiseLevel: 0,
1292
+ minRegionQp: 0,
1293
+ remoteConfigurationChanges: 0,
1294
+ requestedFrameSize: 0,
1295
+ requestedKeyFrames: 0,
1296
+ transmittedFrameSize: 0,
1297
+ transmittedHeight: 0,
1298
+ transmittedKeyFrames: 0,
1299
+ transmittedKeyFramesClient: 0,
1300
+ transmittedKeyFramesConfigurationChange: 0,
1301
+ transmittedKeyFramesFeedback: 0,
1302
+ transmittedKeyFramesLocalDrop: 0,
1303
+ transmittedKeyFramesOtherLayer: 0,
1304
+ transmittedKeyFramesPeriodic: 0,
1305
+ transmittedKeyFramesSceneChange: 0,
1306
+ transmittedKeyFramesStartup: 0,
1307
+ transmittedKeyFramesUnknown: 0,
1308
+ transmittedWidth: 0,
1309
+ },
1310
+ ]);
1311
+ assert.deepEqual(mqeData.videoTransmit[1].streams, [
1312
+ {
1313
+ common: {
1314
+ codec: 'H264',
1315
+ csi: [],
1316
+ duplicateSsci: 0,
1317
+ requestedBitrate: 0,
1318
+ requestedFrames: 0,
1319
+ rtpPackets: 0,
1320
+ ssci: 0,
1321
+ transmittedBitrate: 0.13333333333333333,
1322
+ transmittedFrameRate: 0,
1323
+ },
1324
+ h264CodecProfile: 'BP',
1325
+ isAvatar: false,
1326
+ isHardwareEncoded: false,
1327
+ localConfigurationChanges: 2,
1328
+ maxFrameQp: 0,
1329
+ maxNoiseLevel: 0,
1330
+ minRegionQp: 0,
1331
+ remoteConfigurationChanges: 0,
1332
+ requestedFrameSize: 0,
1333
+ requestedKeyFrames: 0,
1334
+ transmittedFrameSize: 0,
1335
+ transmittedHeight: 0,
1336
+ transmittedKeyFrames: 0,
1337
+ transmittedKeyFramesClient: 0,
1338
+ transmittedKeyFramesConfigurationChange: 0,
1339
+ transmittedKeyFramesFeedback: 0,
1340
+ transmittedKeyFramesLocalDrop: 0,
1341
+ transmittedKeyFramesOtherLayer: 0,
1342
+ transmittedKeyFramesPeriodic: 0,
1343
+ transmittedKeyFramesSceneChange: 0,
1344
+ transmittedKeyFramesStartup: 0,
1345
+ transmittedKeyFramesUnknown: 0,
1346
+ transmittedWidth: 0,
1347
+ },
1348
+ ]);
1349
+ assert.deepEqual(mqeData.videoReceive[0].streams, [
1350
+ {
1351
+ common: {
1352
+ codec: 'H264',
1353
+ concealedFrames: 0,
1354
+ csi: [],
1355
+ maxConcealRunLength: 0,
1356
+ optimalBitrate: 0,
1357
+ optimalFrameRate: 0,
1358
+ receivedBitrate: 0.13333333333333333,
1359
+ receivedFrameRate: 0,
1360
+ renderedFrameRate: 0,
1361
+ requestedBitrate: 0,
1362
+ requestedFrameRate: 0,
1363
+ rtpEndToEndLost: 0,
1364
+ rtpJitter: 0,
1365
+ rtpPackets: 0,
1366
+ ssci: 0,
1367
+ framesDropped: 0,
1368
+ },
1369
+ h264CodecProfile: 'BP',
1370
+ isActiveSpeaker: true,
1371
+ optimalFrameSize: 0,
1372
+ receivedFrameSize: 3600,
1373
+ receivedHeight: 720,
1374
+ receivedKeyFrames: 0,
1375
+ receivedKeyFramesForRequest: 0,
1376
+ receivedKeyFramesSourceChange: 0,
1377
+ receivedKeyFramesUnknown: 0,
1378
+ receivedWidth: 1280,
1379
+ requestedFrameSize: 0,
1380
+ requestedKeyFrames: 0,
1381
+ },
1382
+ ]);
1383
+ assert.deepEqual(mqeData.videoReceive[1].streams, [
1384
+ {
1385
+ common: {
1386
+ codec: 'H264',
1387
+ concealedFrames: 0,
1388
+ csi: [],
1389
+ maxConcealRunLength: 0,
1390
+ optimalBitrate: 0,
1391
+ optimalFrameRate: 0,
1392
+ receivedBitrate: 0.13333333333333333,
1393
+ receivedFrameRate: 0,
1394
+ renderedFrameRate: 0,
1395
+ requestedBitrate: 0,
1396
+ requestedFrameRate: 0,
1397
+ rtpEndToEndLost: 0,
1398
+ rtpJitter: 0,
1399
+ rtpPackets: 0,
1400
+ ssci: 0,
1401
+ framesDropped: 0,
1402
+ },
1403
+ h264CodecProfile: 'BP',
1404
+ isActiveSpeaker: true,
1405
+ optimalFrameSize: 0,
1406
+ receivedFrameSize: 3600,
1407
+ receivedHeight: 720,
1408
+ receivedKeyFrames: 0,
1409
+ receivedKeyFramesForRequest: 0,
1410
+ receivedKeyFramesSourceChange: 0,
1411
+ receivedKeyFramesUnknown: 0,
1412
+ receivedWidth: 1280,
1413
+ requestedFrameSize: 0,
1414
+ requestedKeyFrames: 0,
1415
+ },
1416
+ ]);
1225
1417
  });
1226
-
1418
+
1227
1419
  it('has three streams for video receivers when three exist', async () => {
1228
1420
  pc.getTransceiverStats = sinon.stub().resolves({
1229
1421
  audio: {
@@ -1232,7 +1424,11 @@ describe('plugin-meetings', () => {
1232
1424
  },
1233
1425
  video: {
1234
1426
  senders: [fakeStats.video.senders[0]],
1235
- receivers: [fakeStats.video.receivers[0], fakeStats.video.receivers[0], fakeStats.video.receivers[0]],
1427
+ receivers: [
1428
+ fakeStats.video.receivers[0],
1429
+ fakeStats.video.receivers[0],
1430
+ fakeStats.video.receivers[0],
1431
+ ],
1236
1432
  },
1237
1433
  screenShareAudio: {
1238
1434
  senders: [fakeStats.audio.senders[0]],
@@ -1248,107 +1444,104 @@ describe('plugin-meetings', () => {
1248
1444
 
1249
1445
  await progressTime();
1250
1446
 
1251
- assert.deepEqual(
1252
- mqeData.videoReceive[0].streams,
1253
- [
1254
- {
1255
- common: {
1256
- codec: 'H264',
1257
- concealedFrames: 0,
1258
- csi: [],
1259
- maxConcealRunLength: 0,
1260
- optimalBitrate: 0,
1261
- optimalFrameRate: 0,
1262
- receivedBitrate: 0.13333333333333333,
1263
- receivedFrameRate: 0,
1264
- renderedFrameRate: 0,
1265
- requestedBitrate: 0,
1266
- requestedFrameRate: 0,
1267
- rtpEndToEndLost: 0,
1268
- rtpJitter: 0,
1269
- rtpPackets: 0,
1270
- ssci: 0,
1271
- framesDropped: 0
1272
- },
1273
- h264CodecProfile: 'BP',
1274
- isActiveSpeaker: true,
1275
- optimalFrameSize: 0,
1276
- receivedFrameSize: 3600,
1277
- receivedHeight: 720,
1278
- receivedKeyFrames: 0,
1279
- receivedKeyFramesForRequest: 0,
1280
- receivedKeyFramesSourceChange: 0,
1281
- receivedKeyFramesUnknown: 0,
1282
- receivedWidth: 1280,
1283
- requestedFrameSize: 0,
1284
- requestedKeyFrames: 0
1447
+ assert.deepEqual(mqeData.videoReceive[0].streams, [
1448
+ {
1449
+ common: {
1450
+ codec: 'H264',
1451
+ concealedFrames: 0,
1452
+ csi: [],
1453
+ maxConcealRunLength: 0,
1454
+ optimalBitrate: 0,
1455
+ optimalFrameRate: 0,
1456
+ receivedBitrate: 0.13333333333333333,
1457
+ receivedFrameRate: 0,
1458
+ renderedFrameRate: 0,
1459
+ requestedBitrate: 0,
1460
+ requestedFrameRate: 0,
1461
+ rtpEndToEndLost: 0,
1462
+ rtpJitter: 0,
1463
+ rtpPackets: 0,
1464
+ ssci: 0,
1465
+ framesDropped: 0,
1285
1466
  },
1286
- {
1287
- common: {
1288
- codec: 'H264',
1289
- concealedFrames: 0,
1290
- csi: [],
1291
- maxConcealRunLength: 0,
1292
- optimalBitrate: 0,
1293
- optimalFrameRate: 0,
1294
- receivedBitrate: 0.13333333333333333,
1295
- receivedFrameRate: 0,
1296
- renderedFrameRate: 0,
1297
- requestedBitrate: 0,
1298
- requestedFrameRate: 0,
1299
- rtpEndToEndLost: 0,
1300
- rtpJitter: 0,
1301
- rtpPackets: 0,
1302
- ssci: 0,
1303
- framesDropped: 0
1304
- },
1305
- h264CodecProfile: 'BP',
1306
- isActiveSpeaker: true,
1307
- optimalFrameSize: 0,
1308
- receivedFrameSize: 3600,
1309
- receivedHeight: 720,
1310
- receivedKeyFrames: 0,
1311
- receivedKeyFramesForRequest: 0,
1312
- receivedKeyFramesSourceChange: 0,
1313
- receivedKeyFramesUnknown: 0,
1314
- receivedWidth: 1280,
1315
- requestedFrameSize: 0,
1316
- requestedKeyFrames: 0
1467
+ h264CodecProfile: 'BP',
1468
+ isActiveSpeaker: true,
1469
+ optimalFrameSize: 0,
1470
+ receivedFrameSize: 3600,
1471
+ receivedHeight: 720,
1472
+ receivedKeyFrames: 0,
1473
+ receivedKeyFramesForRequest: 0,
1474
+ receivedKeyFramesSourceChange: 0,
1475
+ receivedKeyFramesUnknown: 0,
1476
+ receivedWidth: 1280,
1477
+ requestedFrameSize: 0,
1478
+ requestedKeyFrames: 0,
1479
+ },
1480
+ {
1481
+ common: {
1482
+ codec: 'H264',
1483
+ concealedFrames: 0,
1484
+ csi: [],
1485
+ maxConcealRunLength: 0,
1486
+ optimalBitrate: 0,
1487
+ optimalFrameRate: 0,
1488
+ receivedBitrate: 0.13333333333333333,
1489
+ receivedFrameRate: 0,
1490
+ renderedFrameRate: 0,
1491
+ requestedBitrate: 0,
1492
+ requestedFrameRate: 0,
1493
+ rtpEndToEndLost: 0,
1494
+ rtpJitter: 0,
1495
+ rtpPackets: 0,
1496
+ ssci: 0,
1497
+ framesDropped: 0,
1317
1498
  },
1318
- {
1319
- common: {
1320
- codec: 'H264',
1321
- concealedFrames: 0,
1322
- csi: [],
1323
- maxConcealRunLength: 0,
1324
- optimalBitrate: 0,
1325
- optimalFrameRate: 0,
1326
- receivedBitrate: 0.13333333333333333,
1327
- receivedFrameRate: 0,
1328
- renderedFrameRate: 0,
1329
- requestedBitrate: 0,
1330
- requestedFrameRate: 0,
1331
- rtpEndToEndLost: 0,
1332
- rtpJitter: 0,
1333
- rtpPackets: 0,
1334
- ssci: 0,
1335
- framesDropped: 0
1336
- },
1337
- h264CodecProfile: 'BP',
1338
- isActiveSpeaker: true,
1339
- optimalFrameSize: 0,
1340
- receivedFrameSize: 3600,
1341
- receivedHeight: 720,
1342
- receivedKeyFrames: 0,
1343
- receivedKeyFramesForRequest: 0,
1344
- receivedKeyFramesSourceChange: 0,
1345
- receivedKeyFramesUnknown: 0,
1346
- receivedWidth: 1280,
1347
- requestedFrameSize: 0,
1348
- requestedKeyFrames: 0
1349
- }
1350
- ]
1351
- );
1499
+ h264CodecProfile: 'BP',
1500
+ isActiveSpeaker: true,
1501
+ optimalFrameSize: 0,
1502
+ receivedFrameSize: 3600,
1503
+ receivedHeight: 720,
1504
+ receivedKeyFrames: 0,
1505
+ receivedKeyFramesForRequest: 0,
1506
+ receivedKeyFramesSourceChange: 0,
1507
+ receivedKeyFramesUnknown: 0,
1508
+ receivedWidth: 1280,
1509
+ requestedFrameSize: 0,
1510
+ requestedKeyFrames: 0,
1511
+ },
1512
+ {
1513
+ common: {
1514
+ codec: 'H264',
1515
+ concealedFrames: 0,
1516
+ csi: [],
1517
+ maxConcealRunLength: 0,
1518
+ optimalBitrate: 0,
1519
+ optimalFrameRate: 0,
1520
+ receivedBitrate: 0.13333333333333333,
1521
+ receivedFrameRate: 0,
1522
+ renderedFrameRate: 0,
1523
+ requestedBitrate: 0,
1524
+ requestedFrameRate: 0,
1525
+ rtpEndToEndLost: 0,
1526
+ rtpJitter: 0,
1527
+ rtpPackets: 0,
1528
+ ssci: 0,
1529
+ framesDropped: 0,
1530
+ },
1531
+ h264CodecProfile: 'BP',
1532
+ isActiveSpeaker: true,
1533
+ optimalFrameSize: 0,
1534
+ receivedFrameSize: 3600,
1535
+ receivedHeight: 720,
1536
+ receivedKeyFrames: 0,
1537
+ receivedKeyFramesForRequest: 0,
1538
+ receivedKeyFramesSourceChange: 0,
1539
+ receivedKeyFramesUnknown: 0,
1540
+ receivedWidth: 1280,
1541
+ requestedFrameSize: 0,
1542
+ requestedKeyFrames: 0,
1543
+ },
1544
+ ]);
1352
1545
  });
1353
1546
  });
1354
1547
  });