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
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import _ from "
|
|
2
|
-
|
|
3
|
-
export default (uiText, data) => {
|
|
4
|
-
let elements = '<div id="'+data.id+'" class="op-setting-panel '+(data.isRoot ? 'animated fadeIn': '')+'" style="max-height: '+data.height+'px">' +
|
|
5
|
-
'<div class="op-setting-title-container">' +
|
|
6
|
-
'<div class="op-setting-title" tabindex="0">' +
|
|
7
|
-
(data.isRoot ? '' : '<span class="op-setting-title-previcon"><</span>') +
|
|
8
|
-
'<span class="op-setting-title-title">'+data.title+'</span>' +
|
|
9
|
-
'</div>'+
|
|
10
|
-
'</div>' +
|
|
11
|
-
'<div class="op-setting-item-container">';
|
|
12
|
-
_.forEach(data.body, function(body){
|
|
13
|
-
elements += settingItemTemplate(body, data.useCheck);
|
|
14
|
-
});
|
|
15
|
-
elements+= '</div>' +
|
|
16
|
-
'</div>';
|
|
17
|
-
return elements;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export const settingItemTemplate = (data, useCheck) => {
|
|
22
|
-
return (
|
|
23
|
-
'<div class="op-setting-item" op-panel-type="'+data.panelType+'" op-data-value="'+data.value+'">' +
|
|
24
|
-
(useCheck?'<span class="op-setting-item-checked '+(data.isCheck?'op-show':'')+'">✓</span>':'' )+
|
|
25
|
-
'<span class="op-setting-item-title">'+data.title+'</span>' +
|
|
26
|
-
(data.hasNext?'<span class="op-setting-item-nexticon">></span><span class="op-setting-item-value">'+data.description+'</span>' : '' )+
|
|
27
|
-
'</div>'
|
|
28
|
-
);
|
|
29
|
-
};
|
|
1
|
+
import _ from "underscore";
|
|
2
|
+
|
|
3
|
+
export default (uiText, data) => {
|
|
4
|
+
let elements = '<div id="'+data.id+'" class="op-setting-panel '+(data.isRoot ? 'animated fadeIn': '')+'" style="max-height: '+data.height+'px">' +
|
|
5
|
+
'<div class="op-setting-title-container">' +
|
|
6
|
+
'<div class="op-setting-title" tabindex="0">' +
|
|
7
|
+
(data.isRoot ? '' : '<span class="op-setting-title-previcon"><</span>') +
|
|
8
|
+
'<span class="op-setting-title-title">'+data.title+'</span>' +
|
|
9
|
+
'</div>'+
|
|
10
|
+
'</div>' +
|
|
11
|
+
'<div class="op-setting-item-container">';
|
|
12
|
+
_.forEach(data.body, function(body){
|
|
13
|
+
elements += settingItemTemplate(body, data.useCheck);
|
|
14
|
+
});
|
|
15
|
+
elements+= '</div>' +
|
|
16
|
+
'</div>';
|
|
17
|
+
return elements;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export const settingItemTemplate = (data, useCheck) => {
|
|
22
|
+
return (
|
|
23
|
+
'<div class="op-setting-item" op-panel-type="'+data.panelType+'" op-data-value="'+data.value+'">' +
|
|
24
|
+
(useCheck?'<span class="op-setting-item-checked '+(data.isCheck?'op-show':'')+'">✓</span>':'' )+
|
|
25
|
+
'<span class="op-setting-item-title">'+data.title+'</span>' +
|
|
26
|
+
(data.hasNext?'<span class="op-setting-item-nexticon">></span><span class="op-setting-item-value">'+data.description+'</span>' : '' )+
|
|
27
|
+
'</div>'
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Created by hoho on 2018. 7. 26..
|
|
3
|
-
*/
|
|
4
|
-
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
-
import PanelManager from "view/global/PanelManager";
|
|
6
|
-
import LA$ from 'utils/likeA$';
|
|
7
|
-
import _ from "
|
|
8
|
-
import {
|
|
9
|
-
CONTENT_LEVEL_CHANGED
|
|
10
|
-
} from "api/constants";
|
|
11
|
-
|
|
12
|
-
const QualityPanel = function ($container, api, data) {
|
|
13
|
-
const $root = LA$(api.getContainerElement());
|
|
14
|
-
let panelManager = PanelManager();
|
|
15
|
-
|
|
16
|
-
data.setFront = function(isFront){
|
|
17
|
-
if(isFront){
|
|
18
|
-
$root.find("#"+data.id).removeClass("background");
|
|
19
|
-
}else{
|
|
20
|
-
$root.find("#"+data.id).addClass("background");
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
const onRendered = function($current, template){
|
|
24
|
-
|
|
25
|
-
//This assistants UI when quality level changes. When you open setting panels.
|
|
26
|
-
api.on(CONTENT_LEVEL_CHANGED, function (data) {
|
|
27
|
-
let newQuality = data.currentQuality;
|
|
28
|
-
if(data.type === "render"){
|
|
29
|
-
_.forEach( $root.find("#"+template.data.id).find(".op-setting-item").get(), function(panel){
|
|
30
|
-
let $panel = LA$(panel);
|
|
31
|
-
if( $panel.find(".op-setting-item-checked").hasClass("op-show")){
|
|
32
|
-
$panel.find(".op-setting-item-checked").removeClass("op-show");
|
|
33
|
-
}
|
|
34
|
-
if(!data.isAuto && newQuality === parseInt($panel.attr("op-data-value"))){
|
|
35
|
-
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
36
|
-
}
|
|
37
|
-
if(data.isAuto && $panel.attr("op-data-value") === "AUTO"){
|
|
38
|
-
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}, template);
|
|
43
|
-
};
|
|
44
|
-
const onDestroyed = function(template){
|
|
45
|
-
api.off(CONTENT_LEVEL_CHANGED, null, template);
|
|
46
|
-
};
|
|
47
|
-
const events = {
|
|
48
|
-
"click .op-setting-item": function (event, $current, template) {
|
|
49
|
-
event.preventDefault();
|
|
50
|
-
let value = LA$(event.currentTarget).attr("op-data-value");
|
|
51
|
-
if(value === "AUTO"){
|
|
52
|
-
api.setAutoQuality(true);
|
|
53
|
-
}else{
|
|
54
|
-
api.setCurrentQuality(parseInt(value));
|
|
55
|
-
}
|
|
56
|
-
panelManager.clear();
|
|
57
|
-
},
|
|
58
|
-
"click .op-setting-title" : function(event, $current, template){
|
|
59
|
-
event.preventDefault();
|
|
60
|
-
panelManager.removeLastItem();
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return OvenTemplate($container, "QualityPanel", api.getConfig(), data, events, onRendered, onDestroyed );
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default QualityPanel;
|
|
1
|
+
/**
|
|
2
|
+
* Created by hoho on 2018. 7. 26..
|
|
3
|
+
*/
|
|
4
|
+
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
+
import PanelManager from "view/global/PanelManager";
|
|
6
|
+
import LA$ from 'utils/likeA$';
|
|
7
|
+
import _ from "underscore";
|
|
8
|
+
import {
|
|
9
|
+
CONTENT_LEVEL_CHANGED
|
|
10
|
+
} from "api/constants";
|
|
11
|
+
|
|
12
|
+
const QualityPanel = function ($container, api, data) {
|
|
13
|
+
const $root = LA$(api.getContainerElement());
|
|
14
|
+
let panelManager = PanelManager();
|
|
15
|
+
|
|
16
|
+
data.setFront = function(isFront){
|
|
17
|
+
if(isFront){
|
|
18
|
+
$root.find("#"+data.id).removeClass("background");
|
|
19
|
+
}else{
|
|
20
|
+
$root.find("#"+data.id).addClass("background");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const onRendered = function($current, template){
|
|
24
|
+
|
|
25
|
+
//This assistants UI when quality level changes. When you open setting panels.
|
|
26
|
+
api.on(CONTENT_LEVEL_CHANGED, function (data) {
|
|
27
|
+
let newQuality = data.currentQuality;
|
|
28
|
+
if(data.type === "render"){
|
|
29
|
+
_.forEach( $root.find("#"+template.data.id).find(".op-setting-item").get(), function(panel){
|
|
30
|
+
let $panel = LA$(panel);
|
|
31
|
+
if( $panel.find(".op-setting-item-checked").hasClass("op-show")){
|
|
32
|
+
$panel.find(".op-setting-item-checked").removeClass("op-show");
|
|
33
|
+
}
|
|
34
|
+
if(!data.isAuto && newQuality === parseInt($panel.attr("op-data-value"))){
|
|
35
|
+
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
36
|
+
}
|
|
37
|
+
if(data.isAuto && $panel.attr("op-data-value") === "AUTO"){
|
|
38
|
+
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}, template);
|
|
43
|
+
};
|
|
44
|
+
const onDestroyed = function(template){
|
|
45
|
+
api.off(CONTENT_LEVEL_CHANGED, null, template);
|
|
46
|
+
};
|
|
47
|
+
const events = {
|
|
48
|
+
"click .op-setting-item": function (event, $current, template) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
let value = LA$(event.currentTarget).attr("op-data-value");
|
|
51
|
+
if(value === "AUTO"){
|
|
52
|
+
api.setAutoQuality(true);
|
|
53
|
+
}else{
|
|
54
|
+
api.setCurrentQuality(parseInt(value));
|
|
55
|
+
}
|
|
56
|
+
panelManager.clear();
|
|
57
|
+
},
|
|
58
|
+
"click .op-setting-title" : function(event, $current, template){
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
panelManager.removeLastItem();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return OvenTemplate($container, "QualityPanel", api.getConfig(), data, events, onRendered, onDestroyed );
|
|
65
|
+
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default QualityPanel;
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Created by hoho on 2018. 7. 26..
|
|
3
|
-
*/
|
|
4
|
-
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
-
import PanelManager from "view/global/PanelManager";
|
|
6
|
-
import LA$ from 'utils/likeA$';
|
|
7
|
-
import {
|
|
8
|
-
SUBTITLE_TRACK_CHANGED
|
|
9
|
-
} from "api/constants";
|
|
10
|
-
import _ from "
|
|
11
|
-
|
|
12
|
-
const SubtitleTrackPanel = function ($container, api, data) {
|
|
13
|
-
const $root = LA$(api.getContainerElement());
|
|
14
|
-
let panelManager = PanelManager();
|
|
15
|
-
|
|
16
|
-
data.setFront = function (isFront) {
|
|
17
|
-
if (isFront) {
|
|
18
|
-
$root.find("#" + data.id).removeClass("background");
|
|
19
|
-
} else {
|
|
20
|
-
$root.find("#" + data.id).addClass("background");
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
const onRendered = function ($current, template) {
|
|
24
|
-
api.on(SUBTITLE_TRACK_CHANGED, function (data) {
|
|
25
|
-
_.forEach($root.find("#" + template.data.id).find(".op-setting-item").get(), function (panel) {
|
|
26
|
-
let $panel = LA$(panel);
|
|
27
|
-
|
|
28
|
-
if ($panel.find(".op-setting-item-checked").hasClass("op-show")) {
|
|
29
|
-
$panel.find(".op-setting-item-checked").removeClass("op-show");
|
|
30
|
-
}
|
|
31
|
-
if (data.currentSubtitleTrack === parseInt($panel.attr("op-data-value"))) {
|
|
32
|
-
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}, template);
|
|
36
|
-
};
|
|
37
|
-
const onDestroyed = function (template) {
|
|
38
|
-
api.off(SUBTITLE_TRACK_CHANGED, null, template);
|
|
39
|
-
};
|
|
40
|
-
const events = {
|
|
41
|
-
"click .op-setting-item": function (event, $current, template) {
|
|
42
|
-
event.preventDefault();
|
|
43
|
-
let value = LA$(event.currentTarget).attr("op-data-value");
|
|
44
|
-
api.setCurrentSubtitleTrack(parseInt(value));
|
|
45
|
-
panelManager.clear();
|
|
46
|
-
},
|
|
47
|
-
"click .op-setting-title": function (event, $current, template) {
|
|
48
|
-
event.preventDefault();
|
|
49
|
-
panelManager.removeLastItem();
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
return OvenTemplate($container, "SubtitleTrackPanel", api.getConfig(), data, events, onRendered, onDestroyed);
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Created by hoho on 2018. 7. 26..
|
|
3
|
+
*/
|
|
4
|
+
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
+
import PanelManager from "view/global/PanelManager";
|
|
6
|
+
import LA$ from 'utils/likeA$';
|
|
7
|
+
import {
|
|
8
|
+
SUBTITLE_TRACK_CHANGED
|
|
9
|
+
} from "api/constants";
|
|
10
|
+
import _ from "underscore";
|
|
11
|
+
|
|
12
|
+
const SubtitleTrackPanel = function ($container, api, data) {
|
|
13
|
+
const $root = LA$(api.getContainerElement());
|
|
14
|
+
let panelManager = PanelManager();
|
|
15
|
+
|
|
16
|
+
data.setFront = function (isFront) {
|
|
17
|
+
if (isFront) {
|
|
18
|
+
$root.find("#" + data.id).removeClass("background");
|
|
19
|
+
} else {
|
|
20
|
+
$root.find("#" + data.id).addClass("background");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const onRendered = function ($current, template) {
|
|
24
|
+
api.on(SUBTITLE_TRACK_CHANGED, function (data) {
|
|
25
|
+
_.forEach($root.find("#" + template.data.id).find(".op-setting-item").get(), function (panel) {
|
|
26
|
+
let $panel = LA$(panel);
|
|
27
|
+
|
|
28
|
+
if ($panel.find(".op-setting-item-checked").hasClass("op-show")) {
|
|
29
|
+
$panel.find(".op-setting-item-checked").removeClass("op-show");
|
|
30
|
+
}
|
|
31
|
+
if (data.currentSubtitleTrack === parseInt($panel.attr("op-data-value"))) {
|
|
32
|
+
$panel.find(".op-setting-item-checked").addClass("op-show");
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}, template);
|
|
36
|
+
};
|
|
37
|
+
const onDestroyed = function (template) {
|
|
38
|
+
api.off(SUBTITLE_TRACK_CHANGED, null, template);
|
|
39
|
+
};
|
|
40
|
+
const events = {
|
|
41
|
+
"click .op-setting-item": function (event, $current, template) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
let value = LA$(event.currentTarget).attr("op-data-value");
|
|
44
|
+
api.setCurrentSubtitleTrack(parseInt(value));
|
|
45
|
+
panelManager.clear();
|
|
46
|
+
},
|
|
47
|
+
"click .op-setting-title": function (event, $current, template) {
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
panelManager.removeLastItem();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return OvenTemplate($container, "SubtitleTrackPanel", api.getConfig(), data, events, onRendered, onDestroyed);
|
|
54
|
+
|
|
55
|
+
};
|
|
56
|
+
|
|
57
57
|
export default SubtitleTrackPanel;
|
|
@@ -20,46 +20,128 @@ const CaptionViewer = function($container, api, playerState){
|
|
|
20
20
|
let isDisable = false;
|
|
21
21
|
let deleteTimer = 0;
|
|
22
22
|
|
|
23
|
+
// Convert VTTCue settings to inline style string for .op-caption-cue wrapper
|
|
24
|
+
function cueToStyleStr(cue) {
|
|
25
|
+
const parts = [];
|
|
26
|
+
|
|
27
|
+
// Writing mode (vertical subtitles)
|
|
28
|
+
if (cue.vertical === 'rl') { parts.push('writing-mode:vertical-rl'); }
|
|
29
|
+
else if (cue.vertical === 'lr') { parts.push('writing-mode:vertical-lr'); }
|
|
30
|
+
|
|
31
|
+
// Width from size (0–100, default 100)
|
|
32
|
+
const size = (typeof cue.size === 'number') ? cue.size : 100;
|
|
33
|
+
parts.push('width:' + size + '%');
|
|
34
|
+
|
|
35
|
+
// Text alignment
|
|
36
|
+
let textAlign = 'center';
|
|
37
|
+
if (cue.align === 'start' || cue.align === 'left') { textAlign = 'left'; }
|
|
38
|
+
else if (cue.align === 'end' || cue.align === 'right') { textAlign = 'right'; }
|
|
39
|
+
parts.push('text-align:' + textAlign);
|
|
40
|
+
|
|
41
|
+
// Horizontal position (left + translateX)
|
|
42
|
+
// VTT spec: position:auto resolves based on align
|
|
43
|
+
// left/start → 0%, right/end → 100%, center → 50%
|
|
44
|
+
let posLeft;
|
|
45
|
+
if (cue.position !== 'auto' && typeof cue.position === 'number') {
|
|
46
|
+
posLeft = cue.position;
|
|
47
|
+
} else {
|
|
48
|
+
posLeft = textAlign === 'left' ? 0 : textAlign === 'right' ? 100 : 50;
|
|
49
|
+
}
|
|
50
|
+
parts.push('left:' + posLeft + '%');
|
|
51
|
+
const xOff = textAlign === 'left' ? '0%' : textAlign === 'right' ? '-100%' : '-50%';
|
|
52
|
+
parts.push('transform:translateX(' + xOff + ')');
|
|
53
|
+
|
|
54
|
+
// Vertical position — must explicitly set both top and bottom to override CSS bottom:60px
|
|
55
|
+
if (cue.line !== 'auto' && typeof cue.line === 'number') {
|
|
56
|
+
if (!cue.snapToLines) {
|
|
57
|
+
// Percentage mode: line% = top edge of cue from top of player (VTT spec)
|
|
58
|
+
// Text grows downward from this point.
|
|
59
|
+
parts.push('top:' + cue.line + '%');
|
|
60
|
+
parts.push('bottom:auto');
|
|
61
|
+
} else {
|
|
62
|
+
// Integer line number mode (e.g. line:-1)
|
|
63
|
+
if (cue.line < 0) {
|
|
64
|
+
parts.push('top:auto');
|
|
65
|
+
parts.push('bottom:' + (Math.abs(cue.line + 1) * 8) + '%');
|
|
66
|
+
} else {
|
|
67
|
+
parts.push('top:' + (cue.line * 8) + '%');
|
|
68
|
+
parts.push('bottom:auto');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return parts.join(';');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function renderCues(cues) {
|
|
77
|
+
let html = '';
|
|
78
|
+
cues.forEach(function(cue) {
|
|
79
|
+
// A cue is "positioned" when line, position, or size is explicitly set
|
|
80
|
+
// (non-default values). Positioned cues skip the default padding/bottom CSS.
|
|
81
|
+
const hasLine = cue.line !== 'auto' && typeof cue.line === 'number';
|
|
82
|
+
const hasPosition = cue.position !== 'auto' && typeof cue.position === 'number';
|
|
83
|
+
const hasSize = typeof cue.size === 'number' && cue.size !== 100;
|
|
84
|
+
const isPositioned = hasLine || hasPosition || hasSize;
|
|
85
|
+
const cls = 'op-caption-cue' + (isPositioned ? ' op-caption-cue-positioned' : '');
|
|
86
|
+
html += '<div class="' + cls + '" style="' + cueToStyleStr(cue) + '">' +
|
|
87
|
+
'<div class="op-caption-text">' + cue.text + '</div>' +
|
|
88
|
+
'</div>';
|
|
89
|
+
});
|
|
90
|
+
$container.find(".op-caption-text-container").html(html);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function clearCues() {
|
|
94
|
+
$container.find(".op-caption-text-container").html('');
|
|
95
|
+
}
|
|
96
|
+
|
|
23
97
|
api.on(CONTENT_CAPTION_CHANGED, function(index) {
|
|
24
98
|
if(index > -1){
|
|
25
99
|
isDisable = false;
|
|
26
100
|
}else{
|
|
27
|
-
isDisable
|
|
28
|
-
|
|
101
|
+
isDisable = true;
|
|
102
|
+
clearCues();
|
|
29
103
|
}
|
|
30
104
|
}, template);
|
|
31
105
|
|
|
32
106
|
api.on(CONTENT_CAPTION_CUE_CHANGED, function(data) {
|
|
33
|
-
if(!isDisable && data && data.text){
|
|
107
|
+
if(!isDisable && data && (data.text || (data.cues && data.cues.length))){
|
|
34
108
|
let hideGap = data.endTime - data.startTime;
|
|
35
109
|
|
|
36
110
|
if(deleteTimer){
|
|
37
111
|
clearTimeout(deleteTimer);
|
|
38
112
|
}
|
|
39
113
|
|
|
40
|
-
|
|
114
|
+
// Normalize: legacy data.text → single default-positioned cue
|
|
115
|
+
const cues = data.cues || [{
|
|
116
|
+
text: data.text,
|
|
117
|
+
line: 'auto',
|
|
118
|
+
snapToLines: true,
|
|
119
|
+
position: 'auto',
|
|
120
|
+
size: 100,
|
|
121
|
+
align: 'center',
|
|
122
|
+
vertical: ''
|
|
123
|
+
}];
|
|
124
|
+
|
|
125
|
+
renderCues(cues);
|
|
41
126
|
|
|
42
127
|
if(hideGap){
|
|
43
128
|
deleteTimer = setTimeout(function(){
|
|
44
|
-
|
|
45
|
-
},hideGap * 1000);
|
|
129
|
+
clearCues();
|
|
130
|
+
}, hideGap * 1000);
|
|
46
131
|
}
|
|
47
|
-
|
|
48
132
|
}
|
|
49
|
-
|
|
50
133
|
}, template);
|
|
51
|
-
|
|
52
|
-
|
|
53
134
|
};
|
|
135
|
+
|
|
54
136
|
const onDestroyed = function(template){
|
|
55
|
-
$container.find(".op-caption-text").
|
|
137
|
+
$container.find(".op-caption-text-container").html('');
|
|
56
138
|
api.off(CONTENT_CAPTION_CHANGED, null, template);
|
|
57
139
|
api.off(CONTENT_CAPTION_CUE_CHANGED, null, template);
|
|
58
140
|
};
|
|
59
|
-
const events = {
|
|
60
|
-
};
|
|
61
141
|
|
|
62
|
-
|
|
142
|
+
const events = {};
|
|
143
|
+
|
|
144
|
+
return OvenTemplate($container, "CaptionViewer", api.getConfig(), playerState, events, onRendered, onDestroyed);
|
|
63
145
|
};
|
|
64
146
|
|
|
65
|
-
export default CaptionViewer;
|
|
147
|
+
export default CaptionViewer;
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Created by Sangwon Oh on 2020. 11. 10..
|
|
3
|
-
*/
|
|
4
|
-
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
-
import _ from '
|
|
6
|
-
import {
|
|
7
|
-
STATE_IDLE,
|
|
8
|
-
STATE_PLAYING,
|
|
9
|
-
STATE_COMPLETE,
|
|
10
|
-
STATE_PAUSED
|
|
11
|
-
} from "api/constants";
|
|
12
|
-
|
|
13
|
-
const WaterMark = function($container, api, playerState){
|
|
14
|
-
|
|
15
|
-
let waterMark = null;
|
|
16
|
-
let textElem = null;
|
|
17
|
-
const defaultPosition = 'top-right';
|
|
18
|
-
const defaultX = '2.8125%';
|
|
19
|
-
const defaultY = '5%';
|
|
20
|
-
const defaultWidth = 'auto';
|
|
21
|
-
const defaultHeight = 'auto';
|
|
22
|
-
const defaultOpacity = 0.7;
|
|
23
|
-
|
|
24
|
-
const onRendered = function($current, template){
|
|
25
|
-
|
|
26
|
-
waterMark = $current.find('.op-watermark');
|
|
27
|
-
textElem = $current.find('.op-watermark-text');
|
|
28
|
-
|
|
29
|
-
let waterMarkOption = api.getConfig().waterMark;
|
|
30
|
-
|
|
31
|
-
let position = waterMarkOption.position || defaultPosition;
|
|
32
|
-
|
|
33
|
-
let y = waterMarkOption.y || defaultY;
|
|
34
|
-
let x = waterMarkOption.x || defaultX;
|
|
35
|
-
|
|
36
|
-
waterMark.css(position.split('-')[0], y);
|
|
37
|
-
waterMark.css(position.split('-')[1], x);
|
|
38
|
-
|
|
39
|
-
let width = waterMarkOption.width || defaultWidth;
|
|
40
|
-
let height = waterMarkOption.height || defaultHeight;
|
|
41
|
-
|
|
42
|
-
waterMark.css('width', width);
|
|
43
|
-
waterMark.css('height', height);
|
|
44
|
-
|
|
45
|
-
let opacity = waterMarkOption.opacity || defaultOpacity;
|
|
46
|
-
waterMark.css('opacity', opacity);
|
|
47
|
-
|
|
48
|
-
if (waterMarkOption.text) {
|
|
49
|
-
|
|
50
|
-
if (waterMarkOption.font) {
|
|
51
|
-
|
|
52
|
-
_.each(waterMarkOption.font, function (value, key) {
|
|
53
|
-
textElem.css(key, value);
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
};
|
|
59
|
-
const onDestroyed = function(){
|
|
60
|
-
//Do nothing!
|
|
61
|
-
};
|
|
62
|
-
const events = {
|
|
63
|
-
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
return OvenTemplate($container, "WaterMark", api.getConfig(), playerState, events, onRendered, onDestroyed );
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export default WaterMark;
|
|
1
|
+
/**
|
|
2
|
+
* Created by Sangwon Oh on 2020. 11. 10..
|
|
3
|
+
*/
|
|
4
|
+
import OvenTemplate from 'view/engine/OvenTemplate';
|
|
5
|
+
import _ from 'underscore';
|
|
6
|
+
import {
|
|
7
|
+
STATE_IDLE,
|
|
8
|
+
STATE_PLAYING,
|
|
9
|
+
STATE_COMPLETE,
|
|
10
|
+
STATE_PAUSED
|
|
11
|
+
} from "api/constants";
|
|
12
|
+
|
|
13
|
+
const WaterMark = function($container, api, playerState){
|
|
14
|
+
|
|
15
|
+
let waterMark = null;
|
|
16
|
+
let textElem = null;
|
|
17
|
+
const defaultPosition = 'top-right';
|
|
18
|
+
const defaultX = '2.8125%';
|
|
19
|
+
const defaultY = '5%';
|
|
20
|
+
const defaultWidth = 'auto';
|
|
21
|
+
const defaultHeight = 'auto';
|
|
22
|
+
const defaultOpacity = 0.7;
|
|
23
|
+
|
|
24
|
+
const onRendered = function($current, template){
|
|
25
|
+
|
|
26
|
+
waterMark = $current.find('.op-watermark');
|
|
27
|
+
textElem = $current.find('.op-watermark-text');
|
|
28
|
+
|
|
29
|
+
let waterMarkOption = api.getConfig().waterMark;
|
|
30
|
+
|
|
31
|
+
let position = waterMarkOption.position || defaultPosition;
|
|
32
|
+
|
|
33
|
+
let y = waterMarkOption.y || defaultY;
|
|
34
|
+
let x = waterMarkOption.x || defaultX;
|
|
35
|
+
|
|
36
|
+
waterMark.css(position.split('-')[0], y);
|
|
37
|
+
waterMark.css(position.split('-')[1], x);
|
|
38
|
+
|
|
39
|
+
let width = waterMarkOption.width || defaultWidth;
|
|
40
|
+
let height = waterMarkOption.height || defaultHeight;
|
|
41
|
+
|
|
42
|
+
waterMark.css('width', width);
|
|
43
|
+
waterMark.css('height', height);
|
|
44
|
+
|
|
45
|
+
let opacity = waterMarkOption.opacity || defaultOpacity;
|
|
46
|
+
waterMark.css('opacity', opacity);
|
|
47
|
+
|
|
48
|
+
if (waterMarkOption.text) {
|
|
49
|
+
|
|
50
|
+
if (waterMarkOption.font) {
|
|
51
|
+
|
|
52
|
+
_.each(waterMarkOption.font, function (value, key) {
|
|
53
|
+
textElem.css(key, value);
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
};
|
|
59
|
+
const onDestroyed = function(){
|
|
60
|
+
//Do nothing!
|
|
61
|
+
};
|
|
62
|
+
const events = {
|
|
63
|
+
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return OvenTemplate($container, "WaterMark", api.getConfig(), playerState, events, onRendered, onDestroyed );
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default WaterMark;
|