@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.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +4 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +27 -8
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.d.ts +1 -1
- package/dist/meetings/index.js +6 -20
- package/dist/meetings/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +22 -26
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/statsAnalyzer/index.d.ts +5 -1
- package/dist/statsAnalyzer/index.js +75 -88
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -23
- package/src/constants.ts +1 -0
- package/src/locus-info/index.ts +4 -1
- package/src/meeting/index.ts +25 -1
- package/src/meetings/index.ts +10 -23
- package/src/reconnection-manager/index.ts +11 -13
- package/src/statsAnalyzer/index.ts +131 -153
- package/test/integration/spec/journey.js +2 -2
- package/test/integration/spec/space-meeting.js +1 -1
- package/test/unit/spec/locus-info/index.js +13 -6
- package/test/unit/spec/meeting/index.js +49 -1
- package/test/unit/spec/meetings/index.js +21 -0
- package/test/unit/spec/metrics/index.js +1 -2
- package/test/unit/spec/reconnection-manager/index.js +1 -11
- 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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
70
|
-
|
|
71
|
-
statsAnalyzer.processOutboundRTPResult(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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(
|
|
97
|
-
|
|
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({
|
|
103
|
-
|
|
104
|
-
statsAnalyzer.processInboundRTPResult(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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({
|
|
152
|
-
|
|
153
|
-
statsAnalyzer.parseAudioSource(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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({
|
|
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.
|
|
435
|
-
receivers: [fakeStats.
|
|
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, () =>
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
901
|
-
await startStatsAnalyzer(
|
|
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(
|
|
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
|
|
910
|
-
await startStatsAnalyzer(
|
|
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.
|
|
1071
|
+
fakeStats.share.senders[0].report[0].packetsSent += 5;
|
|
913
1072
|
await progressTime();
|
|
914
1073
|
|
|
915
|
-
assert(
|
|
1074
|
+
assert(
|
|
1075
|
+
loggerSpy.neverCalledWith(
|
|
1076
|
+
'StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent'
|
|
1077
|
+
)
|
|
1078
|
+
);
|
|
916
1079
|
});
|
|
917
1080
|
|
|
918
|
-
|
|
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:
|
|
1106
|
+
sourceState: 'live',
|
|
921
1107
|
csi: 2,
|
|
922
|
-
id:
|
|
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(
|
|
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
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
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(
|
|
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
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
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: [
|
|
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
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
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
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
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
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
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
|
});
|