ovenplayer 0.10.50 → 0.10.52
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 +121 -5
- package/src/js/api/provider/html5/providers/WebRTC.js +2 -1
- package/src/js/api/provider/html5/providers/WebRTCLoader.js +1 -1
- 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 +6 -2
- 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;
|
|
@@ -105,13 +115,21 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
105
115
|
|
|
106
116
|
let qualityLevel = hls.levels[i];
|
|
107
117
|
|
|
108
|
-
|
|
118
|
+
let label = qualityLevel.width + "x" + qualityLevel.height + ", " + sizeHumanizer(qualityLevel.bitrate, true, "bps");
|
|
119
|
+
let level = {
|
|
109
120
|
bitrate: qualityLevel.bitrate,
|
|
110
121
|
height: qualityLevel.height,
|
|
111
122
|
width: qualityLevel.width,
|
|
112
123
|
index: i,
|
|
113
|
-
label:
|
|
114
|
-
}
|
|
124
|
+
label: label
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
if (qualityLevel.codecSet) {
|
|
128
|
+
level.codecs = qualityLevel.codecSet;
|
|
129
|
+
level.label = label + " (" + qualityLevel.codecSet + ")";
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
spec.qualityLevels.push(level);
|
|
115
133
|
}
|
|
116
134
|
|
|
117
135
|
spec.currentQuality = hls.firstLevel;
|
|
@@ -182,10 +200,104 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
182
200
|
});
|
|
183
201
|
|
|
184
202
|
hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, function (event, data) {
|
|
203
|
+
activeSubtitleTrackId = data.id;
|
|
185
204
|
spec.currentSubtitleTrack = data.id;
|
|
205
|
+
_lastActiveCue = null; // reset so the new track's cue fires immediately
|
|
206
|
+
// Discard cues from tracks no longer in use to free memory
|
|
207
|
+
var keepId = data.id;
|
|
208
|
+
Object.keys(subtitleCuesMap).forEach(function (key) {
|
|
209
|
+
if (Number(key) !== keepId) {
|
|
210
|
+
delete subtitleCuesMap[key];
|
|
211
|
+
}
|
|
212
|
+
});
|
|
186
213
|
that.trigger(SUBTITLE_TRACK_CHANGED, {
|
|
187
214
|
currentSubtitleTrack: spec.currentSubtitleTrack
|
|
188
215
|
});
|
|
216
|
+
// Enable or clear the DOM caption viewer based on track selection
|
|
217
|
+
that.trigger(CONTENT_CAPTION_CHANGED, data.id >= 0 ? 0 : -1);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
hls.on(Hls.Events.CUES_PARSED, function (event, data) {
|
|
221
|
+
// Use the numeric index from hls.subtitleTrack as the key,
|
|
222
|
+
// because data.track can be a string like "default" while
|
|
223
|
+
// hls.subtitleTrack is always the numeric index (e.g. 0).
|
|
224
|
+
var trackId = hls ? hls.subtitleTrack : data.track;
|
|
225
|
+
if (!subtitleCuesMap[trackId]) {
|
|
226
|
+
subtitleCuesMap[trackId] = [];
|
|
227
|
+
}
|
|
228
|
+
data.cues.forEach(function (cue) {
|
|
229
|
+
var exists = subtitleCuesMap[trackId].some(function (c) {
|
|
230
|
+
return c.startTime === cue.startTime && c.text === cue.text;
|
|
231
|
+
});
|
|
232
|
+
if (!exists) {
|
|
233
|
+
subtitleCuesMap[trackId].push(cue);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
// Sliding window: drop oldest cues beyond limit to prevent
|
|
237
|
+
// unbounded growth during long live streams.
|
|
238
|
+
if (subtitleCuesMap[trackId].length > SUBTITLE_CUES_MAX) {
|
|
239
|
+
subtitleCuesMap[trackId].splice(0,
|
|
240
|
+
subtitleCuesMap[trackId].length - SUBTITLE_CUES_MAX);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Reset on seek so that:
|
|
245
|
+
// (a) the same cue re-fires after seeking back into its range, and
|
|
246
|
+
// (b) deleteTimer is recalculated from the new position.
|
|
247
|
+
that.on(CONTENT_SEEKED, function () {
|
|
248
|
+
_lastActiveCue = null;
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
that.on(CONTENT_TIME, function (data) {
|
|
252
|
+
// Read the active track directly from hls.js (more reliable than event-based tracking)
|
|
253
|
+
var currentTrackId = hls ? hls.subtitleTrack : -1;
|
|
254
|
+
|
|
255
|
+
if (currentTrackId < 0) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
var cues = subtitleCuesMap[currentTrackId] || [];
|
|
260
|
+
|
|
261
|
+
if (!cues.length) { return; }
|
|
262
|
+
// Use raw video element time to match against hls.js cue timestamps.
|
|
263
|
+
// data.position may be offset by sectionStart, causing a mismatch.
|
|
264
|
+
var position = element.currentTime;
|
|
265
|
+
|
|
266
|
+
// Collect ALL cues active at this position (handles simultaneous & overlapping cues)
|
|
267
|
+
var activeCueObjects = [];
|
|
268
|
+
var maxEndTime = 0;
|
|
269
|
+
for (var i = 0; i < cues.length; i++) {
|
|
270
|
+
if (position >= cues[i].startTime && position < cues[i].endTime) {
|
|
271
|
+
activeCueObjects.push({
|
|
272
|
+
text: cues[i].text,
|
|
273
|
+
line: cues[i].line,
|
|
274
|
+
snapToLines: cues[i].snapToLines,
|
|
275
|
+
position: cues[i].position,
|
|
276
|
+
size: cues[i].size,
|
|
277
|
+
align: cues[i].align,
|
|
278
|
+
vertical: cues[i].vertical
|
|
279
|
+
});
|
|
280
|
+
if (cues[i].endTime > maxEndTime) {
|
|
281
|
+
maxEndTime = cues[i].endTime;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (activeCueObjects.length === 0) {
|
|
287
|
+
_lastActiveCue = null;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
var combinedText = activeCueObjects.map(function(c) { return c.text; }).join('\n');
|
|
292
|
+
if (_lastActiveCue !== combinedText) {
|
|
293
|
+
_lastActiveCue = combinedText;
|
|
294
|
+
that.trigger(CONTENT_CAPTION_CUE_CHANGED, {
|
|
295
|
+
text: combinedText,
|
|
296
|
+
cues: activeCueObjects,
|
|
297
|
+
startTime: position,
|
|
298
|
+
endTime: maxEndTime
|
|
299
|
+
});
|
|
300
|
+
}
|
|
189
301
|
});
|
|
190
302
|
|
|
191
303
|
hls.on(Hls.Events.LEVEL_UPDATED, function (event, data) {
|
|
@@ -305,6 +417,10 @@ const HlsProvider = function (element, playerConfig, adTagUrl) {
|
|
|
305
417
|
hls.stopLoad();
|
|
306
418
|
}
|
|
307
419
|
|
|
420
|
+
subtitleCuesMap = {};
|
|
421
|
+
activeSubtitleTrackId = -1;
|
|
422
|
+
_lastActiveCue = null;
|
|
423
|
+
|
|
308
424
|
superStop_func();
|
|
309
425
|
};
|
|
310
426
|
|
|
@@ -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,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();
|