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