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