@vidispine/vdt-videojs 22.4.0 → 23.1.0-pre.2

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