@webex/plugin-meetings 3.0.0-beta.16 → 3.0.0-beta.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 +116 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.js +23 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/index.js +226 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +43 -6
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +2 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +48 -0
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +1 -0
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +19 -11
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +3 -3
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +4 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +5 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +652 -459
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +25 -44
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +22 -57
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -0
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +28 -18
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +14 -12
- package/dist/meetings/request.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +14 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +8 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +3 -1
- package/dist/members/request.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +46 -6
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/multistreamMedia.js +4 -0
- package/dist/multistream/multistreamMedia.js.map +1 -1
- package/dist/multistream/receiveSlot.js +3 -3
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +8 -6
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +168 -63
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +63 -51
- package/dist/reachability/index.js.map +1 -1
- package/dist/reactions/constants.js +13 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +25 -12
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +17 -0
- package/dist/recording-controller/enums.js.map +1 -0
- package/dist/recording-controller/index.js +343 -0
- package/dist/recording-controller/index.js.map +1 -0
- package/dist/recording-controller/util.js +63 -0
- package/dist/recording-controller/util.js.map +1 -0
- package/dist/roap/request.js +88 -68
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +72 -47
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/index.js +3 -3
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +18 -6
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/package.json +24 -19
- package/src/breakouts/README.md +190 -0
- package/src/breakouts/breakout.ts +110 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/index.ts +225 -0
- package/src/config.ts +4 -1
- package/src/constants.ts +39 -1
- package/src/locus-info/controlsUtils.ts +2 -0
- package/src/locus-info/index.ts +59 -1
- package/src/locus-info/parser.ts +1 -0
- package/src/locus-info/selfUtils.ts +8 -0
- package/src/media/index.ts +1 -2
- package/src/media/properties.ts +6 -9
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +360 -111
- package/src/meeting/request.ts +9 -31
- package/src/meeting/request.type.ts +2 -0
- package/src/meeting/util.ts +25 -60
- package/src/meeting-info/meeting-info-v2.ts +2 -0
- package/src/meetings/index.ts +10 -5
- package/src/meetings/request.ts +1 -1
- package/src/member/index.ts +9 -0
- package/src/member/util.ts +14 -1
- package/src/members/index.ts +1 -0
- package/src/members/request.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +79 -15
- package/src/multistream/multistreamMedia.ts +4 -0
- package/src/multistream/receiveSlot.ts +17 -12
- package/src/multistream/receiveSlotManager.ts +22 -21
- package/src/multistream/remoteMedia.ts +1 -1
- package/src/multistream/remoteMediaGroup.ts +2 -2
- package/src/multistream/remoteMediaManager.ts +150 -37
- package/src/reachability/index.ts +16 -13
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.type.ts +25 -0
- package/src/reconnection-manager/index.ts +18 -9
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +315 -0
- package/src/recording-controller/util.ts +58 -0
- package/src/roap/request.ts +78 -73
- package/src/roap/turnDiscovery.ts +8 -6
- package/src/statsAnalyzer/index.ts +4 -4
- package/src/statsAnalyzer/mqaUtil.ts +6 -0
- package/test/unit/spec/breakouts/breakout.ts +119 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/index.ts +293 -0
- package/test/unit/spec/locus-info/controlsUtils.js +20 -0
- package/test/unit/spec/locus-info/index.js +103 -0
- package/test/unit/spec/locus-info/selfConstant.js +25 -0
- package/test/unit/spec/locus-info/selfUtils.js +84 -0
- package/test/unit/spec/media/index.ts +1 -1
- package/test/unit/spec/media/properties.ts +9 -9
- package/test/unit/spec/meeting/effectsState.js +5 -1
- package/test/unit/spec/meeting/in-meeting-actions.ts +5 -1
- package/test/unit/spec/meeting/index.js +241 -50
- package/test/unit/spec/meeting/request.js +17 -0
- package/test/unit/spec/meeting/utils.js +28 -122
- package/test/unit/spec/meetings/index.js +1 -0
- package/test/unit/spec/member/util.js +26 -1
- package/test/unit/spec/multistream/mediaRequestManager.ts +312 -50
- package/test/unit/spec/multistream/receiveSlot.ts +6 -6
- package/test/unit/spec/multistream/receiveSlotManager.ts +13 -13
- package/test/unit/spec/multistream/remoteMedia.ts +2 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +354 -65
- package/test/unit/spec/reachability/index.ts +58 -24
- package/test/unit/spec/reconnection-manager/index.js +42 -13
- package/test/unit/spec/recording-controller/index.js +231 -0
- package/test/unit/spec/recording-controller/util.js +102 -0
- package/test/unit/spec/roap/index.ts +2 -1
- package/test/unit/spec/roap/request.ts +114 -0
- package/test/unit/spec/roap/turnDiscovery.ts +45 -29
- package/test/unit/spec/stats-analyzer/index.js +2 -2
- package/test/utils/webex-test-users.js +1 -0
- package/tsconfig.json +6 -0
- package/dist/media/internal-media-core-wrapper.js +0 -18
- package/dist/media/internal-media-core-wrapper.js.map +0 -1
- package/src/media/internal-media-core-wrapper.ts +0 -9
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable require-jsdoc */
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {MediaType} from '@webex/internal-media-core';
|
|
5
5
|
import {
|
|
6
6
|
Configuration,
|
|
7
7
|
Event,
|
|
@@ -17,13 +17,13 @@ import {CSI, ReceiveSlotId} from '@webex/plugin-meetings/src/multistream/receive
|
|
|
17
17
|
import testUtils from '../../../utils/testUtils';
|
|
18
18
|
|
|
19
19
|
class FakeSlot extends EventEmitter {
|
|
20
|
-
public mediaType:
|
|
20
|
+
public mediaType: MediaType;
|
|
21
21
|
|
|
22
22
|
public id: string;
|
|
23
23
|
|
|
24
24
|
public csi?: number;
|
|
25
25
|
|
|
26
|
-
constructor(mediaType:
|
|
26
|
+
constructor(mediaType: MediaType, id: string) {
|
|
27
27
|
super();
|
|
28
28
|
this.mediaType = mediaType;
|
|
29
29
|
this.id = id;
|
|
@@ -37,6 +37,7 @@ class FakeSlot extends EventEmitter {
|
|
|
37
37
|
const DefaultTestConfiguration: Configuration = {
|
|
38
38
|
audio: {
|
|
39
39
|
numOfActiveSpeakerStreams: 3,
|
|
40
|
+
numOfScreenShareStreams: 1,
|
|
40
41
|
},
|
|
41
42
|
video: {
|
|
42
43
|
preferLiveVideo: true,
|
|
@@ -44,7 +45,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
44
45
|
|
|
45
46
|
layouts: {
|
|
46
47
|
AllEqual: {
|
|
47
|
-
screenShareVideo: {size: null},
|
|
48
48
|
activeSpeakerVideoPaneGroups: [
|
|
49
49
|
{
|
|
50
50
|
id: 'main',
|
|
@@ -55,7 +55,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
55
55
|
],
|
|
56
56
|
},
|
|
57
57
|
OnePlusFive: {
|
|
58
|
-
screenShareVideo: {size: null},
|
|
59
58
|
activeSpeakerVideoPaneGroups: [
|
|
60
59
|
{
|
|
61
60
|
id: 'mainBigOne',
|
|
@@ -72,7 +71,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
72
71
|
],
|
|
73
72
|
},
|
|
74
73
|
Single: {
|
|
75
|
-
screenShareVideo: {size: null},
|
|
76
74
|
activeSpeakerVideoPaneGroups: [
|
|
77
75
|
{
|
|
78
76
|
id: 'main',
|
|
@@ -83,7 +81,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
83
81
|
],
|
|
84
82
|
},
|
|
85
83
|
Stage: {
|
|
86
|
-
screenShareVideo: {size: null},
|
|
87
84
|
activeSpeakerVideoPaneGroups: [
|
|
88
85
|
{
|
|
89
86
|
id: 'thumbnails',
|
|
@@ -99,12 +96,19 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
99
96
|
{id: 'stage-4', size: 'medium', csi: undefined},
|
|
100
97
|
],
|
|
101
98
|
},
|
|
99
|
+
ScreenShareView: {
|
|
100
|
+
screenShareVideo: {size: 'medium'},
|
|
101
|
+
activeSpeakerVideoPaneGroups: [
|
|
102
|
+
{
|
|
103
|
+
id: 'thumbnails',
|
|
104
|
+
numPanes: 6,
|
|
105
|
+
size: 'thumbnail',
|
|
106
|
+
priority: 255,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
102
110
|
},
|
|
103
111
|
},
|
|
104
|
-
screenShare: {
|
|
105
|
-
audio: true,
|
|
106
|
-
video: true,
|
|
107
|
-
},
|
|
108
112
|
};
|
|
109
113
|
|
|
110
114
|
describe('RemoteMediaManager', () => {
|
|
@@ -113,18 +117,34 @@ describe('RemoteMediaManager', () => {
|
|
|
113
117
|
let fakeMediaRequestManagers;
|
|
114
118
|
let fakeAudioSlot;
|
|
115
119
|
let fakeVideoSlot;
|
|
120
|
+
let fakeScreenShareAudioSlot;
|
|
121
|
+
let fakeScreenShareVideoSlot;
|
|
116
122
|
|
|
117
123
|
beforeEach(() => {
|
|
118
|
-
fakeAudioSlot = new FakeSlot(
|
|
119
|
-
fakeVideoSlot = new FakeSlot(
|
|
124
|
+
fakeAudioSlot = new FakeSlot(MediaType.AudioMain, 'fake audio slot');
|
|
125
|
+
fakeVideoSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
126
|
+
fakeScreenShareAudioSlot = new FakeSlot(
|
|
127
|
+
MediaType.AudioSlides,
|
|
128
|
+
'fake screen share audio slot'
|
|
129
|
+
);
|
|
130
|
+
fakeScreenShareVideoSlot = new FakeSlot(
|
|
131
|
+
MediaType.VideoSlides,
|
|
132
|
+
'fake screen share video slot'
|
|
133
|
+
);
|
|
120
134
|
|
|
121
135
|
fakeReceiveSlotManager = {
|
|
122
136
|
allocateSlot: sinon.stub().callsFake((mediaType) => {
|
|
123
|
-
|
|
124
|
-
|
|
137
|
+
switch (mediaType) {
|
|
138
|
+
case MediaType.AudioMain:
|
|
139
|
+
return Promise.resolve(fakeAudioSlot);
|
|
140
|
+
case MediaType.VideoMain:
|
|
141
|
+
return Promise.resolve(fakeVideoSlot);
|
|
142
|
+
case MediaType.AudioSlides:
|
|
143
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
144
|
+
case MediaType.VideoSlides:
|
|
145
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
125
146
|
}
|
|
126
|
-
|
|
127
|
-
return Promise.resolve(fakeVideoSlot);
|
|
147
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
128
148
|
}),
|
|
129
149
|
releaseSlot: sinon.stub(),
|
|
130
150
|
};
|
|
@@ -140,6 +160,16 @@ describe('RemoteMediaManager', () => {
|
|
|
140
160
|
cancelRequest: sinon.stub(),
|
|
141
161
|
commit: sinon.stub(),
|
|
142
162
|
},
|
|
163
|
+
screenShareAudio: {
|
|
164
|
+
addRequest: sinon.stub(),
|
|
165
|
+
cancelRequest: sinon.stub(),
|
|
166
|
+
commit: sinon.stub(),
|
|
167
|
+
},
|
|
168
|
+
screenShareVideo: {
|
|
169
|
+
addRequest: sinon.stub(),
|
|
170
|
+
cancelRequest: sinon.stub(),
|
|
171
|
+
commit: sinon.stub(),
|
|
172
|
+
},
|
|
143
173
|
};
|
|
144
174
|
|
|
145
175
|
// create remote media manager with default configuration
|
|
@@ -159,6 +189,8 @@ describe('RemoteMediaManager', () => {
|
|
|
159
189
|
fakeMediaRequestManagers.video.addRequest.resetHistory();
|
|
160
190
|
fakeMediaRequestManagers.video.cancelRequest.resetHistory();
|
|
161
191
|
fakeMediaRequestManagers.video.commit.resetHistory();
|
|
192
|
+
fakeMediaRequestManagers.screenShareVideo.commit.resetHistory();
|
|
193
|
+
fakeMediaRequestManagers.screenShareAudio.commit.resetHistory();
|
|
162
194
|
};
|
|
163
195
|
|
|
164
196
|
describe('start', () => {
|
|
@@ -176,8 +208,8 @@ describe('RemoteMediaManager', () => {
|
|
|
176
208
|
await remoteMediaManager.start();
|
|
177
209
|
|
|
178
210
|
// check that the 2nd start() creates slots and media requests and is not a no-op
|
|
179
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
180
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
211
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioMain);
|
|
212
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
181
213
|
|
|
182
214
|
assert.called(fakeMediaRequestManagers.audio.addRequest);
|
|
183
215
|
assert.called(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -187,25 +219,18 @@ describe('RemoteMediaManager', () => {
|
|
|
187
219
|
let createdAudioGroup: RemoteMediaGroup | null = null;
|
|
188
220
|
|
|
189
221
|
// create a config with just audio, no video at all and no screen share
|
|
190
|
-
const config = {
|
|
222
|
+
const config: Configuration = {
|
|
191
223
|
audio: {
|
|
192
224
|
numOfActiveSpeakerStreams: 5,
|
|
225
|
+
numOfScreenShareStreams: 0,
|
|
193
226
|
},
|
|
194
227
|
video: {
|
|
195
228
|
preferLiveVideo: false,
|
|
196
229
|
initialLayoutId: 'empty',
|
|
197
230
|
layouts: {
|
|
198
|
-
empty: {
|
|
199
|
-
screenShareVideo: {
|
|
200
|
-
size: null,
|
|
201
|
-
},
|
|
202
|
-
},
|
|
231
|
+
empty: {},
|
|
203
232
|
},
|
|
204
233
|
},
|
|
205
|
-
screenShare: {
|
|
206
|
-
audio: false,
|
|
207
|
-
video: false,
|
|
208
|
-
},
|
|
209
234
|
};
|
|
210
235
|
|
|
211
236
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -223,7 +248,7 @@ describe('RemoteMediaManager', () => {
|
|
|
223
248
|
await testUtils.flushPromises();
|
|
224
249
|
|
|
225
250
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 5);
|
|
226
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
251
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioMain);
|
|
227
252
|
|
|
228
253
|
assert.isNotNull(createdAudioGroup);
|
|
229
254
|
if (createdAudioGroup) {
|
|
@@ -231,7 +256,7 @@ describe('RemoteMediaManager', () => {
|
|
|
231
256
|
assert.isTrue(
|
|
232
257
|
createdAudioGroup
|
|
233
258
|
.getRemoteMedia()
|
|
234
|
-
.every((remoteMedia) => remoteMedia.mediaType ===
|
|
259
|
+
.every((remoteMedia) => remoteMedia.mediaType === MediaType.AudioMain)
|
|
235
260
|
);
|
|
236
261
|
assert.strictEqual(createdAudioGroup.getRemoteMedia('pinned').length, 0);
|
|
237
262
|
}
|
|
@@ -255,9 +280,6 @@ describe('RemoteMediaManager', () => {
|
|
|
255
280
|
|
|
256
281
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
257
282
|
config.video.layouts.huge = {
|
|
258
|
-
screenShareVideo: {
|
|
259
|
-
size: null,
|
|
260
|
-
},
|
|
261
283
|
activeSpeakerVideoPaneGroups: [
|
|
262
284
|
{
|
|
263
285
|
id: 'big one',
|
|
@@ -267,6 +289,8 @@ describe('RemoteMediaManager', () => {
|
|
|
267
289
|
},
|
|
268
290
|
],
|
|
269
291
|
};
|
|
292
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
293
|
+
delete config.video.layouts.ScreenShareView;
|
|
270
294
|
|
|
271
295
|
remoteMediaManager = new RemoteMediaManager(
|
|
272
296
|
fakeReceiveSlotManager,
|
|
@@ -279,7 +303,7 @@ describe('RemoteMediaManager', () => {
|
|
|
279
303
|
// even though our "big one" layout is not the default one, the remote media manager should still
|
|
280
304
|
// preallocate enough video receive slots for it up front
|
|
281
305
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 99);
|
|
282
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
306
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
283
307
|
});
|
|
284
308
|
|
|
285
309
|
it('starts with the initial layout', async () => {
|
|
@@ -302,8 +326,128 @@ describe('RemoteMediaManager', () => {
|
|
|
302
326
|
receivedLayoutInfo.activeSpeakerVideoPanes.main.getRemoteMedia().length,
|
|
303
327
|
9
|
|
304
328
|
);
|
|
329
|
+
assert.isUndefined(receivedLayoutInfo.screenShareVideo); // the initial layout has no screen share
|
|
305
330
|
}
|
|
306
331
|
});
|
|
332
|
+
|
|
333
|
+
it('creates RemoteMedia for screen share audio correctly', async () => {
|
|
334
|
+
let createdAudioGroup: RemoteMediaGroup | null = null;
|
|
335
|
+
|
|
336
|
+
const NUM_STREAMS = 2;
|
|
337
|
+
|
|
338
|
+
// create a config with just screen share audio, nothing else
|
|
339
|
+
const config: Configuration = {
|
|
340
|
+
audio: {
|
|
341
|
+
numOfActiveSpeakerStreams: 0,
|
|
342
|
+
numOfScreenShareStreams: NUM_STREAMS,
|
|
343
|
+
},
|
|
344
|
+
video: {
|
|
345
|
+
preferLiveVideo: false,
|
|
346
|
+
initialLayoutId: 'empty',
|
|
347
|
+
layouts: {
|
|
348
|
+
empty: {},
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
354
|
+
fakeReceiveSlotManager,
|
|
355
|
+
fakeMediaRequestManagers,
|
|
356
|
+
config
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
remoteMediaManager.on(Event.ScreenShareAudioCreated, (audio: RemoteMediaGroup) => {
|
|
360
|
+
createdAudioGroup = audio;
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
remoteMediaManager.start();
|
|
364
|
+
|
|
365
|
+
await testUtils.flushPromises();
|
|
366
|
+
|
|
367
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, NUM_STREAMS);
|
|
368
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioSlides);
|
|
369
|
+
|
|
370
|
+
assert.isNotNull(createdAudioGroup);
|
|
371
|
+
if (createdAudioGroup) {
|
|
372
|
+
assert.strictEqual(createdAudioGroup.getRemoteMedia().length, NUM_STREAMS);
|
|
373
|
+
assert.isTrue(
|
|
374
|
+
createdAudioGroup
|
|
375
|
+
.getRemoteMedia()
|
|
376
|
+
.every((remoteMedia) => remoteMedia.mediaType === MediaType.AudioSlides)
|
|
377
|
+
);
|
|
378
|
+
assert.strictEqual(createdAudioGroup.getRemoteMedia('pinned').length, 0);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareAudio.addRequest);
|
|
382
|
+
assert.calledWith(
|
|
383
|
+
fakeMediaRequestManagers.screenShareAudio.addRequest,
|
|
384
|
+
sinon.match({
|
|
385
|
+
policyInfo: sinon.match({
|
|
386
|
+
policy: 'active-speaker',
|
|
387
|
+
priority: 255,
|
|
388
|
+
}),
|
|
389
|
+
receiveSlots: Array(NUM_STREAMS).fill(fakeScreenShareAudioSlot),
|
|
390
|
+
codecInfo: undefined,
|
|
391
|
+
})
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('creates a single receive slot for screen share video if any layout has screen share', async () => {
|
|
396
|
+
// create a config with 2 layouts that use screen share
|
|
397
|
+
const config: Configuration = {
|
|
398
|
+
audio: {
|
|
399
|
+
numOfActiveSpeakerStreams: 0,
|
|
400
|
+
numOfScreenShareStreams: 0,
|
|
401
|
+
},
|
|
402
|
+
video: {
|
|
403
|
+
preferLiveVideo: false,
|
|
404
|
+
initialLayoutId: 'first',
|
|
405
|
+
layouts: {
|
|
406
|
+
first: {
|
|
407
|
+
screenShareVideo: { size: 'small'}
|
|
408
|
+
},
|
|
409
|
+
second: {
|
|
410
|
+
screenShareVideo: { size: 'medium'}
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
417
|
+
fakeReceiveSlotManager,
|
|
418
|
+
fakeMediaRequestManagers,
|
|
419
|
+
config
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
await remoteMediaManager.start();
|
|
423
|
+
|
|
424
|
+
// even though 2 layouts use screen share, only 1 video screen share slot should be created
|
|
425
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 1);
|
|
426
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoSlides);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it('does not create any receive slot for screen share video if none of the layouts have screen share', async () => {
|
|
430
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
431
|
+
|
|
432
|
+
config.audio.numOfActiveSpeakerStreams = 0;
|
|
433
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
434
|
+
|
|
435
|
+
// delete the only layout that uses screen share
|
|
436
|
+
delete config.video.layouts.ScreenShareView;
|
|
437
|
+
|
|
438
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
439
|
+
fakeReceiveSlotManager,
|
|
440
|
+
fakeMediaRequestManagers,
|
|
441
|
+
config
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
await remoteMediaManager.start();
|
|
445
|
+
|
|
446
|
+
// we don't expect any audio and for video there should be no VideoSlides, so all the calls should be just for VideoMain
|
|
447
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
|
|
307
451
|
});
|
|
308
452
|
|
|
309
453
|
describe('constructor', () => {
|
|
@@ -325,7 +469,6 @@ describe('RemoteMediaManager', () => {
|
|
|
325
469
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
326
470
|
|
|
327
471
|
config.video.layouts.test = {
|
|
328
|
-
screenShareVideo: {size: null},
|
|
329
472
|
activeSpeakerVideoPaneGroups: [
|
|
330
473
|
{
|
|
331
474
|
id: 'someDuplicate',
|
|
@@ -361,7 +504,6 @@ describe('RemoteMediaManager', () => {
|
|
|
361
504
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
362
505
|
|
|
363
506
|
config.video.layouts.test = {
|
|
364
|
-
screenShareVideo: {size: null},
|
|
365
507
|
activeSpeakerVideoPaneGroups: [
|
|
366
508
|
{
|
|
367
509
|
id: 'group1',
|
|
@@ -397,7 +539,6 @@ describe('RemoteMediaManager', () => {
|
|
|
397
539
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
398
540
|
|
|
399
541
|
config.video.layouts.test = {
|
|
400
|
-
screenShareVideo: {size: null},
|
|
401
542
|
memberVideoPanes: [
|
|
402
543
|
{id: 'paneA', size: 'best', csi: 123},
|
|
403
544
|
{id: 'paneB', size: 'large', csi: 222},
|
|
@@ -414,6 +555,7 @@ describe('RemoteMediaManager', () => {
|
|
|
414
555
|
);
|
|
415
556
|
}, 'invalid config: duplicate member video pane id: paneB');
|
|
416
557
|
});
|
|
558
|
+
|
|
417
559
|
});
|
|
418
560
|
|
|
419
561
|
describe('stop', () => {
|
|
@@ -421,12 +563,17 @@ describe('RemoteMediaManager', () => {
|
|
|
421
563
|
let audioStopStub;
|
|
422
564
|
let videoActiveSpeakerGroupStopStub;
|
|
423
565
|
const memberVideoPaneStopStubs: any[] = [];
|
|
566
|
+
let screenShareAudioStopStub;
|
|
567
|
+
let screenShareVideoStopStub;
|
|
424
568
|
|
|
425
|
-
// change the initial layout to one that has both active speakers and
|
|
569
|
+
// change the initial layout to one that has both active speakers and receiver selected videos
|
|
426
570
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
427
571
|
|
|
428
572
|
config.video.initialLayoutId = 'Stage';
|
|
429
573
|
|
|
574
|
+
// and also modify it to have screen share so we can test that too
|
|
575
|
+
config.video.layouts['Stage'].screenShareVideo = {size: 'medium'};
|
|
576
|
+
|
|
430
577
|
remoteMediaManager = new RemoteMediaManager(
|
|
431
578
|
fakeReceiveSlotManager,
|
|
432
579
|
fakeMediaRequestManagers,
|
|
@@ -437,6 +584,10 @@ describe('RemoteMediaManager', () => {
|
|
|
437
584
|
audioStopStub = sinon.stub(audio, 'stop');
|
|
438
585
|
});
|
|
439
586
|
|
|
587
|
+
remoteMediaManager.on(Event.ScreenShareAudioCreated, (audio: RemoteMediaGroup) => {
|
|
588
|
+
screenShareAudioStopStub = sinon.stub(audio, 'stop');
|
|
589
|
+
});
|
|
590
|
+
|
|
440
591
|
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
441
592
|
// The "Stage" layout that we're using has only 1 active speaker group called "thumbnails"
|
|
442
593
|
videoActiveSpeakerGroupStopStub = sinon.stub(
|
|
@@ -447,12 +598,14 @@ describe('RemoteMediaManager', () => {
|
|
|
447
598
|
Object.values(layoutInfo.memberVideoPanes).forEach((pane) => {
|
|
448
599
|
memberVideoPaneStopStubs.push(sinon.stub(pane, 'stop'));
|
|
449
600
|
});
|
|
601
|
+
|
|
602
|
+
screenShareVideoStopStub = sinon.stub(layoutInfo.screenShareVideo, 'stop');
|
|
450
603
|
});
|
|
451
604
|
|
|
452
605
|
await remoteMediaManager.start();
|
|
453
606
|
|
|
454
|
-
// we're using the default config that requires 3 main audio slots
|
|
455
|
-
assert.callCount(fakeReceiveSlotManager.allocateSlot,
|
|
607
|
+
// we're using the default config that requires 3 main audio slots, 10 video slots (for Stage2x2With6ThumbnailsLayout), 1 screenshare audio, 1 screenshare video
|
|
608
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 15);
|
|
456
609
|
|
|
457
610
|
// our layout has 4 member video panes, we should have a stub for each of these panes' stop methods
|
|
458
611
|
assert.strictEqual(memberVideoPaneStopStubs.length, 4);
|
|
@@ -462,16 +615,20 @@ describe('RemoteMediaManager', () => {
|
|
|
462
615
|
remoteMediaManager.stop();
|
|
463
616
|
|
|
464
617
|
// check that all slots have been released
|
|
465
|
-
assert.callCount(fakeReceiveSlotManager.releaseSlot,
|
|
618
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 15);
|
|
466
619
|
|
|
467
620
|
// and that all RemoteMedia and RemoteMediaGroups have been stopped
|
|
468
621
|
assert.calledOnce(audioStopStub);
|
|
469
622
|
assert.calledWith(audioStopStub, true);
|
|
623
|
+
assert.calledOnce(screenShareAudioStopStub);
|
|
624
|
+
assert.calledWith(screenShareAudioStopStub, true);
|
|
470
625
|
assert.calledOnce(videoActiveSpeakerGroupStopStub);
|
|
471
626
|
memberVideoPaneStopStubs.forEach((stub) => {
|
|
472
627
|
assert.calledOnce(stub);
|
|
473
628
|
});
|
|
474
629
|
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
630
|
+
assert.calledOnce(screenShareVideoStopStub);
|
|
631
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.commit);
|
|
475
632
|
});
|
|
476
633
|
|
|
477
634
|
it('can be called multiple times', async () => {
|
|
@@ -511,7 +668,7 @@ describe('RemoteMediaManager', () => {
|
|
|
511
668
|
await remoteMediaManager.setLayout('Stage');
|
|
512
669
|
|
|
513
670
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 9);
|
|
514
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
671
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
515
672
|
});
|
|
516
673
|
|
|
517
674
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
@@ -538,7 +695,7 @@ describe('RemoteMediaManager', () => {
|
|
|
538
695
|
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
539
696
|
const slot = call.args[0];
|
|
540
697
|
|
|
541
|
-
assert.strictEqual(slot.mediaType,
|
|
698
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
542
699
|
});
|
|
543
700
|
});
|
|
544
701
|
|
|
@@ -600,6 +757,104 @@ describe('RemoteMediaManager', () => {
|
|
|
600
757
|
});
|
|
601
758
|
});
|
|
602
759
|
|
|
760
|
+
it('emits Event.VideoLayoutChanged with correct data', async () => {
|
|
761
|
+
// setup the initial layout to be empty and a testLayout that has screen share, active speaker groups and member video panes
|
|
762
|
+
const config: Configuration = {
|
|
763
|
+
audio: {
|
|
764
|
+
numOfActiveSpeakerStreams: 0,
|
|
765
|
+
numOfScreenShareStreams: 0,
|
|
766
|
+
},
|
|
767
|
+
video: {
|
|
768
|
+
preferLiveVideo: true,
|
|
769
|
+
initialLayoutId: 'empty',
|
|
770
|
+
layouts: {
|
|
771
|
+
empty: {},
|
|
772
|
+
testLayout: {
|
|
773
|
+
screenShareVideo: {size: 'very small'},
|
|
774
|
+
activeSpeakerVideoPaneGroups: [
|
|
775
|
+
{
|
|
776
|
+
id: 'big',
|
|
777
|
+
numPanes: 10,
|
|
778
|
+
priority: 255,
|
|
779
|
+
size: 'large',
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
id: 'small',
|
|
783
|
+
numPanes: 3,
|
|
784
|
+
priority: 254,
|
|
785
|
+
size: 'medium',
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
memberVideoPanes: [
|
|
789
|
+
{id: 'pane 1', size: 'best', csi: 555},
|
|
790
|
+
{id: 'pane 2', size: 'best', csi: undefined},
|
|
791
|
+
],
|
|
792
|
+
},
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
798
|
+
fakeReceiveSlotManager,
|
|
799
|
+
fakeMediaRequestManagers,
|
|
800
|
+
config
|
|
801
|
+
);
|
|
802
|
+
|
|
803
|
+
await remoteMediaManager.start();
|
|
804
|
+
|
|
805
|
+
resetHistory();
|
|
806
|
+
|
|
807
|
+
let receivedLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
808
|
+
|
|
809
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo) => {
|
|
810
|
+
receivedLayoutInfo = layoutInfo;
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
// switch to the test layout
|
|
814
|
+
await remoteMediaManager.setLayout('testLayout');
|
|
815
|
+
|
|
816
|
+
assert.isNotNull(receivedLayoutInfo);
|
|
817
|
+
|
|
818
|
+
if (receivedLayoutInfo) {
|
|
819
|
+
assert.strictEqual(receivedLayoutInfo.layoutId, 'testLayout');
|
|
820
|
+
|
|
821
|
+
// check screen share video
|
|
822
|
+
assert.isTrue(!!receivedLayoutInfo.screenShareVideo);
|
|
823
|
+
assert.strictEqual(receivedLayoutInfo.screenShareVideo.mediaType, MediaType.VideoSlides);
|
|
824
|
+
|
|
825
|
+
// check member videos
|
|
826
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.memberVideoPanes).length, 2);
|
|
827
|
+
Object.values(receivedLayoutInfo.memberVideoPanes).forEach((remoteMedia) =>
|
|
828
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
// check the 2 active speaker groups
|
|
832
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.activeSpeakerVideoPanes).length, 2);
|
|
833
|
+
|
|
834
|
+
// "big" group
|
|
835
|
+
assert.strictEqual(
|
|
836
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big.getRemoteMedia().length,
|
|
837
|
+
10
|
|
838
|
+
);
|
|
839
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big
|
|
840
|
+
.getRemoteMedia()
|
|
841
|
+
.forEach((remoteMedia) =>
|
|
842
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
843
|
+
);
|
|
844
|
+
|
|
845
|
+
// "small" group
|
|
846
|
+
assert.strictEqual(
|
|
847
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small.getRemoteMedia().length,
|
|
848
|
+
3
|
|
849
|
+
);
|
|
850
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small
|
|
851
|
+
.getRemoteMedia()
|
|
852
|
+
.forEach((remoteMedia) =>
|
|
853
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
|
|
603
858
|
describe('switching between different receiver selected layouts', () => {
|
|
604
859
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
605
860
|
let slotCounter: number;
|
|
@@ -620,7 +875,7 @@ describe('RemoteMediaManager', () => {
|
|
|
620
875
|
slotCounter += 1;
|
|
621
876
|
const newSlotId = `fake video slot ${slotCounter}`;
|
|
622
877
|
|
|
623
|
-
fakeSlots[newSlotId] = new FakeSlot(
|
|
878
|
+
fakeSlots[newSlotId] = new FakeSlot(MediaType.VideoMain, newSlotId);
|
|
624
879
|
return fakeSlots[newSlotId];
|
|
625
880
|
});
|
|
626
881
|
|
|
@@ -652,12 +907,12 @@ describe('RemoteMediaManager', () => {
|
|
|
652
907
|
// This test starts with a layout that has 5 receiver selected video slots
|
|
653
908
|
// and switches to a different layout that has fewer slots, but 2 of them match CSIs
|
|
654
909
|
// from the initial layout. We want to verify that these 2 slots get re-used correctly.
|
|
910
|
+
// There are no screen share or audio slots being used in this test.
|
|
911
|
+
delete config.video.layouts.ScreenShareView;
|
|
655
912
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
656
|
-
config.
|
|
657
|
-
config.screenShare.video = false;
|
|
913
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
658
914
|
config.video.initialLayoutId = 'biggerLayout';
|
|
659
915
|
config.video.layouts['biggerLayout'] = {
|
|
660
|
-
screenShareVideo: {size: null},
|
|
661
916
|
memberVideoPanes: [
|
|
662
917
|
{id: '1', size: 'best', csi: 100},
|
|
663
918
|
{id: '2', size: 'best', csi: 200},
|
|
@@ -667,7 +922,6 @@ describe('RemoteMediaManager', () => {
|
|
|
667
922
|
],
|
|
668
923
|
};
|
|
669
924
|
config.video.layouts['smallerLayout'] = {
|
|
670
|
-
screenShareVideo: {size: null},
|
|
671
925
|
memberVideoPanes: [
|
|
672
926
|
{id: '1', size: 'medium', csi: 200}, // this csi matches pane '2' from biggerLayout
|
|
673
927
|
{id: '2', size: 'medium', csi: 123},
|
|
@@ -717,16 +971,15 @@ describe('RemoteMediaManager', () => {
|
|
|
717
971
|
// This test starts with a layout that has video slot with a specific CSI
|
|
718
972
|
// and switches to a different layout that 2 panes with that same CSI.
|
|
719
973
|
// We want to verify that the slot gets reused, but also that a 2nd slot is allocated.
|
|
974
|
+
// There are no screen share or audio slots being used in this test.
|
|
975
|
+
delete config.video.layouts.ScreenShareView;
|
|
720
976
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
721
|
-
config.
|
|
722
|
-
config.screenShare.video = false;
|
|
977
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
723
978
|
config.video.initialLayoutId = 'initialEmptyLayout';
|
|
724
979
|
config.video.layouts['initialEmptyLayout'] = {
|
|
725
|
-
screenShareVideo: {size: null},
|
|
726
980
|
memberVideoPanes: [{id: '2', size: 'medium', csi: 456}],
|
|
727
981
|
};
|
|
728
982
|
config.video.layouts['layoutWithDuplicateCSIs'] = {
|
|
729
|
-
screenShareVideo: {size: null},
|
|
730
983
|
memberVideoPanes: [
|
|
731
984
|
{id: '1', size: 'medium', csi: 123},
|
|
732
985
|
{id: '2', size: 'medium', csi: 456},
|
|
@@ -899,16 +1152,18 @@ describe('RemoteMediaManager', () => {
|
|
|
899
1152
|
});
|
|
900
1153
|
|
|
901
1154
|
it('cancels all media requests for the previous layout when switching to a new one', async () => {
|
|
1155
|
+
// setup the initial layout to have screen share, active speaker groups and member video panes
|
|
902
1156
|
const config: Configuration = {
|
|
903
1157
|
audio: {
|
|
904
1158
|
numOfActiveSpeakerStreams: 0,
|
|
1159
|
+
numOfScreenShareStreams: 0,
|
|
905
1160
|
},
|
|
906
1161
|
video: {
|
|
907
1162
|
preferLiveVideo: true,
|
|
908
1163
|
initialLayoutId: 'initial',
|
|
909
1164
|
layouts: {
|
|
910
1165
|
initial: {
|
|
911
|
-
screenShareVideo: {size:
|
|
1166
|
+
screenShareVideo: {size: 'best'},
|
|
912
1167
|
activeSpeakerVideoPaneGroups: [
|
|
913
1168
|
{
|
|
914
1169
|
id: 'big',
|
|
@@ -928,15 +1183,9 @@ describe('RemoteMediaManager', () => {
|
|
|
928
1183
|
{id: 'pane 2', size: 'best', csi: 234},
|
|
929
1184
|
],
|
|
930
1185
|
},
|
|
931
|
-
other: {
|
|
932
|
-
screenShareVideo: {size: null},
|
|
933
|
-
},
|
|
1186
|
+
other: {},
|
|
934
1187
|
},
|
|
935
1188
|
},
|
|
936
|
-
screenShare: {
|
|
937
|
-
audio: false,
|
|
938
|
-
video: false,
|
|
939
|
-
},
|
|
940
1189
|
};
|
|
941
1190
|
|
|
942
1191
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -959,9 +1208,15 @@ describe('RemoteMediaManager', () => {
|
|
|
959
1208
|
|
|
960
1209
|
return `receiver selected request ${receiverSelectedRequestCounter}`;
|
|
961
1210
|
});
|
|
1211
|
+
// setup the mock for screen share addRequest - this one should be called just once
|
|
1212
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest.callsFake(() => {
|
|
1213
|
+
return 'video screen share request id';
|
|
1214
|
+
});
|
|
962
1215
|
|
|
963
1216
|
await remoteMediaManager.start();
|
|
964
1217
|
|
|
1218
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.addRequest);
|
|
1219
|
+
|
|
965
1220
|
resetHistory();
|
|
966
1221
|
|
|
967
1222
|
// switch to "other" layout
|
|
@@ -979,11 +1234,45 @@ describe('RemoteMediaManager', () => {
|
|
|
979
1234
|
fakeMediaRequestManagers.video.cancelRequest,
|
|
980
1235
|
'receiver selected request 2'
|
|
981
1236
|
);
|
|
1237
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.cancelRequest);
|
|
1238
|
+
assert.calledWith(
|
|
1239
|
+
fakeMediaRequestManagers.screenShareVideo.cancelRequest,
|
|
1240
|
+
'video screen share request id'
|
|
1241
|
+
);
|
|
982
1242
|
|
|
983
1243
|
// new layout has no videos, so no new requests should be sent out
|
|
984
|
-
// check that 2 correct active speaker media requests were sent out
|
|
985
1244
|
assert.callCount(fakeMediaRequestManagers.video.addRequest, 0);
|
|
986
1245
|
});
|
|
1246
|
+
|
|
1247
|
+
it('sends media request for screen share if layout contains screen share', async () => {
|
|
1248
|
+
const allEqualMediaRequestId = 'fake request id';
|
|
1249
|
+
|
|
1250
|
+
fakeMediaRequestManagers.video.addRequest.returns(allEqualMediaRequestId);
|
|
1251
|
+
|
|
1252
|
+
await remoteMediaManager.start();
|
|
1253
|
+
|
|
1254
|
+
resetHistory();
|
|
1255
|
+
|
|
1256
|
+
// switch to a layout that contains a screen share video pane
|
|
1257
|
+
await remoteMediaManager.setLayout('ScreenShareView');
|
|
1258
|
+
|
|
1259
|
+
// check that a correct active speaker media request for screen share has been sent out
|
|
1260
|
+
assert.callCount(fakeMediaRequestManagers.screenShareVideo.addRequest, 1);
|
|
1261
|
+
assert.calledWith(
|
|
1262
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest,
|
|
1263
|
+
sinon.match({
|
|
1264
|
+
policyInfo: sinon.match({
|
|
1265
|
+
policy: 'active-speaker',
|
|
1266
|
+
priority: 255,
|
|
1267
|
+
}),
|
|
1268
|
+
receiveSlots: [fakeScreenShareVideoSlot],
|
|
1269
|
+
codecInfo: sinon.match({
|
|
1270
|
+
codec: 'h264',
|
|
1271
|
+
maxFs: 3600,
|
|
1272
|
+
}),
|
|
1273
|
+
})
|
|
1274
|
+
);
|
|
1275
|
+
});
|
|
987
1276
|
});
|
|
988
1277
|
});
|
|
989
1278
|
|
|
@@ -1123,7 +1412,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1123
1412
|
|
|
1124
1413
|
// new slot should be allocated
|
|
1125
1414
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1126
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1415
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1127
1416
|
|
|
1128
1417
|
// and a media request sent out
|
|
1129
1418
|
assert.calledOnce(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1152,7 +1441,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1152
1441
|
|
|
1153
1442
|
// new slot should be allocated
|
|
1154
1443
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1155
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1444
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1156
1445
|
|
|
1157
1446
|
// but no media requests sent out
|
|
1158
1447
|
assert.notCalled(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1181,7 +1470,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1181
1470
|
await remoteMediaManager.start();
|
|
1182
1471
|
await remoteMediaManager.setLayout('Stage');
|
|
1183
1472
|
|
|
1184
|
-
const fakeNewSlot = new FakeSlot(
|
|
1473
|
+
const fakeNewSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
1185
1474
|
const fakeRequestId = 'fake request id';
|
|
1186
1475
|
|
|
1187
1476
|
fakeReceiveSlotManager.allocateSlot.resolves(fakeNewSlot);
|