ovenplayer 0.10.49 → 0.10.51
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/ovenplayer.js +1 -1
- package/dist/ovenplayer.js.map +1 -1
- package/package.json +49 -49
- package/src/js/api/Configurator.js +1 -1
- package/src/js/api/ads/vast/Ad.js +237 -237
- package/src/js/api/caption/Loader.js +1 -1
- package/src/js/api/caption/Manager.js +1 -1
- package/src/js/api/caption/parser/VttParser.js +1541 -1542
- package/src/js/api/playlist/Manager.js +229 -229
- package/src/js/api/provider/html5/providers/Dash.js +286 -286
- package/src/js/api/provider/html5/providers/Hls.js +110 -2
- package/src/js/api/provider/html5/providers/WebRTC.js +2 -1
- package/src/js/api/provider/html5/providers/WebRTCLoader.js +35 -2
- package/src/js/api/provider/utils.js +69 -69
- package/src/js/ovenplayer.sdk.js +143 -143
- package/src/js/utils/likeA$.js +241 -242
- package/src/js/utils/resize-sensor.js +145 -168
- package/src/js/utils/strings.js +104 -104
- package/src/js/view/components/controls/settingPanel/audioTrackPanel.js +57 -57
- package/src/js/view/components/controls/settingPanel/main.js +1 -1
- package/src/js/view/components/controls/settingPanel/mainTemplate.js +29 -29
- package/src/js/view/components/controls/settingPanel/qualityPanel.js +68 -68
- package/src/js/view/components/controls/settingPanel/subtitleTrackPanel.js +56 -56
- package/src/js/view/components/helpers/captionViewer.js +97 -15
- package/src/js/view/components/helpers/captionViewerTemplate.js +1 -2
- package/src/js/view/components/helpers/waterMark.js +69 -69
- package/src/js/view/engine/OvenTemplate.js +158 -158
- package/src/js/view/global/PanelManager.js +47 -47
- package/src/stylesheet/ovenplayer.less +52 -21
- package/src/js/utils/adapter.js +0 -4944
- package/src/js/utils/captions/vttCue.js +0 -308
- package/src/js/utils/captions/vttRegion.js +0 -136
- package/src/js/utils/polyfills/dom.js +0 -634
- package/src/js/utils/underscore.js +0 -6
|
@@ -16,7 +16,11 @@ import {
|
|
|
16
16
|
PLAYER_NOT_ACCEPTABLE_ERROR,
|
|
17
17
|
CONTENT_LEVEL_CHANGED,
|
|
18
18
|
AUDIO_TRACK_CHANGED,
|
|
19
|
-
SUBTITLE_TRACK_CHANGED
|
|
19
|
+
SUBTITLE_TRACK_CHANGED,
|
|
20
|
+
CONTENT_CAPTION_CHANGED,
|
|
21
|
+
CONTENT_CAPTION_CUE_CHANGED,
|
|
22
|
+
CONTENT_TIME,
|
|
23
|
+
CONTENT_SEEKED
|
|
20
24
|
} from "api/constants";
|
|
21
25
|
|
|
22
26
|
import sizeHumanizer from "utils/sizeHumanizer";
|
|
@@ -36,11 +40,17 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
36
40
|
let loadRetryer = null;
|
|
37
41
|
let isManifestLoaded = false;
|
|
38
42
|
let firstLoaded = false;
|
|
43
|
+
let subtitleCuesMap = {}; // { [trackId: number]: VTTCue[] }
|
|
44
|
+
let activeSubtitleTrackId = -1;
|
|
45
|
+
let _lastActiveCue = null;
|
|
46
|
+
let _subtitleDebugTimer = 0;
|
|
47
|
+
const SUBTITLE_CUES_MAX = 200; // sliding window limit per track (live stream guard)
|
|
39
48
|
|
|
40
49
|
try {
|
|
41
50
|
|
|
42
51
|
let hlsConfig = {
|
|
43
|
-
debug: false
|
|
52
|
+
debug: false,
|
|
53
|
+
renderTextTracksNatively: false // Disable native TextTrack rendering so subtitles are drawn via DOM
|
|
44
54
|
};
|
|
45
55
|
|
|
46
56
|
let hlsConfigFromPlayerConfig = playerConfig.getConfig().hlsConfig;
|
|
@@ -182,10 +192,104 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
182
192
|
});
|
|
183
193
|
|
|
184
194
|
hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, function (event, data) {
|
|
195
|
+
activeSubtitleTrackId = data.id;
|
|
185
196
|
spec.currentSubtitleTrack = data.id;
|
|
197
|
+
_lastActiveCue = null; // reset so the new track's cue fires immediately
|
|
198
|
+
// Discard cues from tracks no longer in use to free memory
|
|
199
|
+
var keepId = data.id;
|
|
200
|
+
Object.keys(subtitleCuesMap).forEach(function (key) {
|
|
201
|
+
if (Number(key) !== keepId) {
|
|
202
|
+
delete subtitleCuesMap[key];
|
|
203
|
+
}
|
|
204
|
+
});
|
|
186
205
|
that.trigger(SUBTITLE_TRACK_CHANGED, {
|
|
187
206
|
currentSubtitleTrack: spec.currentSubtitleTrack
|
|
188
207
|
});
|
|
208
|
+
// Enable or clear the DOM caption viewer based on track selection
|
|
209
|
+
that.trigger(CONTENT_CAPTION_CHANGED, data.id >= 0 ? 0 : -1);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
hls.on(Hls.Events.CUES_PARSED, function (event, data) {
|
|
213
|
+
// Use the numeric index from hls.subtitleTrack as the key,
|
|
214
|
+
// because data.track can be a string like "default" while
|
|
215
|
+
// hls.subtitleTrack is always the numeric index (e.g. 0).
|
|
216
|
+
var trackId = hls ? hls.subtitleTrack : data.track;
|
|
217
|
+
if (!subtitleCuesMap[trackId]) {
|
|
218
|
+
subtitleCuesMap[trackId] = [];
|
|
219
|
+
}
|
|
220
|
+
data.cues.forEach(function (cue) {
|
|
221
|
+
var exists = subtitleCuesMap[trackId].some(function (c) {
|
|
222
|
+
return c.startTime === cue.startTime && c.text === cue.text;
|
|
223
|
+
});
|
|
224
|
+
if (!exists) {
|
|
225
|
+
subtitleCuesMap[trackId].push(cue);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// Sliding window: drop oldest cues beyond limit to prevent
|
|
229
|
+
// unbounded growth during long live streams.
|
|
230
|
+
if (subtitleCuesMap[trackId].length > SUBTITLE_CUES_MAX) {
|
|
231
|
+
subtitleCuesMap[trackId].splice(0,
|
|
232
|
+
subtitleCuesMap[trackId].length - SUBTITLE_CUES_MAX);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Reset on seek so that:
|
|
237
|
+
// (a) the same cue re-fires after seeking back into its range, and
|
|
238
|
+
// (b) deleteTimer is recalculated from the new position.
|
|
239
|
+
that.on(CONTENT_SEEKED, function () {
|
|
240
|
+
_lastActiveCue = null;
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
that.on(CONTENT_TIME, function (data) {
|
|
244
|
+
// Read the active track directly from hls.js (more reliable than event-based tracking)
|
|
245
|
+
var currentTrackId = hls ? hls.subtitleTrack : -1;
|
|
246
|
+
|
|
247
|
+
if (currentTrackId < 0) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var cues = subtitleCuesMap[currentTrackId] || [];
|
|
252
|
+
|
|
253
|
+
if (!cues.length) { return; }
|
|
254
|
+
// Use raw video element time to match against hls.js cue timestamps.
|
|
255
|
+
// data.position may be offset by sectionStart, causing a mismatch.
|
|
256
|
+
var position = element.currentTime;
|
|
257
|
+
|
|
258
|
+
// Collect ALL cues active at this position (handles simultaneous & overlapping cues)
|
|
259
|
+
var activeCueObjects = [];
|
|
260
|
+
var maxEndTime = 0;
|
|
261
|
+
for (var i = 0; i < cues.length; i++) {
|
|
262
|
+
if (position >= cues[i].startTime && position < cues[i].endTime) {
|
|
263
|
+
activeCueObjects.push({
|
|
264
|
+
text: cues[i].text,
|
|
265
|
+
line: cues[i].line,
|
|
266
|
+
snapToLines: cues[i].snapToLines,
|
|
267
|
+
position: cues[i].position,
|
|
268
|
+
size: cues[i].size,
|
|
269
|
+
align: cues[i].align,
|
|
270
|
+
vertical: cues[i].vertical
|
|
271
|
+
});
|
|
272
|
+
if (cues[i].endTime > maxEndTime) {
|
|
273
|
+
maxEndTime = cues[i].endTime;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (activeCueObjects.length === 0) {
|
|
279
|
+
_lastActiveCue = null;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
var combinedText = activeCueObjects.map(function(c) { return c.text; }).join('\n');
|
|
284
|
+
if (_lastActiveCue !== combinedText) {
|
|
285
|
+
_lastActiveCue = combinedText;
|
|
286
|
+
that.trigger(CONTENT_CAPTION_CUE_CHANGED, {
|
|
287
|
+
text: combinedText,
|
|
288
|
+
cues: activeCueObjects,
|
|
289
|
+
startTime: position,
|
|
290
|
+
endTime: maxEndTime
|
|
291
|
+
});
|
|
292
|
+
}
|
|
189
293
|
});
|
|
190
294
|
|
|
191
295
|
hls.on(Hls.Events.LEVEL_UPDATED, function (event, data) {
|
|
@@ -305,6 +409,10 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
305
409
|
hls.stopLoad();
|
|
306
410
|
}
|
|
307
411
|
|
|
412
|
+
subtitleCuesMap = {};
|
|
413
|
+
activeSubtitleTrackId = -1;
|
|
414
|
+
_lastActiveCue = null;
|
|
415
|
+
|
|
308
416
|
superStop_func();
|
|
309
417
|
};
|
|
310
418
|
|
|
@@ -201,6 +201,7 @@ const WebRTC = function (element, playerConfig, adTagUrl) {
|
|
|
201
201
|
that.once(ERROR, function () {
|
|
202
202
|
|
|
203
203
|
connected = false;
|
|
204
|
+
destroyWebRtcLoader();
|
|
204
205
|
});
|
|
205
206
|
|
|
206
207
|
connectionCheckTimer = setTimeout(function () {
|
|
@@ -281,7 +282,7 @@ const WebRTC = function (element, playerConfig, adTagUrl) {
|
|
|
281
282
|
|
|
282
283
|
that.play = () => {
|
|
283
284
|
|
|
284
|
-
if (!webrtcLoader
|
|
285
|
+
if (!webrtcLoader) {
|
|
285
286
|
loadWebRTCLoader();
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _ from "
|
|
1
|
+
import _ from "underscore";
|
|
2
2
|
import { analUserAgent } from "utils/browser";
|
|
3
3
|
import {
|
|
4
4
|
ERRORS,
|
|
@@ -34,6 +34,8 @@ const WebRTCLoader = function (provider,
|
|
|
34
34
|
let ws = null;
|
|
35
35
|
let wsConnected = false;
|
|
36
36
|
|
|
37
|
+
let transportPolicy = getTransportQuery(webSocketUrl);
|
|
38
|
+
|
|
37
39
|
let mainStream = null;
|
|
38
40
|
|
|
39
41
|
// used for getting media stream from OME or host peer
|
|
@@ -81,6 +83,24 @@ const WebRTCLoader = function (provider,
|
|
|
81
83
|
}
|
|
82
84
|
})();
|
|
83
85
|
|
|
86
|
+
function getTransportQuery(webSocketUrl) {
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const url = new URL(webSocketUrl);
|
|
90
|
+
const transport = url.searchParams.get('transport');
|
|
91
|
+
|
|
92
|
+
if (transport === null) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const normalized = transport.toLowerCase();
|
|
97
|
+
|
|
98
|
+
return normalized;
|
|
99
|
+
|
|
100
|
+
} catch (e) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
84
104
|
|
|
85
105
|
function getPeerConnectionById(id) {
|
|
86
106
|
|
|
@@ -257,6 +277,7 @@ const WebRTCLoader = function (provider,
|
|
|
257
277
|
} else if (iceServers) {
|
|
258
278
|
|
|
259
279
|
// second priority using ice servers from ome and force using TCP
|
|
280
|
+
|
|
260
281
|
peerConnectionConfig.iceServers = [];
|
|
261
282
|
|
|
262
283
|
for (let i = 0; i < iceServers.length; i++) {
|
|
@@ -299,8 +320,20 @@ const WebRTCLoader = function (provider,
|
|
|
299
320
|
peerConnectionConfig.iceServers.push(regIceServer);
|
|
300
321
|
}
|
|
301
322
|
|
|
302
|
-
|
|
323
|
+
// webrtcConfig.iceTransportPolicy has first priority than transport query for iceTransportPolicy because it is more specific setting for player.
|
|
324
|
+
if (playerConfig.getConfig().webrtcConfig &&
|
|
325
|
+
playerConfig.getConfig().webrtcConfig.iceTransportPolicy) {
|
|
326
|
+
peerConnectionConfig.iceTransportPolicy = playerConfig.getConfig().webrtcConfig.iceTransportPolicy;
|
|
327
|
+
} else {
|
|
328
|
+
|
|
329
|
+
let iceTransportPolicy = 'relay';
|
|
330
|
+
|
|
331
|
+
if (transportPolicy === 'all') {
|
|
332
|
+
iceTransportPolicy = 'all';
|
|
333
|
+
}
|
|
303
334
|
|
|
335
|
+
peerConnectionConfig.iceTransportPolicy = iceTransportPolicy;
|
|
336
|
+
}
|
|
304
337
|
} else {
|
|
305
338
|
|
|
306
339
|
// last priority using default ice servers.
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Created by hoho on 2018. 11. 12..
|
|
3
|
-
*/
|
|
4
|
-
import { ERROR, STATE_ERROR } from "api/constants";
|
|
5
|
-
import _ from "
|
|
6
|
-
|
|
7
|
-
export const extractVideoElement = function (elementOrMse) {
|
|
8
|
-
if (_.isElement(elementOrMse)) {
|
|
9
|
-
return elementOrMse;
|
|
10
|
-
}
|
|
11
|
-
if (elementOrMse.getVideoElement) {
|
|
12
|
-
return elementOrMse.getVideoElement();
|
|
13
|
-
} else if (elementOrMse.media) {
|
|
14
|
-
return elementOrMse.media;
|
|
15
|
-
}
|
|
16
|
-
return null;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const separateLive = function (mse) {
|
|
20
|
-
//ToDo : You consider hlsjs. But not now because we don't support hlsjs.
|
|
21
|
-
|
|
22
|
-
if (mse && mse.isDynamic) {
|
|
23
|
-
return mse.isDynamic();
|
|
24
|
-
} else {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const errorTrigger = function (error, provider) {
|
|
30
|
-
if (provider) {
|
|
31
|
-
provider.setState(STATE_ERROR);
|
|
32
|
-
provider.pause();
|
|
33
|
-
provider.trigger(ERROR, error);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const pickCurrentSource = (sources, playerConfig) => {
|
|
39
|
-
|
|
40
|
-
let sourceIndex = 0;
|
|
41
|
-
|
|
42
|
-
if (sources) {
|
|
43
|
-
|
|
44
|
-
if (playerConfig.getSourceIndex() === -1) {
|
|
45
|
-
|
|
46
|
-
for (var i = 0; i < sources.length; i++) {
|
|
47
|
-
if (sources[i].default) {
|
|
48
|
-
sourceIndex = i;
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
} else {
|
|
53
|
-
|
|
54
|
-
sourceIndex = playerConfig.getSourceIndex();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return sourceIndex;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function getSeekableStartEnd(mediaElement) {
|
|
63
|
-
let start = mediaElement.seekable.start(0);
|
|
64
|
-
let end = mediaElement.seekable.end(mediaElement.seekable.length - 1);
|
|
65
|
-
return {
|
|
66
|
-
start: start,
|
|
67
|
-
end: end
|
|
68
|
-
};
|
|
69
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Created by hoho on 2018. 11. 12..
|
|
3
|
+
*/
|
|
4
|
+
import { ERROR, STATE_ERROR } from "api/constants";
|
|
5
|
+
import _ from "underscore";
|
|
6
|
+
|
|
7
|
+
export const extractVideoElement = function (elementOrMse) {
|
|
8
|
+
if (_.isElement(elementOrMse)) {
|
|
9
|
+
return elementOrMse;
|
|
10
|
+
}
|
|
11
|
+
if (elementOrMse.getVideoElement) {
|
|
12
|
+
return elementOrMse.getVideoElement();
|
|
13
|
+
} else if (elementOrMse.media) {
|
|
14
|
+
return elementOrMse.media;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const separateLive = function (mse) {
|
|
20
|
+
//ToDo : You consider hlsjs. But not now because we don't support hlsjs.
|
|
21
|
+
|
|
22
|
+
if (mse && mse.isDynamic) {
|
|
23
|
+
return mse.isDynamic();
|
|
24
|
+
} else {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const errorTrigger = function (error, provider) {
|
|
30
|
+
if (provider) {
|
|
31
|
+
provider.setState(STATE_ERROR);
|
|
32
|
+
provider.pause();
|
|
33
|
+
provider.trigger(ERROR, error);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const pickCurrentSource = (sources, playerConfig) => {
|
|
39
|
+
|
|
40
|
+
let sourceIndex = 0;
|
|
41
|
+
|
|
42
|
+
if (sources) {
|
|
43
|
+
|
|
44
|
+
if (playerConfig.getSourceIndex() === -1) {
|
|
45
|
+
|
|
46
|
+
for (var i = 0; i < sources.length; i++) {
|
|
47
|
+
if (sources[i].default) {
|
|
48
|
+
sourceIndex = i;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
|
|
54
|
+
sourceIndex = playerConfig.getSourceIndex();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return sourceIndex;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getSeekableStartEnd(mediaElement) {
|
|
63
|
+
let start = mediaElement.seekable.start(0);
|
|
64
|
+
let end = mediaElement.seekable.end(mediaElement.seekable.length - 1);
|
|
65
|
+
return {
|
|
66
|
+
start: start,
|
|
67
|
+
end: end
|
|
68
|
+
};
|
|
69
|
+
}
|
package/src/js/ovenplayer.sdk.js
CHANGED
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
import API from 'api/Api';
|
|
2
|
-
import {isWebRTC, checkAndGetContainerElement} from 'utils/validator';
|
|
3
|
-
import _ from "
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Main OvenPlayerSDK object
|
|
7
|
-
*/
|
|
8
|
-
function ovenPlayerFactory() {
|
|
9
|
-
|
|
10
|
-
const OvenPlayerSDK = {};
|
|
11
|
-
|
|
12
|
-
const playerList = OvenPlayerSDK.playerList = [];
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Create player instance and return it.
|
|
16
|
-
*
|
|
17
|
-
* @param {string | dom element} container Id of container element or container element
|
|
18
|
-
* @param {object} options The options
|
|
19
|
-
*/
|
|
20
|
-
OvenPlayerSDK.create = function (container, options) {
|
|
21
|
-
|
|
22
|
-
if (!window.OvenPlayerConsole || Object.keys(window.OvenPlayerConsole).length === 0) {
|
|
23
|
-
window.OvenPlayerConsole = {};
|
|
24
|
-
OvenPlayerConsole['log'] = function () {
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let containerElement = checkAndGetContainerElement(container);
|
|
29
|
-
|
|
30
|
-
const playerInstance = API(containerElement);
|
|
31
|
-
playerInstance.init(options);
|
|
32
|
-
|
|
33
|
-
playerList.push(playerInstance);
|
|
34
|
-
|
|
35
|
-
return playerInstance;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Gets the player instance list.
|
|
40
|
-
*
|
|
41
|
-
* @return {array} The player list.
|
|
42
|
-
*/
|
|
43
|
-
OvenPlayerSDK.getPlayerList = function () {
|
|
44
|
-
|
|
45
|
-
return playerList;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Gets the player instance by container id.
|
|
50
|
-
*
|
|
51
|
-
* @param {string} containerId The container identifier
|
|
52
|
-
* @return {obeject | null} The player instance.
|
|
53
|
-
*/
|
|
54
|
-
OvenPlayerSDK.getPlayerByContainerId = function (containerId) {
|
|
55
|
-
|
|
56
|
-
for (let i = 0; i < playerList.length; i++) {
|
|
57
|
-
|
|
58
|
-
if (playerList[i].getContainerId() === containerId) {
|
|
59
|
-
|
|
60
|
-
return playerList[i];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return null;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Gets the player instance by index.
|
|
69
|
-
*
|
|
70
|
-
* @param {number} index The index
|
|
71
|
-
* @return {object | null} The player instance.
|
|
72
|
-
*/
|
|
73
|
-
OvenPlayerSDK.getPlayerByIndex = function (index) {
|
|
74
|
-
|
|
75
|
-
const playerInstance = playerList[index];
|
|
76
|
-
|
|
77
|
-
if (playerInstance) {
|
|
78
|
-
|
|
79
|
-
return playerInstance;
|
|
80
|
-
} else {
|
|
81
|
-
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Remove the player instance by playerInstance.
|
|
88
|
-
*
|
|
89
|
-
* @param {playerInstance} playerInstance
|
|
90
|
-
* @return {null}
|
|
91
|
-
*/
|
|
92
|
-
OvenPlayerSDK.removePlayer = function (playerInstance) {
|
|
93
|
-
|
|
94
|
-
for (let i = 0; i < playerList.length; i++) {
|
|
95
|
-
|
|
96
|
-
if (playerList[i] === playerInstance) {
|
|
97
|
-
playerList.splice(i, 1);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Generate webrtc source for player source type.
|
|
104
|
-
*
|
|
105
|
-
* @param {Object | Array} source webrtc source
|
|
106
|
-
* @return {Array} Player source Object.
|
|
107
|
-
*/
|
|
108
|
-
OvenPlayerSDK.generateWebrtcUrls = function (sources) {
|
|
109
|
-
return (_.isArray(sources) ? sources : [sources]).map(function (source, index) {
|
|
110
|
-
if (source.host && isWebRTC(source.host) && source.application && source.stream) {
|
|
111
|
-
return {
|
|
112
|
-
file: source.host + "/" + source.application + "/" + source.stream,
|
|
113
|
-
type: "webrtc",
|
|
114
|
-
label: source.label ? source.label : "webrtc-" + (index + 1)
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Whether show the player core log or not.
|
|
122
|
-
*
|
|
123
|
-
* @param {boolean} boolean run debug mode or not.
|
|
124
|
-
* @return {boolean} run debug mode or not.
|
|
125
|
-
*/
|
|
126
|
-
OvenPlayerSDK.debug = function (isDebugMode) {
|
|
127
|
-
|
|
128
|
-
if (isDebugMode) {
|
|
129
|
-
window.OvenPlayerConsole = {log: window['console']['log']};
|
|
130
|
-
} else {
|
|
131
|
-
window.OvenPlayerConsole = {
|
|
132
|
-
log: function () {
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return isDebugMode;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
return OvenPlayerSDK;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
export default ovenPlayerFactory();
|
|
1
|
+
import API from 'api/Api';
|
|
2
|
+
import {isWebRTC, checkAndGetContainerElement} from 'utils/validator';
|
|
3
|
+
import _ from "underscore";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Main OvenPlayerSDK object
|
|
7
|
+
*/
|
|
8
|
+
function ovenPlayerFactory() {
|
|
9
|
+
|
|
10
|
+
const OvenPlayerSDK = {};
|
|
11
|
+
|
|
12
|
+
const playerList = OvenPlayerSDK.playerList = [];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create player instance and return it.
|
|
16
|
+
*
|
|
17
|
+
* @param {string | dom element} container Id of container element or container element
|
|
18
|
+
* @param {object} options The options
|
|
19
|
+
*/
|
|
20
|
+
OvenPlayerSDK.create = function (container, options) {
|
|
21
|
+
|
|
22
|
+
if (!window.OvenPlayerConsole || Object.keys(window.OvenPlayerConsole).length === 0) {
|
|
23
|
+
window.OvenPlayerConsole = {};
|
|
24
|
+
OvenPlayerConsole['log'] = function () {
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let containerElement = checkAndGetContainerElement(container);
|
|
29
|
+
|
|
30
|
+
const playerInstance = API(containerElement);
|
|
31
|
+
playerInstance.init(options);
|
|
32
|
+
|
|
33
|
+
playerList.push(playerInstance);
|
|
34
|
+
|
|
35
|
+
return playerInstance;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Gets the player instance list.
|
|
40
|
+
*
|
|
41
|
+
* @return {array} The player list.
|
|
42
|
+
*/
|
|
43
|
+
OvenPlayerSDK.getPlayerList = function () {
|
|
44
|
+
|
|
45
|
+
return playerList;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Gets the player instance by container id.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} containerId The container identifier
|
|
52
|
+
* @return {obeject | null} The player instance.
|
|
53
|
+
*/
|
|
54
|
+
OvenPlayerSDK.getPlayerByContainerId = function (containerId) {
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < playerList.length; i++) {
|
|
57
|
+
|
|
58
|
+
if (playerList[i].getContainerId() === containerId) {
|
|
59
|
+
|
|
60
|
+
return playerList[i];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Gets the player instance by index.
|
|
69
|
+
*
|
|
70
|
+
* @param {number} index The index
|
|
71
|
+
* @return {object | null} The player instance.
|
|
72
|
+
*/
|
|
73
|
+
OvenPlayerSDK.getPlayerByIndex = function (index) {
|
|
74
|
+
|
|
75
|
+
const playerInstance = playerList[index];
|
|
76
|
+
|
|
77
|
+
if (playerInstance) {
|
|
78
|
+
|
|
79
|
+
return playerInstance;
|
|
80
|
+
} else {
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Remove the player instance by playerInstance.
|
|
88
|
+
*
|
|
89
|
+
* @param {playerInstance} playerInstance
|
|
90
|
+
* @return {null}
|
|
91
|
+
*/
|
|
92
|
+
OvenPlayerSDK.removePlayer = function (playerInstance) {
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < playerList.length; i++) {
|
|
95
|
+
|
|
96
|
+
if (playerList[i] === playerInstance) {
|
|
97
|
+
playerList.splice(i, 1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Generate webrtc source for player source type.
|
|
104
|
+
*
|
|
105
|
+
* @param {Object | Array} source webrtc source
|
|
106
|
+
* @return {Array} Player source Object.
|
|
107
|
+
*/
|
|
108
|
+
OvenPlayerSDK.generateWebrtcUrls = function (sources) {
|
|
109
|
+
return (_.isArray(sources) ? sources : [sources]).map(function (source, index) {
|
|
110
|
+
if (source.host && isWebRTC(source.host) && source.application && source.stream) {
|
|
111
|
+
return {
|
|
112
|
+
file: source.host + "/" + source.application + "/" + source.stream,
|
|
113
|
+
type: "webrtc",
|
|
114
|
+
label: source.label ? source.label : "webrtc-" + (index + 1)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Whether show the player core log or not.
|
|
122
|
+
*
|
|
123
|
+
* @param {boolean} boolean run debug mode or not.
|
|
124
|
+
* @return {boolean} run debug mode or not.
|
|
125
|
+
*/
|
|
126
|
+
OvenPlayerSDK.debug = function (isDebugMode) {
|
|
127
|
+
|
|
128
|
+
if (isDebugMode) {
|
|
129
|
+
window.OvenPlayerConsole = {log: window['console']['log']};
|
|
130
|
+
} else {
|
|
131
|
+
window.OvenPlayerConsole = {
|
|
132
|
+
log: function () {
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return isDebugMode;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
return OvenPlayerSDK;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
export default ovenPlayerFactory();
|