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