@webex/plugin-meetings 3.0.0-beta.1 → 3.0.0-beta.2
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/common/errors/webex-errors.js +5 -29
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/constants.js +15 -74
- package/dist/constants.js.map +1 -1
- package/dist/media/index.js +68 -213
- package/dist/media/index.js.map +1 -1
- package/dist/media/internal-media-core-wrapper.js +22 -0
- package/dist/media/internal-media-core-wrapper.js.map +1 -0
- package/dist/media/properties.js +20 -25
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +0 -27
- package/dist/media/util.js.map +1 -1
- package/dist/meeting/index.js +694 -432
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +1 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +3 -44
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +64 -5
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +24 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/members/index.js +68 -0
- package/dist/members/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +132 -0
- package/dist/multistream/mediaRequestManager.js.map +1 -0
- package/dist/multistream/multistreamMedia.js +116 -0
- package/dist/multistream/multistreamMedia.js.map +1 -0
- package/dist/multistream/receiveSlot.js +209 -0
- package/dist/multistream/receiveSlot.js.map +1 -0
- package/dist/multistream/receiveSlotManager.js +195 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -0
- package/dist/multistream/remoteMedia.js +284 -0
- package/dist/multistream/remoteMedia.js.map +1 -0
- package/dist/multistream/remoteMediaGroup.js +243 -0
- package/dist/multistream/remoteMediaGroup.js.map +1 -0
- package/dist/multistream/remoteMediaManager.js +1113 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -0
- package/dist/reconnection-manager/index.js +109 -130
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +57 -240
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +2 -114
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +11 -5
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/global.js +2 -0
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +39 -36
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/package.json +20 -19
- package/src/common/errors/webex-errors.js +0 -18
- package/src/constants.ts +139 -180
- package/src/media/index.js +60 -194
- package/src/media/internal-media-core-wrapper.ts +9 -0
- package/src/media/properties.js +19 -25
- package/src/media/util.js +0 -22
- package/src/meeting/index.js +565 -320
- package/src/meeting/request.js +1 -0
- package/src/meeting/util.js +3 -46
- package/src/meetings/index.js +30 -1
- package/src/meetings/util.js +23 -2
- package/src/members/index.js +48 -0
- package/src/multistream/mediaRequestManager.ts +164 -0
- package/src/multistream/multistreamMedia.ts +92 -0
- package/src/multistream/receiveSlot.ts +141 -0
- package/src/multistream/receiveSlotManager.ts +142 -0
- package/src/multistream/remoteMedia.ts +219 -0
- package/src/multistream/remoteMediaGroup.ts +224 -0
- package/src/multistream/remoteMediaManager.ts +911 -0
- package/src/reconnection-manager/index.js +40 -53
- package/src/roap/index.js +47 -207
- package/src/roap/request.js +1 -72
- package/src/roap/turnDiscovery.ts +12 -6
- package/src/statsAnalyzer/global.js +2 -0
- package/src/statsAnalyzer/index.js +32 -46
- package/test/integration/spec/journey.js +1 -1
- package/test/unit/spec/media/index.ts +223 -0
- package/test/unit/spec/media/properties.ts +73 -82
- package/test/unit/spec/meeting/effectsState.js +1 -3
- package/test/unit/spec/meeting/index.js +420 -228
- package/test/unit/spec/meeting/muteState.js +7 -0
- package/test/unit/spec/meeting/utils.js +61 -2
- package/test/unit/spec/meetings/index.js +0 -4
- package/test/unit/spec/members/index.js +164 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +511 -0
- package/test/unit/spec/multistream/receiveSlot.ts +104 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +173 -0
- package/test/unit/spec/multistream/remoteMedia.ts +217 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +396 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1251 -0
- package/test/unit/spec/roap/index.ts +63 -35
- package/test/unit/spec/stats-analyzer/index.js +19 -22
- package/dist/peer-connection-manager/index.js +0 -794
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/roap/collection.js +0 -73
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.js +0 -337
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/state.js +0 -164
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/util.js +0 -102
- package/dist/roap/util.js.map +0 -1
- package/src/peer-connection-manager/index.js +0 -723
- package/src/roap/collection.js +0 -63
- package/src/roap/handler.js +0 -252
- package/src/roap/state.js +0 -149
- package/src/roap/util.js +0 -93
- package/test/unit/spec/peerconnection-manager/index.js +0 -188
- package/test/unit/spec/peerconnection-manager/utils.js +0 -48
- package/test/unit/spec/roap/util.js +0 -30
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
|
|
3
|
+
import {MediaConnection as MC} from '@webex/internal-media-core';
|
|
4
|
+
import {RemoteMediaGroup} from '@webex/plugin-meetings/src/multistream/remoteMediaGroup';
|
|
5
|
+
import {RemoteMedia} from '@webex/plugin-meetings/src/multistream/remoteMedia';
|
|
6
|
+
import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
|
|
7
|
+
import sinon from 'sinon';
|
|
8
|
+
import {assert} from '@webex/test-helper-chai';
|
|
9
|
+
|
|
10
|
+
class FakeSlot extends EventEmitter {
|
|
11
|
+
public mediaType: MC.MediaType;
|
|
12
|
+
|
|
13
|
+
public id: string;
|
|
14
|
+
|
|
15
|
+
constructor(mediaType: MC.MediaType, id: string) {
|
|
16
|
+
super();
|
|
17
|
+
this.mediaType = mediaType;
|
|
18
|
+
this.id = id;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('RemoteMediaGroup', () => {
|
|
23
|
+
const NUM_SLOTS = 10;
|
|
24
|
+
|
|
25
|
+
let fakeMediaRequestManager;
|
|
26
|
+
let fakeReceiveSlots;
|
|
27
|
+
|
|
28
|
+
let activeSpeakerRequestCounter;
|
|
29
|
+
let receiverSelectedRequestCounter;
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
activeSpeakerRequestCounter = 0;
|
|
33
|
+
receiverSelectedRequestCounter = 0;
|
|
34
|
+
|
|
35
|
+
fakeMediaRequestManager = {
|
|
36
|
+
addRequest: sinon.stub().callsFake((mediaRequest) => {
|
|
37
|
+
if (mediaRequest.policyInfo.policy === 'active-speaker') {
|
|
38
|
+
activeSpeakerRequestCounter += 1;
|
|
39
|
+
|
|
40
|
+
return `fake active speaker request ${activeSpeakerRequestCounter}`;
|
|
41
|
+
}
|
|
42
|
+
receiverSelectedRequestCounter += 1;
|
|
43
|
+
|
|
44
|
+
return `fake receiver selected request ${receiverSelectedRequestCounter}`;
|
|
45
|
+
}),
|
|
46
|
+
cancelRequest: sinon.stub(),
|
|
47
|
+
commit: sinon.stub(),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
fakeReceiveSlots = Array(NUM_SLOTS)
|
|
51
|
+
.fill(null)
|
|
52
|
+
.map((_, index) => new FakeSlot(MC.MediaType.VideoMain, `fake receive slot ${index}`));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const getLastActiveSpeakerRequestId = () =>
|
|
56
|
+
`fake active speaker request ${activeSpeakerRequestCounter}`;
|
|
57
|
+
|
|
58
|
+
const resetHistory = () => {
|
|
59
|
+
fakeMediaRequestManager.addRequest.resetHistory();
|
|
60
|
+
fakeMediaRequestManager.cancelRequest.resetHistory();
|
|
61
|
+
fakeMediaRequestManager.commit.resetHistory();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
describe('constructor', () => {
|
|
65
|
+
it('creates a list or RemoteMedia objects and sends the active speaker media request', () => {
|
|
66
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 211, true, {
|
|
67
|
+
resolution: 'medium',
|
|
68
|
+
preferLiveVideo: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
|
|
72
|
+
assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
|
|
73
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
|
|
74
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
|
|
75
|
+
|
|
76
|
+
assert.strictEqual(
|
|
77
|
+
group.getRemoteMedia('all').every((item) => item instanceof RemoteMedia),
|
|
78
|
+
true
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
assert.calledOnce(fakeMediaRequestManager.addRequest);
|
|
82
|
+
assert.calledWith(
|
|
83
|
+
fakeMediaRequestManager.addRequest,
|
|
84
|
+
sinon.match({
|
|
85
|
+
policyInfo: sinon.match({
|
|
86
|
+
policy: 'active-speaker',
|
|
87
|
+
priority: 211,
|
|
88
|
+
}),
|
|
89
|
+
receiveSlots: fakeReceiveSlots,
|
|
90
|
+
codecInfo: sinon.match({
|
|
91
|
+
codec: 'h264',
|
|
92
|
+
maxFs: 3600,
|
|
93
|
+
}),
|
|
94
|
+
}),
|
|
95
|
+
true
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('pinning', () => {
|
|
101
|
+
it('works as expected', () => {
|
|
102
|
+
const PINNED_INDEX = 2;
|
|
103
|
+
const PINNED_INDEX2 = 0;
|
|
104
|
+
const CSI = 11111;
|
|
105
|
+
const CSI2 = 12345;
|
|
106
|
+
|
|
107
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
|
|
108
|
+
resolution: 'medium',
|
|
109
|
+
preferLiveVideo: true,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// initially nothing should be pinned
|
|
113
|
+
assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
|
|
114
|
+
assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
|
|
115
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
|
|
116
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
|
|
117
|
+
|
|
118
|
+
// take one instance of remote media from the group
|
|
119
|
+
const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
|
|
120
|
+
|
|
121
|
+
resetHistory();
|
|
122
|
+
|
|
123
|
+
// pin it
|
|
124
|
+
group.pin(remoteMedia, CSI);
|
|
125
|
+
|
|
126
|
+
assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
|
|
127
|
+
assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
|
|
128
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
|
|
129
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
|
|
130
|
+
|
|
131
|
+
assert.strictEqual(group.isPinned(remoteMedia), true);
|
|
132
|
+
|
|
133
|
+
// now check that correct media requests were sent...
|
|
134
|
+
|
|
135
|
+
const expectedReceiverSelectedSlots = [fakeReceiveSlots[PINNED_INDEX]];
|
|
136
|
+
const expectedActiveSpeakerReceiveSlots = fakeReceiveSlots.filter(
|
|
137
|
+
(_, idx) => idx !== PINNED_INDEX
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// the previous active speaker media request for the group should have been cancelled
|
|
141
|
+
assert.calledOnce(fakeMediaRequestManager.cancelRequest);
|
|
142
|
+
assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake active speaker request 1');
|
|
143
|
+
// a new one should be sent for active speaker and for receiver selected
|
|
144
|
+
assert.calledTwice(fakeMediaRequestManager.addRequest);
|
|
145
|
+
assert.calledWith(
|
|
146
|
+
fakeMediaRequestManager.addRequest,
|
|
147
|
+
sinon.match({
|
|
148
|
+
policyInfo: sinon.match({
|
|
149
|
+
policy: 'active-speaker',
|
|
150
|
+
priority: 255,
|
|
151
|
+
}),
|
|
152
|
+
receiveSlots: expectedActiveSpeakerReceiveSlots,
|
|
153
|
+
codecInfo: sinon.match({
|
|
154
|
+
codec: 'h264',
|
|
155
|
+
maxFs: 3600,
|
|
156
|
+
}),
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
assert.calledWith(
|
|
160
|
+
fakeMediaRequestManager.addRequest,
|
|
161
|
+
sinon.match({
|
|
162
|
+
policyInfo: sinon.match({
|
|
163
|
+
policy: 'receiver-selected',
|
|
164
|
+
csi: CSI,
|
|
165
|
+
}),
|
|
166
|
+
receiveSlots: expectedReceiverSelectedSlots,
|
|
167
|
+
codecInfo: sinon.match({
|
|
168
|
+
codec: 'h264',
|
|
169
|
+
maxFs: 3600,
|
|
170
|
+
}),
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
resetHistory();
|
|
175
|
+
|
|
176
|
+
// pin another video
|
|
177
|
+
const remoteMedia2 = group.getRemoteMedia('all')[PINNED_INDEX2];
|
|
178
|
+
|
|
179
|
+
group.pin(remoteMedia2, CSI2);
|
|
180
|
+
|
|
181
|
+
assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
|
|
182
|
+
assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
|
|
183
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 2);
|
|
184
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 2);
|
|
185
|
+
|
|
186
|
+
assert.strictEqual(group.isPinned(remoteMedia2), true);
|
|
187
|
+
|
|
188
|
+
// now check that correct media requests were sent...
|
|
189
|
+
const expectedReceiverSelectedSlots2 = [fakeReceiveSlots[PINNED_INDEX2]];
|
|
190
|
+
const expectedActiveSpeakerReceiveSlots2 = fakeReceiveSlots.filter(
|
|
191
|
+
(_, idx) => idx !== PINNED_INDEX && idx !== PINNED_INDEX2
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// the previous active speaker media request for the group should have been cancelled
|
|
195
|
+
assert.calledOnce(fakeMediaRequestManager.cancelRequest);
|
|
196
|
+
assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake active speaker request 2');
|
|
197
|
+
// a new one should be sent for active speaker and for receiver selected
|
|
198
|
+
assert.calledTwice(fakeMediaRequestManager.addRequest);
|
|
199
|
+
assert.calledWith(
|
|
200
|
+
fakeMediaRequestManager.addRequest,
|
|
201
|
+
sinon.match({
|
|
202
|
+
policyInfo: sinon.match({
|
|
203
|
+
policy: 'active-speaker',
|
|
204
|
+
priority: 255,
|
|
205
|
+
}),
|
|
206
|
+
receiveSlots: expectedActiveSpeakerReceiveSlots2,
|
|
207
|
+
codecInfo: sinon.match({
|
|
208
|
+
codec: 'h264',
|
|
209
|
+
maxFs: 3600,
|
|
210
|
+
}),
|
|
211
|
+
})
|
|
212
|
+
);
|
|
213
|
+
assert.calledWith(
|
|
214
|
+
fakeMediaRequestManager.addRequest,
|
|
215
|
+
sinon.match({
|
|
216
|
+
policyInfo: sinon.match({
|
|
217
|
+
policy: 'receiver-selected',
|
|
218
|
+
csi: CSI2,
|
|
219
|
+
}),
|
|
220
|
+
receiveSlots: expectedReceiverSelectedSlots2,
|
|
221
|
+
codecInfo: sinon.match({
|
|
222
|
+
codec: 'h264',
|
|
223
|
+
maxFs: 3600,
|
|
224
|
+
}),
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
resetHistory();
|
|
229
|
+
|
|
230
|
+
// now unpin the video pane that was first pinned
|
|
231
|
+
group.unpin(remoteMedia);
|
|
232
|
+
|
|
233
|
+
// one pane should still remain pinned
|
|
234
|
+
assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
|
|
235
|
+
assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
|
|
236
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
|
|
237
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
|
|
238
|
+
|
|
239
|
+
assert.strictEqual(group.isPinned(remoteMedia), false);
|
|
240
|
+
|
|
241
|
+
// the previous requests for the group and the individual remote media should have been cancelled
|
|
242
|
+
assert.calledTwice(fakeMediaRequestManager.cancelRequest);
|
|
243
|
+
assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake active speaker request 3');
|
|
244
|
+
assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
|
|
245
|
+
|
|
246
|
+
// a new one should be sent for active speaker
|
|
247
|
+
assert.calledOnce(fakeMediaRequestManager.addRequest);
|
|
248
|
+
assert.calledWith(
|
|
249
|
+
fakeMediaRequestManager.addRequest,
|
|
250
|
+
sinon.match({
|
|
251
|
+
policyInfo: sinon.match({
|
|
252
|
+
policy: 'active-speaker',
|
|
253
|
+
priority: 255,
|
|
254
|
+
}),
|
|
255
|
+
codecInfo: sinon.match({
|
|
256
|
+
codec: 'h264',
|
|
257
|
+
maxFs: 3600,
|
|
258
|
+
}),
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
// checking that the receiveSlots array passed in to addRequest() has the right length without
|
|
262
|
+
// being strict on the order of elements in it:
|
|
263
|
+
const receiveSlotsArg = fakeMediaRequestManager.addRequest.getCall(0).args[0].receiveSlots;
|
|
264
|
+
|
|
265
|
+
assert.strictEqual(receiveSlotsArg.length, fakeReceiveSlots.length - 1);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('works as expected when pin() is called on already pinned RemoteMedia', () => {
|
|
269
|
+
const PINNED_INDEX = 4;
|
|
270
|
+
|
|
271
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
|
|
272
|
+
resolution: 'medium',
|
|
273
|
+
preferLiveVideo: true,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// take one instance of remote media from the group
|
|
277
|
+
const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
|
|
278
|
+
|
|
279
|
+
resetHistory();
|
|
280
|
+
|
|
281
|
+
// pin it
|
|
282
|
+
group.pin(remoteMedia, 1234);
|
|
283
|
+
|
|
284
|
+
resetHistory();
|
|
285
|
+
// normally this would result in the underlying receive slot csi to be updated, because we're using fake
|
|
286
|
+
// receive slots, we have to do that manually:
|
|
287
|
+
fakeReceiveSlots[PINNED_INDEX].csi = 1234;
|
|
288
|
+
|
|
289
|
+
// pin again to same CSI
|
|
290
|
+
group.pin(remoteMedia, 1234);
|
|
291
|
+
|
|
292
|
+
assert.notCalled(fakeMediaRequestManager.addRequest);
|
|
293
|
+
assert.notCalled(fakeMediaRequestManager.cancelRequest);
|
|
294
|
+
assert.notCalled(fakeMediaRequestManager.commit);
|
|
295
|
+
|
|
296
|
+
// again, this time without even specifying the csi
|
|
297
|
+
group.pin(remoteMedia);
|
|
298
|
+
|
|
299
|
+
assert.notCalled(fakeMediaRequestManager.addRequest);
|
|
300
|
+
assert.notCalled(fakeMediaRequestManager.cancelRequest);
|
|
301
|
+
assert.notCalled(fakeMediaRequestManager.commit);
|
|
302
|
+
|
|
303
|
+
// pin it again but to a different CSI
|
|
304
|
+
group.pin(remoteMedia, 2345);
|
|
305
|
+
|
|
306
|
+
// it should trigger a new receiver selected media request
|
|
307
|
+
assert.calledOnce(fakeMediaRequestManager.addRequest);
|
|
308
|
+
assert.calledWith(
|
|
309
|
+
fakeMediaRequestManager.addRequest,
|
|
310
|
+
sinon.match({
|
|
311
|
+
policyInfo: sinon.match({
|
|
312
|
+
policy: 'receiver-selected',
|
|
313
|
+
csi: 2345,
|
|
314
|
+
}),
|
|
315
|
+
receiveSlots: [fakeReceiveSlots[PINNED_INDEX]],
|
|
316
|
+
codecInfo: sinon.match({
|
|
317
|
+
codec: 'h264',
|
|
318
|
+
maxFs: 3600,
|
|
319
|
+
}),
|
|
320
|
+
})
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe('stop()', () => {
|
|
326
|
+
it('stops all RemoteMedia in the group', () => {
|
|
327
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
|
|
328
|
+
resolution: 'medium',
|
|
329
|
+
preferLiveVideo: true,
|
|
330
|
+
});
|
|
331
|
+
const stopStubs: any[] = [];
|
|
332
|
+
|
|
333
|
+
group.getRemoteMedia('all').forEach((remoteMedia) => {
|
|
334
|
+
stopStubs.push(sinon.stub(remoteMedia, 'stop'));
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// pin a few remote media instances
|
|
338
|
+
group.pin(group.getRemoteMedia('unpinned')[2], 12345);
|
|
339
|
+
group.pin(group.getRemoteMedia('unpinned')[1], 12345);
|
|
340
|
+
group.pin(group.getRemoteMedia('unpinned')[0], 12345);
|
|
341
|
+
|
|
342
|
+
assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 3);
|
|
343
|
+
assert.strictEqual(group.getRemoteMedia('pinned').length, 3);
|
|
344
|
+
|
|
345
|
+
resetHistory();
|
|
346
|
+
|
|
347
|
+
group.stop(true);
|
|
348
|
+
|
|
349
|
+
// check that all remote media (including pinned ones) have been stopped
|
|
350
|
+
stopStubs.forEach((stub) => {
|
|
351
|
+
assert.calledOnce(stub);
|
|
352
|
+
assert.calledWith(stub, false);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// and that we've cancelled the media request for this group
|
|
356
|
+
assert.calledOnce(fakeMediaRequestManager.cancelRequest);
|
|
357
|
+
assert.calledWith(fakeMediaRequestManager.cancelRequest, getLastActiveSpeakerRequestId());
|
|
358
|
+
assert.calledOnce(fakeMediaRequestManager.commit);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
describe('includes()', () => {
|
|
363
|
+
it('checks if a given RemoteMedia belongs to the group', () => {
|
|
364
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
|
|
365
|
+
resolution: 'medium',
|
|
366
|
+
preferLiveVideo: true,
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const unpinnedRemoteMediaFromGroup = group.getRemoteMedia('all')[0];
|
|
370
|
+
const otherRemoteMedia = new RemoteMedia(
|
|
371
|
+
new FakeSlot(MC.MediaType.VideoMain, 'other slot') as unknown as ReceiveSlot,
|
|
372
|
+
fakeMediaRequestManager
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
group.pin(group.getRemoteMedia('all')[1], 12345);
|
|
376
|
+
const pinnedRemoteMedia = group.getRemoteMedia('pinned')[0];
|
|
377
|
+
|
|
378
|
+
// by default includes() uses 'all' filter
|
|
379
|
+
assert.strictEqual(group.includes(unpinnedRemoteMediaFromGroup), true);
|
|
380
|
+
assert.strictEqual(group.includes(otherRemoteMedia), false);
|
|
381
|
+
assert.strictEqual(group.includes(pinnedRemoteMedia), true);
|
|
382
|
+
|
|
383
|
+
assert.strictEqual(group.includes(unpinnedRemoteMediaFromGroup, 'all'), true);
|
|
384
|
+
assert.strictEqual(group.includes(otherRemoteMedia, 'all'), false);
|
|
385
|
+
assert.strictEqual(group.includes(pinnedRemoteMedia, 'all'), true);
|
|
386
|
+
|
|
387
|
+
assert.strictEqual(group.includes(unpinnedRemoteMediaFromGroup, 'pinned'), false);
|
|
388
|
+
assert.strictEqual(group.includes(otherRemoteMedia, 'pinned'), false);
|
|
389
|
+
assert.strictEqual(group.includes(pinnedRemoteMedia, 'pinned'), true);
|
|
390
|
+
|
|
391
|
+
assert.strictEqual(group.includes(unpinnedRemoteMediaFromGroup, 'unpinned'), true);
|
|
392
|
+
assert.strictEqual(group.includes(pinnedRemoteMedia, 'unpinned'), false);
|
|
393
|
+
assert.strictEqual(group.includes(otherRemoteMedia, 'unpinned'), false);
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
});
|