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.
Files changed (34) hide show
  1. package/dist/ovenplayer.js +1 -1
  2. package/dist/ovenplayer.js.map +1 -1
  3. package/package.json +49 -49
  4. package/src/js/api/Configurator.js +1 -1
  5. package/src/js/api/ads/vast/Ad.js +237 -237
  6. package/src/js/api/caption/Loader.js +1 -1
  7. package/src/js/api/caption/Manager.js +1 -1
  8. package/src/js/api/caption/parser/VttParser.js +1541 -1542
  9. package/src/js/api/playlist/Manager.js +229 -229
  10. package/src/js/api/provider/html5/providers/Dash.js +286 -286
  11. package/src/js/api/provider/html5/providers/Hls.js +110 -2
  12. package/src/js/api/provider/html5/providers/WebRTC.js +2 -1
  13. package/src/js/api/provider/html5/providers/WebRTCLoader.js +35 -2
  14. package/src/js/api/provider/utils.js +69 -69
  15. package/src/js/ovenplayer.sdk.js +143 -143
  16. package/src/js/utils/likeA$.js +241 -242
  17. package/src/js/utils/resize-sensor.js +145 -168
  18. package/src/js/utils/strings.js +104 -104
  19. package/src/js/view/components/controls/settingPanel/audioTrackPanel.js +57 -57
  20. package/src/js/view/components/controls/settingPanel/main.js +1 -1
  21. package/src/js/view/components/controls/settingPanel/mainTemplate.js +29 -29
  22. package/src/js/view/components/controls/settingPanel/qualityPanel.js +68 -68
  23. package/src/js/view/components/controls/settingPanel/subtitleTrackPanel.js +56 -56
  24. package/src/js/view/components/helpers/captionViewer.js +97 -15
  25. package/src/js/view/components/helpers/captionViewerTemplate.js +1 -2
  26. package/src/js/view/components/helpers/waterMark.js +69 -69
  27. package/src/js/view/engine/OvenTemplate.js +158 -158
  28. package/src/js/view/global/PanelManager.js +47 -47
  29. package/src/stylesheet/ovenplayer.less +52 -21
  30. package/src/js/utils/adapter.js +0 -4944
  31. package/src/js/utils/captions/vttCue.js +0 -308
  32. package/src/js/utils/captions/vttRegion.js +0 -136
  33. package/src/js/utils/polyfills/dom.js +0 -634
  34. package/src/js/utils/underscore.js +0 -6
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "ovenplayer",
3
- "version": "0.10.49",
4
- "description": "OvenPlayer is Open-Source HTML5 Player. OvenPlayer supports WebRTC Signaling from OvenMediaEngine for Sub-Second Latency Streaming.",
5
- "main": "dist/ovenplayer.js",
6
- "scripts": {
7
- "watch": "webpack --config webpack.development.js --watch",
8
- "build": "webpack --config webpack.config.js"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/OvenMediaLabs/OvenPlayer.git"
13
- },
14
- "keywords": [
15
- "Sub-Second Latency Streaming",
16
- "WebRTC",
17
- "OvenMediaEngine",
18
- "Low Latency HTTP",
19
- "MPEG-DASH",
20
- "HLS",
21
- "HTML5",
22
- "Video",
23
- "Player"
24
- ],
25
- "author": "OvenMedia Labs Inc.",
26
- "license": "MIT",
27
- "bugs": {
28
- "url": "https://github.com/OvenMediaLabs/OvenPlayer/issues"
29
- },
30
- "homepage": "https://www.ovenmediaengine.com/ovenplayer",
31
- "devDependencies": {
32
- "@babel/core": "^7.15.0",
33
- "@babel/preset-env": "^7.15.0",
34
- "babel-loader": "^8.2.2",
35
- "css-loader": "^6.2.0",
36
- "less": "^4.1.1",
37
- "less-loader": "^10.0.1",
38
- "style-loader": "^3.2.1",
39
- "webpack": "^5.51.1",
40
- "webpack-bundle-analyzer": "^3.0.3",
41
- "webpack-cli": "^4.8.0",
42
- "webpack-merge": "^5.8.0",
43
- "raw-loader": "^4.0.2"
44
- },
45
- "dependencies": {
46
- "core-js": "^3.16.3",
47
- "whatwg-fetch": "^3.6.2"
48
- }
49
- }
1
+ {
2
+ "name": "ovenplayer",
3
+ "version": "0.10.51",
4
+ "description": "OvenPlayer is Open-Source HTML5 Player. OvenPlayer supports WebRTC Signaling from OvenMediaEngine for Sub-Second Latency Streaming.",
5
+ "main": "dist/ovenplayer.js",
6
+ "scripts": {
7
+ "watch": "webpack --config webpack.development.js --watch",
8
+ "build": "webpack --config webpack.config.js"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/OvenMediaLabs/OvenPlayer.git"
13
+ },
14
+ "keywords": [
15
+ "Sub-Second Latency Streaming",
16
+ "WebRTC",
17
+ "OvenMediaEngine",
18
+ "Low Latency HTTP",
19
+ "MPEG-DASH",
20
+ "HLS",
21
+ "HTML5",
22
+ "Video",
23
+ "Player"
24
+ ],
25
+ "author": "OvenMedia Labs Inc.",
26
+ "license": "MIT",
27
+ "bugs": {
28
+ "url": "https://github.com/OvenMediaLabs/OvenPlayer/issues"
29
+ },
30
+ "homepage": "https://github.com/OvenMediaLabs/OvenPlayer",
31
+ "devDependencies": {
32
+ "@babel/core": "^7.15.0",
33
+ "@babel/preset-env": "^7.15.0",
34
+ "@types/google_interactive_media_ads_types": "^3.697.1",
35
+ "babel-loader": "^8.2.2",
36
+ "core-js": "^3.16.3",
37
+ "css-loader": "^6.2.0",
38
+ "less": "^4.1.1",
39
+ "less-loader": "^10.0.1",
40
+ "media-captions": "^0.0.18",
41
+ "raw-loader": "^4.0.2",
42
+ "style-loader": "^3.2.1",
43
+ "underscore": "^1.13.7",
44
+ "webpack": "^5.51.1",
45
+ "webpack-bundle-analyzer": "^3.0.3",
46
+ "webpack-cli": "^4.8.0",
47
+ "webpack-merge": "^5.8.0"
48
+ }
49
+ }
@@ -1,4 +1,4 @@
1
- import _ from "utils/underscore";
1
+ import _ from "underscore";
2
2
  import deepMerge from "utils/deepMerge";
