@antmedia/web_player 2.8.0-SNAPSHOT
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/.project +17 -0
- package/.settings/.jsdtscope +7 -0
- package/.settings/org.eclipse.wst.jsdt.ui.superType.container +1 -0
- package/.settings/org.eclipse.wst.jsdt.ui.superType.name +1 -0
- package/LICENSE +201 -0
- package/README.md +1 -0
- package/api-extractor.json +38 -0
- package/codecov.yml +6 -0
- package/dist/_commonjsHelpers-ed042b00.js +10 -0
- package/dist/aframe-master-42bb78a9.js +7139 -0
- package/dist/browser/web_player.js +976 -0
- package/dist/dash.all.min-84806d51.js +36 -0
- package/dist/es/_commonjsHelpers-7d1333e8.js +7 -0
- package/dist/es/aframe-master-a6146619.js +7137 -0
- package/dist/es/dash.all.min-4a2772b6.js +34 -0
- package/dist/es/index.d.ts +227 -0
- package/dist/es/index.js +1 -0
- package/dist/es/video-js.min-8b4dfe88.js +3 -0
- package/dist/es/video.es-22056625.js +31061 -0
- package/dist/es/videojs-contrib-quality-levels.es-5f5b5f23.js +287 -0
- package/dist/es/videojs-hls-quality-selector.es-3c54e1cd.js +391 -0
- package/dist/es/videojs-webrtc-plugin-b9e4da27.js +3 -0
- package/dist/es/videojs-webrtc-plugin.es-f41400f7.js +7649 -0
- package/dist/es/web_player.js +1262 -0
- package/dist/index.d.ts +227 -0
- package/dist/index.js +7 -0
- package/dist/video-js.min-7e4ae47a.js +5 -0
- package/dist/video.es-72122d04.js +31067 -0
- package/dist/videojs-contrib-quality-levels.es-ef3cec9e.js +289 -0
- package/dist/videojs-hls-quality-selector.es-562309df.js +393 -0
- package/dist/videojs-webrtc-plugin-d30c3e7a.js +5 -0
- package/dist/videojs-webrtc-plugin.es-ac81d249.js +7651 -0
- package/dist/web_player.js +1265 -0
- package/karma.conf.cjs +74 -0
- package/package.json +68 -0
- package/rollup.config.browser.cjs +16 -0
- package/rollup.config.module.cjs +42 -0
- package/src/index.js +1 -0
- package/src/web_player.js +1133 -0
- package/test/embedded-player.test.js +864 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
|
|
2
|
+
import { STATIC_VIDEO_HTML, WebPlayer } from '../dist/es/web_player.js';
|
|
3
|
+
|
|
4
|
+
//import { isMobile } from "../../../main/js/fetch.stream.js";
|
|
5
|
+
|
|
6
|
+
describe("WebPlayer", function() {
|
|
7
|
+
|
|
8
|
+
var clock;
|
|
9
|
+
|
|
10
|
+
var sandbox;
|
|
11
|
+
|
|
12
|
+
beforeEach(function () {
|
|
13
|
+
clock = sinon.useFakeTimers();
|
|
14
|
+
sandbox = sinon.createSandbox();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
// Restore the default sandbox here
|
|
20
|
+
sinon.restore();
|
|
21
|
+
clock.restore();
|
|
22
|
+
sandbox.restore();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("Check default parameters", async function() {
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
var videoContainer = document.createElement("video_container");
|
|
29
|
+
|
|
30
|
+
var placeHolder = document.createElement("place_holder");
|
|
31
|
+
|
|
32
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
33
|
+
var windowComponent = { location : locationComponent,
|
|
34
|
+
document: document};
|
|
35
|
+
|
|
36
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
37
|
+
|
|
38
|
+
expect(player.streamId).to.equal('stream123');
|
|
39
|
+
expect(player.playOrder).to.eql(["webrtc","hls"]);
|
|
40
|
+
expect(player.token).to.be.null;
|
|
41
|
+
expect(player.is360).to.be.false;
|
|
42
|
+
expect(player.playType).to.eql(['mp4','webm']);
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
//the following is a test autoPlay is still true in mobile. We just try to play the stream if mobile browser can play or not
|
|
46
|
+
//in autoPlay mode
|
|
47
|
+
expect(player.autoPlay).to.true;
|
|
48
|
+
expect(player.mute).to.true;
|
|
49
|
+
expect(player.isMuted()).to.be.true;
|
|
50
|
+
expect(player.targetLatency).to.equal(3);
|
|
51
|
+
expect(player.subscriberId).to.be.null;
|
|
52
|
+
expect(player.subscriberCode).to.be.null;
|
|
53
|
+
expect(player.containerElement).to.equal(videoContainer);
|
|
54
|
+
expect(player.placeHolderElement).to.equal(placeHolder);
|
|
55
|
+
expect(player.iceConnected).to.false;
|
|
56
|
+
expect(player.errorCalled).to.false;
|
|
57
|
+
|
|
58
|
+
expect(player.getSecurityQueryParams()).to.be.equal("");
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("Check url parameters", async function() {
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
var videoContainer = document.createElement("video_container");
|
|
70
|
+
|
|
71
|
+
var placeHolder = document.createElement("place_holder");
|
|
72
|
+
|
|
73
|
+
var token = "this_is_the_token";
|
|
74
|
+
var subscriberId = "this_is_subscriber_id";
|
|
75
|
+
var subscriberCode = "this_is_subscriber_id_subscriberCode"
|
|
76
|
+
var locationComponent = { href : 'http://example.com?id=stream123',
|
|
77
|
+
pathname:"/",
|
|
78
|
+
search: "?id=stream123&playOrder=webrtc,hls,dash&token="+token+"&is360=true"+
|
|
79
|
+
"&playType=webm&mute=false&targetLatency=6&subscriberId="+subscriberId+ "&subscriberCode="+subscriberCode+"&autoplay=false"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
};
|
|
83
|
+
var windowComponent = { location : locationComponent,
|
|
84
|
+
document: document};
|
|
85
|
+
|
|
86
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
87
|
+
|
|
88
|
+
expect(player.streamId).to.equal('stream123');
|
|
89
|
+
expect(player.playOrder).to.eql(["webrtc","hls","dash"]);
|
|
90
|
+
expect(player.token).to.be.equal(token);
|
|
91
|
+
expect(player.is360).to.be.true;
|
|
92
|
+
expect(player.playType).to.eql(['webm']);
|
|
93
|
+
expect(player.autoPlay).to.false;
|
|
94
|
+
expect(player.mute).to.false;
|
|
95
|
+
expect(player.isMuted()).to.be.false;
|
|
96
|
+
expect(player.targetLatency).to.equal(6);
|
|
97
|
+
expect(player.subscriberId).to.equal(subscriberId);
|
|
98
|
+
expect(player.subscriberCode).to.equal(subscriberCode);
|
|
99
|
+
expect(player.containerElement).to.equal(videoContainer);
|
|
100
|
+
expect(player.placeHolderElement).to.equal(placeHolder);
|
|
101
|
+
expect(player.iceConnected).to.false;
|
|
102
|
+
expect(player.errorCalled).to.false;
|
|
103
|
+
|
|
104
|
+
expect(player.getSecurityQueryParams()).to.be.equal("&token="+token+"&subscriberId="+subscriberId+"&subscriberCode="+subscriberCode);
|
|
105
|
+
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("CheckConfigParameters", async function(){
|
|
109
|
+
|
|
110
|
+
var videoContainer = document.createElement("video_container");
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
var player = new WebPlayer({
|
|
115
|
+
streamId:"streamConfig",
|
|
116
|
+
}, videoContainer, null);
|
|
117
|
+
|
|
118
|
+
expect(player.streamId).to.be.equal("streamConfig");
|
|
119
|
+
expect(player.containerElement).to.equal(videoContainer);
|
|
120
|
+
expect(player.placeHolderElement).to.be.null;
|
|
121
|
+
expect(player.playOrder).to.eql(["webrtc","hls"]);
|
|
122
|
+
expect(player.token).to.be.null;
|
|
123
|
+
expect(player.is360).to.be.false;
|
|
124
|
+
expect(player.playType).to.eql(['mp4','webm']);
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
//the following is a test autoPlay is still true in mobile. We just try to play the stream if mobile browser can play or not
|
|
128
|
+
//in autoPlay mode
|
|
129
|
+
expect(player.autoPlay).to.true;
|
|
130
|
+
expect(player.mute).to.true;
|
|
131
|
+
expect(player.isMuted()).to.be.true;
|
|
132
|
+
expect(player.targetLatency).to.equal(3);
|
|
133
|
+
expect(player.subscriberId).to.be.null;
|
|
134
|
+
expect(player.subscriberCode).to.be.null;
|
|
135
|
+
expect(player.iceConnected).to.false;
|
|
136
|
+
expect(player.errorCalled).to.false;
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
var placeHolder = document.createElement("place_holder");
|
|
140
|
+
var player = new WebPlayer({
|
|
141
|
+
streamId:"streamConfig123",
|
|
142
|
+
playOrder: ["webrtc","hls","dash"],
|
|
143
|
+
token: "token",
|
|
144
|
+
is360: true,
|
|
145
|
+
playType: ["webm"],
|
|
146
|
+
autoPlay: false,
|
|
147
|
+
mute: false,
|
|
148
|
+
targetLatency: 5,
|
|
149
|
+
subscriberId: "subscriberId",
|
|
150
|
+
subscriberCode: "subscriberCode",
|
|
151
|
+
httpBaseURL: "http://example.antmedia.io:5080/WebRTCAppEE",
|
|
152
|
+
}, videoContainer, placeHolder);
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
expect(player.streamId).to.be.equal("streamConfig123");
|
|
156
|
+
expect(player.containerElement).to.be.equal(videoContainer);
|
|
157
|
+
expect(player.placeHolderElement).to.be.equal(placeHolder);
|
|
158
|
+
expect(player.playOrder).to.eql(["webrtc","hls","dash"]);
|
|
159
|
+
expect(player.token).to.be.equal("token");
|
|
160
|
+
expect(player.is360).to.be.true;
|
|
161
|
+
expect(player.playType).to.eql(['webm']);
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
//the following is a test autoPlay is still true in mobile. We just try to play the stream if mobile browser can play or not
|
|
165
|
+
//in autoPlay mode
|
|
166
|
+
expect(player.autoPlay).to.false;
|
|
167
|
+
expect(player.mute).to.false;
|
|
168
|
+
expect(player.isMuted()).to.be.false;
|
|
169
|
+
expect(player.targetLatency).to.equal(5);
|
|
170
|
+
expect(player.subscriberId).to.be.equal('subscriberId');
|
|
171
|
+
expect(player.subscriberCode).to.be.equal('subscriberCode');
|
|
172
|
+
|
|
173
|
+
expect(player.httpBaseURL).to.be.equal('http://example.antmedia.io:5080/WebRTCAppEE');
|
|
174
|
+
|
|
175
|
+
expect(player.websocketURL).to.be.equal('ws://example.antmedia.io:5080/WebRTCAppEE/streamConfig123.webrtc');
|
|
176
|
+
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("loadComponents", async function(){
|
|
180
|
+
|
|
181
|
+
this.timeout(10000);
|
|
182
|
+
var videoContainer = document.createElement("video_container");
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
var player = new WebPlayer({
|
|
187
|
+
streamId:"streamConfig",
|
|
188
|
+
}, videoContainer, null);
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
{
|
|
192
|
+
await player.initialize().then(()=> {
|
|
193
|
+
|
|
194
|
+
}).catch((err) => {
|
|
195
|
+
expect.fail("it should not fail because it's already loaded");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
{
|
|
201
|
+
player.playOrder = ["dash"];
|
|
202
|
+
await player.initialize().then(()=> {
|
|
203
|
+
|
|
204
|
+
}).catch((err) => {
|
|
205
|
+
expect.fail("it should not fail because we skip videojs and dash is already loaded");
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
{
|
|
210
|
+
player.playOrder = ["hls","dash"];
|
|
211
|
+
|
|
212
|
+
await player.loadWebRTCComponents().then(() => {
|
|
213
|
+
//it will just return promise
|
|
214
|
+
}).catch((err) => {
|
|
215
|
+
expect.fail("it should not reject");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
player.playOrder = ["webrtc", "dash"];
|
|
220
|
+
|
|
221
|
+
await player.loadWebRTCComponents().then(() => {
|
|
222
|
+
expect.fail("it should reject because it's not loadable here");
|
|
223
|
+
}).catch((err) => {
|
|
224
|
+
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("Check if not stream id", async function() {
|
|
232
|
+
var videoContainer = document.createElement("video_container");
|
|
233
|
+
|
|
234
|
+
var placeHolder = document.createElement("place_holder");
|
|
235
|
+
|
|
236
|
+
var locationComponent = { href : 'http://example.com', search: "", pathname:"/" };
|
|
237
|
+
var windowComponent = { location : locationComponent,
|
|
238
|
+
document: document};
|
|
239
|
+
try {
|
|
240
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
241
|
+
//it should throw error
|
|
242
|
+
expect.fail("it should throw exception");
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
//expected because there is no stream id
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var locationComponent = { href : 'http://example.com?name=stream123', search: "?name=stream123", pathname:"/" };
|
|
249
|
+
var windowComponent = { location : locationComponent,
|
|
250
|
+
document: document};
|
|
251
|
+
|
|
252
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
253
|
+
|
|
254
|
+
expect(player.streamId).to.equal('stream123');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
it("Check http resource is available", async function() {
|
|
260
|
+
|
|
261
|
+
var videoContainer = document.createElement("video_container");
|
|
262
|
+
|
|
263
|
+
var placeHolder = document.createElement("place_holder");
|
|
264
|
+
|
|
265
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123" , pathname:"/", hostname:"example.antmedia.io", port:"5080"};
|
|
266
|
+
var windowComponent = { location : locationComponent,
|
|
267
|
+
document: document};
|
|
268
|
+
|
|
269
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
270
|
+
|
|
271
|
+
var streamsFolder = "testfolder";
|
|
272
|
+
|
|
273
|
+
function mockApiSuccess(body = {}) {
|
|
274
|
+
return new window.Response(JSON.stringify(body), {
|
|
275
|
+
status: 200,
|
|
276
|
+
headers: { 'Content-type': 'application/json' }
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
var fake = sinon.replace(window, "fetch", sinon.fake.returns(Promise.resolve(mockApiSuccess())));
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
var testFolder = "testFolder";
|
|
284
|
+
var streamId = "stream123";
|
|
285
|
+
var extension = "m3u8";
|
|
286
|
+
await player.checkStreamExistsViaHttp(testFolder, streamId, extension).then((streamPath) => {
|
|
287
|
+
expect(streamPath).to.be.equal("http://example.antmedia.io:5080" + "/" + testFolder + "/" + streamId + "_adaptive" + "." + extension);
|
|
288
|
+
}).catch((err) => {
|
|
289
|
+
expect.fail("it should not throw exception. error:" + err);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
testFolder = "testFolder";
|
|
293
|
+
streamId = "stream123";
|
|
294
|
+
await player.checkStreamExistsViaHttp(testFolder, testFolder + "/" + streamId, extension).then((streamPath) => {
|
|
295
|
+
console.log("stream path: " + streamPath);
|
|
296
|
+
expect(streamPath).to.be.equal("http://example.antmedia.io:5080" + "/" + testFolder + "/" + streamId + "_adaptive" + "." + extension);
|
|
297
|
+
}).catch((err) => {
|
|
298
|
+
expect.fail("it should not throw exception");
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
testFolder = "testFolder";
|
|
303
|
+
streamId = "stream123";
|
|
304
|
+
var token = "token2323kjfalskfhakf";
|
|
305
|
+
player.token = token;
|
|
306
|
+
await player.checkStreamExistsViaHttp(testFolder, streamId, extension).then((streamPath) => {
|
|
307
|
+
console.log("stream path: " + streamPath);
|
|
308
|
+
expect(streamPath).to.be.equal("http://example.antmedia.io:5080" + "/" + testFolder + "/" + streamId + "_adaptive" + "." + extension + "?&token=" + token);
|
|
309
|
+
}).catch((err) => {
|
|
310
|
+
expect.fail("it should not throw exception");
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
it("Check when http resource is not available", async function() {
|
|
317
|
+
|
|
318
|
+
var videoContainer = document.createElement("video_container");
|
|
319
|
+
|
|
320
|
+
var placeHolder = document.createElement("place_holder");
|
|
321
|
+
|
|
322
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
323
|
+
var windowComponent = { location : locationComponent,
|
|
324
|
+
document: document};
|
|
325
|
+
|
|
326
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
327
|
+
|
|
328
|
+
var streamsFolder = "testfolder";
|
|
329
|
+
|
|
330
|
+
function mockApiSuccess(body = {}) {
|
|
331
|
+
return new window.Response(JSON.stringify(body), {
|
|
332
|
+
status: 200,
|
|
333
|
+
headers: { 'Content-type': 'application/json' }
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
var testFolder = "testFolder";
|
|
339
|
+
var streamId = "stream123";
|
|
340
|
+
var extension = "m3u8";
|
|
341
|
+
|
|
342
|
+
function mockApiFail(body = {}) {
|
|
343
|
+
return new window.Response(JSON.stringify(body), {
|
|
344
|
+
status: 404,
|
|
345
|
+
headers: { 'Content-type': 'application/json' }
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
var fake = sinon.replace(window, "fetch", sinon.fake.returns(Promise.resolve(mockApiFail())));
|
|
350
|
+
|
|
351
|
+
await player.checkStreamExistsViaHttp(testFolder, streamId, extension).then((streamPath) => {
|
|
352
|
+
expect.fail("it should not reject");
|
|
353
|
+
}).catch((err) => {
|
|
354
|
+
expect(err).to.be.equal("resource_is_not_available");
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
it("destroy", async function() {
|
|
361
|
+
var videoContainer = document.createElement("video_container");
|
|
362
|
+
|
|
363
|
+
var placeHolder = document.createElement("place_holder");
|
|
364
|
+
|
|
365
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
366
|
+
var windowComponent = { location : locationComponent,
|
|
367
|
+
document: document};
|
|
368
|
+
|
|
369
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
370
|
+
|
|
371
|
+
var destroyDashPlayer = sinon.replace(player, "destroyDashPlayer", sinon.fake());
|
|
372
|
+
var destroyVideoJSPlayer = sinon.replace(player, "destroyVideoJSPlayer", sinon.fake());
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
player.destroy();
|
|
376
|
+
|
|
377
|
+
expect(destroyDashPlayer.calledOnce).to.be.true;
|
|
378
|
+
expect(destroyVideoJSPlayer.calledOnce).to.be.true;
|
|
379
|
+
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it("tryNextTech", async function() {
|
|
383
|
+
var videoContainer = document.createElement("video_container");
|
|
384
|
+
|
|
385
|
+
var placeHolder = document.createElement("place_holder");
|
|
386
|
+
|
|
387
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
388
|
+
var windowComponent = { location : locationComponent,
|
|
389
|
+
document: document};
|
|
390
|
+
|
|
391
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
392
|
+
|
|
393
|
+
var destroyDashPlayer = sinon.replace(player, "destroyDashPlayer", sinon.fake());
|
|
394
|
+
var destroyVideoJSPlayer = sinon.replace(player, "destroyVideoJSPlayer", sinon.fake());
|
|
395
|
+
var playIfExists = sinon.replace(player, "playIfExists", sinon.fake());
|
|
396
|
+
var setPlayerVisible = sinon.replace(player, "setPlayerVisible", sinon.fake());
|
|
397
|
+
|
|
398
|
+
player.playOrder = ["webrtc","hls"];
|
|
399
|
+
player.currentPlayType = "webrtc";
|
|
400
|
+
|
|
401
|
+
player.tryNextTech();
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
expect(destroyDashPlayer.calledOnce).to.be.true;
|
|
406
|
+
expect(destroyVideoJSPlayer.calledOnce).to.be.true;
|
|
407
|
+
expect(setPlayerVisible.calledOnce).to.be.true;
|
|
408
|
+
expect(setPlayerVisible.calledWithMatch(false)).to.be.true;
|
|
409
|
+
|
|
410
|
+
clock.tick(2500);
|
|
411
|
+
|
|
412
|
+
expect(playIfExists.calledOnce).to.be.false;
|
|
413
|
+
|
|
414
|
+
clock.tick(3500);
|
|
415
|
+
|
|
416
|
+
expect(playIfExists.calledOnce).to.be.true;
|
|
417
|
+
expect(playIfExists.calledWithMatch("hls")).to.be.true;
|
|
418
|
+
|
|
419
|
+
player.currentPlayType = "hls";
|
|
420
|
+
|
|
421
|
+
player.tryNextTech();
|
|
422
|
+
clock.tick(3500);
|
|
423
|
+
expect(playIfExists.callCount).to.be.equal(2);
|
|
424
|
+
expect(playIfExists.calledWithMatch("webrtc")).to.be.true;
|
|
425
|
+
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
it("play", async function() {
|
|
430
|
+
var videoContainer = document.createElement("video_container");
|
|
431
|
+
|
|
432
|
+
var placeHolder = document.createElement("place_holder");
|
|
433
|
+
|
|
434
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
435
|
+
var windowComponent = { location : locationComponent,
|
|
436
|
+
document: document,
|
|
437
|
+
addEventListener: window.addEventListener};
|
|
438
|
+
|
|
439
|
+
const fixture = document.createElement('div');
|
|
440
|
+
fixture.innerHTML = STATIC_VIDEO_HTML;
|
|
441
|
+
|
|
442
|
+
// Append the fixture element to the document body
|
|
443
|
+
document.body.appendChild(fixture);
|
|
444
|
+
|
|
445
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
446
|
+
var playIfExists = sinon.replace(player, "playIfExists", sinon.fake());
|
|
447
|
+
|
|
448
|
+
player.play();
|
|
449
|
+
|
|
450
|
+
expect(playIfExists.callCount).to.be.equal(1);
|
|
451
|
+
sinon.restore();
|
|
452
|
+
|
|
453
|
+
var locationComponent = { href : 'http://example.com?id=streams/stream123.mp4', search: "?id=streams/stream123.mp4", pathname:"/", hostname:"example.antmedia.io", port:"5080" };
|
|
454
|
+
var windowComponent = { location : locationComponent,
|
|
455
|
+
document: document,
|
|
456
|
+
addEventListener: window.addEventListener};
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
460
|
+
|
|
461
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
462
|
+
|
|
463
|
+
player.play();
|
|
464
|
+
|
|
465
|
+
expect(playWithVideoJS.calledWithExactly("http://example.antmedia.io:5080/streams/stream123.mp4", "mp4")).to.be.true;
|
|
466
|
+
|
|
467
|
+
sinon.restore();
|
|
468
|
+
|
|
469
|
+
var makeVideoJSVisibleWhenReady = sinon.replace(player, "makeVideoJSVisibleWhenReady", sinon.fake());
|
|
470
|
+
|
|
471
|
+
player.play();
|
|
472
|
+
expect(makeVideoJSVisibleWhenReady.calledOnce).to.be.true;
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
sinon.restore();
|
|
476
|
+
var locationComponent = { href : 'http://example.com?id=streams/stream123/stream123.mpd', search: "?id=streams/stream123/stream123.mpd", pathname:"/" };
|
|
477
|
+
var windowComponent = { location : locationComponent,
|
|
478
|
+
document: document,
|
|
479
|
+
addEventListener: window.addEventListener};
|
|
480
|
+
|
|
481
|
+
player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
482
|
+
var playViaDash = sinon.replace(player, "playViaDash", sinon.fake());
|
|
483
|
+
player.play();
|
|
484
|
+
expect(playViaDash.calledWithMatch("streams/stream123/stream123.mpd", "mpd")).to.be.true;
|
|
485
|
+
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
it("makeVideoJSVisibleWhenInitialized", async function()
|
|
490
|
+
{
|
|
491
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
492
|
+
var windowComponent = { location : locationComponent,
|
|
493
|
+
document: document,
|
|
494
|
+
addEventListener: window.addEventListener};
|
|
495
|
+
|
|
496
|
+
console.log("makeVideoJSVisibleWhenInitialized--------------------");
|
|
497
|
+
|
|
498
|
+
var videoContainer = document.createElement("video_container");
|
|
499
|
+
|
|
500
|
+
var placeHolder = document.createElement("place_holder");
|
|
501
|
+
|
|
502
|
+
videoContainer.innerHTML = STATIC_VIDEO_HTML;
|
|
503
|
+
|
|
504
|
+
// Append the fixture element to the document body
|
|
505
|
+
document.body.appendChild(videoContainer);
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
509
|
+
sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("streams/stream123.m3u8")));
|
|
510
|
+
|
|
511
|
+
var makeVisibleWhenInitialzed = sinon.replace(player, "makeVideoJSVisibleWhenReady", sinon.fake());
|
|
512
|
+
|
|
513
|
+
await player.playIfExists("hls");
|
|
514
|
+
|
|
515
|
+
expect(makeVisibleWhenInitialzed.calledOnce).to.be.true;
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
console.log("makeVideoJSVisibleWhenInitialized-----------end---------");
|
|
519
|
+
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
it("makeDashPlayerVisibleWhenInitialized", async function()
|
|
524
|
+
{
|
|
525
|
+
var locationComponent = { href : 'http://example.com?id=streams/stream123/stream123.mpd', search: "?id=streams/stream123/stream123.mpd&playOrder=dash", pathname:"/" };
|
|
526
|
+
var windowComponent = { location : locationComponent,
|
|
527
|
+
document: document,
|
|
528
|
+
addEventListener: window.addEventListener};
|
|
529
|
+
|
|
530
|
+
var videoContainer = document.createElement("video_container");
|
|
531
|
+
|
|
532
|
+
var placeHolder = document.createElement("place_holder");
|
|
533
|
+
|
|
534
|
+
videoContainer.innerHTML = STATIC_VIDEO_HTML;
|
|
535
|
+
|
|
536
|
+
// Append the fixture element to the document body
|
|
537
|
+
document.body.appendChild(videoContainer);
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
541
|
+
var makeVisibleWhenInitialzed = sinon.replace(player, "makeDashPlayerVisibleWhenInitialized", sinon.fake());
|
|
542
|
+
|
|
543
|
+
await player.initialize();
|
|
544
|
+
|
|
545
|
+
player.play();
|
|
546
|
+
expect(makeVisibleWhenInitialzed.calledOnce).to.be.true;
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
it("playIfExistsWebRTC", async function() {
|
|
553
|
+
var videoContainer = document.createElement("video_container");
|
|
554
|
+
|
|
555
|
+
var placeHolder = document.createElement("place_holder");
|
|
556
|
+
|
|
557
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname: "/", hostname:"example.com", port:5080 };
|
|
558
|
+
var windowComponent = { location : locationComponent,
|
|
559
|
+
document: document,
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
564
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
565
|
+
|
|
566
|
+
await player.playIfExists("webrtc");
|
|
567
|
+
expect(playWithVideoJS.callCount).to.be.equal(1);
|
|
568
|
+
expect(playWithVideoJS.calledWithExactly("ws://example.com:5080/stream123.webrtc", "webrtc")).to.be.true;
|
|
569
|
+
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
it("playIfExists", async function() {
|
|
573
|
+
var videoContainer = document.createElement("video_container");
|
|
574
|
+
|
|
575
|
+
var placeHolder = document.createElement("place_holder");
|
|
576
|
+
|
|
577
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname: "/", hostname:"example.com", port:5080 };
|
|
578
|
+
var windowComponent = { location : locationComponent,
|
|
579
|
+
document: document,
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("streams/stream123.m3u8")));
|
|
587
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
588
|
+
var setPlayerVisible = sinon.replace(player, "setPlayerVisible", sinon.fake());
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
await player.playIfExists("hls");
|
|
592
|
+
|
|
593
|
+
expect(playWithVideoJS.called).to.be.true;
|
|
594
|
+
expect(playWithVideoJS.calledWithMatch("streams/stream123.m3u8")).to.be.true;
|
|
595
|
+
expect(setPlayerVisible.called).to.be.true;
|
|
596
|
+
expect(setPlayerVisible.calledWithMatch(false)).to.be.true;
|
|
597
|
+
|
|
598
|
+
await player.playIfExists("webrtc");
|
|
599
|
+
expect(playWithVideoJS.callCount).to.be.equal(2);
|
|
600
|
+
expect(playWithVideoJS.calledWithMatch("ws://example.com:5080/stream123.webrtc", "webrtc")).to.be.true;
|
|
601
|
+
|
|
602
|
+
sinon.restore();
|
|
603
|
+
|
|
604
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
605
|
+
sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("streams/stream123.mp4")));
|
|
606
|
+
await player.playIfExists("vod");
|
|
607
|
+
|
|
608
|
+
expect(playWithVideoJS.callCount).to.be.equal(1);
|
|
609
|
+
expect(playWithVideoJS.calledWithMatch("streams/stream123.mp4", "mp4")).to.be.true;
|
|
610
|
+
|
|
611
|
+
sinon.restore();
|
|
612
|
+
|
|
613
|
+
var playViaDash = sinon.replace(player, "playViaDash", sinon.fake());
|
|
614
|
+
sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("streams/stream123/stream123.mpd")));
|
|
615
|
+
|
|
616
|
+
await player.playIfExists("dash");
|
|
617
|
+
expect(playViaDash.callCount).to.be.equal(1);
|
|
618
|
+
expect(playViaDash.calledWithMatch("streams/stream123/stream123.mpd")).to.be.true;
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
sinon.restore();
|
|
623
|
+
var tryNextTech = sinon.replace(player, "tryNextTech", sinon.fake());
|
|
624
|
+
sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.reject("")));
|
|
625
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
626
|
+
|
|
627
|
+
await player.playIfExists("hls");
|
|
628
|
+
expect(tryNextTech.callCount).to.be.equal(1);
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
await player.playIfExists("dash");
|
|
632
|
+
expect(tryNextTech.callCount).to.be.equal(2);
|
|
633
|
+
|
|
634
|
+
await player.playIfExists("vod");
|
|
635
|
+
//because it will not tryNextTech if promises fails
|
|
636
|
+
expect(tryNextTech.callCount).to.be.equal(2);
|
|
637
|
+
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it("playVoD", async function() {
|
|
641
|
+
//Confirming the fix for this issue
|
|
642
|
+
//https://github.com/ant-media/Ant-Media-Server/issues/5137
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
var videoContainer = document.createElement("video_container");
|
|
647
|
+
|
|
648
|
+
var placeHolder = document.createElement("place_holder");
|
|
649
|
+
|
|
650
|
+
var locationComponent = { href : 'http://example.com?id=stream123.mp4', search: "?id=stream123.mp4" , pathname:"/"};
|
|
651
|
+
var windowComponent = { location : locationComponent,
|
|
652
|
+
document: document,
|
|
653
|
+
addEventListener: window.addEventListener};
|
|
654
|
+
|
|
655
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
656
|
+
var checkStreamExistsViaHttp = sinon.replace(player, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("streams/stream123.mp4")));
|
|
657
|
+
var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
658
|
+
|
|
659
|
+
await player.playIfExists("vod");
|
|
660
|
+
|
|
661
|
+
expect(checkStreamExistsViaHttp.calledWithMatch(WebPlayer.STREAMS_FOLDER, "stream123.mp4", "")).to.be.true;
|
|
662
|
+
expect(playWithVideoJS.calledWithMatch("streams/stream123.mp4", "mp4")).to.be.true;
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
sinon.restore();
|
|
666
|
+
|
|
667
|
+
locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname:"/" };
|
|
668
|
+
windowComponent = { location : locationComponent,
|
|
669
|
+
document: document,
|
|
670
|
+
addEventListener: window.addEventListener};
|
|
671
|
+
|
|
672
|
+
var player2 = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
673
|
+
checkStreamExistsViaHttp = sinon.replace(player2, "checkStreamExistsViaHttp", sinon.fake.returns(Promise.resolve("")));
|
|
674
|
+
expect(player2.playType[0]).to.be.equal("mp4");
|
|
675
|
+
|
|
676
|
+
player2.playIfExists("vod");
|
|
677
|
+
|
|
678
|
+
expect(checkStreamExistsViaHttp.calledWithMatch(WebPlayer.STREAMS_FOLDER, "stream123", "mp4")).to.be.true;
|
|
679
|
+
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
it("handleWebRTCInfoMessages", async function() {
|
|
684
|
+
|
|
685
|
+
var videoContainer = document.createElement("video_container");
|
|
686
|
+
|
|
687
|
+
var placeHolder = document.createElement("place_holder");
|
|
688
|
+
|
|
689
|
+
var locationComponent = { href: 'http://example.com?id=stream123.mp4', search: "?id=stream123.mp4", pathname: "/" };
|
|
690
|
+
var windowComponent = {
|
|
691
|
+
location: locationComponent,
|
|
692
|
+
document: document,
|
|
693
|
+
addEventListener: window.addEventListener
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
697
|
+
var tryNextTech = sinon.replace(player, "tryNextTech", sinon.fake.returns(Promise.resolve("")));
|
|
698
|
+
var infos = {
|
|
699
|
+
info: "ice_connection_state_changed",
|
|
700
|
+
obj: {
|
|
701
|
+
state: "completed"
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
expect(player.iceConnected).to.be.false;
|
|
705
|
+
player.handleWebRTCInfoMessages(infos);
|
|
706
|
+
expect(player.iceConnected).to.be.true;
|
|
707
|
+
|
|
708
|
+
infos = {
|
|
709
|
+
info: "ice_connection_state_changed",
|
|
710
|
+
obj: {
|
|
711
|
+
state: "failed"
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
player.handleWebRTCInfoMessages(infos);
|
|
715
|
+
|
|
716
|
+
expect(tryNextTech.calledOnce).to.be.true;
|
|
717
|
+
|
|
718
|
+
infos = {
|
|
719
|
+
info: "closed",
|
|
720
|
+
|
|
721
|
+
}
|
|
722
|
+
player.handleWebRTCInfoMessages(infos);
|
|
723
|
+
|
|
724
|
+
expect(tryNextTech.calledTwice).to.be.true;
|
|
725
|
+
|
|
726
|
+
await player.playIfExists("webrtc");
|
|
727
|
+
|
|
728
|
+
expect(player.videojsPlayer).to.not.be.null;
|
|
729
|
+
|
|
730
|
+
var pauseMethod = sinon.replace(player.videojsPlayer, "pause", sinon.fake());
|
|
731
|
+
var playMethod = sinon.replace(player.videojsPlayer, "play", sinon.fake());
|
|
732
|
+
|
|
733
|
+
infos = {
|
|
734
|
+
info: "resolutionChangeInfo",
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
player.handleWebRTCInfoMessages(infos);
|
|
738
|
+
|
|
739
|
+
expect(pauseMethod.calledOnce).to.be.true;
|
|
740
|
+
expect(playMethod.calledOnce).to.be.false;
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
clock.tick(1500);
|
|
744
|
+
|
|
745
|
+
expect(pauseMethod.calledOnce).to.be.true;
|
|
746
|
+
expect(playMethod.calledOnce).to.be.true;
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
it("webrtc-info-event", async function() {
|
|
753
|
+
|
|
754
|
+
var videoContainer = document.createElement("video_container");
|
|
755
|
+
|
|
756
|
+
var placeHolder = document.createElement("place_holder");
|
|
757
|
+
|
|
758
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname: "/" };
|
|
759
|
+
var windowComponent = { location : locationComponent,
|
|
760
|
+
document: document,
|
|
761
|
+
addEventListener: window.addEventListener};
|
|
762
|
+
|
|
763
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
764
|
+
|
|
765
|
+
var handleWebRTCInfoMessages = sinon.replace(player, "handleWebRTCInfoMessages", sinon.fake());
|
|
766
|
+
await player.playIfExists("webrtc");
|
|
767
|
+
|
|
768
|
+
var infos = {
|
|
769
|
+
info: "closed",
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
var event = {
|
|
773
|
+
data: "any"
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
player.videojsPlayer.trigger("webrtc-info", { infos, event});
|
|
777
|
+
|
|
778
|
+
expect(handleWebRTCInfoMessages.calledOnce).to.be.true;
|
|
779
|
+
expect(handleWebRTCInfoMessages.calledWithMatch({ infos , event})).to.be.true;
|
|
780
|
+
|
|
781
|
+
})
|
|
782
|
+
|
|
783
|
+
it("destroyVideoJSPlayer", async function() {
|
|
784
|
+
|
|
785
|
+
var videoContainer = document.createElement("video_container");
|
|
786
|
+
|
|
787
|
+
var placeHolder = document.createElement("place_holder");
|
|
788
|
+
|
|
789
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname: "/" };
|
|
790
|
+
var windowComponent = { location : locationComponent,
|
|
791
|
+
document: document,
|
|
792
|
+
addEventListener: window.addEventListener};
|
|
793
|
+
|
|
794
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
795
|
+
|
|
796
|
+
expect(player.videojsPlayer).to.be.null
|
|
797
|
+
|
|
798
|
+
await player.playIfExists("webrtc");
|
|
799
|
+
|
|
800
|
+
expect(player.videojsPlayer).to.not.be.null;
|
|
801
|
+
|
|
802
|
+
player.destroyVideoJSPlayer();
|
|
803
|
+
expect(player.videojsPlayer).to.be.null
|
|
804
|
+
})
|
|
805
|
+
|
|
806
|
+
it("sendWebRTCData", async function() {
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
var videoContainer = document.createElement("video_container");
|
|
810
|
+
|
|
811
|
+
var placeHolder = document.createElement("place_holder");
|
|
812
|
+
|
|
813
|
+
var videoPlayer = document.createElement("video");
|
|
814
|
+
videoPlayer.id = WebPlayer.VIDEO_PLAYER_ID;
|
|
815
|
+
|
|
816
|
+
var locationComponent = { href : 'http://example.com?id=stream123', search: "?id=stream123", pathname: "/", hostname:"example.com", port:5080 };
|
|
817
|
+
var windowComponent = { location : locationComponent,
|
|
818
|
+
document: document,
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
823
|
+
//var playWithVideoJS = sinon.replace(player, "playWithVideoJS", sinon.fake());
|
|
824
|
+
|
|
825
|
+
await player.playIfExists("webrtc");
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
var sendDataViaWebRTC = sinon.fake();
|
|
829
|
+
player.videojsPlayer.sendDataViaWebRTC = sendDataViaWebRTC;
|
|
830
|
+
|
|
831
|
+
//send data and it should increase the call count
|
|
832
|
+
var result = player.sendWebRTCData("data");
|
|
833
|
+
expect(sendDataViaWebRTC.callCount).to.be.equal(1);
|
|
834
|
+
expect(result).to.be.true;
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
sendDataViaWebRTC = sinon.fake.throws(new Error("error"));
|
|
838
|
+
player.videojsPlayer.sendDataViaWebRTC = sendDataViaWebRTC;
|
|
839
|
+
result = player.sendWebRTCData("data");
|
|
840
|
+
expect(result).to.be.false;
|
|
841
|
+
expect(sendDataViaWebRTC.callCount).to.be.equal(1);
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
//destroy the player and send again, it should not increase the call count
|
|
845
|
+
player.destroyVideoJSPlayer();
|
|
846
|
+
result = player.sendWebRTCData("data");
|
|
847
|
+
expect(result).to.be.false;
|
|
848
|
+
expect(sendDataViaWebRTC.callCount).to.be.equal(1);
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|