@vidispine/vdt-videojs 21.3.0 → 22.1.0-pre.1

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 (55) hide show
  1. package/README.md +4 -4
  2. package/deprecated-app/README.md +21 -0
  3. package/{demo.html → deprecated-app/index.html} +1 -1
  4. package/{demo.js → deprecated-app/index.js} +69 -41
  5. package/{samples → deprecated-app/samples}/birds-es.vvt +0 -0
  6. package/{samples → deprecated-app/samples}/birds.vvt +0 -0
  7. package/{tests.js → deprecated-app/tests.js} +87 -54
  8. package/{lib/style.css → dist/index.css} +755 -55
  9. package/dist/index.es.js +2099 -0
  10. package/dist/index.js +2112 -0
  11. package/dist/index.umd.js +2115 -0
  12. package/package.json +29 -85
  13. package/rollup.config.js +54 -0
  14. package/src/constants.js +1 -1
  15. package/src/externalControls.js +14 -18
  16. package/src/helpOverlay.js +12 -16
  17. package/src/helpers.js +3 -3
  18. package/src/index.js +3 -9
  19. package/src/index.stories.mdx +59 -0
  20. package/src/menu.api.stories.mdx +59 -0
  21. package/src/menu.js +23 -19
  22. package/src/{menu.example.md → menu.usage.stories.mdx} +31 -21
  23. package/src/osd.js +24 -18
  24. package/src/player.api.stories.mdx +120 -0
  25. package/src/player.js +157 -108
  26. package/src/player.scss +2 -0
  27. package/src/{player.example.md → player.usage.stories.mdx} +18 -8
  28. package/src/seekBar.js +85 -48
  29. package/src/timeCodeDisplay.js +39 -31
  30. package/src/videoTime.js +4 -4
  31. package/build.js +0 -233
  32. package/lib/index.cjs.js +0 -3240
  33. package/lib/index.esm.js +0 -3227
  34. package/lib/index.umd.js +0 -3243
  35. package/lib/package.json +0 -13
  36. package/lib/src/constants.js +0 -51
  37. package/lib/src/externalControls.js +0 -307
  38. package/lib/src/helpOverlay.js +0 -106
  39. package/lib/src/helpers.js +0 -34
  40. package/lib/src/index.js +0 -13
  41. package/lib/src/menu.js +0 -365
  42. package/lib/src/osd.js +0 -91
  43. package/lib/src/player.js +0 -943
  44. package/lib/src/seekBar.js +0 -833
  45. package/lib/src/timeCodeDisplay.js +0 -253
  46. package/lib/src/videoTime.js +0 -66
  47. package/log.js +0 -24
  48. package/src/_index.stories.js +0 -24
  49. package/src/externalControls.stories.js +0 -6
  50. package/src/helpOverlay.stories.js +0 -6
  51. package/src/menu.classMethods.md +0 -47
  52. package/src/player.classMethods.md +0 -108
  53. package/src/player.stories.js +0 -14
  54. package/src/seekBar.stories.js +0 -8
  55. package/tmp/player.css +0 -1