3
3
 
4
4
  import {
@@ -1,237 +1,237 @@
1
- /**
2
- * Created by hoho on 25/06/2019.
3
- */
4
-
5
- import { VASTClient, VASTTracker } from 'utils/vast-client';
6
- import AdsEventsListener from "api/ads/vast/Listener";
7
- import {TEMP_VIDEO_URL} from "api/ads/utils";
8
- import {
9
- ERROR,
10
- STATE_IDLE,
11
- STATE_PLAYING,
12
- STATE_STALLED,
13
- STATE_LOADING,
14
- STATE_COMPLETE,
15
- STATE_AD_LOADED,
16
- STATE_AD_PLAYING,
17
- STATE_AD_PAUSED,
18
- STATE_AD_COMPLETE,
19
- STATE_AD_ERROR,
20
- CONTENT_META,
21
- PROVIDER_DASH
22
- } from "api/constants";
23
-
24
- const Ad = function(elVideo, provider, playerConfig, adTagUrl){
25
- const AUTOPLAY_NOT_ALLOWED = "autoplayNotAllowed";
26
-
27
- let that = {};
28
- let spec = {
29
- started: false, //player started
30
- active : false, //on Ad
31
- isVideoEnded : false,
32
- lang : playerConfig.getLanguage()
33
- };
34
- let adsErrorOccurred = false;
35
- let listener = null;
36
-
37
- let container = "";
38
- let elAdVideo = null;
39
- let textView = "";
40
- let adButton = "";
41
-
42
- let autoplayAllowed = false, autoplayRequiresMuted = false;
43
- let browser = playerConfig.getBrowser();
44
- let isMobile = browser.os === "Android" || browser.os === "iOS";
45
-
46
- const createAdContainer = () => {
47
- let adContainer = document.createElement('div');
48
- adContainer.setAttribute('class', 'op-ads');
49
- adContainer.setAttribute('id', 'op-ads');
50
- playerConfig.getContainer().append(adContainer);
51
-
52
- elAdVideo = document.createElement('video');
53
- elAdVideo.setAttribute('playsinline', 'true');
54
- elAdVideo.setAttribute('title', 'Advertisement');
55
- elAdVideo.setAttribute('class', 'op-ads-vast-video');
56
-
57
- adButton = document.createElement('div');
58
- adButton.setAttribute('class', 'op-ads-button');
59
-
60
- textView = document.createElement('div');
61
- textView.setAttribute('class', 'op-ads-textview');
62
-
63
- adButton.append(textView);
64
- adContainer.append(elAdVideo);
65
- adContainer.append(adButton);
66
-
67
- return adContainer;
68
- };
69
-
70
- container = createAdContainer();
71
-
72
- let vastClient = new VASTClient();
73
- let vastTracker = null;
74
- let ad = null;
75
-
76
-
77
- const OnAdError = function(error){
78
- console.log(error);
79
- adsErrorOccurred = true;
80
- elAdVideo.style.display = "none";
81
- provider.trigger(STATE_AD_ERROR, {code : error.code, message : error.message});
82
- spec.active = false;
83
- spec.started = true;
84
- provider.play();
85
- };
86
-
87
- const initRequest = function () {
88
- vastClient.get(adTagUrl) .then(res => {
89
- // Do something with the parsed VAST response
90
- OvenPlayerConsole.log("VAST : initRequest()");
91
- ad = res.ads[0];
92
- if(!ad){
93
- throw {code : 401, message : "File not found. Unable to find Linear/MediaFile from URI."};
94
- }
95
- vastTracker = new VASTTracker(vastClient, ad, ad.creatives[0]);
96
-
97
- OvenPlayerConsole.log("VAST : created ad tracker.");
98
-
99
- listener = AdsEventsListener(elAdVideo, vastTracker, provider, spec, adButton, textView, OnAdError);
100
-
101
- let videoURL = "";
102
- if(ad.creatives && ad.creatives.length > 0 && ad.creatives[0].mediaFiles && ad.creatives[0].mediaFiles.length > 0 && ad.creatives[0].mediaFiles[0].fileURL){
103
- videoURL = ad.creatives[0].mediaFiles[0].fileURL;
104
- OvenPlayerConsole.log("VAST : media url : ", videoURL);
105
- }
106
- elAdVideo.src = videoURL;
107
-
108
- //keep volume even if playlist item changes.
109
- elAdVideo.volume = elVideo.volume;
110
- elAdVideo.muted = elVideo.muted;
111
-
112
- }).catch(function(error){
113
- OnAdError(error);
114
- });
115
-
116
- };
117
-
118
-
119
-
120
- const checkAutoplaySupport = function () {
121
- OvenPlayerConsole.log("VAST : checkAutoplaySupport() ");
122
-
123
- let temporarySupportCheckVideo = document.createElement('video');
124
- temporarySupportCheckVideo.setAttribute('playsinline', 'true');
125
- temporarySupportCheckVideo.src = TEMP_VIDEO_URL;
126
- temporarySupportCheckVideo.load();
127
-
128
-
129
- elAdVideo.load(); //for ios User Interaction problem
130
- //Dash has already loaded when triggered provider.play() always.
131
- if(isMobile && provider.getName() !== PROVIDER_DASH ){
132
- //Main video sets user gesture when temporarySupportCheckVideo triggered checking.
133
- elVideo.load();
134
- }
135
- const clearAndReport = function(_autoplayAllowed, _autoplayRequiresMuted){
136
- autoplayAllowed = _autoplayAllowed;
137
- autoplayRequiresMuted = _autoplayRequiresMuted;
138
- temporarySupportCheckVideo.pause();
139
- temporarySupportCheckVideo.remove();
140
- };
141
-
142
- return new Promise(function(resolve, reject){
143
- if(!temporarySupportCheckVideo.play){
144
- //I can't remember this case...
145
- OvenPlayerConsole.log("VAST : !temporarySupportCheckVideo.play");
146
- clearAndReport(true, false);
147
- resolve();
148
- }else{
149
- let playPromise = temporarySupportCheckVideo.play();
150
- if (playPromise !== undefined) {
151
- playPromise.then(function(){
152
- OvenPlayerConsole.log("VAST : auto play allowed.");
153
- // If we make it here, unmuted autoplay works.
154
- clearAndReport(true, false);
155
- resolve();
156
- }).catch(function(error){
157
- OvenPlayerConsole.log("VAST : auto play failed", error.message);
158
- clearAndReport(false, false);
159
- resolve();
160
- });
161
- }else{
162
- OvenPlayerConsole.log("VAST : promise not support");
163
- //Maybe this is IE11....
164
- clearAndReport(true, false);
165
- resolve();
166
- }
167
- }
168
- });
169
- }
170
- that.isActive = () => {
171
- return spec.active;
172
- };
173
- that.started = () => {
174
- return spec.started;
175
- };
176
- that.play = () => {
177
- if(spec.started){
178
- return elAdVideo.play();
179
- }else{
180
- return new Promise(function (resolve, reject) {
181
-
182
- const checkMainContentLoaded = function(){
183
-
184
- //wait for main contents meta loaded.
185
- //have to trigger CONTENT_META first. next trigger AD_CHANGED.
186
- //initControlUI first -> init ad UI
187
- //Maybe google ima waits content loaded internal.
188
- if(provider.metaLoaded()){
189
- OvenPlayerConsole.log("VAST : main contents meta loaded.");
190
- checkAutoplaySupport().then(function(){
191
- if( (playerConfig.isAutoStart() && !autoplayAllowed) ){
192
- OvenPlayerConsole.log("VAST : autoplayAllowed : false");
193
- spec.started = false;
194
- reject(new Error(AUTOPLAY_NOT_ALLOWED));
195
- }else{
196
- initRequest();
197
-
198
- resolve();
199
- }
200
- });
201
-
202
- }else{
203
- setTimeout(checkMainContentLoaded, 100);
204
- }
205
-
206
- };
207
- checkMainContentLoaded();
208
-
209
- });
210
- }
211
- };
212
- that.pause = () => {
213
- elAdVideo.pause();
214
- };
215
-
216
- //End Of Main Contents.
217
- that.videoEndedCallback = (completeContentCallback) => {
218
-
219
- completeContentCallback();
220
- //check true when main contents ended.
221
- spec.isVideoEnded = true;
222
- };
223
- that.destroy = () => {
224
- if(listener){
225
- listener.destroy();
226
- listener = null;
227
- }
228
- vastTracker = null;
229
- vastClient = null;
230
-
231
- container.remove();
232
-
233
- };
234
- return that;
235
- };
236
-
237
- export default Ad;
1
+ /**
2
+ * Created by hoho on 25/06/2019.
3
+ */
4
+
5
+ import { VASTClient, VASTTracker } from 'utils/vast-client';
6
+ import AdsEventsListener from "api/ads/vast/Listener";
7
+ import {TEMP_VIDEO_URL} from "api/ads/utils";
8
+ import {
9
+ ERROR,
10
+ STATE_IDLE,
11
+ STATE_PLAYING,
12
+ STATE_STALLED,
13
+ STATE_LOADING,
14
+ STATE_COMPLETE,
15
+ STATE_AD_LOADED,
16
+ STATE_AD_PLAYING,
17
+ STATE_AD_PAUSED,
18
+ STATE_AD_COMPLETE,
19
+ STATE_AD_ERROR,
20
+ CONTENT_META,
21
+ PROVIDER_DASH
22
+ } from "api/constants";
23
+
24
+ const Ad = function(elVideo, provider, playerConfig, adTagUrl){
25
+ const AUTOPLAY_NOT_ALLOWED = "autoplayNotAllowed";
26
+
27
+ let that = {};
28
+ let spec = {
29
+ started: false, //player started
30
+ active : false, //on Ad
31
+ isVideoEnded : false,
32
+ lang : playerConfig.getLanguage()
33
+ };
34
+ let adsErrorOccurred = false;
35
+ let listener = null;
36
+
37
+ let container = "";
38
+ let elAdVideo = null;
39
+ let textView = "";
40
+ let adButton = "";
41
+
42
+ let autoplayAllowed = false, autoplayRequiresMuted = false;
43
+ let browser = playerConfig.getBrowser();
44
+ let isMobile = browser.os === "Android" || browser.os === "iOS";
45
+
46
+ const createAdContainer = () => {
47
+ let adContainer = document.createElement('div');
48
+ adContainer.setAttribute('class', 'op-ads');
49
+ adContainer.setAttribute('id', 'op-ads');
50
+ playerConfig.getContainer().append(adContainer);
51
+
52
+ elAdVideo = document.createElement('video');
53
+ elAdVideo.setAttribute('playsinline', 'true');
54
+ elAdVideo.setAttribute('title', 'Advertisement');
55
+ elAdVideo.setAttribute('class', 'op-ads-vast-video');
56
+
57
+ adButton = document.createElement('div');
58
+ adButton.setAttribute('class', 'op-ads-button');
59
+
60
+ textView = document.createElement('div');
61
+ textView.setAttribute('class', 'op-ads-textview');
62
+
63
+ adButton.append(textView);
64
+ adContainer.append(elAdVideo);
65
+ adContainer.append(adButton);
66
+
67
+ return adContainer;
68
+ };
69
+
70
+ container = createAdContainer();
71
+
72
+ let vastClient = new VASTClient();
73
+ let vastTracker = null;
74
+ let ad = null;
75
+
76
+
77
+ const OnAdError = function(error){
78
+ console.log(error);
79
+ adsErrorOccurred = true;
80
+ elAdVideo.style.display = "none";
81
+ provider.trigger(STATE_AD_ERROR, {code : error.code, message : error.message});
82
+ spec.active = false;
83
+ spec.started = true;
84
+ provider.play();
85
+ };
86
+
87
+ const initRequest = function () {
88
+ vastClient.get(adTagUrl) .then(res => {
89
+ // Do something with the parsed VAST response
90
+ OvenPlayerConsole.log("VAST : initRequest()");
91
+ ad = res.ads[0];
92
+ if(!ad){
93
+ throw {code : 401, message : "File not found. Unable to find Linear/MediaFile from URI."};
94
+ }
95
+ vastTracker = new VASTTracker(vastClient, ad, ad.creatives[0]);
96
+
97
+ OvenPlayerConsole.log("VAST : created ad tracker.");
98
+
99
+ listener = AdsEventsListener(elAdVideo, vastTracker, provider, spec, adButton, textView, OnAdError);
100
+
101
+ let videoURL = "";
102
+ if(ad.creatives && ad.creatives.length > 0 && ad.creatives[0].mediaFiles && ad.creatives[0].mediaFiles.length > 0 && ad.creatives[0].mediaFiles[0].fileURL){
103
+ videoURL = ad.creatives[0].mediaFiles[0].fileURL;
104
+ OvenPlayerConsole.log("VAST : media url : ", videoURL);
105
+ }
106
+ elAdVideo.src = videoURL;
107
+
108
+ //keep volume even if playlist item changes.
109
+ elAdVideo.volume = elVideo.volume;
110
+ elAdVideo.muted = elVideo.muted;
111
+
112
+ }).catch(function(error){
113
+ OnAdError(error);
114
+ });
115
+
116
+ };
117
+
118
+
119
+
120
+ const checkAutoplaySupport = function () {
121
+ OvenPlayerConsole.log("VAST : checkAutoplaySupport() ");
122
+
123
+ let temporarySupportCheckVideo = document.createElement('video');
124
+ temporarySupportCheckVideo.setAttribute('playsinline', 'true');
125
+ temporarySupportCheckVideo.src = TEMP_VIDEO_URL;
126
+ temporarySupportCheckVideo.load();
127
+
128
+
129
+ elAdVideo.load(); //for ios User Interaction problem
130
+ //Dash has already loaded when triggered provider.play() always.
131
+ if(isMobile && provider.getName() !== PROVIDER_DASH ){
132
+ //Main video sets user gesture when temporarySupportCheckVideo triggered checking.
133
+ elVideo.load();
134
+ }
135
+ const clearAndReport = function(_autoplayAllowed, _autoplayRequiresMuted){
136
+ autoplayAllowed = _autoplayAllowed;
137
+ autoplayRequiresMuted = _autoplayRequiresMuted;
138
+ temporarySupportCheckVideo.pause();
139
+ temporarySupportCheckVideo.remove();
140
+ };
141
+
142
+ return new Promise(function(resolve, reject){
143
+ if(!temporarySupportCheckVideo.play){
144
+ //I can't remember this case...
145
+ OvenPlayerConsole.log("VAST : !temporarySupportCheckVideo.play");
146
+ clearAndReport(true, false);
147
+ resolve();
148
+ }else{
149
+ let playPromise = temporarySupportCheckVideo.play();
150
+ if (playPromise !== undefined) {
151
+ playPromise.then(function(){
152
+ OvenPlayerConsole.log("VAST : auto play allowed.");
153
+ // If we make it here, unmuted autoplay works.
154
+ clearAndReport(true, false);
155
+ resolve();
156
+ }).catch(function(error){
157
+ OvenPlayerConsole.log("VAST : auto play failed", error.message);
158
+ clearAndReport(false, false);
159
+ resolve();
160
+ });
161
+ }else{
162
+ OvenPlayerConsole.log("VAST : promise not support");
163
+ //Maybe this is IE11....
164
+ clearAndReport(true, false);
165
+ resolve();
166
+ }
167
+ }
168
+ });
169
+ }
170
+ that.isActive = () => {
171
+ return spec.active;
172
+ };
173
+ that.started = () => {
174
+ return spec.started;
175
+ };
176
+ that.play = () => {
177
+ if(spec.started){
178
+ return elAdVideo.play();
179
+ }else{
180
+ return new Promise(function (resolve, reject) {
181
+
182
+ const checkMainContentLoaded = function(){
183
+
184
+ //wait for main contents meta loaded.
185
+ //have to trigger CONTENT_META first. next trigger AD_CHANGED.
186
+ //initControlUI first -> init ad UI
187
+ //Maybe google ima waits content loaded internal.
188
+ if(provider.metaLoaded()){
189
+ OvenPlayerConsole.log("VAST : main contents meta loaded.");
190
+ checkAutoplaySupport().then(function(){
191
+ if( (playerConfig.isAutoStart() && !autoplayAllowed) ){
192
+ OvenPlayerConsole.log("VAST : autoplayAllowed : false");
193
+ spec.started = false;
194
+ reject(new Error(AUTOPLAY_NOT_ALLOWED));
195
+ }else{
196
+ initRequest();
197
+
198
+ resolve();
199
+ }
200
+ });
201
+
202
+ }else{
203
+ setTimeout(checkMainContentLoaded, 100);
204
+ }
205
+
206
+ };
207
+ checkMainContentLoaded();
208
+
209
+ });
210
+ }
211
+ };
212
+ that.pause = () => {
213
+ elAdVideo.pause();
214
+ };
215
+
216
+ //End Of Main Contents.
217
+ that.videoEndedCallback = (completeContentCallback) => {
218
+
219
+ completeContentCallback();
220
+ //check true when main contents ended.
221
+ spec.isVideoEnded = true;
222
+ };
223
+ that.destroy = () => {
224
+ if(listener){
225
+ listener.destroy();
226
+ listener = null;
227
+ }
228
+ vastTracker = null;
229
+ vastClient = null;
230
+
231
+ container.remove();
232
+
233
+ };
234
+ return that;
235
+ };
236
+
237
+ export default Ad;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import SrtParser from "api/caption/parser/SrtParser";
5
5
  import WebVTT from 'api/caption/parser/VttParser'
6
- import VTTCue from 'utils/captions/vttCue'
6
+ import {VTTCue} from 'media-captions'
7
7
  import SmiParser from 'api/caption/parser/SmiParser'
8
8
 
9
9
  const Loader = function () {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import CaptionLoader from 'api/caption/Loader';
5
5
  import {READY, ERRORS, ERROR, PLAYER_CAPTION_ERROR, CONTENT_META, CONTENT_TIME, CONTENT_CAPTION_CUE_CHANGED, CONTENT_CAPTION_CHANGED} from "api/constants";
6
- import _ from "utils/underscore";
6
+ import _ from "underscore";
7
7
 
8
8
  const isSupport = function(kind){
9
9
  return kind === 'subtitles' || kind === 'captions';