ovenplayer 0.10.2 → 0.10.3-3.alpha-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/LICENSE +1 -1
- package/README.md +39 -46
- package/dist/ovenplayer.js +1 -1
- package/dist/ovenplayer.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/fonts/seek-icons.svg +13 -13
- package/src/js/api/Api.js +231 -140
- package/src/js/api/Configurator.js +6 -3
- package/src/js/api/SupportChecker.js +9 -3
- package/src/js/api/constants.js +203 -15
- package/src/js/api/media/Manager.js +15 -106
- package/src/js/api/provider/Controller.js +5 -6
- package/src/js/api/provider/html5/Provider.js +107 -86
- package/src/js/api/provider/html5/providers/Dash.js +39 -110
- package/src/js/api/provider/html5/providers/Hls.js +139 -99
- package/src/js/api/provider/html5/providers/Html5.js +3 -1
- package/src/js/api/provider/html5/providers/WebRTC.js +207 -37
- package/src/js/api/provider/html5/providers/WebRTCLoader.js +247 -116
- package/src/js/ovenplayer.js +5 -9
- package/src/js/ovenplayer.sdk.js +5 -6
- package/src/js/utils/browser.js +6 -1
- package/src/js/utils/getTouchSection.js +23 -0
- package/src/js/utils/likeA$.js +4 -3
- package/src/js/utils/resize-sensor.js +168 -1
- package/src/js/utils/underscore.js +5 -5
- package/src/js/view/components/controls/fullScreenButton.js +22 -15
- package/src/js/view/components/controls/main.js +33 -20
- package/src/js/view/components/controls/playlistPanel.js +1 -1
- package/src/js/view/components/controls/progressBar.js +151 -76
- package/src/js/view/components/controls/settingButton.js +65 -48
- package/src/js/view/components/controls/settingPanel/audioTrackPanel.js +57 -0
- package/src/js/view/components/controls/settingPanel/captionPanel.js +1 -1
- package/src/js/view/components/controls/settingPanel/main.js +110 -80
- package/src/js/view/components/controls/settingPanel/qualityPanel.js +2 -2
- package/src/js/view/components/controls/settingPanel/sourcePanel.js +1 -1
- package/src/js/view/components/controls/settingPanel/speedPanel.js +1 -1
- package/src/js/view/components/controls/settingPanel/timeDisplayPanel.js +1 -1
- package/src/js/view/components/controls/timeDisplay.js +95 -23
- package/src/js/view/components/controls/timeDisplayTemplate.js +1 -1
- package/src/js/view/components/controls/volumeButton.js +2 -3
- package/src/js/view/components/helpers/captionViewer.js +1 -1
- package/src/js/view/components/helpers/contextPanel.js +1 -1
- package/src/js/view/components/helpers/contextPanelTemplate.js +1 -1
- package/src/js/view/components/helpers/main.js +21 -0
- package/src/js/view/components/helpers/thumbnailTemplate.js +0 -1
- package/src/js/view/engine/Templates.js +2 -0
- package/src/js/view/view.js +53 -14
- package/src/js/view/viewTemplate.js +8 -8
- package/src/stylesheet/ovenplayer.less +565 -308
|
@@ -9,19 +9,30 @@ import {
|
|
|
9
9
|
PLAYER_WEBRTC_SET_LOCAL_DESC_ERROR,
|
|
10
10
|
PLAYER_WEBRTC_NETWORK_SLOW,
|
|
11
11
|
PLAYER_WEBRTC_UNEXPECTED_DISCONNECT,
|
|
12
|
-
|
|
12
|
+
PLAYER_WEBRTC_INTERNAL_ERROR,
|
|
13
|
+
OME_P2P_MODE,
|
|
14
|
+
CONTENT_LEVEL_CHANGED,
|
|
15
|
+
PEER_CONNECTION_PREPARED
|
|
13
16
|
} from "api/constants";
|
|
17
|
+
import sizeHumanizer from "../../../../utils/sizeHumanizer";
|
|
18
|
+
import {PEER_CONNECTION_DESTROYED} from "../../../constants";
|
|
14
19
|
|
|
15
20
|
|
|
16
|
-
const WebRTCLoader = function (provider,
|
|
21
|
+
const WebRTCLoader = function (provider,
|
|
22
|
+
webSocketUrl,
|
|
23
|
+
loadCallback,
|
|
24
|
+
connectedCallback,
|
|
25
|
+
internalErrorCallback,
|
|
26
|
+
errorTrigger,
|
|
27
|
+
playerConfig,
|
|
28
|
+
spec) {
|
|
17
29
|
|
|
18
30
|
let defaultConnectionConfig = {};
|
|
19
31
|
|
|
20
32
|
let that = {};
|
|
21
33
|
|
|
22
34
|
let ws = null;
|
|
23
|
-
|
|
24
|
-
let wsPing = null;
|
|
35
|
+
let wsConnected = false;
|
|
25
36
|
|
|
26
37
|
let mainStream = null;
|
|
27
38
|
|
|
@@ -34,12 +45,15 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
34
45
|
//closed websocket by ome or client.
|
|
35
46
|
let wsClosedByPlayer = false;
|
|
36
47
|
|
|
37
|
-
let
|
|
48
|
+
let recoverPacketLoss = false;
|
|
49
|
+
|
|
50
|
+
let playlistFromOme = null;
|
|
51
|
+
let autoQuality = false;
|
|
38
52
|
|
|
39
53
|
if (playerConfig.getConfig().webrtcConfig &&
|
|
40
|
-
playerConfig.getConfig().webrtcConfig.
|
|
54
|
+
playerConfig.getConfig().webrtcConfig.recoverPacketLoss === true) {
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
recoverPacketLoss = true;
|
|
43
57
|
}
|
|
44
58
|
|
|
45
59
|
let generatePublicCandidate = true;
|
|
@@ -54,8 +68,10 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
54
68
|
|
|
55
69
|
let currentBrowser = analUserAgent();
|
|
56
70
|
|
|
71
|
+
let existingHandler = null;
|
|
72
|
+
|
|
57
73
|
(function () {
|
|
58
|
-
|
|
74
|
+
existingHandler = window.onbeforeunload;
|
|
59
75
|
window.onbeforeunload = function (event) {
|
|
60
76
|
if (existingHandler) {
|
|
61
77
|
existingHandler(event);
|
|
@@ -65,6 +81,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
65
81
|
}
|
|
66
82
|
})();
|
|
67
83
|
|
|
84
|
+
|
|
68
85
|
function getPeerConnectionById(id) {
|
|
69
86
|
|
|
70
87
|
let peerConnection = null;
|
|
@@ -163,7 +180,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
163
180
|
// return opus format number
|
|
164
181
|
function getOpusFormatNumber(sdp) {
|
|
165
182
|
|
|
166
|
-
const lines = sdp.split('\n');
|
|
183
|
+
const lines = sdp.split('\r\n');
|
|
167
184
|
let opusFormatNumber = -1;
|
|
168
185
|
|
|
169
186
|
for (let i = 0; i < lines.length - 1; i++) {
|
|
@@ -182,7 +199,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
182
199
|
|
|
183
200
|
function checkOpusIsStereo(sdp, opusFormatNumber) {
|
|
184
201
|
|
|
185
|
-
const lines = sdp.split('\n');
|
|
202
|
+
const lines = sdp.split('\r\n');
|
|
186
203
|
|
|
187
204
|
let stereo = false;
|
|
188
205
|
|
|
@@ -205,7 +222,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
205
222
|
|
|
206
223
|
function mungeSdpForceStereoOpus(sdp, opusFormatNumber) {
|
|
207
224
|
|
|
208
|
-
const lines = sdp.split('\n');
|
|
225
|
+
const lines = sdp.split('\r\n');
|
|
209
226
|
|
|
210
227
|
// find this line and modify. "a=fmtp:102 minptime=10;useinbandfec=1"
|
|
211
228
|
for (let i = 0; i < lines.length - 1; i++) {
|
|
@@ -221,10 +238,10 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
221
238
|
}
|
|
222
239
|
}
|
|
223
240
|
|
|
224
|
-
return lines.join('\n');
|
|
241
|
+
return lines.join('\r\n');
|
|
225
242
|
}
|
|
226
243
|
|
|
227
|
-
function createMainPeerConnection(id, peerId, sdp, candidates, iceServers
|
|
244
|
+
function createMainPeerConnection(id, peerId, sdp, candidates, iceServers) {
|
|
228
245
|
|
|
229
246
|
let peerConnectionConfig = {};
|
|
230
247
|
|
|
@@ -276,7 +293,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
276
293
|
}
|
|
277
294
|
}
|
|
278
295
|
|
|
279
|
-
regIceServer.username = iceServer.user_name;
|
|
296
|
+
regIceServer.username = iceServer.username || iceServer.user_name;
|
|
280
297
|
regIceServer.credential = iceServer.credential;
|
|
281
298
|
|
|
282
299
|
peerConnectionConfig.iceServers.push(regIceServer);
|
|
@@ -292,7 +309,19 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
292
309
|
|
|
293
310
|
OvenPlayerConsole.log("Main Peer Connection Config : ", peerConnectionConfig);
|
|
294
311
|
|
|
295
|
-
let peerConnection =
|
|
312
|
+
let peerConnection = null;
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
|
|
316
|
+
peerConnection = new RTCPeerConnection(peerConnectionConfig);
|
|
317
|
+
provider.trigger(PEER_CONNECTION_PREPARED, peerConnection);
|
|
318
|
+
|
|
319
|
+
} catch (error) {
|
|
320
|
+
let tempError = ERRORS.codes[PLAYER_WEBRTC_INTERNAL_ERROR];
|
|
321
|
+
tempError.error = error;
|
|
322
|
+
closePeer(tempError);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
296
325
|
|
|
297
326
|
mainPeerConnectionInfo = {
|
|
298
327
|
id: id,
|
|
@@ -301,56 +330,54 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
301
330
|
};
|
|
302
331
|
|
|
303
332
|
//Set remote description when I received sdp from server.
|
|
304
|
-
peerConnection.setRemoteDescription(new RTCSessionDescription(sdp))
|
|
305
|
-
.then(function () {
|
|
333
|
+
peerConnection.setRemoteDescription(new RTCSessionDescription(sdp)).then(function () {
|
|
306
334
|
|
|
307
|
-
|
|
308
|
-
.then(function (desc) {
|
|
335
|
+
peerConnection.createAnswer().then(function (desc) {
|
|
309
336
|
|
|
310
|
-
|
|
337
|
+
const opusFormatNumber = getOpusFormatNumber(sdp.sdp);
|
|
311
338
|
|
|
312
|
-
|
|
339
|
+
if (opusFormatNumber > -1) {
|
|
313
340
|
|
|
314
|
-
|
|
341
|
+
if (checkOpusIsStereo(sdp.sdp, opusFormatNumber)) {
|
|
315
342
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
343
|
+
//If offer has opus and if it is stereo, munge local sdp to force stereo=1
|
|
344
|
+
//Thanks to community https://github.com/AirenSoft/OvenMediaEngine/issues/203
|
|
345
|
+
desc.sdp = mungeSdpForceStereoOpus(desc.sdp, opusFormatNumber);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
321
348
|
|
|
322
|
-
|
|
349
|
+
OvenPlayerConsole.log('Local SDP', desc);
|
|
323
350
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
351
|
+
sendMessage(ws, {
|
|
352
|
+
id: id,
|
|
353
|
+
peer_id: peerId,
|
|
354
|
+
command: 'answer',
|
|
355
|
+
sdp: desc
|
|
356
|
+
});
|
|
328
357
|
|
|
329
|
-
|
|
330
|
-
id: id,
|
|
331
|
-
peer_id: peerId,
|
|
332
|
-
command: 'answer',
|
|
333
|
-
sdp: localSDP
|
|
334
|
-
});
|
|
358
|
+
OvenPlayerConsole.log("create Host Answer : success");
|
|
335
359
|
|
|
336
|
-
|
|
360
|
+
peerConnection.setLocalDescription(desc).then(function () {
|
|
337
361
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
})
|
|
349
|
-
.catch(function (error) {
|
|
350
|
-
let tempError = ERRORS.codes[PLAYER_WEBRTC_SET_REMOTE_DESC_ERROR];
|
|
362
|
+
|
|
363
|
+
}).catch(function (error) {
|
|
364
|
+
|
|
365
|
+
let tempError = ERRORS.codes[PLAYER_WEBRTC_SET_LOCAL_DESC_ERROR];
|
|
366
|
+
tempError.error = error;
|
|
367
|
+
closePeer(tempError);
|
|
368
|
+
});
|
|
369
|
+
}).catch(function (error) {
|
|
370
|
+
|
|
371
|
+
let tempError = ERRORS.codes[PLAYER_WEBRTC_CREATE_ANSWER_ERROR];
|
|
351
372
|
tempError.error = error;
|
|
352
373
|
closePeer(tempError);
|
|
353
374
|
});
|
|
375
|
+
}).catch(function (error) {
|
|
376
|
+
|
|
377
|
+
let tempError = ERRORS.codes[PLAYER_WEBRTC_SET_REMOTE_DESC_ERROR];
|
|
378
|
+
tempError.error = error;
|
|
379
|
+
closePeer(tempError);
|
|
380
|
+
});
|
|
354
381
|
|
|
355
382
|
if (candidates) {
|
|
356
383
|
|
|
@@ -358,12 +385,12 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
358
385
|
}
|
|
359
386
|
|
|
360
387
|
peerConnection.onicecandidate = function (e) {
|
|
388
|
+
|
|
361
389
|
if (e.candidate) {
|
|
362
390
|
|
|
363
|
-
OvenPlayerConsole.log("WebRTCLoader send candidate to server : "
|
|
391
|
+
OvenPlayerConsole.log("WebRTCLoader send candidate to server : ", e.candidate);
|
|
364
392
|
|
|
365
393
|
// console.log('Main Peer Connection candidate', e.candidate);
|
|
366
|
-
|
|
367
394
|
sendMessage(ws, {
|
|
368
395
|
id: id,
|
|
369
396
|
peer_id: peerId,
|
|
@@ -372,14 +399,38 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
372
399
|
});
|
|
373
400
|
}
|
|
374
401
|
};
|
|
402
|
+
|
|
375
403
|
peerConnection.onconnectionstatechange = function (e) {
|
|
376
|
-
//
|
|
404
|
+
//ConnectionState
|
|
377
405
|
OvenPlayerConsole.log("[on connection state change]", peerConnection.connectionState, e);
|
|
378
406
|
|
|
407
|
+
// firefox and opera do not support onconnectionstatechange (Jan 07, 2021)
|
|
408
|
+
// double check with oniceconnectionstatechange
|
|
409
|
+
if (peerConnection.connectionState === 'connected') {
|
|
410
|
+
|
|
411
|
+
if (connectedCallback) {
|
|
412
|
+
connectedCallback();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
peerConnection.onicecandidateerror = function (e) {
|
|
418
|
+
|
|
379
419
|
};
|
|
420
|
+
|
|
421
|
+
peerConnection.onicegatheringstatechange = function (e) {
|
|
422
|
+
|
|
423
|
+
};
|
|
424
|
+
|
|
380
425
|
peerConnection.oniceconnectionstatechange = function (e) {
|
|
381
426
|
OvenPlayerConsole.log("[on ice connection state change]", peerConnection.iceConnectionState, e);
|
|
382
427
|
|
|
428
|
+
if (peerConnection.iceConnectionState === 'connected') {
|
|
429
|
+
|
|
430
|
+
if (connectedCallback) {
|
|
431
|
+
connectedCallback();
|
|
432
|
+
}
|
|
433
|
+
}
|
|
383
434
|
/*
|
|
384
435
|
* https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState
|
|
385
436
|
* Checks to ensure that components are still connected failed for at least one component of the RTCPeerConnection. This is a less stringent test than "failed" and may trigger intermittently and resolve just as spontaneously on less reliable networks, or during temporary disconnections. When the problem resolves, the connection may return to the "connected" state.
|
|
@@ -395,13 +446,14 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
395
446
|
}
|
|
396
447
|
}
|
|
397
448
|
};
|
|
449
|
+
|
|
398
450
|
peerConnection.ontrack = function (e) {
|
|
399
451
|
|
|
400
452
|
OvenPlayerConsole.log("stream received.");
|
|
401
453
|
|
|
402
|
-
OvenPlayerConsole.log('Recovery On Packet Loss :',
|
|
454
|
+
OvenPlayerConsole.log('Recovery On Packet Loss :', recoverPacketLoss);
|
|
403
455
|
|
|
404
|
-
if (
|
|
456
|
+
if (recoverPacketLoss) {
|
|
405
457
|
extractLossPacketsOnNetworkStatus(mainPeerConnectionInfo);
|
|
406
458
|
}
|
|
407
459
|
|
|
@@ -418,7 +470,15 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
418
470
|
|
|
419
471
|
let receiver = receivers[i];
|
|
420
472
|
|
|
421
|
-
receiver.
|
|
473
|
+
if (receiver.track.kind === 'audio') {
|
|
474
|
+
|
|
475
|
+
receiver.playoutDelayHint = hint;
|
|
476
|
+
receiver.jitterBufferDelayHint = hint;
|
|
477
|
+
} else {
|
|
478
|
+
|
|
479
|
+
receiver.playoutDelayHint = hint;
|
|
480
|
+
}
|
|
481
|
+
|
|
422
482
|
OvenPlayerConsole.log("WebRTC playoutDelayHint", receiver, hint);
|
|
423
483
|
}
|
|
424
484
|
|
|
@@ -517,37 +577,17 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
517
577
|
let newDomain = generateDomainFromUrl(webSocketUrl);
|
|
518
578
|
let ip = findIp(cloneCandidate.candidate);
|
|
519
579
|
|
|
520
|
-
|
|
580
|
+
return new Promise(function (resolve, reject) {
|
|
521
581
|
|
|
522
|
-
|
|
523
|
-
}
|
|
582
|
+
if (ip === '' || ip === newDomain) {
|
|
524
583
|
|
|
525
|
-
|
|
584
|
+
resolve(null);
|
|
585
|
+
}
|
|
526
586
|
|
|
527
587
|
// firefox browser throws a candidate parsing exception when a domain name is set at the address property. So we resolve the dns using google dns resolve api.
|
|
528
588
|
if (currentBrowser.browser === 'Firefox' && !findIp(newDomain)) {
|
|
529
589
|
|
|
530
|
-
|
|
531
|
-
.then(resp => resp.json())
|
|
532
|
-
.then(data => {
|
|
533
|
-
|
|
534
|
-
if (data && data.Answer && data.Answer.length > 0) {
|
|
535
|
-
|
|
536
|
-
if (data.Answer[0].data) {
|
|
537
|
-
|
|
538
|
-
let relsolvedIp = data.Answer[0].data;
|
|
539
|
-
|
|
540
|
-
cloneCandidate.candidate = cloneCandidate.candidate.replace(ip, relsolvedIp);
|
|
541
|
-
resolve(cloneCandidate);
|
|
542
|
-
} else {
|
|
543
|
-
|
|
544
|
-
resolve(null);
|
|
545
|
-
}
|
|
546
|
-
} else {
|
|
547
|
-
|
|
548
|
-
resolve(null);
|
|
549
|
-
}
|
|
550
|
-
});
|
|
590
|
+
resolve(null);
|
|
551
591
|
|
|
552
592
|
} else {
|
|
553
593
|
|
|
@@ -599,7 +639,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
599
639
|
}
|
|
600
640
|
}
|
|
601
641
|
|
|
602
|
-
function initWebSocket(
|
|
642
|
+
function initWebSocket() {
|
|
603
643
|
|
|
604
644
|
try {
|
|
605
645
|
|
|
@@ -607,15 +647,11 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
607
647
|
|
|
608
648
|
ws.onopen = function () {
|
|
609
649
|
|
|
650
|
+
wsConnected = true;
|
|
651
|
+
|
|
610
652
|
sendMessage(ws, {
|
|
611
653
|
command: "request_offer"
|
|
612
654
|
});
|
|
613
|
-
|
|
614
|
-
// wsPing = setInterval(function () {
|
|
615
|
-
//
|
|
616
|
-
// sendMessage(ws, {command: "ping"});
|
|
617
|
-
//
|
|
618
|
-
// }, 20 * 1000);
|
|
619
655
|
};
|
|
620
656
|
|
|
621
657
|
ws.onmessage = function (e) {
|
|
@@ -641,15 +677,11 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
641
677
|
return;
|
|
642
678
|
}
|
|
643
679
|
|
|
644
|
-
if (!message.id) {
|
|
645
|
-
|
|
646
|
-
OvenPlayerConsole.log('ID must be not null');
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
680
|
if (message.command === 'offer') {
|
|
651
681
|
|
|
652
|
-
|
|
682
|
+
let iceServers = message.iceServers || message.ice_servers;
|
|
683
|
+
|
|
684
|
+
createMainPeerConnection(message.id, message.peer_id, message.sdp, message.candidates, iceServers);
|
|
653
685
|
if (message.peer_id === 0) {
|
|
654
686
|
provider.trigger(OME_P2P_MODE, false);
|
|
655
687
|
} else {
|
|
@@ -693,6 +725,57 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
693
725
|
addIceCandidate(peerConnection3, message.candidates);
|
|
694
726
|
}
|
|
695
727
|
|
|
728
|
+
if (message.command === 'notification') {
|
|
729
|
+
|
|
730
|
+
if (message.type === 'playlist') {
|
|
731
|
+
|
|
732
|
+
const renditions = message.message.renditions;
|
|
733
|
+
playlistFromOme = message.message;
|
|
734
|
+
|
|
735
|
+
for (let i = 0; i < renditions.length; i++) {
|
|
736
|
+
|
|
737
|
+
let rendition = renditions[i];
|
|
738
|
+
|
|
739
|
+
spec.qualityLevels.push({
|
|
740
|
+
bitrate: rendition.video_track.video.bitrate,
|
|
741
|
+
height: rendition.video_track.video.height,
|
|
742
|
+
width: rendition.video_track.video.width,
|
|
743
|
+
index: i,
|
|
744
|
+
label: rendition.name
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
spec.currentQuality = 0;
|
|
749
|
+
autoQuality = message.message.auto;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
if (message.type === 'rendition_changed') {
|
|
753
|
+
|
|
754
|
+
const rendition = message.message;
|
|
755
|
+
|
|
756
|
+
if (message.auto) {
|
|
757
|
+
autoQuality = message.auto;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
let qualityIndex = -1;
|
|
761
|
+
|
|
762
|
+
for (let i = 0; i < playlistFromOme.renditions.length; i ++) {
|
|
763
|
+
|
|
764
|
+
if (rendition.rendition_name === playlistFromOme.renditions[i].name) {
|
|
765
|
+
qualityIndex = i;
|
|
766
|
+
spec.currentQuality = i;
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
provider.trigger(CONTENT_LEVEL_CHANGED, {
|
|
772
|
+
isAuto: autoQuality,
|
|
773
|
+
currentQuality: qualityIndex,
|
|
774
|
+
type: "render"
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
696
779
|
if (message.command === 'stop') {
|
|
697
780
|
|
|
698
781
|
if (mainPeerConnectionInfo.peerId === message.peer_id) {
|
|
@@ -724,10 +807,20 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
724
807
|
}
|
|
725
808
|
}
|
|
726
809
|
};
|
|
727
|
-
ws.onclose = function () {
|
|
810
|
+
ws.onclose = function (e) {
|
|
728
811
|
|
|
729
812
|
if (!wsClosedByPlayer) {
|
|
730
813
|
|
|
814
|
+
if (connectedCallback) {
|
|
815
|
+
if (!wsConnected) {
|
|
816
|
+
|
|
817
|
+
// If the websocket is closed while there is no connection,
|
|
818
|
+
// it is judged as a timeout.
|
|
819
|
+
closePeer();
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
731
824
|
let tempError = ERRORS.codes[PLAYER_WEBRTC_WS_ERROR];
|
|
732
825
|
|
|
733
826
|
if (mainPeerConnectionInfo) {
|
|
@@ -740,13 +833,6 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
740
833
|
|
|
741
834
|
ws.onerror = function (error) {
|
|
742
835
|
|
|
743
|
-
//Why Edge Browser calls onerror() when ws.close()?
|
|
744
|
-
if (!wsClosedByPlayer) {
|
|
745
|
-
let tempError = ERRORS.codes[PLAYER_WEBRTC_WS_ERROR];
|
|
746
|
-
tempError.error = error;
|
|
747
|
-
closePeer(tempError);
|
|
748
|
-
// reject(error);
|
|
749
|
-
}
|
|
750
836
|
};
|
|
751
837
|
|
|
752
838
|
} catch (error) {
|
|
@@ -758,13 +844,9 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
758
844
|
function initialize() {
|
|
759
845
|
|
|
760
846
|
OvenPlayerConsole.log("WebRTCLoader connecting...");
|
|
847
|
+
OvenPlayerConsole.log("WebRTCLoader url : " + webSocketUrl);
|
|
761
848
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
OvenPlayerConsole.log("WebRTCLoader url : " + webSocketUrl);
|
|
765
|
-
|
|
766
|
-
initWebSocket(resolve, reject);
|
|
767
|
-
});
|
|
849
|
+
initWebSocket();
|
|
768
850
|
}
|
|
769
851
|
|
|
770
852
|
function closePeer(error) {
|
|
@@ -794,6 +876,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
794
876
|
}
|
|
795
877
|
|
|
796
878
|
mainPeerConnectionInfo.peerConnection = null;
|
|
879
|
+
provider.trigger(PEER_CONNECTION_DESTROYED);
|
|
797
880
|
mainPeerConnectionInfo = null;
|
|
798
881
|
}
|
|
799
882
|
|
|
@@ -813,9 +896,6 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
813
896
|
clientPeerConnections = {};
|
|
814
897
|
}
|
|
815
898
|
|
|
816
|
-
clearInterval(wsPing);
|
|
817
|
-
wsPing = null;
|
|
818
|
-
|
|
819
899
|
if (ws) {
|
|
820
900
|
OvenPlayerConsole.log('Closing websocket connection...');
|
|
821
901
|
OvenPlayerConsole.log("Send Signaling : Stop.");
|
|
@@ -825,7 +905,7 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
825
905
|
2 (CLOSING)
|
|
826
906
|
3 (CLOSED)
|
|
827
907
|
*/
|
|
828
|
-
if (ws.readyState ===
|
|
908
|
+
if (ws.readyState === 1) {
|
|
829
909
|
|
|
830
910
|
wsClosedByPlayer = true;
|
|
831
911
|
|
|
@@ -846,6 +926,11 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
846
926
|
ws = null;
|
|
847
927
|
|
|
848
928
|
if (error) {
|
|
929
|
+
|
|
930
|
+
if (internalErrorCallback) {
|
|
931
|
+
internalErrorCallback(error);
|
|
932
|
+
}
|
|
933
|
+
|
|
849
934
|
errorTrigger(error, provider);
|
|
850
935
|
}
|
|
851
936
|
}
|
|
@@ -858,12 +943,58 @@ const WebRTCLoader = function (provider, webSocketUrl, loadCallback, errorTrigge
|
|
|
858
943
|
|
|
859
944
|
}
|
|
860
945
|
|
|
946
|
+
provider.setCurrentQuality = (qualityIndex) => {
|
|
947
|
+
|
|
948
|
+
if (!playlistFromOme) {
|
|
949
|
+
return -1;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
let rendition = playlistFromOme.renditions[qualityIndex];
|
|
953
|
+
|
|
954
|
+
if (!rendition) {
|
|
955
|
+
return spec.currentQuality;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
sendMessage(ws, {
|
|
959
|
+
command: 'change_rendition',
|
|
960
|
+
id: mainPeerConnectionInfo.id,
|
|
961
|
+
rendition_name: rendition.name,
|
|
962
|
+
auto: false
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
autoQuality = false;
|
|
966
|
+
|
|
967
|
+
spec.currentQuality = qualityIndex;
|
|
968
|
+
return spec.currentQuality;
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
provider.isAutoQuality = () => {
|
|
972
|
+
|
|
973
|
+
return autoQuality;
|
|
974
|
+
};
|
|
975
|
+
|
|
976
|
+
provider.setAutoQuality = (auto) => {
|
|
977
|
+
|
|
978
|
+
sendMessage(ws, {
|
|
979
|
+
command: 'change_rendition',
|
|
980
|
+
id: mainPeerConnectionInfo.id,
|
|
981
|
+
auto: auto
|
|
982
|
+
});
|
|
983
|
+
autoQuality = auto;
|
|
984
|
+
};
|
|
985
|
+
|
|
861
986
|
that.connect = () => {
|
|
862
|
-
|
|
987
|
+
|
|
988
|
+
initialize();
|
|
863
989
|
};
|
|
864
990
|
|
|
865
991
|
that.destroy = () => {
|
|
992
|
+
|
|
993
|
+
wsClosedByPlayer = true;
|
|
866
994
|
closePeer();
|
|
995
|
+
|
|
996
|
+
window.onbeforeunload = existingHandler;
|
|
997
|
+
existingHandler = null;
|
|
867
998
|
};
|
|
868
999
|
|
|
869
1000
|
return that;
|
package/src/js/ovenplayer.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import {version} from 'version'
|
|
1
2
|
import OvenPlayerSDK from './ovenplayer.sdk'
|
|
2
|
-
import {checkAndGetContainerElement} from 'utils/validator'
|
|
3
|
+
import {checkAndGetContainerElement} from 'utils/validator'
|
|
3
4
|
import View from './view/view';
|
|
4
5
|
|
|
5
6
|
function ovenPlayerFactory() {
|
|
@@ -16,19 +17,14 @@ function ovenPlayerFactory() {
|
|
|
16
17
|
|
|
17
18
|
const playerInstance = OvenPlayerSDK.create(player.getMediaElementContainer(), options);
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
Object.assign(playerInstance, {
|
|
21
|
-
getContainerId: function () {
|
|
22
|
-
return containerElement.id;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
20
|
player.setApi(playerInstance);
|
|
27
21
|
|
|
22
|
+
OvenPlayerConsole.log("[OvenPlayer] v."+ version);
|
|
23
|
+
|
|
28
24
|
return playerInstance;
|
|
29
25
|
};
|
|
30
26
|
|
|
31
27
|
return OvenPlayer;
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
export default ovenPlayerFactory()
|
|
30
|
+
export default ovenPlayerFactory()
|
package/src/js/ovenplayer.sdk.js
CHANGED
|
@@ -84,20 +84,19 @@ function ovenPlayerFactory() {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* Remove the player instance by
|
|
87
|
+
* Remove the player instance by playerInstance.
|
|
88
88
|
*
|
|
89
|
-
* @param {
|
|
89
|
+
* @param {playerInstance} playerInstance
|
|
90
90
|
* @return {null}
|
|
91
91
|
*/
|
|
92
|
-
OvenPlayerSDK.removePlayer = function (
|
|
93
|
-
for (let i = 0; i < playerList.length; i++) {
|
|
92
|
+
OvenPlayerSDK.removePlayer = function (playerInstance) {
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
for (let i = 0; i < playerList.length; i++) {
|
|
96
95
|
|
|
96
|
+
if (playerList[i] === playerInstance) {
|
|
97
97
|
playerList.splice(i, 1);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
|
|
101
100
|
};
|
|
102
101
|
|
|
103
102
|
/**
|
package/src/js/utils/browser.js
CHANGED
|
@@ -209,7 +209,12 @@ export const analUserAgent = function(){
|
|
|
209
209
|
|
|
210
210
|
case 'iOS':
|
|
211
211
|
osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer);
|
|
212
|
-
|
|
212
|
+
if (osVersion) {
|
|
213
|
+
osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0);
|
|
214
|
+
} else {
|
|
215
|
+
osVersion = '';
|
|
216
|
+
}
|
|
217
|
+
|
|
213
218
|
break;
|
|
214
219
|
}
|
|
215
220
|
|