@@ -0,0 +1,2115 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('mousetrap'), require('video.js/dist/alt/video.core.min')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'mousetrap', 'video.js/dist/alt/video.core.min'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vdtVideojs = {}, global.mousetrap, global.videojs));
5
+ })(this, (function (exports, mousetrap, videojs) { 'use strict';
6
+
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var mousetrap__default = /*#__PURE__*/_interopDefaultLegacy(mousetrap);
10
+ var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs);
11
+
12
+ var name = "@vidispine/vdt-videojs";
13
+ var version = "22.1.0-pre.1";
14
+ var license = "UNLICENSED";
15
+ var main = "dist/index.js";
16
+ var module = "dist/index.es.js";
17
+ var browser = "dist/index.umd.js";
18
+ var author = "Oto Inša <otoinsa@bertelsmann.de>";
19
+ var scripts = {
20
+ build: "rm -rf dist/ && rollup -c",
21
+ "build:watch": "rm -rf dist/*.js* && rollup -c -w --environment DEVELOPMENT",
22
+ lint: "eslint \"./{src/**/*,*}.{js,md}\"",
23
+ "lint:fix": "yarn lint --fix"
24
+ };
25
+ var dependencies = {
26
+ mousetrap: "^1.6.3",
27
+ "video.js": "^7.6.6"
28
+ };
29
+ var devDependencies = {
30
+ "@babel/core": "^7.17.0",
31
+ "@rollup/plugin-babel": "^5.3.0",
32
+ "@rollup/plugin-commonjs": "^21.0.1",
33
+ "@rollup/plugin-json": "^4.1.0",
34
+ "@rollup/plugin-node-resolve": "^13.1.3",
35
+ "@vidispine/eslint-config-base": "^22.1.0-pre.1",
36
+ "@vidispine/eslint-config-storybook": "*",
37
+ "babel-plugin-transform-runtime": "^6.23.0",
38
+ rollup: "^2.67.0",
39
+ "rollup-plugin-cleanup": "^3.2.1",
40
+ "rollup-plugin-peer-deps-external": "^2.2.4",
41
+ "rollup-plugin-sass": "^1.2.10"
42
+ };
43
+ var browserslist = [
44
+ "since 2017-06"
45
+ ];
46
+ var eslintConfig = {
47
+ "extends": [
48
+ "@vidispine/eslint-config-base",
49
+ "@vidispine/eslint-config-storybook"
50
+ ]
51
+ };
52
+ var prettier = "@vidispine/prettier-config";
53
+ var pkgInfo = {
54
+ name: name,
55
+ version: version,
56
+ license: license,
57
+ "private": false,
58
+ main: main,
59
+ module: module,
60
+ browser: browser,
61
+ author: author,
62
+ scripts: scripts,
63
+ dependencies: dependencies,
64
+ devDependencies: devDependencies,
65
+ browserslist: browserslist,
66
+ eslintConfig: eslintConfig,
67
+ prettier: prettier
68
+ };
69
+
70
+ const defaults = Object.freeze({
71
+ frameRate: 30000 / 1001,
72
+ jumpSeconds: 10,
73
+ inactivityTimeout: 1200,
74
+ audioInactivityTimeout: 0
75
+ });
76
+ const osd = Object.freeze({
77
+ play: 0,
78
+ pause: 1,
79
+ volchange: 2,
80
+ jumpForward: 3,
81
+ jumpBackward: 4
82
+ });
83
+ const settings = Object.freeze({
84
+ volume: 'volume-setting',
85
+ subLang: 'subtitles-language',
86
+ subs: 'subtitles-enabled'
87
+ });
88
+ const classNames = Object.freeze({
89
+ poster: 'has-poster',
90
+ subtitles: 'has-subtitles',
91
+ subtitlesActive: 'subtitles-active',
92
+ onDark: 'on-dark',
93
+ loading: 'loading'
94
+ });
95
+ const colors = Object.freeze({
96
+ gray: '#787878',
97
+ light: 'rgba(255,255,255,.75)'
98
+ });
99
+ const packageInfo = Object.freeze({
100
+ name: pkgInfo.name.split('/')[1],
101
+ vendor: pkgInfo.name.split('/')[0]
102
+ });
103
+ const constants$2 = Object.freeze({
104
+ defaults,
105
+ settings,
106
+ classNames,
107
+ colors,
108
+ osd,
109
+ packageInfo
110
+ });
111
+
112
+ function truncate(input, len) {
113
+ if (input.length > len) return "".concat(input.substring(0, len), "...");
114
+ return input;
115
+ }
116
+ function reactiveSetters() {
117
+ function handleNewProps(props) {
118
+ if (typeof props === 'object') {
119
+ const keys = Object.getOwnPropertyNames(props);
120
+ const proto = Object.getPrototypeOf(this);
121
+ keys.forEach(key => {
122
+ const descriptor = Object.getOwnPropertyDescriptor(proto, key);
123
+ if (descriptor && descriptor.set) {
124
+ this[key] = props[key];
125
+ }
126
+ });
127
+ }
128
+ }
129
+ this.handleNewProps = handleNewProps;
130
+ }
131
+ function sanitize(str) {
132
+ const temp = document.createElement('div');
133
+ temp.textContent = str;
134
+ return temp.innerHTML;
135
+ }
136
+
137
+ const buttonNames = Object.freeze({
138
+ play: 'play-pause',
139
+ start: 'start',
140
+ fb: 'frame-backward',
141
+ ff: 'frame-forward',
142
+ end: 'end'
143
+ });
144
+ const buttons = [
145
+ buttonNames.start, buttonNames.fb, buttonNames.play, buttonNames.ff, buttonNames.end];
146
+ const CSS$2 = "\n .vdt-external-controls{\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .control{\n flex: 1;\n flex-grow: 1;\n height: 100%;\n align-contents: center;\n align-self: center;\n text-align: center;\n vertical-align: middle;\n cursor: pointer;\n user-select: none;\n height: 20px;\n padding-top: 10px;\n padding-bottom: 10px;\n }\n\n .control .icon{\n display: inline-block;\n height: 20px;\n white-space: nowrap;\n opacity: .9;\n }\n\n .control:hover .icon{ opacity: 1; }\n\n .control .icon:before{\n opacity: 1;\n flex: 1;\n align-self: center;\n content: \" \";\n display: inline-block;\n margin: 0 auto;\n\n /* triangles */\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 16px 0 16px 23px;\n border-color: transparent transparent transparent ".concat(colors.gray, ";\n }\n\n .vdt-external-controls.").concat(classNames.onDark, " .control .icon:before{\n border-color: transparent transparent transparent ").concat(colors.light, ";\n }\n\n /* specific buttons */\n\n .control.").concat(buttonNames.start, ",\n .control.").concat(buttonNames.end, "{\n height: 20px;\n }\n\n .control.").concat(buttonNames.play, "{\n height: 30px;\n padding-top: 0px;\n padding-bottom: 0px;\n }\n\n .control.").concat(buttonNames.play, " .icon{\n height: 30px;\n }\n\n .control.").concat(buttonNames.ff, " .icon:before,\n .control.").concat(buttonNames.fb, " .icon:before,\n .control.").concat(buttonNames.end, " .icon:before,\n .control.").concat(buttonNames.start, " .icon:before{\n border-width: 10px 0 10px 16px;\n }\n\n .control.").concat(buttonNames.fb, " .icon,\n .control.").concat(buttonNames.start, "{\n transform: rotate(180deg);\n }\n\n .control.").concat(buttonNames.end, " .icon:after,\n .control.").concat(buttonNames.start, " .icon:after{\n content: \" \";\n width: 4px;\n height: 20px;\n display: inline-block;\n background: ").concat(colors.gray, ";\n }\n\n .vdt-external-controls.").concat(classNames.onDark, " .control.").concat(buttonNames.end, " .icon:after,\n .vdt-external-controls.").concat(classNames.onDark, " .control.").concat(buttonNames.start, " .icon:after{\n background: ").concat(colors.light, ";\n }\n\n /* stateful styles */\n .control.").concat(buttonNames.play, ".playing .icon:before{\n height: 30px;\n width: 6px;\n border-width: 0px 8px 0px 8px;\n border-color: transparent ").concat(colors.gray, " transparent ").concat(colors.gray, ";\n }\n\n .vdt-external-controls.").concat(classNames.onDark, " .control.").concat(buttonNames.play, ".playing .icon:before{\n border-color: transparent ").concat(colors.light, " transparent ").concat(colors.light, ";\n }\n\n .vdt-external-controls.").concat(classNames.loading, " .control.").concat(buttonNames.play, "{\n border-color: transparent #f00 transparent #f00;\n }\n");
147
+ class ExternalControls {
148
+ constructor(props) {
149
+ this.props = props;
150
+ reactiveSetters.apply(this);
151
+ this.state = {
152
+ playing: false,
153
+ onDark: false,
154
+ loading: false
155
+ };
156
+ this.shadowRoot = document.createElement('div');
157
+ this.shadowRoot.className = 'vdt-external-controls-wrapper';
158
+ this.container = document.createElement('div');
159
+ this.container.className = 'vdt-external-controls';
160
+ if (this.props.target) {
161
+ this.props.target.appendChild(this.shadowRoot);
162
+ this.shadow = this.shadowRoot.attachShadow({
163
+ mode: 'open'
164
+ });
165
+ this.style = document.createElement('style');
166
+ this.style.type = 'text/css';
167
+ this.style.appendChild(document.createTextNode(CSS$2));
168
+ this.shadow.appendChild(this.style);
169
+ this.shadow.appendChild(this.container);
170
+ }
171
+ this.handleNewProps(props);
172
+ this.bindEvents();
173
+ this.draw();
174
+ }
175
+ draw() {
176
+ this.buttons = {};
177
+ const excludes = this.props.excludes || [];
178
+ buttons.forEach(buttonName => {
179
+ if (excludes.indexOf(buttonName) < 0) {
180
+ const btn = document.createElement('div');
181
+ btn.className = "control ".concat(buttonName);
182
+ btn.innerHTML = '<span class="icon"></span>';
183
+ btn.onclick = () => {
184
+ this.handlePress(buttonName);
185
+ };
186
+ this.buttons[buttonName] = btn;
187
+ this.container.appendChild(btn);
188
+ }
189
+ });
190
+ }
191
+ bindEvents() {
192
+ if (this.props.player && this.props.player.videojs) {
193
+ const {
194
+ player
195
+ } = this.props;
196
+ player.videojs.on('play', () => {
197
+ this.playing = true;
198
+ });
199
+ player.videojs.on('pause', () => {
200
+ this.playing = false;
201
+ });
202
+ player.videojs.on('stop', () => {
203
+ this.playing = false;
204
+ });
205
+ }
206
+ }
207
+ handlePress(buttonName) {
208
+ if (this.props.player) {
209
+ const {
210
+ player
211
+ } = this.props;
212
+ if (player.osd) player.osd.disable();
213
+ switch (buttonName) {
214
+ case buttonNames.start:
215
+ player.toStart();
216
+ break;
217
+ case buttonNames.fb:
218
+ player.triggerHotkey('left');
219
+ break;
220
+ case buttonNames.play:
221
+ player.triggerHotkey('k');
222
+ break;
223
+ case buttonNames.ff:
224
+ player.triggerHotkey('right');
225
+ break;
226
+ case buttonNames.end:
227
+ player.toEnd();
228
+ break;
229
+ }
230
+ if (player.osd) player.osd.enable();
231
+ } else {
232
+ switch (buttonName) {
233
+ case buttonNames.start:
234
+ if (this.props.onPrev) this.props.onPrev();
235
+ break;
236
+ case buttonNames.fb:
237
+ if (this.props.onFB) this.props.onFB();
238
+ break;
239
+ case buttonNames.play:
240
+ if (this.playing) {
241
+ if (this.props.onPause) this.props.onPause();
242
+ } else if (this.props.onPlay) this.props.onPlay();
243
+ break;
244
+ case buttonNames.ff:
245
+ if (this.props.onFF) this.props.onFF();
246
+ break;
247
+ case buttonNames.end:
248
+ if (this.props.onNext) this.props.onNext();
249
+ break;
250
+ }
251
+ }
252
+ }
253
+ set playing(bool) {
254
+ if (bool) {
255
+ this.state.playing = true;
256
+ this.buttons[buttonNames.play].classList.add('playing');
257
+ } else {
258
+ this.state.playing = false;
259
+ this.buttons[buttonNames.play].classList.remove('playing');
260
+ }
261
+ }
262
+ get playing() {
263
+ return this.state.playing;
264
+ }
265
+ set onDark(bool) {
266
+ if (bool) {
267
+ this.state.onDark = true;
268
+ this.container.classList.add(classNames.onDark);
269
+ } else {
270
+ this.state.onDark = false;
271
+ this.container.classList.remove(classNames.onDark);
272
+ }
273
+ }
274
+ get onDark() {
275
+ return this.container.classList.contains(classNames.onDark);
276
+ }
277
+ set loading(bool) {
278
+ if (bool) {
279
+ this.state.loading = true;
280
+ this.container.classList.add(classNames.loading);
281
+ } else {
282
+ this.state.loading = false;
283
+ this.container.classList.remove(classNames.loading);
284
+ }
285
+ }
286
+ get loading() {
287
+ return this.state.loading;
288
+ }
289
+ }
290
+ ExternalControls.buttonNames = buttonNames;
291
+
292
+ function _defineProperty(obj, key, value) {
293
+ if (key in obj) {
294
+ Object.defineProperty(obj, key, {
295
+ value: value,
296
+ enumerable: true,
297
+ configurable: true,
298
+ writable: true
299
+ });
300
+ } else {
301
+ obj[key] = value;
302
+ }
303
+ return obj;
304
+ }
305
+
306
+ class HelpOverlay {
307
+ constructor(props) {
308
+ this.props = props;
309
+ this.state = {
310
+ active: this.props.active || false
311
+ };
312
+ this.container = document.createElement('div');
313
+ this.container.className = 'vdt-help-overlay';
314
+ this.container.innerHTML = '';
315
+ this.container.onclick = () => {
316
+ this.hide();
317
+ };
318
+ if (this.props.target) this.props.target.appendChild(this.container);
319
+ this.draw();
320
+ }
321
+ draw() {
322
+ let tableRowMarkup = '';
323
+ const rows = [['⎵', 'Play / Pause'], ['⇧', 'Increase volume '], ['⇩', 'Decrease volume'], ['⇨', 'Step frame forward'], ['⇦', 'Step frame backward'], ['M', 'Mute / Unmute'], ['J', 'Seek 10 seconds backward'], ['K', 'Play / Pause'], ['L', 'Seek 10 seconds forward'], ['C', 'Toggle subtitles'], ['N', 'Toggle settings menu'], ['H', 'Toggle this help overlay']];
324
+ const halfpointIndex = Math.round(rows.length / 2);
325
+ const columns = [rows.slice(0, halfpointIndex), rows.slice(halfpointIndex, rows.length)];
326
+ for (let i = 0; i < halfpointIndex; i += 1) {
327
+ tableRowMarkup += "\n <tr>\n <td><div>".concat(columns[0][i][0], "</div></td>\n <td>- ").concat(columns[0][i][1], "</td>\n\n <td>").concat(columns[1][i] ? "<div>".concat(columns[1][i][0], "</div>") : '', "</td>\n <td>").concat(columns[1][i] ? "- ".concat(columns[1][i][1]) : '', "</td>\n </tr>\n ");
328
+ }
329
+ this.container.innerHTML = "\n <table>\n <tbody>\n <tr>\n <td class=\"vdt-help-contents\">\n <table><tbody>".concat(tableRowMarkup, "</tbody></table>\n </td>\n </tr>\n </tbody>\n </table>\n ");
330
+ }
331
+ show() {
332
+ if (!this.state.active) {
333
+ this.container.classList.add('active');
334
+ this.state.active = true;
335
+ mousetrap__default["default"].bind('esc', () => {
336
+ this.hide();
337
+ });
338
+ if (this.props.onToggle) this.props.onToggle(true);
339
+ }
340
+ }
341
+ hide() {
342
+ if (this.state.active) {
343
+ this.container.classList.remove('active');
344
+ this.state.active = false;
345
+ mousetrap__default["default"].unbind('esc');
346
+ if (this.props.onToggle) this.props.onToggle(false);
347
+ }
348
+ }
349
+ toggle() {
350
+ if (this.state.active) {
351
+ this.hide();
352
+ } else {
353
+ this.show();
354
+ }
355
+ }
356
+ }
357
+
358
+ function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
359
+ function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
360
+ const constants$1 = Object.freeze({
361
+ className: 'vdt-menu',
362
+ menuClassName: 'menu',
363
+ subLvlClassName: 'sub-level',
364
+ menuItemClassName: 'menu-item',
365
+ animationLength: 300,
366
+ defaults: {
367
+ bgColor: 'rgba(0,0,0,.8)',
368
+ textColor: '#999',
369
+ textColorDark: '#333',
370
+ textColorLight: 'rgba(255,255,255)',
371
+ bgColorLight: 'rgba(255,255,255,.2)',
372
+ bgColorSelected: 'rgba(255,255,255,.1)'
373
+ }
374
+ });
375
+ const CSS$1 = () => "\n .".concat(constants$1.menuClassName, "{\n position: relative;\n height: 100%;\n width: 200%;\n // min-width: 200px;\n right: 0px;\n bottom: 0px;\n background: ").concat(constants$1.defaults.bgColor, ";\n z-index: 1px;\n transform: translate3d(100%, 0px, 0px);\n transition: all 300ms ease-in-out;\n box-shadow: 0px 0px 30px rgb;\n -webkit-backdrop-filter: blur(10px);\n overflow: hidden;\n }\n\n .").concat(constants$1.menuClassName, " .level-1{\n float: left;\n }\n\n .").concat(constants$1.menuClassName, " div h3{\n padding: 16px 24px;\n font-size: 12px;\n border-bottom: 1px solid ").concat(constants$1.defaults.bgColorLight, "\n }\n\n .").concat(constants$1.menuClassName, " .level-2 h3{\n cursor: pointer;\n position: relative;\n }\n .").concat(constants$1.menuClassName, " .level-2 h3:before{\n content: '\u25C2';\n margin-left: -12px;\n width: 12px;\n display: inline-block;\n position: absolute;\n margin-top: -1px;\n }\n\n .").concat(constants$1.menuClassName, " .level-1,\n .").concat(constants$1.menuClassName, " .level-2{\n transform: translate3d(0px, 0px, 0px);\n transition: all 300ms ease-in-out;\n width: 50%;\n height: 100%;\n float: left;\n }\n\n .").concat(constants$1.menuClassName, ".sub-level .level-1,\n .").concat(constants$1.menuClassName, ".sub-level .level-2{\n transform: translate3d(-100%, 0px, 0px);\n }\n\n .").concat(constants$1.menuClassName, " table{\n border-collapse: collapse;\n width: 100%;\n }\n\n .").concat(constants$1.menuClassName, ".open{\n transform: translate3d(0px, 0px, 0px);\n }\n\n .").concat(constants$1.menuClassName, " tr{\n cursor: pointer;\n height: 40px;\n }\n\n .").concat(constants$1.menuClassName, " tr.selected{\n background: ").concat(constants$1.defaults.bgColorSelected, ";\n }\n\n\n .").concat(constants$1.menuClassName, " tr td{\n color: white;\n font-size: 15px;\n vertical-align: middle;\n }\n\n \n .").concat(constants$1.menuClassName, " tr:hover td{\n color: white;\n background: ").concat(constants$1.defaults.bgColorLight, ";\n }\n\n .").concat(constants$1.menuClassName, " tr td.title{\n padding-top: 12px;\n padding-bottom: 12px;\n font-weight: 300;\n font-family: Helvetica, Arial, sans-serif; \n }\n\n .").concat(constants$1.menuClassName, " tr td.caret{\n font-size: 12px;\n }\n\n .").concat(constants$1.menuClassName, " tr td:first-child{\n padding-left: 24px;\n }\n\n .").concat(constants$1.menuClassName, " tr td:last-child{\n padding-right: 16px;\n }\n\n .").concat(constants$1.menuClassName, " tr.has-items td:last-child{\n text-align: right;\n }\n\n .").concat(constants$1.menuClassName, " tr.has-items td.subtitle{\n font-size: 12px;\n text-align: right;\n color: ").concat(constants$1.defaults.textColorLight, ";\n }\n");
376
+ class MenuDisplayItem {
377
+ constructor(props) {
378
+ this.props = props;
379
+ const classNames = [constants$1.menuItemClassName, this.props.items && 'has-items', this.props.selected && 'selected'];
380
+ this.container = document.createElement('tr');
381
+ this.container.className = classNames.join(' ');
382
+ if (this.props.target) this.props.target.appendChild(this.container);
383
+ this.container.onclick = event => {
384
+ if (this.props.onClick) this.props.onClick(event);
385
+ };
386
+ this.render();
387
+ }
388
+ render() {
389
+ if (this.props.items) {
390
+ this.container.innerHTML = "\n <td class=\"title\"></td>\n <td class=\"subtitle\"></td>\n <td class=\"caret\">\u25B7</td>\n ";
391
+ } else {
392
+ this.container.innerHTML = "\n <td class=\"title\"></td>\n ";
393
+ }
394
+ const titleNode = this.container.getElementsByClassName('title')[0];
395
+ const subtitleNode = this.props.items ? this.container.getElementsByClassName('subtitle')[0] : false;
396
+ titleNode.textContent = this.props.title;
397
+ if (subtitleNode) subtitleNode.textContent = this.props.subtitle;
398
+ }
399
+ }
400
+ class Menu {
401
+ constructor(props) {
402
+ this.props = props;
403
+ this.container = document.createElement('div');
404
+ this.container.className = "".concat(constants$1.className);
405
+ this.state = {
406
+ opened: false,
407
+ selectedItem: 0,
408
+ items: [],
409
+ subItems: []
410
+ };
411
+ this.mount();
412
+ this.draw();
413
+ }
414
+ mount() {
415
+ if (this.props.target) {
416
+ this.container.style.position = 'absolute';
417
+ this.container.style.bottom = this.container.style.right = '0px';
418
+ this.container.style.height = '100%';
419
+ this.container.style.overflow = 'hidden';
420
+ this.container.style.width = '30%';
421
+ this.container.style.minWidth = '250px';
422
+ this.container.style.maxWidth = '320px';
423
+ this.shadow = this.container.attachShadow({
424
+ mode: 'open'
425
+ });
426
+ if (this.props.target) this.props.target.appendChild(this.container);
427
+ this.menuContainer = document.createElement('div');
428
+ this.menuContainer.className = 'menu';
429
+ this.shadow.appendChild(this.menuContainer);
430
+ this.style = document.createElement('style');
431
+ this.style.type = 'text/css';
432
+ this.style.innerHTML = CSS$1();
433
+ this.shadow.appendChild(this.style);
434
+ }
435
+ }
436
+ draw() {
437
+ const mainDiv = document.createElement('div');
438
+ mainDiv.className = 'level-1';
439
+ this.mainLevel = document.createElement('table');
440
+ mainDiv.innerHTML = '<h3>Settings</h3>';
441
+ mainDiv.appendChild(this.mainLevel);
442
+ const subDiv = document.createElement('div');
443
+ subDiv.className = 'level-2';
444
+ this.subLvlTitle = document.createElement('h3');
445
+ this.subLvlTitle.onclick = () => {
446
+ this.up();
447
+ };
448
+ subDiv.appendChild(this.subLvlTitle);
449
+ this.secondaryLevel = document.createElement('table');
450
+ subDiv.appendChild(this.secondaryLevel);
451
+ this.menuContainer.appendChild(mainDiv);
452
+ this.menuContainer.appendChild(subDiv);
453
+ this.props.items.forEach(menuItem => {
454
+ const activeTitle = menuItem.items[menuItem.getActiveIndex(menuItem.items)].title || '';
455
+ const displayItem = new MenuDisplayItem(_objectSpread$1({
456
+ target: this.mainLevel,
457
+ subtitle: activeTitle,
458
+ onClick: () => {
459
+ this.handleSupItemSelected(menuItem);
460
+ }
461
+ }, menuItem));
462
+ this.state.items.push(displayItem);
463
+ });
464
+ }
465
+ open() {
466
+ this.render();
467
+ this.menuContainer.classList.add('open');
468
+ if (this.props.onOpen) this.props.onOpen();
469
+ this.state.opened = true;
470
+ if (!this.handleClicksWhenMenuOpened) {
471
+ this.handleClicksWhenMenuOpened = function (event) {
472
+ if (this.state.opened) {
473
+ event.stopPropagation();
474
+ const isClickInside = this.container.contains(event.target);
475
+ if (!isClickInside) {
476
+ this.close();
477
+ }
478
+ }
479
+ }.bind(this);
480
+ }
481
+ this.handleClicksWhenMenuOpenedTimeout = setTimeout(() => {
482
+ document.addEventListener('click', this.handleClicksWhenMenuOpened);
483
+ mousetrap__default["default"].bind('esc', this.close.bind(this));
484
+ }, constants$1.animationLength);
485
+ }
486
+ close() {
487
+ this.menuContainer.classList.remove('open');
488
+ this.state.opened = false;
489
+ if (this.handleClicksWhenMenuOpenedTimeout) clearTimeout(this.handleClicksWhenMenuOpenedTimeout);
490
+ document.removeEventListener('click', this.handleClicksWhenMenuOpened);
491
+ if (this.props.onClose) this.props.onClose();
492
+ mousetrap__default["default"].unbind('esc');
493
+ }
494
+ toggle() {
495
+ if (this.state.opened) {
496
+ this.close();
497
+ } else {
498
+ this.open();
499
+ }
500
+ }
501
+ up() {
502
+ this.menuContainer.classList.remove(constants$1.subLvlClassName);
503
+ this.render();
504
+ }
505
+ handleSupItemSelected(item) {
506
+ this.subLvlTitle.textContent = item.title;
507
+ this.renderSubItems(item.items, item.getActiveIndex(item.items));
508
+ this.menuContainer.classList.add(constants$1.subLvlClassName);
509
+ }
510
+ renderSubItems(items) {
511
+ let activeIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
512
+ this.secondaryLevel.innerHTML = '';
513
+ const subItemRefs = [];
514
+ items.forEach((menuItem, index) => {
515
+ const displayItem = new MenuDisplayItem(_objectSpread$1(_objectSpread$1({
516
+ target: this.secondaryLevel
517
+ }, menuItem), {}, {
518
+ onClick: event => {
519
+ this.handleSubItemSelected(event, menuItem);
520
+ },
521
+ selected: index === activeIndex
522
+ }));
523
+ subItemRefs.push(displayItem);
524
+ });
525
+ this.state.subItems = subItemRefs;
526
+ }
527
+ handleSubItemSelected(event, item) {
528
+ this.close();
529
+ if (item.onClick) item.onClick(event, item);
530
+ this.up();
531
+ }
532
+ get opened() {
533
+ return this.state.opened;
534
+ }
535
+ set opened(bool) {
536
+ this.state.opened = bool;
537
+ }
538
+ render() {
539
+ this.state.items.forEach((menuDisplayItem, index) => {
540
+ const {
541
+ items
542
+ } = this.props;
543
+ const activeIndex = items[index].getActiveIndex(items[index].items);
544
+ const activeTitle = items[index].items[activeIndex].title;
545
+ menuDisplayItem.props.subtitle = activeTitle;
546
+ menuDisplayItem.render();
547
+ });
548
+ }
549
+ }
550
+
551
+ class OSD {
552
+ constructor(props) {
553
+ this.props = props;
554
+ this.state = {
555
+ enabled: true
556
+ };
557
+ this.container = document.createElement('div');
558
+ this.container.className = 'vdt-player-osd';
559
+ this.container.innerHTML = "\n <table>\n <tbody>\n <td>\n <div class=\"osd-feedback-icon\"></div>\n </td>\n </tbody>\n </table>\n ";
560
+ this.iconEl = this.container.getElementsByClassName('osd-feedback-icon')[0];
561
+ if (this.props.target) this.props.target.appendChild(this.container);
562
+ }
563
+ feedback(feedbackType) {
564
+ let details = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
565
+ if (!this.state.enabled) {
566
+ return;
567
+ }
568
+ let className;
569
+ switch (feedbackType) {
570
+ case osd.pause:
571
+ className = 'pause';
572
+ break;
573
+ case osd.play:
574
+ className = 'play';
575
+ break;
576
+ case osd.volchange:
577
+ const currentVolumeLevel = details.volume;
578
+ let perceivedVolumeLevel;
579
+ if (currentVolumeLevel === 0) {
580
+ perceivedVolumeLevel = 'null';
581
+ } else if (currentVolumeLevel > 0.65) {
582
+ perceivedVolumeLevel = 'high';
583
+ } else if (currentVolumeLevel < 0.35) {
584
+ perceivedVolumeLevel = 'low';
585
+ } else {
586
+ perceivedVolumeLevel = 'mid';
587
+ }
588
+ className = "volchange ".concat(perceivedVolumeLevel);
589
+ break;
590
+ case osd.jumpForward:
591
+ className = 'forward-jump';
592
+ break;
593
+ case osd.jumpBackward:
594
+ className = 'backward-jump';
595
+ break;
596
+ }
597
+ if (this.osdTimeout) {
598
+ this.container.classList.remove('active');
599
+ clearTimeout(this.osdTimeout);
600
+ }
601
+ this.container.classList.add('active');
602
+ this.osdTimeout = setTimeout(() => {
603
+ this.container.classList.remove('active');
604
+ }, 200);
605
+ this.iconEl.className = "osd-feedback-icon ".concat(className);
606
+ }
607
+ disable() {
608
+ this.state.enabled = false;
609
+ }
610
+ enable() {
611
+ this.state.enabled = true;
612
+ }
613
+ }
614
+
615
+ const constants = Object.freeze({
616
+ className: 'vdt-seekbar',
617
+ defaults: {
618
+ bgColor: '#fafafa',
619
+ fillColor: '#f00',
620
+ regionColor: '#f6e58d',
621
+ markerWidth: 16,
622
+ regionAccentColor: '#00a8ff',
623
+ transitionTime: 300
624
+ },
625
+ markerTypes: {
626
+ in: 'in',
627
+ out: 'out'
628
+ }
629
+ });
630
+ const CSS = (bgColor, fillColor) => "\n .".concat(constants.className, "{\n user-select: none;\n background: ").concat(colors.light, ";\n height: 6px;\n width: 100%;\n position: relative;\n cursor: pointer;\n z-index: 5;\n }\n\n .").concat(classNames.onDark, ".").concat(constants.className, "{\n background: ").concat(colors.gray, ";\n }\n\n .fill, .load-indicator{\n height: 100%;\n display: inline-block;\n position: absolute;\n left: 0px;\n top: 0px;\n background: ").concat(fillColor, ";\n transition: width ").concat(constants.defaults.transitionTime, "ms linear;\n z-index: 2;\n }\n\n .load-indicator{\n background: #e1e1e1;\n z-index: 1;\n opacity: .2;\n transition: none;\n }\n\n .").concat(classNames.onDark, ".").concat(constants.className, " .load-indicator{\n background: white;\n }\n\n .").concat(constants.className, ".dragging .fill{\n transition: none;\n }\n\n\n .marker, .region{\n position: absolute;\n top: 0px;\n height: 100%;\n background: cyan;\n width: 1px;\n display: inline-block;\n z-index: 4;\n }\n\n .marker{\n transition: opacity ").concat(constants.defaults.transitionTime, "ms linear;\n }\n\n .marker{ display: none; }\n .marker.active{ display: initial; }\n\n .marker .handle{\n position: absolute;\n bottom: 10px; right: 0px;\n width: ").concat(constants.defaults.markerWidth, "px;\n height: 28px;\n background: #999;\n border-radius: 3px;\n cursor: col-resize;\n z-index: 3;\n box-sizing: border-box;\n }\n\n .marker.regional .handle{\n background: ").concat(constants.defaults.regionAccentColor, ";\n box-shadow: -2px 1px 1px rgba(0,0,0,.1);\n }\n\n .marker.regional.in .handle{\n box-shadow: 2px 1px 1px rgba(0,0,0,.1);\n }\n\n .marker.in .handle{\n border-bottom-left-radius: 40px;\n }\n\n .marker.out .handle{\n left: 1px;\n right: initial;\n border-bottom-right-radius: 20px;\n }\n\n .handle:active{\n background: ").concat(constants.defaults.regionColor, ";\n }\n\n .region{\n position: absolute;\n width: auto;\n background: ").concat(constants.defaults.regionColor, ";\n opacity: .7;\n }\n\n .region.nav{\n background: transparent;\n opacity: 1;\n border-left: 1px solid cyan;\n }\n\n .region.nav .bubble,\n .region.nav:after{\n content: \" \";\n height: 16px;\n bottom: 10px;\n width: 16px;\n border-radius: 16px;\n background: ").concat(constants.defaults.regionAccentColor, ";\n position: absolute;\n margin-left: -8px;\n transition: transform 200ms ease-out;\n transform: translate3d(0px, 0px, 0px);\n transform-origin: bottom center;\n }\n\n .region.nav .popout{\n width: 160px;\n z-index: 4;\n background: rgba(28, 28, 28, .7);\n color: white;\n font-size: 14px;\n min-height: 100px;\n bottom: 16px;\n left: -80px;\n position: absolute;\n border-radius: 8px;\n -webkit-backdrop-filter: blur(10px);\n font-family: Arial, Helvetica, sans-serif;\n overflow: hidden;\n opacity: 0;\n visibility: hidden;\n }\n\n .region.nav.right-aligned .popout{\n right: 0px;\n left: initial;\n }\n\n .region.nav.left-aligned .popout{\n left: -32px;\n } \n\n .region.nav .popout .title{\n padding: 4px 14px;\n text-align: center;\n color: black;\n background: white;\n }\n\n .region.nav .popout .annotation{\n padding: 8px 12px;\n font-weight: light;\n color: rgba(255,255,255,.9);\n }\n\n .region.nav:after{\n width: 1px;\n left: 8px;\n height: 10px;\n bottom: 0px;\n background: #00a8ff;\n }\n\n .region.nav:hover{\n background: rgba(28, 28, 28, .5);\n }\n\n .region.nav.has-popout:hover .bubble{\n background: rgba(28, 28, 28, .8);\n opacity: 1;\n z-index: 3;\n }\n\n .region.nav:hover:after,\n .region.nav:hover:before{\n background: rgba(28, 28, 28, .8);\n }\n\n .region.nav:hover .popout{\n opacity: 1;\n visibility: visible;\n }\n\n .").concat(constants.className, ".dragging .bubble{\n transform: scale3d(.75,.75,.75);\n }\n\n .").concat(constants.className, ".hide-markers .marker{\n opacity: 0;\n }\n\n");
631
+ class Region {
632
+ constructor(props) {
633
+ const regionDefaultProps = {
634
+ in: null,
635
+ out: null,
636
+ title: '',
637
+ annotation: '',
638
+ el: null
639
+ };
640
+ Object.assign(this, regionDefaultProps, props);
641
+ }
642
+ }
643
+ class SeekBar {
644
+ constructor(props) {
645
+ this.props = props;
646
+ reactiveSetters.apply(this);
647
+ this.container = document.createElement('div');
648
+ this.container.className = "".concat(constants.className, "-wrapper");
649
+ this.state = {
650
+ in: null,
651
+ out: null,
652
+ markersEnabled: this.props.markersEnabled === undefined ? true : this.props.markersEnabled,
653
+ regions: [],
654
+ dragging: false
655
+ };
656
+ this.markers = {};
657
+ if (this.props.target) {
658
+ this.shadow = this.container.attachShadow({
659
+ mode: 'open'
660
+ });
661
+ this.props.target.appendChild(this.container);
662
+ this.style = document.createElement('style');
663
+ this.style.type = 'text/css';
664
+ const bgColor = this.props.bgColor ? this.props.bgColor : constants.defaults.bgColor;
665
+ const fillColor = this.props.fillColor ? this.props.fillColor : constants.defaults.fillColor;
666
+ this.style.innerHTML = CSS(sanitize(bgColor), sanitize(fillColor));
667
+ this.shadow.appendChild(this.style);
668
+ }
669
+ this.bindEvents();
670
+ this.draw();
671
+ this.bindHotkeys();
672
+ const {
673
+ player
674
+ } = this.props;
675
+ if (player) {
676
+ player.videojs.on('loadedmetadata', () => {
677
+ this.handleNewProps(this.props);
678
+ });
679
+ }
680
+ }
681
+ bindEvents() {
682
+ if (this.props.player) {
683
+ const {
684
+ player
685
+ } = this.props;
686
+ player.videojs.on('timeupdate', () => {
687
+ const progressFraction = player.videojs.currentTime() / player.videojs.duration();
688
+ this.fill.style.width = "".concat(100 * progressFraction, "%");
689
+ });
690
+ player.videojs.on('progress', () => {
691
+ this.percentLoaded = player.percentLoaded;
692
+ });
693
+ }
694
+ }
695
+ bindHotkeys() {
696
+ this.bindings = [];
697
+ if (this.props.player) {
698
+ const {
699
+ player
700
+ } = this.props;
701
+ this.bindings = [{
702
+ key: ['i'],
703
+ method: () => {
704
+ if (this.markersEnabled) this.in = player.videojs.currentTime();
705
+ }
706
+ }, {
707
+ key: ['o'],
708
+ method: () => {
709
+ if (this.markersEnabled) this.out = player.videojs.currentTime();
710
+ }
711
+ }, {
712
+ key: ['shift+i'],
713
+ method: () => {
714
+ if (this.markersEnabled) this.navigateToIn();
715
+ }
716
+ }, {
717
+ key: ['shift+o'],
718
+ method: () => {
719
+ if (this.markersEnabled) this.navigateToOut();
720
+ }
721
+ }];
722
+ }
723
+ if (this.props.player) {
724
+ const {
725
+ player
726
+ } = this.props;
727
+ mousetrap__default["default"].bind('i', () => {
728
+ if (this.markersEnabled) this.in = player.videojs.currentTime();
729
+ });
730
+ mousetrap__default["default"].bind('o', () => {
731
+ if (this.markersEnabled) this.out = player.videojs.currentTime();
732
+ });
733
+ mousetrap__default["default"].bind('shift+i', () => {
734
+ if (this.markersEnabled) this.navigateToIn();
735
+ });
736
+ mousetrap__default["default"].bind('shift+o', () => {
737
+ if (this.markersEnabled) this.navigateToOut();
738
+ });
739
+ }
740
+ this.bindings.forEach(binding => {
741
+ mousetrap__default["default"].bind(binding.key, e => {
742
+ binding.method(e);
743
+ });
744
+ });
745
+ }
746
+ unbindHotKeys() {
747
+ this.bindings && this.bindings.forEach(binding => {
748
+ mousetrap__default["default"].unbind(binding.key);
749
+ });
750
+ }
751
+ handleSeek(event) {
752
+ if (this.props.player) {
753
+ const {
754
+ player
755
+ } = this.props;
756
+ if (this.state.regions) {
757
+ let clickedOnRegion = false;
758
+ let preventSeek = false;
759
+ this.state.regions.forEach(region => {
760
+ if (region.el.contains(event.target)) {
761
+ if (this.props.onRegionClick) {
762
+ preventSeek = this.props.onRegionClick(region);
763
+ if (!preventSeek) {
764
+ player.seekTo(region.in);
765
+ }
766
+ } else {
767
+ player.seekTo(region.in);
768
+ }
769
+ clickedOnRegion = true;
770
+ }
771
+ });
772
+ if (clickedOnRegion) return;
773
+ }
774
+ const seekFractionX = (event.clientX - this.bar.getBoundingClientRect().left) / this.bar.offsetWidth;
775
+ const timeToSeek = seekFractionX * player.videojs.duration();
776
+ player.seekTo(timeToSeek);
777
+ }
778
+ }
779
+ handleSeekDrag(mouseDownEvent) {
780
+ const barOffset = this.bar.getBoundingClientRect().left;
781
+ const barWidth = this.bar.getBoundingClientRect().width;
782
+ const duration = this.props.player.videojs.duration();
783
+ let left;
784
+ const drag = e => {
785
+ left = e.clientX - barOffset;
786
+ const pxDragged = Math.abs(mouseDownEvent.clientX - e.clientX);
787
+ if (left >= 0 && left < barWidth && pxDragged > 1) {
788
+ this.dragging = true;
789
+ const fractionFromStart = parseFloat(left) / barWidth;
790
+ const seconds = fractionFromStart * duration;
791
+ this.props.player.videojs.currentTime(seconds);
792
+ }
793
+ e.preventDefault();
794
+ };
795
+ const stopDrag = e => {
796
+ this.dragging = false;
797
+ document.removeEventListener('mousemove', drag, false);
798
+ document.removeEventListener('mouseup', stopDrag, false);
799
+ const fractionFromStart = parseFloat(left) / barWidth;
800
+ const seconds = fractionFromStart * duration;
801
+ this.props.player.videojs.currentTime(seconds);
802
+ e.stopPropagation();
803
+ };
804
+ document.addEventListener('mousemove', drag, false);
805
+ document.addEventListener('mouseup', stopDrag, false);
806
+ }
807
+ draw() {
808
+ this.bar = document.createElement('div');
809
+ this.bar.className = constants.className;
810
+ this.bar.onclick = e => {
811
+ if (!e.target.classList.contains('marker') && !e.target.classList.contains('handle')) {
812
+ this.handleSeek(e);
813
+ }
814
+ };
815
+ this.bar.addEventListener('mousedown', e => {
816
+ e.preventDefault();
817
+ if (!this.dragging) {
818
+ this.handleSeekDrag(e);
819
+ }
820
+ }, false);
821
+ this.fill = document.createElement('div');
822
+ this.fill.className = 'fill';
823
+ this.loadIndicator = document.createElement('div');
824
+ this.loadIndicator.className = 'load-indicator';
825
+ this.region = document.createElement('div');
826
+ this.region.className = 'region';
827
+ this.bar.appendChild(this.fill);
828
+ this.bar.appendChild(this.loadIndicator);
829
+ this.bar.appendChild(this.region);
830
+ this.shadow.appendChild(this.bar);
831
+ this.drawMarkers();
832
+ }
833
+ drawMarkers() {
834
+ if (this.markersEnabled) {
835
+ const markerIn = this.markers[constants.markerTypes.in] = document.createElement('div');
836
+ const markerOut = this.markers[constants.markerTypes.out] = document.createElement('div');
837
+ markerIn.className = "marker ".concat(constants.markerTypes.in);
838
+ markerOut.className = "marker ".concat(constants.markerTypes.out);
839
+ const handleIn = document.createElement('div');
840
+ const handleOut = document.createElement('div');
841
+ handleIn.className = handleOut.className = 'handle';
842
+ handleIn.addEventListener('mousedown', e => {
843
+ e.preventDefault();
844
+ e.stopPropagation();
845
+ this.handleMarkerDrag(markerIn, constants.markerTypes.in, e);
846
+ }, false);
847
+ handleOut.addEventListener('mousedown', e => {
848
+ e.preventDefault();
849
+ e.stopPropagation();
850
+ this.handleMarkerDrag(markerOut, constants.markerTypes.out, e);
851
+ }, false);
852
+ markerIn.appendChild(handleIn);
853
+ markerOut.appendChild(handleOut);
854
+ this.bar.appendChild(markerIn);
855
+ this.bar.appendChild(markerOut);
856
+ }
857
+ }
858
+ updateMarkers(marker) {
859
+ this.markers[marker.type].style.left = "".concat(marker.value * 100, "%");
860
+ this.markers[marker.type].classList.add('active');
861
+ if (this.state.regions) {
862
+ const matchingRegions = [];
863
+ const isRegional = matchingRegions.length > 0;
864
+ if (isRegional) {
865
+ this.markers[marker.type].classList.add('regional');
866
+ } else {
867
+ this.markers[marker.type].classList.remove('regional');
868
+ }
869
+ }
870
+ this.drawInAndOutRegion();
871
+ }
872
+ drawInAndOutRegion() {
873
+ if (this.state.in !== null && this.state.out !== null) {
874
+ this.region.style.left = this.markers[constants.markerTypes.in].style.left;
875
+ this.region.style.right = "".concat(100 - parseFloat(this.markers[constants.markerTypes.out].style.left.replace('%', '')), "%");
876
+ }
877
+ }
878
+ handleMarkerDrag(markerNode, type, mouseDownEvent) {
879
+ const barOffset = this.bar.getBoundingClientRect().left;
880
+ const barWidth = this.bar.getBoundingClientRect().width;
881
+ const duration = this.props.player.videojs.duration();
882
+ let dragHappened = false;
883
+ const drag = e => {
884
+ const pxDragged = Math.abs(mouseDownEvent.clientX - e.clientX);
885
+ const markerOffset = type === constants.markerTypes.in ? constants.defaults.markerWidth / 2 : -(constants.defaults.markerWidth / 2);
886
+ const left = e.clientX - barOffset + markerOffset;
887
+ if (left >= 0 && left < barWidth && pxDragged > 1) {
888
+ dragHappened = this.dragging = true;
889
+ markerNode.style.left = "".concat(left, "px");
890
+ markerNode.classList.add('active');
891
+ const fractionFromStart = parseFloat(markerNode.getBoundingClientRect().left - barOffset) / barWidth;
892
+ const seconds = fractionFromStart * duration;
893
+ this.props.player.videojs.currentTime(seconds);
894
+ }
895
+ e.preventDefault();
896
+ };
897
+ const stopDrag = e => {
898
+ this.dragging = false;
899
+ document.removeEventListener('mousemove', drag, false);
900
+ document.removeEventListener('mouseup', stopDrag, false);
901
+ const fractionFromStart = parseFloat(markerNode.getBoundingClientRect().left - barOffset) / barWidth;
902
+ const seconds = fractionFromStart * duration;
903
+ this[type] = seconds;
904
+ this.props.player.videojs.currentTime(seconds);
905
+ if (!dragHappened) {
906
+ if (type === constants.markerTypes.in) {
907
+ this.navigateToIn();
908
+ } else {
909
+ this.navigateToOut();
910
+ }
911
+ }
912
+ this.props.onDragFinish && this.props.onDragFinish({
913
+ type,
914
+ seconds
915
+ });
916
+ e.stopPropagation();
917
+ };
918
+ document.addEventListener('mousemove', drag, false);
919
+ document.addEventListener('mouseup', stopDrag, false);
920
+ }
921
+ cleanupMarkers() {
922
+ let removedMarker = false;
923
+ if (this.state.in === null) {
924
+ this.markers[constants.markerTypes.in].classList.remove('active');
925
+ removedMarker = true;
926
+ }
927
+ if (this.state.out === null) {
928
+ this.markers[constants.markerTypes.out].classList.remove('active');
929
+ removedMarker = true;
930
+ }
931
+ if (removedMarker) {
932
+ this.region.style.left = 'initial';
933
+ this.region.style.right = 'initial';
934
+ }
935
+ }
936
+ clearMarkers() {
937
+ this.in = null;
938
+ this.out = null;
939
+ }
940
+ setInFromCurrent() {
941
+ this.in = this.props.player.videojs.currentTime();
942
+ }
943
+ setOutFromCurrent() {
944
+ this.out = this.props.player.videojs.currentTime();
945
+ }
946
+ navigateToIn() {
947
+ const {
948
+ player
949
+ } = this.props;
950
+ player.seekTo(this.in);
951
+ }
952
+ navigateToOut() {
953
+ const {
954
+ player
955
+ } = this.props;
956
+ player.seekTo(this.out);
957
+ }
958
+ set in(val) {
959
+ if (!this.state.markersEnabled) return;
960
+ this.state.in = val;
961
+ if (val !== null && val !== undefined) {
962
+ const {
963
+ player
964
+ } = this.props;
965
+ this.updateMarkers({
966
+ type: constants.markerTypes.in,
967
+ value: val / player.videojs.duration()
968
+ });
969
+ if (this.state.out !== null && val > this.state.out) {
970
+ this.out = null;
971
+ }
972
+ this.props.onIn && this.props.onIn(this.state.in);
973
+ } else {
974
+ this.cleanupMarkers();
975
+ }
976
+ }
977
+ get in() {
978
+ return this.state.in;
979
+ }
980
+ set out(val) {
981
+ if (!this.state.markersEnabled) return;
982
+ this.state.out = val;
983
+ if (val !== null && val !== undefined) {
984
+ const {
985
+ player
986
+ } = this.props;
987
+ this.updateMarkers({
988
+ type: constants.markerTypes.out,
989
+ value: val / player.videojs.duration()
990
+ });
991
+ if (this.state.in != null && val < this.state.in) {
992
+ this.in = null;
993
+ }
994
+ this.props.onOut && this.props.onOut(this.state.out);
995
+ } else {
996
+ this.cleanupMarkers();
997
+ }
998
+ }
999
+ get out() {
1000
+ return this.state.out;
1001
+ }
1002
+ get markersEnabled() {
1003
+ return this.state.markersEnabled;
1004
+ }
1005
+ set markersEnabled(bool) {
1006
+ if (typeof bool === 'boolean') {
1007
+ if (!bool) {
1008
+ this.clearMarkers();
1009
+ this.state.markersEnabled = false;
1010
+ } else {
1011
+ !this.markersEnabled && this.drawMarkers();
1012
+ this.state.markersEnabled = true;
1013
+ }
1014
+ }
1015
+ }
1016
+ set regions(regionArray) {
1017
+ if (this.state.regions.length < 1) {
1018
+ regionArray && regionArray.forEach(region => {
1019
+ this.addRegion(region);
1020
+ });
1021
+ } else {
1022
+ this.state.regions.forEach((region, index) => {
1023
+ this.removeRegion(index);
1024
+ });
1025
+ this.state.regions = [];
1026
+ this.regions = regionArray;
1027
+ }
1028
+ }
1029
+ get regions() {
1030
+ return this.state.regions;
1031
+ }
1032
+ set dragging(bool) {
1033
+ if (bool && !this.state.dragging) {
1034
+ this.state.dragging = true;
1035
+ this.bar.classList.add('dragging');
1036
+ } else if (!bool && this.state.dragging) {
1037
+ this.state.dragging = false;
1038
+ this.bar.classList.remove('dragging');
1039
+ }
1040
+ }
1041
+ get dragging() {
1042
+ return this.state.dragging;
1043
+ }
1044
+ addRegion(regionObj) {
1045
+ if (regionObj.constructor.name === Region.name) {
1046
+ this.state.regions.push(regionObj);
1047
+ this.drawRegion(regionObj);
1048
+ } else {
1049
+ this.addRegion(new Region(regionObj));
1050
+ }
1051
+ }
1052
+ removeRegion(param) {
1053
+ if (typeof param === typeof Region) ; else {
1054
+ this.state.regions[param].el.remove();
1055
+ this.state.regions[param] = null;
1056
+ delete this.state.regions[param];
1057
+ }
1058
+ }
1059
+ drawRegion(region) {
1060
+ const duration = this.props.player.videojs.duration();
1061
+ const inPoint = region.in;
1062
+ const leftPercentage = inPoint / duration * 100;
1063
+ const rightPercentage = (duration - region.out) / duration * 100;
1064
+ const regionEl = document.createElement('div');
1065
+ regionEl.className = 'region nav ';
1066
+ regionEl.innerHTML = '<div class="bubble"></div>';
1067
+ if (region.title && region.annotation) {
1068
+ let alignmentClassName = '';
1069
+ if (leftPercentage > 70) alignmentClassName = 'right-aligned';
1070
+ if (leftPercentage < 30) alignmentClassName = 'left-aligned';
1071
+ regionEl.className += " has-popout ".concat(alignmentClassName);
1072
+ const popout = document.createElement('div');
1073
+ popout.className = 'popout';
1074
+ popout.innerHTML = "\n <div class=\"title\">\n ".concat(sanitize(region.title), "\n </div>\n <div class=\"annotation\">\n ").concat(truncate(sanitize(region.annotation), 72), "\n </div>\n ");
1075
+ regionEl.appendChild(popout);
1076
+ }
1077
+ regionEl.style.left = "".concat(leftPercentage, "%");
1078
+ regionEl.style.right = "".concat(rightPercentage, "%");
1079
+ region.el = regionEl;
1080
+ this.bar.appendChild(regionEl);
1081
+ }
1082
+ set onDark(bool) {
1083
+ if (bool) {
1084
+ this.bar.classList.add(classNames.onDark);
1085
+ } else {
1086
+ this.bar.classList.remove(classNames.onDark);
1087
+ }
1088
+ }
1089
+ get onDark() {
1090
+ return this.container.classList.contains(classNames.onDark);
1091
+ }
1092
+ set percentLoaded(val) {
1093
+ this.loadIndicator.style.width = "".concat(val, "%");
1094
+ }
1095
+ destroy() {
1096
+ this.unbindHotKeys();
1097
+ }
1098
+ toggleMarkers() {
1099
+ if (this.bar.classList.contains('hide-markers')) {
1100
+ this.showMarkers();
1101
+ } else {
1102
+ this.hideMarkers();
1103
+ }
1104
+ }
1105
+ hideMarkers() {
1106
+ this.bar.classList.add('hide-markers');
1107
+ }
1108
+ showMarkers() {
1109
+ this.bar.classList.remove('hide-markers');
1110
+ }
1111
+ }
1112
+ SeekBar.Region = Region;
1113
+
1114
+ const timeCodeNodeNames = ['hours', 'minutes', 'seconds', 'frame'];
1115
+ class TimeCodeDisplay {
1116
+ constructor(props) {
1117
+ this.props = props;
1118
+ this.state = {
1119
+ selectedNode: null
1120
+ };
1121
+ const classNames = ['vdt-timecode', 'vjs-time-control',
1122
+ !this.props.onInput ? 'duration' : ''
1123
+ ];
1124
+ this.container = document.createElement('div');
1125
+ this.container.className = classNames.join(' ');
1126
+ this.nodeNames = [].concat(timeCodeNodeNames);
1127
+ this.nodes = {};
1128
+ this.nodeNames.forEach((nodeName, index) => {
1129
+ const node = document.createElement('input');
1130
+ node.className = nodeName;
1131
+ node.tabIndex = -1;
1132
+ if (this.props.onInput) {
1133
+ node.maxLength = 2;
1134
+ node.onfocus = e => {
1135
+ this.handleInputFocus(e, nodeName);
1136
+ };
1137
+ node.onblur = e => {
1138
+ this.handleInputBlur(e, nodeName);
1139
+ };
1140
+ node.onmouseup = e => {
1141
+ e.preventDefault();
1142
+ e.currentTarget.select();
1143
+ };
1144
+ node.onkeydown = e => {
1145
+ this.handleTimeCodeInput(e, nodeName);
1146
+ };
1147
+ node.onkeyup = e => {
1148
+ this.handleTimeCodeInputOnKeyUp(e, nodeName);
1149
+ };
1150
+ } else {
1151
+ node.readOnly = true;
1152
+ }
1153
+ this.nodes[nodeName] = node;
1154
+ const colon = document.createElement('span');
1155
+ colon.innerHTML = ':';
1156
+ this.container.appendChild(node);
1157
+ index !== this.nodeNames.length - 1 && this.container.appendChild(colon);
1158
+ });
1159
+ if (this.props.target) {
1160
+ if (this.props.appendAfter) {
1161
+ this.props.target.parentNode.insertBefore(this.container, this.props.target.nextSibling);
1162
+ } else {
1163
+ this.props.target.appendChild(this.container);
1164
+ }
1165
+ this.reset();
1166
+ } else {
1167
+ console.error("Unable to instantiate a new ".concat(this.constructor.name, " without target DOM node"));
1168
+ }
1169
+ }
1170
+ update(valuesObj) {
1171
+ const startCount = this.nodeNames.length - 1;
1172
+ let i;
1173
+ for (i = startCount; i > -1; i--) {
1174
+ const key = this.nodeNames[i];
1175
+ if (typeof valuesObj[key] !== 'undefined' && valuesObj[key] !== parseInt(this.nodes[key].value, 10) && key !== this.state.selectedNode) {
1176
+ const str = valuesObj[key].toString();
1177
+ this.nodes[key].value = this.toDigitPairStr(str);
1178
+ }
1179
+ }
1180
+ }
1181
+ reset() {
1182
+ this.update({
1183
+ hours: 0,
1184
+ minutes: 0,
1185
+ seconds: 0,
1186
+ frame: 0
1187
+ });
1188
+ }
1189
+ handleInputFocus(e, nodeName) {
1190
+ this.state.selectedNode = nodeName;
1191
+ this.nodes[nodeName].select();
1192
+ this.props.onInputFocus && this.props.onInputFocus(nodeName);
1193
+ }
1194
+ handleInputBlur(e, nodeName) {
1195
+ this.state.selectedNode = null;
1196
+ this.props.onInputBlur && this.props.onInputBlur(nodeName);
1197
+ }
1198
+ sanitize(input) {
1199
+ const output = input.replace(/[^0-9]/g, '');
1200
+ return output;
1201
+ }
1202
+ toDigitPairStr(strValue) {
1203
+ return strValue.length < 2 ? "0".concat(strValue) : strValue;
1204
+ }
1205
+ handleTimeCodeInput(e, nodeName) {
1206
+ const nodeIndex = this.nodeNames.indexOf(nodeName);
1207
+ switch (e.code) {
1208
+ case 'Enter':
1209
+ this.checkAndNormalizeAllInputs();
1210
+ this.props.onInput && this.props.onInput(e, nodeName, {
1211
+ hours: this.hours,
1212
+ minutes: this.minutes,
1213
+ seconds: this.seconds,
1214
+ frame: this.frame
1215
+ });
1216
+ this[nodeName] = e.currentTarget.value;
1217
+ e.currentTarget.blur();
1218
+ break;
1219
+ case 'Tab':
1220
+ e.preventDefault();
1221
+ if (!e.shiftKey) {
1222
+ if (nodeIndex + 1 <= this.nodeNames.length - 1) {
1223
+ this.nodes[this.nodeNames[nodeIndex + 1]].focus();
1224
+ } else {
1225
+ this.nodes[this.nodeNames[0]].focus();
1226
+ }
1227
+ } else if (nodeIndex - 1 >= 0) {
1228
+ this.nodes[this.nodeNames[nodeIndex - 1]].focus();
1229
+ } else {
1230
+ this.nodes[this.nodeNames[this.nodeNames.length - 1]].focus();
1231
+ }
1232
+ break;
1233
+ }
1234
+ }
1235
+ handleTimeCodeInputOnKeyUp(e, nodeName) {
1236
+ if (this.nodes[nodeName].value.length === 2 && !isNaN(e.key)) {
1237
+ const nodeIndex = this.nodeNames.indexOf(nodeName);
1238
+ if (nodeIndex + 1 <= this.nodeNames.length - 1) {
1239
+ this.nodes[this.nodeNames[nodeIndex + 1]].focus();
1240
+ }
1241
+ }
1242
+ }
1243
+ checkAndNormalizeAllInputs() {
1244
+ this.nodeNames.forEach(nodeName => {
1245
+ if (this.nodes[nodeName].value.length < 1) {
1246
+ this.nodes[nodeName].value = '00';
1247
+ }
1248
+ this.nodes[nodeName].value = this.toDigitPairStr(this.sanitize(this.nodes[nodeName].value));
1249
+ });
1250
+ }
1251
+ set frame(val) {
1252
+ this.nodes.frame.value = this.toDigitPairStr(val);
1253
+ }
1254
+ get frame() {
1255
+ return parseInt(this.nodes.frame.value, 10);
1256
+ }
1257
+ set seconds(val) {
1258
+ this.nodes.seconds.value = this.toDigitPairStr(val);
1259
+ }
1260
+ get seconds() {
1261
+ return parseInt(this.nodes.seconds.value, 10);
1262
+ }
1263
+ set minutes(val) {
1264
+ this.nodes.minutes.value = this.toDigitPairStr(val);
1265
+ }
1266
+ get minutes() {
1267
+ return parseInt(this.nodes.minutes.value, 10);
1268
+ }
1269
+ set hours(val) {
1270
+ this.nodes.hours.value = this.toDigitPairStr(val);
1271
+ }
1272
+ get hours() {
1273
+ return parseInt(this.nodes.hours.value, 10);
1274
+ }
1275
+ getFormatted(key) {
1276
+ return this.toDigitPairStr(this[key].toString());
1277
+ }
1278
+ get smpte() {
1279
+ return {
1280
+ hours: this.hours,
1281
+ minutes: this.minutes,
1282
+ seconds: this.seconds,
1283
+ frame: this.frame
1284
+ };
1285
+ }
1286
+ set smpte(o) {
1287
+ this.update(o);
1288
+ }
1289
+ get smpteString() {
1290
+ return "".concat(this.getFormatted('hours'), ":").concat(this.getFormatted('minutes'), ":").concat(this.getFormatted('seconds'), ":").concat(this.getFormatted('frame'));
1291
+ }
1292
+ set external(bool) {
1293
+ if (bool) {
1294
+ this.container.classList.add('external');
1295
+ } else {
1296
+ this.container.classList.remove('external');
1297
+ }
1298
+ }
1299
+ get external() {
1300
+ return this.container.classList.contains('external');
1301
+ }
1302
+ }
1303
+
1304
+ class VideoTime {
1305
+ constructor(props) {
1306
+ if (props.frameRate === undefined) {
1307
+ delete this;
1308
+ throw new Error('No "frameRate" option provided, refer to docs.');
1309
+ } else {
1310
+ this.props = props;
1311
+ }
1312
+ }
1313
+ secondsToFramesFromStart(seconds) {
1314
+ let frame = seconds * this.props.frameRate;
1315
+ frame = Math.round(frame);
1316
+ return frame;
1317
+ }
1318
+ currentTimeToFramesFromStart(currentTime) {
1319
+ return this.secondsToFramesFromStart(currentTime);
1320
+ }
1321
+ secondsToFrame(seconds) {
1322
+ let frame = this.secondsToFramesFromStart(seconds) % this.props.frameRate;
1323
+ frame = Math.round(frame);
1324
+ return frame;
1325
+ }
1326
+ currentFrame(currentTime) {
1327
+ return Math.round(this.secondsToFrame(currentTime));
1328
+ }
1329
+ frameToCurrentTimeFromStart(frame) {
1330
+ return frame / this.props.frameRate;
1331
+ }
1332
+ smpteToCurrentTimeFromStart(values) {
1333
+ return values.hours * 3600 + values.minutes * 60 + values.seconds + values.frame / this.props.frameRate;
1334
+ }
1335
+ secondsFromStartToSMPTE(secondsFromStart) {
1336
+ let secondsFS = secondsFromStart;
1337
+ const hours = Math.floor(secondsFS / 3600);
1338
+ const minutesWithoutHours = secondsFS / 60 - 60 * hours;
1339
+ secondsFS %= 3600;
1340
+ const minutes = Math.floor(minutesWithoutHours);
1341
+ const seconds = Math.floor(secondsFS % 60);
1342
+ const frame = this.secondsToFrame(secondsFS);
1343
+ return {
1344
+ hours,
1345
+ minutes,
1346
+ seconds,
1347
+ frame
1348
+ };
1349
+ }
1350
+ }
1351
+
1352
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
1353
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
1354
+ const correctMimeTypes = {
1355
+ 'audio/x-aac': 'audio/aac'
1356
+ };
1357
+ const sanitizeMimeType = mimeType => correctMimeTypes[mimeType] || mimeType;
1358
+ class Player {
1359
+ constructor(props) {
1360
+ this.props = props;
1361
+ reactiveSetters.apply(this);
1362
+ const classNames = [
1363
+ 'video-js', 'vjs-big-play-centered', this.props.posterUrl ? constants$2.classNames.poster : '', this.props.subtitles && this.props.subtitles.length > 0 ? constants$2.classNames.subtitles : '', 'init'
1364
+ ];
1365
+ this.externalTimecodes = {
1366
+ duration: [],
1367
+ playback: []
1368
+ };
1369
+ this.timeConverter = new VideoTime({
1370
+ frameRate: this.props.frameRate || constants$2.defaults.frameRate
1371
+ });
1372
+ this.videoEl = document.createElement('video');
1373
+ this.videoEl.crossOrigin = this.props.crossOrigin;
1374
+ this.videoEl.id = 'vdt-video';
1375
+ this.videoEl.className = classNames.join(' ');
1376
+ this.videoEl.controls = true;
1377
+ if (this.props.sources) {
1378
+ if (this.props.sources.length > 1) {
1379
+ this.props.sources.sort(a => a.type.indexOf('mp4') > 0 ? 1 : -1);
1380
+ }
1381
+ this.props.sources.forEach(source => {
1382
+ const aSource = document.createElement('source');
1383
+ aSource.src = source.src;
1384
+ aSource.type = sanitizeMimeType(source.type);
1385
+ this.videoEl.appendChild(aSource);
1386
+ });
1387
+ }
1388
+ this.videoEl.onloadedmetadata = () => {
1389
+ if (this.durationTimeCode) {
1390
+ this.setDurationTimeCode();
1391
+ }
1392
+ if (this.videojs.el_) this.videojs.el_.classList.remove('init');
1393
+ };
1394
+ setTimeout(() => {
1395
+ if (this.videojs.el_) this.videojs.el_.classList.remove('init');
1396
+ }, 2000);
1397
+ if (this.props.subtitles) {
1398
+ this.props.subtitles.forEach(sub => {
1399
+ const subtitleTag = document.createElement('track');
1400
+ subtitleTag.kind = 'subtitles';
1401
+ subtitleTag.srclang = sub.lang;
1402
+ subtitleTag.label = sub.label;
1403
+ if (typeof sub.src === 'string') {
1404
+ subtitleTag.src = sub.src;
1405
+ } else {
1406
+ subtitleTag.src = window.URL.createObjectURL(sub.src);
1407
+ }
1408
+ this.videoEl.appendChild(subtitleTag);
1409
+ });
1410
+ }
1411
+ if (this.props.target) this.props.target.appendChild(this.videoEl);
1412
+ const showDefaultTimeDisplay = this.props.timecode !== true;
1413
+ const controlsEnabled = this.props.controls !== false;
1414
+ const options = this.props.options || {};
1415
+ this.videojs = new videojs__default["default"]('vdt-video', _objectSpread({
1416
+ responsive: true,
1417
+ fluid: true,
1418
+ controls: controlsEnabled,
1419
+ alwaysCaptureHotkeys: false,
1420
+ controlBar: {
1421
+ RemainingTimeDisplay: false,
1422
+ timeDivider: showDefaultTimeDisplay,
1423
+ durationDisplay: showDefaultTimeDisplay,
1424
+ currentTimeDisplay: showDefaultTimeDisplay
1425
+ },
1426
+ inactivityTimeout: this.audioOnly ? constants$2.defaults.audioInactivityTimeout : constants$2.defaults.inactivityTimeout,
1427
+ preload: 'auto',
1428
+ captionsButton: false,
1429
+ subsCapsButton: false,
1430
+ subtitlesButton: false,
1431
+ textTrackSettings: false,
1432
+ html5: {
1433
+ nativeTextTracks: false
1434
+ },
1435
+ languages: {
1436
+ en: {
1437
+ 'captions off': 'off',
1438
+ 'subtitles off': 'off'
1439
+ }
1440
+ }
1441
+ }, options));
1442
+ if (this.props.posterUrl) this.videojs.poster(this.props.posterUrl);
1443
+ this.handleNewProps(this.props);
1444
+ this.videojs.ready(() => {
1445
+ this.bindHotkeys();
1446
+ this.bindEvents();
1447
+ if (this.props.onReady) this.props.onReady(this.videojs);
1448
+ this.restoreSettings();
1449
+ this.setupTimeCode();
1450
+ this.doEsothericWork();
1451
+ this.setupMenu();
1452
+ this.setupCustomSeekbar();
1453
+ });
1454
+ }
1455
+ setupCustomSeekbar() {
1456
+ if (this.props.seekBar) {
1457
+ this.videojs.controlBar.progressControl.disable();
1458
+ this.videojs.controlBar.progressControl.hide();
1459
+ const target = this.container.getElementsByClassName('vjs-control-bar')[0];
1460
+ const props = _objectSpread({
1461
+ target,
1462
+ player: this,
1463
+ onDark: this.props.onDark
1464
+ }, this.props.seekBar);
1465
+ this.seekBar = new SeekBar(props);
1466
+ this.videojs.on('userinactive', () => {
1467
+ if (!this.controlsBelowPlayer) {
1468
+ var _this$seekBar$hideMar, _this$seekBar;
1469
+ if (this.seekBar) (_this$seekBar$hideMar = (_this$seekBar = this.seekBar).hideMarkers) === null || _this$seekBar$hideMar === void 0 ? void 0 : _this$seekBar$hideMar.call(_this$seekBar);
1470
+ } else {
1471
+ var _this$seekBar2, _this$seekBar2$showMa;
1472
+ (_this$seekBar2 = this.seekBar) === null || _this$seekBar2 === void 0 ? void 0 : (_this$seekBar2$showMa = _this$seekBar2.showMarkers) === null || _this$seekBar2$showMa === void 0 ? void 0 : _this$seekBar2$showMa.call(_this$seekBar2);
1473
+ }
1474
+ });
1475
+ this.videojs.on('useractive', () => {
1476
+ if (this.seekBar) this.seekBar.showMarkers();
1477
+ });
1478
+ }
1479
+ }
1480
+ setupTimeCode() {
1481
+ let externalTimecodeInstance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1482
+ const props = {
1483
+ onInput: (e, nodeName, values) => {
1484
+ this.seekTo(this.timeConverter.smpteToCurrentTimeFromStart(values));
1485
+ },
1486
+ onInputFocus: () => {
1487
+ this.videojs.options_.inactivityTimeout = 0;
1488
+ this.videojs.cache_.inactivityTimeout = 0;
1489
+ this.videojs.reportUserActivity();
1490
+ this.videojs.pause();
1491
+ },
1492
+ onInputBlur: () => {
1493
+ this.videojs.options().inactivityTimeout = constants$2.defaults.inactivityTimeout;
1494
+ this.videojs.cache_.inactivityTimeout = constants$2.defaults.inactivityTimeout;
1495
+ }
1496
+ };
1497
+ if (externalTimecodeInstance !== null) {
1498
+ externalTimecodeInstance.props = Object.assign(externalTimecodeInstance.props, props);
1499
+ this.externalTimecodes.playback.push(externalTimecodeInstance);
1500
+ } else if (this.props.timecode === true) {
1501
+ if (this.props.controls !== false) {
1502
+ const target = document.getElementsByClassName('vjs-volume-panel')[0];
1503
+ this.timeCode = new TimeCodeDisplay(Object.assign(props, {
1504
+ target,
1505
+ appendAfter: true
1506
+ }));
1507
+ this.durationTimeCode = new TimeCodeDisplay({
1508
+ target: this.timeCode.container,
1509
+ appendAfter: true
1510
+ });
1511
+ }
1512
+ }
1513
+ if (this.timeCode || this.externalTimecodes.playback.length > 0) {
1514
+ this.videojs.on('timeupdate', () => {
1515
+ this.updateTimeCode();
1516
+ });
1517
+ this.videojs.on('play', () => {
1518
+ this.updateTimeCodeFrame();
1519
+ });
1520
+ }
1521
+ }
1522
+ updateTimeCode() {
1523
+ const currentSecond = this.videojs.currentTime();
1524
+ const props = this.timeConverter.secondsFromStartToSMPTE(currentSecond);
1525
+ if (this.timeCode) this.timeCode.update(props);
1526
+ if (this.externalTimecodes.playback.length > 0) {
1527
+ this.externalTimecodes.playback.forEach(timecode => {
1528
+ timecode.update(props);
1529
+ });
1530
+ }
1531
+ }
1532
+ updateTimeCodeFrame() {
1533
+ const frame = this.timeConverter.currentFrame(this.videojs.currentTime());
1534
+ if (this.timeCode) this.timeCode.update({
1535
+ frame
1536
+ });
1537
+ if (this.externalTimecodes.playback.length > 0) {
1538
+ this.externalTimecodes.playback.forEach(timecode => {
1539
+ timecode.update({
1540
+ frame
1541
+ });
1542
+ });
1543
+ }
1544
+ if (!this.videojs.paused()) {
1545
+ this.rafID = requestAnimationFrame(() => {
1546
+ this.updateTimeCodeFrame();
1547
+ });
1548
+ }
1549
+ }
1550
+ setDurationTimeCode() {
1551
+ const durationInSeconds = this.videojs.duration();
1552
+ const props = this.timeConverter.secondsFromStartToSMPTE(durationInSeconds);
1553
+ props.frame = this.timeConverter.secondsToFrame(durationInSeconds);
1554
+ this.durationTimeCode.update(props);
1555
+ this.durationTimeCode.container.classList.add('duration');
1556
+ }
1557
+ bindHotkeys() {
1558
+ this.bindings = [{
1559
+ key: ['space', 'k'],
1560
+ method: e => {
1561
+ if (e.preventDefault) e.preventDefault();
1562
+ this.togglePlayback();
1563
+ }
1564
+ }, {
1565
+ key: 'j',
1566
+ method: () => {
1567
+ if (this.videojs.hasStarted_) this.jumpBackward();
1568
+ }
1569
+ }, {
1570
+ key: 'l',
1571
+ method: () => {
1572
+ if (this.videojs.hasStarted_) this.jumpForward();
1573
+ }
1574
+ }, {
1575
+ key: ['.', 'right'],
1576
+ method: () => {
1577
+ this.frameForward();
1578
+ }
1579
+ }, {
1580
+ key: [',', 'left'],
1581
+ method: () => {
1582
+ this.frameBackward();
1583
+ }
1584
+ }, {
1585
+ key: 'f',
1586
+ method: () => {
1587
+ this.toggleFullscreen();
1588
+ }
1589
+ }, {
1590
+ key: 'm',
1591
+ method: () => {
1592
+ this.toggleMute();
1593
+ }
1594
+ }, {
1595
+ key: 'up',
1596
+ method: e => {
1597
+ if (e.preventDefault) e.preventDefault();
1598
+ this.volumeUp();
1599
+ }
1600
+ }, {
1601
+ key: 'down',
1602
+ method: e => {
1603
+ if (e.preventDefault) e.preventDefault();
1604
+ this.volumeDown();
1605
+ }
1606
+ }, {
1607
+ key: 'h',
1608
+ method: () => {
1609
+ this.help.toggle();
1610
+ }
1611
+ }, {
1612
+ key: 'n',
1613
+ method: () => {
1614
+ if (this.menu) this.menu.toggle();
1615
+ }
1616
+ }];
1617
+ if (this.props.subtitles) {
1618
+ this.bindings.push({
1619
+ key: 'c',
1620
+ method: () => {
1621
+ this.toggleSubs();
1622
+ }
1623
+ });
1624
+ }
1625
+ this.bindings.forEach(binding => {
1626
+ mousetrap__default["default"].bind(binding.key, e => {
1627
+ binding.method(e);
1628
+ this.onHotkeyPressed(binding.key);
1629
+ });
1630
+ });
1631
+ }
1632
+ unbindHotKeys() {
1633
+ if (this.bindings) this.bindings.forEach(binding => {
1634
+ mousetrap__default["default"].unbind(binding.key);
1635
+ });
1636
+ }
1637
+ bindEvents() {
1638
+ this.videojs.on('volumechange', () => {
1639
+ this.persistSetting(constants$2.settings.volume, this.volume);
1640
+ });
1641
+ this.videojs.textTracks().on('change', () => {
1642
+ const tracks = this.videojs.textTracks().tracks_;
1643
+ const selected = tracks.filter(track => track.mode === 'showing');
1644
+ const areAnyTxtTracksActive = selected.length > 0;
1645
+ if (areAnyTxtTracksActive) {
1646
+ this.videojs.el_.classList.add(constants$2.classNames.subtitlesActive);
1647
+ this.persistSetting(constants$2.settings.subs, true);
1648
+ this.persistSetting(constants$2.settings.subLang, selected[0].language);
1649
+ } else {
1650
+ this.videojs.el_.classList.remove(constants$2.classNames.subtitlesActive);
1651
+ this.persistSetting(constants$2.settings.subs, false);
1652
+ }
1653
+ });
1654
+ }
1655
+ volumeUp() {
1656
+ this.videojs.controlBar.volumePanel.volumeControl.volumeBar.stepForward();
1657
+ this.osd.feedback(constants$2.osd.volchange, {
1658
+ volume: this.volume
1659
+ });
1660
+ }
1661
+ volumeDown() {
1662
+ this.videojs.controlBar.volumePanel.volumeControl.volumeBar.stepBack();
1663
+ this.osd.feedback(constants$2.osd.volchange, {
1664
+ volume: this.volume
1665
+ });
1666
+ }
1667
+ toggleMute() {
1668
+ if (!this.videojs.muted()) {
1669
+ this.videojs.muted(true);
1670
+ this.osd.feedback(constants$2.osd.volchange, {
1671
+ volume: this.volume
1672
+ });
1673
+ } else {
1674
+ this.videojs.muted(false);
1675
+ this.osd.feedback(constants$2.osd.volchange, {
1676
+ volume: this.volume
1677
+ });
1678
+ }
1679
+ }
1680
+ toggleFullscreen() {
1681
+ if (this.videojs.isFullscreen()) {
1682
+ this.videojs.exitFullscreen();
1683
+ } else {
1684
+ this.videojs.requestFullscreen();
1685
+ }
1686
+ }
1687
+ seek(secs) {
1688
+ let time = this.videojs.currentTime() + secs;
1689
+ if (time < 0) {
1690
+ time = 0;
1691
+ }
1692
+ this.videojs.currentTime(time);
1693
+ }
1694
+ seekTo(sec) {
1695
+ if (!this.videojs.hasStarted()) this.videojs.hasStarted(true);
1696
+ this.videojs.currentTime(sec);
1697
+ }
1698
+ jumpForward() {
1699
+ this.seek(constants$2.defaults.jumpSeconds);
1700
+ this.osd.feedback(constants$2.osd.jumpForward);
1701
+ }
1702
+ jumpBackward() {
1703
+ this.seek(-constants$2.defaults.jumpSeconds);
1704
+ this.osd.feedback(constants$2.osd.jumpBackward);
1705
+ }
1706
+ frameForward() {
1707
+ const thisFrame = this.timeConverter.secondsToFramesFromStart(this.videojs.currentTime());
1708
+ const nextFrame = Math.round(thisFrame) + 1;
1709
+ this.videojs.currentTime(this.timeConverter.frameToCurrentTimeFromStart(nextFrame));
1710
+ }
1711
+ frameBackward() {
1712
+ const thisFrame = this.timeConverter.secondsToFramesFromStart(this.videojs.currentTime());
1713
+ const previousFrame = Math.round(thisFrame) - 1;
1714
+ this.videojs.currentTime(this.timeConverter.frameToCurrentTimeFromStart(previousFrame));
1715
+ }
1716
+ secondsToFramesFromStart(seconds) {
1717
+ const frameRate = this.props.frameRate || constants$2.defaults.frameRate;
1718
+ let frame = seconds * frameRate;
1719
+ frame = Math.round(frame);
1720
+ return frame;
1721
+ }
1722
+ doEsothericWork() {
1723
+ if (this.props.color) {
1724
+ document.getElementsByClassName('vjs-play-progress')[0].style.backgroundColor = this.props.color;
1725
+ }
1726
+ this.osd = new OSD({
1727
+ target: this.videoEl.parentElement
1728
+ });
1729
+ if (this.props.onCinema) {
1730
+ this.videoEl.parentElement.classList.add('has-cinema-button');
1731
+ this.cinema = false;
1732
+ this.addButtonToControlBar({
1733
+ onClick: () => {
1734
+ this.props.onCinema(!this.cinema);
1735
+ this.cinema = !this.cinema;
1736
+ },
1737
+ componentName: 'CinemaButton',
1738
+ className: 'vdt-cinema-button',
1739
+ title: 'Cinema-mode'
1740
+ });
1741
+ }
1742
+ if (this.props.onScreenshot) {
1743
+ this.videoEl.parentElement.classList.add('has-screenshot-button');
1744
+ this.addButtonToControlBar({
1745
+ onClick: () => {
1746
+ this.props.onScreenshot(this.videojs.currentTime());
1747
+ },
1748
+ componentName: 'ScreenshotButton',
1749
+ className: 'vdt-screenshot-button',
1750
+ title: 'Screenshot'
1751
+ });
1752
+ }
1753
+ this.help = new HelpOverlay({
1754
+ target: this.videoEl.parentElement,
1755
+ onToggle: willShow => {
1756
+ if (this.menu && this.menu.opened) {
1757
+ this.menu.close();
1758
+ }
1759
+ if (willShow && !this.controlsBelowPlayer) {
1760
+ this.hideControls();
1761
+ } else {
1762
+ this.showControls();
1763
+ }
1764
+ }
1765
+ });
1766
+ }
1767
+ restoreSettings() {
1768
+ const volume = localStorage.getItem(constants$2.settings.volume);
1769
+ const subsEnabled = localStorage.getItem(constants$2.settings.subs);
1770
+ const subLang = localStorage.getItem(constants$2.settings.subLang);
1771
+ this.settings = {
1772
+ [constants$2.settings.volume]: volume !== null ? Math.round(volume * 100) / 100 : 1,
1773
+ [constants$2.settings.subLang]: subLang !== null ? subLang : 'en',
1774
+ [constants$2.settings.subs]: subsEnabled !== null ? JSON.parse(subsEnabled) : false
1775
+ };
1776
+ this.volume = this.settings[constants$2.settings.volume];
1777
+ if (this.settings[constants$2.settings.subs]) {
1778
+ this.enableSubs();
1779
+ }
1780
+ }
1781
+ persistSetting(key, val) {
1782
+ this.settings[key] = val;
1783
+ localStorage.setItem(key, val);
1784
+ }
1785
+ enableSubs() {
1786
+ const subs = this.videojs.textTracks();
1787
+ for (let i = 0; i < subs.length; i += 1) {
1788
+ const sub = subs[i];
1789
+ if (sub.language === this.settings[constants$2.settings.subLang]) {
1790
+ sub.mode = 'showing';
1791
+ } else {
1792
+ sub.mode = 'hidden';
1793
+ }
1794
+ }
1795
+ }
1796
+ disableSubs() {
1797
+ const subs = this.videojs.textTracks();
1798
+ for (let i = 0; i < subs.length; i += 1) {
1799
+ const sub = subs[i];
1800
+ sub.mode = 'hidden';
1801
+ }
1802
+ }
1803
+ toggleSubs() {
1804
+ if (this.videojs.textTracks().length > 0) {
1805
+ if (this.videojs.textTracks().tracks_.filter(track => track.mode === 'showing').length > 0) {
1806
+ this.disableSubs();
1807
+ } else {
1808
+ this.enableSubs();
1809
+ }
1810
+ }
1811
+ }
1812
+ addButtonToControlBar(options) {
1813
+ const Button = videojs__default["default"].getComponent('Button');
1814
+ const CustomButton = videojs__default["default"].extend(Button, {
1815
+ constructor: function constructor() {
1816
+ Button.apply(this, arguments);
1817
+ if (options.className) this.el_.classList.add(options.className);
1818
+ if (options.title) {
1819
+ this.el_.title = options.title;
1820
+ }
1821
+ },
1822
+ handleClick: () => {
1823
+ if (options.onClick) options.onClick();
1824
+ }
1825
+ });
1826
+ videojs__default["default"].registerComponent(options.componentName, CustomButton);
1827
+ this.videojs.getChild('controlBar').addChild(options.componentName, {}, 7);
1828
+ }
1829
+ get volume() {
1830
+ return this.videojs.controlBar.volumePanel.volumeControl.volumeBar.getPercent();
1831
+ }
1832
+ set volume(floatVal) {
1833
+ if (floatVal === 0) {
1834
+ this.videojs.muted(true);
1835
+ } else {
1836
+ this.videojs.muted(false);
1837
+ this.videojs.volume(floatVal);
1838
+ }
1839
+ }
1840
+ setupMenu() {
1841
+ const menuItems = this.props.menuItems || [];
1842
+ const sourcesMenuItems = [];
1843
+ if (this.props.sources.length > 1) {
1844
+ this.props.sources.forEach(source => {
1845
+ if (source.label) {
1846
+ sourcesMenuItems.push({
1847
+ title: source.label,
1848
+ onClick: () => {
1849
+ this.src = source;
1850
+ }
1851
+ });
1852
+ }
1853
+ });
1854
+ menuItems.push({
1855
+ title: 'Sources',
1856
+ getActiveIndex: () => {
1857
+ const matchingSource = this.props.sources.find(source => source.src === this.videojs.src());
1858
+ return sourcesMenuItems.indexOf(sourcesMenuItems.find(menuItem => menuItem.title === matchingSource.label));
1859
+ },
1860
+ items: sourcesMenuItems
1861
+ });
1862
+ }
1863
+ if (this.props.subtitles && this.props.subtitles.length > 0) {
1864
+ const subtitleMenuItems = [{
1865
+ title: 'Off',
1866
+ onClick: () => {
1867
+ this.disableSubs();
1868
+ }
1869
+ }];
1870
+ this.props.subtitles.forEach((subtitle, index) => {
1871
+ subtitleMenuItems.push({
1872
+ title: subtitle.label,
1873
+ onClick: () => {
1874
+ const subs = this.videojs.textTracks();
1875
+ for (let i = 0; i < subs.length; i += 1) {
1876
+ const sub = subs[i];
1877
+ if (i === index) {
1878
+ sub.mode = 'showing';
1879
+ } else {
1880
+ sub.mode = 'hidden';
1881
+ }
1882
+ }
1883
+ }
1884
+ });
1885
+ });
1886
+ menuItems.push({
1887
+ title: 'Subtitles',
1888
+ getActiveIndex: () => {
1889
+ const subs = this.videojs.textTracks();
1890
+ for (let i = 0; i < subs.length; i += 1) {
1891
+ const sub = subs[i];
1892
+ if (sub.mode === 'showing') {
1893
+ return i + 1;
1894
+ }
1895
+ }
1896
+ return 0;
1897
+ },
1898
+ items: subtitleMenuItems
1899
+ });
1900
+ }
1901
+ if (menuItems.length > 0) {
1902
+ const target = this.videojs.el_;
1903
+ this.menu = new Menu({
1904
+ target,
1905
+ items: menuItems,
1906
+ onOpen: () => {
1907
+ if (!this.controlsBelowPlayer) this.hideControls();
1908
+ },
1909
+ onClose: () => {
1910
+ if (!this.controlsBelowPlayer) this.videojs.controls(true);
1911
+ }
1912
+ });
1913
+ this.videoEl.parentElement.classList.add('has-vdt-menu');
1914
+ this.addButtonToControlBar({
1915
+ onClick: () => {
1916
+ this.menu.toggle();
1917
+ },
1918
+ componentName: 'SettingsMenuButton',
1919
+ className: 'vdt-settings-menu-button',
1920
+ title: 'Settings'
1921
+ });
1922
+ }
1923
+ }
1924
+ hideControls() {
1925
+ this.videojs.userActive(false);
1926
+ this.videojs.controls(false);
1927
+ this.videojs.fluid(true);
1928
+ this.videoEl.parentElement.classList.remove('vjs-user-active');
1929
+ this.videojs.userActive(false);
1930
+ }
1931
+ showControls() {
1932
+ this.videojs.fluid(!this.controlsBelowPlayer);
1933
+ this.videojs.controls(true);
1934
+ this.videojs.userActive(true);
1935
+ }
1936
+ toggleControls() {
1937
+ if (this.videojs.controls()) {
1938
+ this.hideControls();
1939
+ } else {
1940
+ this.showControls();
1941
+ }
1942
+ }
1943
+ onHotkeyPressed(key) {
1944
+ if (key !== 'h' && this.help.state.active) {
1945
+ this.help.hide();
1946
+ }
1947
+ }
1948
+ triggerHotkey(key) {
1949
+ mousetrap__default["default"].trigger(key);
1950
+ }
1951
+ toStart() {
1952
+ this.videojs.currentTime(0);
1953
+ }
1954
+ toEnd() {
1955
+ this.videojs.currentTime(this.videojs.duration());
1956
+ }
1957
+ replay() {
1958
+ this.toStart();
1959
+ this.videojs.play();
1960
+ }
1961
+ play() {
1962
+ this.videojs.play();
1963
+ }
1964
+ pause() {
1965
+ if (!this.videojs.paused()) this.videojs.pause();
1966
+ }
1967
+ togglePlayback() {
1968
+ if (this.videojs.paused()) {
1969
+ this.play();
1970
+ if (this.videojs.hasStarted_) this.osd.feedback(constants$2.osd.play);
1971
+ } else {
1972
+ this.pause();
1973
+ this.osd.feedback(constants$2.osd.pause);
1974
+ }
1975
+ }
1976
+ updateSmpte(valuesObj) {
1977
+ const startCount = this.nodeNames.length - 1;
1978
+ let i;
1979
+ for (i = startCount; i > -1; i -= 1) {
1980
+ const key = this.nodeNames[i];
1981
+ if (typeof valuesObj[key] !== 'undefined' && valuesObj[key] !== parseInt(this.nodes[key].value, 10) && key !== this.state.selectedNode) {
1982
+ const str = valuesObj[key].toString();
1983
+ this.nodes[key].value = this.toDigitPairStr(str);
1984
+ }
1985
+ }
1986
+ }
1987
+ destroy() {
1988
+ this.videojs.paused(true);
1989
+ if (this.rafID) cancelAnimationFrame(this.rafID);
1990
+ this.videojs.dispose();
1991
+ this.unbindHotKeys();
1992
+ if (this.seekBar) this.seekBar.destroy();
1993
+ }
1994
+ get container() {
1995
+ return this.videoEl.parentElement;
1996
+ }
1997
+ set onDark(bool) {
1998
+ if (bool) {
1999
+ this.container.classList.add('on-dark');
2000
+ } else {
2001
+ this.container.classList.remove('on-dark');
2002
+ }
2003
+ if (this.seekBar) {
2004
+ this.seekBar.onDark = bool;
2005
+ }
2006
+ }
2007
+ get onDark() {
2008
+ return this.container.classList.contains('on-dark');
2009
+ }
2010
+ set controlsBelowPlayer(bool) {
2011
+ if (this.videojs.controls()) {
2012
+ if (bool) {
2013
+ this.container.classList.add('controls-below-player');
2014
+ this.videojs.fluid(false);
2015
+ } else {
2016
+ this.container.classList.remove('controls-below-player');
2017
+ this.videojs.fluid(true);
2018
+ }
2019
+ }
2020
+ }
2021
+ get controlsBelowPlayer() {
2022
+ return this.container.classList.contains('controls-below-player');
2023
+ }
2024
+ get smpte() {
2025
+ const currentSecond = this.videojs.currentTime();
2026
+ return this.timeConverter.secondsFromStartToSMPTE(currentSecond);
2027
+ }
2028
+ set smpte(o) {
2029
+ this.updateSmpte(o);
2030
+ }
2031
+ set src(_ref) {
2032
+ let {
2033
+ src,
2034
+ type = 'video/mp4',
2035
+ label = null
2036
+ } = _ref;
2037
+ const currentTime = this.videojs.currentTime();
2038
+ const source = this.props.sources.find(aSource => aSource.src === src);
2039
+ const onReady = () => {
2040
+ let initdone = false;
2041
+ this.videojs.on('loadedmetadata', () => {
2042
+ this.videojs.currentTime(currentTime);
2043
+ });
2044
+ this.videojs.on('canplaythrough', () => {
2045
+ if (!initdone) {
2046
+ this.videojs.currentTime(currentTime);
2047
+ initdone = true;
2048
+ this.videojs.play();
2049
+ }
2050
+ });
2051
+ };
2052
+ if (source && Array.isArray(source) && source.length > 0) {
2053
+ this.videojs.addClass('vjs-waiting');
2054
+ this.videojs.src(_objectSpread({}, source[0]));
2055
+ onReady();
2056
+ } else {
2057
+ this.videojs.addClass('vjs-waiting');
2058
+ this.videojs.src(this.addSrc(src, type, label));
2059
+ onReady();
2060
+ }
2061
+ }
2062
+ get src() {
2063
+ return this.videojs.src();
2064
+ }
2065
+ addSrc(src, type, label) {
2066
+ const newSource = {
2067
+ src,
2068
+ type,
2069
+ label
2070
+ };
2071
+ const index = this.props.sources.push(newSource) - 1;
2072
+ return this.props.sources[index];
2073
+ }
2074
+ removeSrc(url) {
2075
+ }
2076
+ set controls(bool) {
2077
+ if (bool) {
2078
+ this.showControls();
2079
+ } else {
2080
+ this.hideControls();
2081
+ }
2082
+ }
2083
+ get percentLoaded() {
2084
+ const r = this.videojs.buffered();
2085
+ const percentLoaded = r.end(0) / this.videojs.duration() * 100;
2086
+ return percentLoaded;
2087
+ }
2088
+ }
2089
+ const button = videojs__default["default"].prototype.constructor.getComponent('Button');
2090
+ button.prototype.handleKeyDown = function (e) {
2091
+ if (e.keyCode === 32) {
2092
+ e.preventDefault();
2093
+ }
2094
+ };
2095
+ videojs__default["default"].prototype.constructor.registerComponent('Button', button);
2096
+ const subsButton = videojs__default["default"].prototype.constructor.getComponent('SubsCapsButton');
2097
+ class CustomSubsCapsButton extends subsButton {
2098
+ constructor(player) {
2099
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2100
+ super(player, options);
2101
+ this.menuButton_.off('mouseenter');
2102
+ this.menuButton_.off('mouseleave');
2103
+ }
2104
+ }
2105
+ videojs__default["default"].prototype.constructor.registerComponent('SubsCapsButton', CustomSubsCapsButton);
2106
+
2107
+ exports.ExternalControls = ExternalControls;
2108
+ exports.Player = Player;
2109
+ exports.SeekBar = SeekBar;
2110
+ exports.TimeCodeDisplay = TimeCodeDisplay;
2111
+ exports.VideoTime = VideoTime;
2112
+
2113
+ Object.defineProperty(exports, '__esModule', { value: true });
2114
+
2115
+ }));