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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +4 -4
  2. package/deprecated-app/README.md +21 -0
  3. package/{demo.html → deprecated-app/index.html} +1 -1
  4. package/{demo.js → deprecated-app/index.js} +69 -41
  5. package/{samples → deprecated-app/samples}/birds-es.vvt +0 -0
  6. package/{samples → deprecated-app/samples}/birds.vvt +0 -0
  7. package/{tests.js → deprecated-app/tests.js} +87 -54
  8. package/{lib/style.css → dist/index.css} +755 -55
  9. package/dist/index.es.js +2099 -0
  10. package/dist/index.js +2112 -0
  11. package/dist/index.umd.js +2115 -0
  12. package/package.json +29 -85
  13. package/rollup.config.js +54 -0
  14. package/src/constants.js +1 -1
  15. package/src/externalControls.js +14 -18
  16. package/src/helpOverlay.js +12 -16
  17. package/src/helpers.js +3 -3
  18. package/src/index.js +3 -9
  19. package/src/index.stories.mdx +59 -0
  20. package/src/menu.api.stories.mdx +59 -0
  21. package/src/menu.js +23 -19
  22. package/src/{menu.example.md → menu.usage.stories.mdx} +31 -21
  23. package/src/osd.js +24 -18
  24. package/src/player.api.stories.mdx +120 -0
  25. package/src/player.js +157 -108
  26. package/src/player.scss +2 -0
  27. package/src/{player.example.md → player.usage.stories.mdx} +18 -8
  28. package/src/seekBar.js +85 -48
  29. package/src/timeCodeDisplay.js +39 -31
  30. package/src/videoTime.js +4 -4
  31. package/build.js +0 -233
  32. package/lib/index.cjs.js +0 -3240
  33. package/lib/index.esm.js +0 -3227
  34. package/lib/index.umd.js +0 -3243
  35. package/lib/package.json +0 -13
  36. package/lib/src/constants.js +0 -51
  37. package/lib/src/externalControls.js +0 -307
  38. package/lib/src/helpOverlay.js +0 -106
  39. package/lib/src/helpers.js +0 -34
  40. package/lib/src/index.js +0 -13
  41. package/lib/src/menu.js +0 -365
  42. package/lib/src/osd.js +0 -91
  43. package/lib/src/player.js +0 -943
  44. package/lib/src/seekBar.js +0 -833
  45. package/lib/src/timeCodeDisplay.js +0 -253
  46. package/lib/src/videoTime.js +0 -66
  47. package/log.js +0 -24
  48. package/src/_index.stories.js +0 -24
  49. package/src/externalControls.stories.js +0 -6
  50. package/src/helpOverlay.stories.js +0 -6
  51. package/src/menu.classMethods.md +0 -47
  52. package/src/player.classMethods.md +0 -108
  53. package/src/player.stories.js +0 -14
  54. package/src/seekBar.stories.js +0 -8
  55. package/tmp/player.css +0 -1
package/lib/src/player.js DELETED
@@ -1,943 +0,0 @@
1
-
2
- import videojs from 'video.js/dist/alt/video.core.min';
3
- import mousetrap from 'mousetrap';
4
-
5
- import constants from './constants';
6
- import { reactiveSetters } from './helpers';
7
-
8
- import OSD from './osd';
9
- import TimeCodeDisplay from './timeCodeDisplay';
10
- import HelpOverlay from './helpOverlay';
11
- import Menu from './menu';
12
- import SeekBar from './seekBar';
13
-
14
- import VideoTime from './videoTime';
15
-
16
- const correctMimeTypes = {
17
- 'audio/x-aac': 'audio/aac',
18
- };
19
- const sanitizeMimeType = (mimeType) => correctMimeTypes[mimeType] || mimeType;
20
-
21
- export default class Player {
22
- constructor(props) {
23
- this.props = props;
24
- reactiveSetters.apply(this);
25
-
26
- const classNames = [
27
- 'video-js',
28
- 'vjs-big-play-centered',
29
- (this.props.posterUrl) ? constants.classNames.poster : '',
30
- (this.props.subtitles && this.props.subtitles.length > 0) ? constants.classNames.subtitles : '',
31
- 'init',
32
- ];
33
-
34
- this.externalTimecodes = {
35
-
36
- duration: [],
37
- playback: [],
38
- };
39
-
40
- this.timeConverter = new VideoTime({
41
- frameRate: this.props.frameRate || constants.defaults.frameRate,
42
- });
43
-
44
-
45
- this.videoEl = document.createElement('video');
46
- this.videoEl.crossOrigin = this.props.crossOrigin;
47
- this.videoEl.id = 'vdt-video';
48
- this.videoEl.className = classNames.join(' ');
49
- this.videoEl.controls = true;
50
-
51
-
52
- if (this.props.sources) {
53
-
54
- if (this.props.sources.length > 1) {
55
- this.props.sources.sort((a) => ((a.type.indexOf('mp4') > 0) ? 1 : -1));
56
- }
57
-
58
-
59
- this.props.sources.forEach((source) => {
60
- const aSource = document.createElement('source');
61
- aSource.src = source.src;
62
- aSource.type = sanitizeMimeType(source.type);
63
- this.videoEl.appendChild(aSource);
64
- });
65
- }
66
-
67
- this.videoEl.onloadedmetadata = () => {
68
- if (this.durationTimeCode) {
69
- this.setDurationTimeCode();
70
- }
71
-
72
- this.videojs.el_.classList.remove('init');
73
- };
74
-
75
-
76
- setTimeout(() => {
77
- if (this.videojs.el_) {
78
- this.videojs.el_.classList.remove('init');
79
- }
80
- }, 2000);
81
-
82
-
83
- if (this.props.subtitles) {
84
- this.props.subtitles.forEach((sub) => {
85
- const subtitleTag = document.createElement('track');
86
- subtitleTag.kind = 'subtitles';
87
- subtitleTag.srclang = sub.lang;
88
- subtitleTag.label = sub.label;
89
-
90
-
91
- if (typeof sub.src === 'string') {
92
- subtitleTag.src = sub.src;
93
- } else {
94
- subtitleTag.src = window.URL.createObjectURL(sub.src);
95
- }
96
-
97
- this.videoEl.appendChild(subtitleTag);
98
- });
99
- }
100
-
101
-
102
- if (this.props.target) {
103
- this.props.target && this.props.target.appendChild(this.videoEl);
104
- }
105
-
106
- const showDefaultTimeDisplay = (this.props.timecode !== true);
107
- const controlsEnabled = (this.props.controls !== false);
108
- const options = this.props.options || {};
109
-
110
- this.videojs = new videojs('vdt-video', {
111
- responsive: true,
112
- fluid: true,
113
- controls: controlsEnabled,
114
- alwaysCaptureHotkeys: false,
115
- controlBar: {
116
- RemainingTimeDisplay: false,
117
- timeDivider: showDefaultTimeDisplay,
118
- durationDisplay: showDefaultTimeDisplay,
119
- currentTimeDisplay: showDefaultTimeDisplay,
120
- },
121
- inactivityTimeout: (this.audioOnly) ? constants.defaults.audioInactivityTimeout : constants.defaults.inactivityTimeout,
122
- preload: 'auto',
123
- captionsButton: false,
124
- subsCapsButton: false,
125
- subtitlesButton: false,
126
- textTrackSettings: false,
127
- html5: {
128
- nativeTextTracks: false,
129
- },
130
- languages: {
131
- en: {
132
- 'captions off': 'off',
133
- 'subtitles off': 'off',
134
- },
135
- },
136
- ...options,
137
- });
138
-
139
-
140
- this.props.posterUrl && this.videojs.poster(this.props.posterUrl);
141
-
142
-
143
- this.handleNewProps(this.props);
144
-
145
-
146
- this.videojs.ready(() => {
147
- this.bindHotkeys();
148
- this.bindEvents();
149
- this.props.onReady && this.props.onReady(this.videojs);
150
-
151
- this.restoreSettings();
152
- this.setupTimeCode();
153
- this.doEsothericWork();
154
- this.setupMenu();
155
- this.setupCustomSeekbar();
156
- });
157
- }
158
-
159
- setupCustomSeekbar() {
160
- if (this.props.seekBar) {
161
-
162
- this.videojs.controlBar.progressControl.disable();
163
- this.videojs.controlBar.progressControl.hide();
164
-
165
- const target = this.container.getElementsByClassName('vjs-control-bar')[0];
166
- const props = {
167
- target,
168
- player: this,
169
- onDark: this.props.onDark,
170
- ...this.props.seekBar,
171
- };
172
-
173
- this.seekBar = new SeekBar(props);
174
-
175
-
176
- this.videojs.on('userinactive', () => {
177
- if (!this.controlsBelowPlayer) {
178
- this.seekBar && this.seekBar.hideMarkers();
179
- } else {
180
- this.seekBar && this.seekBar.showMarkers();
181
- }
182
- });
183
-
184
- this.videojs.on('useractive', () => {
185
- this.seekBar && this.seekBar.showMarkers();
186
- });
187
- }
188
- }
189
-
190
- setupTimeCode(externalTimecodeInstance = null) {
191
- const props = {
192
- onInput: (e, nodeName, values) => {
193
-
194
- this.seekTo(this.timeConverter.smpteToCurrentTimeFromStart(values));
195
- },
196
- onInputFocus: () => {
197
- this.videojs.options_.inactivityTimeout = 0;
198
- this.videojs.cache_.inactivityTimeout = 0;
199
- this.videojs.reportUserActivity();
200
-
201
-
202
- this.videojs.pause();
203
- },
204
- onInputBlur: () => {
205
- this.videojs.options().inactivityTimeout = constants.defaults.inactivityTimeout;
206
- this.videojs.cache_.inactivityTimeout = constants.defaults.inactivityTimeout;
207
- },
208
- };
209
-
210
- if (externalTimecodeInstance !== null) {
211
- externalTimecodeInstance.props = Object.assign(externalTimecodeInstance.props, props);
212
- this.externalTimecodes.playback.push(externalTimecodeInstance);
213
- } else if (this.props.timecode === true) {
214
-
215
- if (this.props.controls !== false) {
216
- const target = document.getElementsByClassName('vjs-volume-panel')[0];
217
-
218
- this.timeCode = new TimeCodeDisplay(Object.assign(props, { target, appendAfter: true }));
219
-
220
-
221
- this.durationTimeCode = new TimeCodeDisplay({
222
- target: this.timeCode.container,
223
- appendAfter: true,
224
- });
225
- }
226
- }
227
-
228
- if (this.timeCode || this.externalTimecodes.playback.length > 0) {
229
-
230
- this.videojs.on('timeupdate', () => {
231
- this.updateTimeCode();
232
- });
233
-
234
- this.videojs.on('play', () => {
235
- this.updateTimeCodeFrame();
236
- });
237
- }
238
- }
239
-
240
- updateTimeCode() {
241
- const currentSecond = this.videojs.currentTime();
242
- const props = this.timeConverter.secondsFromStartToSMPTE(currentSecond);
243
-
244
- this.timeCode && this.timeCode.update(props);
245
-
246
- if (this.externalTimecodes.playback.length > 0) {
247
- this.externalTimecodes.playback.forEach((timecode) => {
248
- timecode.update(props);
249
- });
250
- }
251
- }
252
-
253
- updateTimeCodeFrame() {
254
- const frame = this.timeConverter.currentFrame(this.videojs.currentTime());
255
-
256
- this.timeCode && this.timeCode.update({ frame });
257
-
258
- if (this.externalTimecodes.playback.length > 0) {
259
- this.externalTimecodes.playback.forEach((timecode) => {
260
- timecode.update({ frame });
261
- });
262
- }
263
-
264
-
265
- if (!this.videojs.paused()) {
266
- this.rafID = requestAnimationFrame(() => { this.updateTimeCodeFrame(); });
267
- }
268
- }
269
-
270
- setDurationTimeCode() {
271
- const durationInSeconds = this.videojs.duration();
272
- const props = this.timeConverter.secondsFromStartToSMPTE(durationInSeconds);
273
- props.frame = this.timeConverter.secondsToFrame(durationInSeconds);
274
-
275
- this.durationTimeCode.update(props);
276
- this.durationTimeCode.container.classList.add('duration');
277
- }
278
-
279
- bindHotkeys() {
280
- this.bindings = [
281
- {
282
- key: ['space', 'k'],
283
- method: (e) => {
284
-
285
- (e.preventDefault) && e.preventDefault();
286
- this.togglePlayback();
287
- },
288
- },
289
- {
290
- key: 'j',
291
- method: () => {
292
- this.videojs.hasStarted_ && this.jumpBackward();
293
- },
294
- },
295
- {
296
- key: 'l',
297
- method: () => {
298
- this.videojs.hasStarted_ && this.jumpForward();
299
- },
300
- },
301
- {
302
- key: ['.', 'right'],
303
- method: () => {
304
- this.frameForward();
305
- },
306
- },
307
- {
308
- key: [',', 'left'],
309
- method: () => {
310
- this.frameBackward();
311
- },
312
- },
313
- {
314
- key: 'f',
315
- method: () => {
316
- this.toggleFullscreen();
317
- },
318
- },
319
- {
320
- key: 'm',
321
- method: () => {
322
- this.toggleMute();
323
- },
324
- },
325
- {
326
- key: 'up',
327
- method: (e) => {
328
- e.preventDefault && e.preventDefault();
329
- this.volumeUp();
330
- },
331
- },
332
- {
333
- key: 'down',
334
- method: (e) => {
335
- e.preventDefault && e.preventDefault();
336
- this.volumeDown();
337
- },
338
- },
339
- {
340
- key: 'h',
341
- method: () => {
342
- this.help.toggle();
343
- },
344
- },
345
- {
346
- key: 'n',
347
- method: () => {
348
- this.menu && this.menu.toggle();
349
- },
350
- },
351
- ];
352
-
353
- if (this.props.subtitles) {
354
- this.bindings.push({
355
- key: 'c',
356
- method: () => {
357
- this.toggleSubs();
358
- },
359
- });
360
- }
361
-
362
-
363
- this.bindings.forEach((binding) => {
364
- mousetrap.bind(binding.key, (e) => {
365
- binding.method(e);
366
- this.onHotkeyPressed(binding.key);
367
- });
368
- });
369
- }
370
-
371
- unbindHotKeys() {
372
- this.bindings && this.bindings.forEach((binding) => {
373
- mousetrap.unbind(binding.key);
374
- });
375
- }
376
-
377
- bindEvents() {
378
- this.videojs.on('volumechange', () => {
379
- this.persistSetting(constants.settings.volume, this.volume);
380
- });
381
-
382
- this.videojs.textTracks().on('change', () => {
383
- const tracks = this.videojs.textTracks().tracks_;
384
- const selected = tracks.filter((track) => (track.mode === 'showing'));
385
- const areAnyTxtTracksActive = selected.length > 0;
386
-
387
- if (areAnyTxtTracksActive) {
388
- this.videojs.el_.classList.add(constants.classNames.subtitlesActive);
389
- this.persistSetting(constants.settings.subs, true);
390
- this.persistSetting(constants.settings.subLang, selected[0].language);
391
- } else {
392
- this.videojs.el_.classList.remove(constants.classNames.subtitlesActive);
393
- this.persistSetting(constants.settings.subs, false);
394
- }
395
- });
396
- }
397
-
398
- volumeUp() {
399
- this.videojs.controlBar.volumePanel.volumeControl.volumeBar.stepForward();
400
- this.osd.feedback(constants.osd.volchange, { volume: this.volume });
401
- }
402
-
403
- volumeDown() {
404
- this.videojs.controlBar.volumePanel.volumeControl.volumeBar.stepBack();
405
- this.osd.feedback(constants.osd.volchange, { volume: this.volume });
406
- }
407
-
408
- toggleMute() {
409
- if (!this.videojs.muted()) {
410
- this.videojs.muted(true);
411
- this.osd.feedback(constants.osd.volchange, { volume: this.volume });
412
- } else {
413
- this.videojs.muted(false);
414
- this.osd.feedback(constants.osd.volchange, { volume: this.volume });
415
- }
416
- }
417
-
418
- toggleFullscreen() {
419
- if (this.videojs.isFullscreen()) {
420
- this.videojs.exitFullscreen();
421
- } else {
422
- this.videojs.requestFullscreen();
423
- }
424
- }
425
-
426
- seek(secs) {
427
- let time = this.videojs.currentTime() + secs;
428
-
429
- if (time < 0) {
430
- time = 0;
431
- }
432
-
433
- this.videojs.currentTime(time);
434
- }
435
-
436
- seekTo(sec) {
437
- !this.videojs.hasStarted() && this.videojs.hasStarted(true);
438
- this.videojs.currentTime(sec);
439
- }
440
-
441
- jumpForward() {
442
- this.seek(constants.defaults.jumpSeconds);
443
- this.osd.feedback(constants.osd.jumpForward);
444
- }
445
-
446
- jumpBackward() {
447
- this.seek(-constants.defaults.jumpSeconds);
448
- this.osd.feedback(constants.osd.jumpBackward);
449
- }
450
-
451
- frameForward() {
452
- const thisFrame = this.timeConverter.secondsToFramesFromStart(this.videojs.currentTime());
453
- const nextFrame = Math.round(thisFrame) + 1;
454
-
455
- this.videojs.currentTime(this.timeConverter.frameToCurrentTimeFromStart(nextFrame));
456
- }
457
-
458
- frameBackward() {
459
- const thisFrame = this.timeConverter.secondsToFramesFromStart(this.videojs.currentTime());
460
- const previousFrame = Math.round(thisFrame) - 1;
461
-
462
- this.videojs.currentTime(this.timeConverter.frameToCurrentTimeFromStart(previousFrame));
463
- }
464
-
465
- secondsToFramesFromStart(seconds) {
466
- const frameRate = this.props.frameRate || constants.defaults.frameRate;
467
- let frame = seconds * frameRate;
468
- frame = Math.round(frame);
469
- return frame;
470
- }
471
-
472
- doEsothericWork() {
473
- if (this.props.color) {
474
- document.getElementsByClassName('vjs-play-progress')[0].style.backgroundColor = this.props.color;
475
- }
476
-
477
-
478
- this.osd = new OSD({
479
- target: this.videoEl.parentElement,
480
- });
481
-
482
-
483
- if (this.props.onCinema) {
484
- this.videoEl.parentElement.classList.add('has-cinema-button');
485
- this.cinema = false;
486
-
487
- this.addButtonToControlBar({
488
- onClick: () => {
489
- this.props.onCinema(!this.cinema);
490
- this.cinema = !this.cinema;
491
- },
492
- componentName: 'CinemaButton',
493
- className: 'vdt-cinema-button',
494
- title: 'Cinema-mode',
495
- });
496
- }
497
-
498
-
499
- if (this.props.onScreenshot) {
500
- this.videoEl.parentElement.classList.add('has-screenshot-button');
501
-
502
- this.addButtonToControlBar({
503
- onClick: () => {
504
- this.props.onScreenshot(this.videojs.currentTime());
505
- },
506
- componentName: 'ScreenshotButton',
507
- className: 'vdt-screenshot-button',
508
- title: 'Screenshot',
509
- });
510
- }
511
-
512
-
513
- this.help = new HelpOverlay({
514
- target: this.videoEl.parentElement,
515
- onToggle: (willShow) => {
516
- if (this.menu && this.menu.opened) {
517
- this.menu.close();
518
- }
519
- if (willShow && !this.controlsBelowPlayer) {
520
- this.hideControls();
521
- } else {
522
- this.showControls();
523
- }
524
- },
525
- });
526
- }
527
-
528
- restoreSettings() {
529
-
530
- const volume = localStorage.getItem(constants.settings.volume);
531
- const subsEnabled = localStorage.getItem(constants.settings.subs);
532
- const subLang = localStorage.getItem(constants.settings.subLang);
533
-
534
-
535
- this.settings = {
536
-
537
- [constants.settings.volume]: (volume !== null) ? Math.round(volume * 100) / 100 : 1,
538
- [constants.settings.subLang]: (subLang !== null) ? subLang : 'en',
539
- [constants.settings.subs]: (subsEnabled !== null) ? JSON.parse(subsEnabled) : false,
540
- };
541
-
542
-
543
- this.volume = this.settings[constants.settings.volume];
544
-
545
- if (this.settings[constants.settings.subs]) {
546
- this.enableSubs();
547
- }
548
- }
549
-
550
- persistSetting(key, val) {
551
- this.settings[key] = val;
552
- localStorage.setItem(key, val);
553
- }
554
-
555
- enableSubs() {
556
- const subs = this.videojs.textTracks();
557
-
558
- for (let i = 0; i < subs.length; i++) {
559
- const sub = subs[i];
560
- if (sub.language === this.settings[constants.settings.subLang]) {
561
- sub.mode = 'showing';
562
- } else {
563
- sub.mode = 'hidden';
564
- }
565
- }
566
- }
567
-
568
- disableSubs() {
569
- const subs = this.videojs.textTracks();
570
-
571
- for (let i = 0; i < subs.length; i++) {
572
- const sub = subs[i];
573
- sub.mode = 'hidden';
574
- }
575
- }
576
-
577
- toggleSubs() {
578
- if (this.videojs.textTracks().length > 0) {
579
- if (this.videojs.textTracks().tracks_.filter((track) => (track.mode === 'showing')).length > 0) {
580
- this.disableSubs();
581
- } else {
582
- this.enableSubs();
583
- }
584
- }
585
- }
586
-
587
- addButtonToControlBar(options) {
588
- const Button = videojs.getComponent('Button');
589
- const CustomButton = videojs.extend(Button, {
590
- constructor: function () {
591
- Button.apply(this, arguments);
592
- options.className && this.el_.classList.add(options.className);
593
- if (options.title) { this.el_.title = options.title; }
594
- },
595
- handleClick: () => {
596
- options.onClick && options.onClick();
597
- },
598
- });
599
-
600
- videojs.registerComponent(options.componentName, CustomButton);
601
- this.videojs.getChild('controlBar').addChild(options.componentName, {}, 7);
602
- }
603
-
604
-
605
- get volume() {
606
- return this.videojs.controlBar.volumePanel.volumeControl.volumeBar.getPercent();
607
- }
608
-
609
- set volume(floatVal) {
610
- if (floatVal === 0) {
611
- this.videojs.muted(true);
612
- } else {
613
- this.videojs.muted(false);
614
- this.videojs.volume(floatVal);
615
- }
616
- }
617
-
618
- setupMenu() {
619
- const menuItems = this.props.menuItems || [];
620
- const sourcesMenuItems = [];
621
- if (this.props.sources.length > 1) {
622
- this.props.sources.forEach((source) => {
623
- if (source.label) {
624
- sourcesMenuItems.push({
625
- title: source.label,
626
- onClick: () => {
627
- this.src = source;
628
- },
629
- });
630
- }
631
- });
632
-
633
- menuItems.push({
634
- title: 'Sources',
635
- getActiveIndex: () => {
636
- const matchingSource = this.props.sources.find((source) => (source.src === this.videojs.src()));
637
- return sourcesMenuItems.indexOf(sourcesMenuItems.find((menuItem) => (menuItem.title === matchingSource.label)));
638
- },
639
- items: sourcesMenuItems,
640
- });
641
- }
642
-
643
-
644
- if (this.props.subtitles && this.props.subtitles.length > 0) {
645
-
646
- const subtitleMenuItems = [{
647
- title: 'Off',
648
- onClick: () => {
649
- this.disableSubs();
650
- },
651
- }];
652
-
653
-
654
-
655
-
656
-
657
-
658
-
659
-
660
-
661
-
662
-
663
- this.props.subtitles.forEach((subtitle, index) => {
664
- subtitleMenuItems.push({
665
- title: subtitle.label,
666
- onClick: () => {
667
- const subs = this.videojs.textTracks();
668
- for (let i = 0; i < subs.length; i++) {
669
- const sub = subs[i];
670
- if (i === index) {
671
- sub.mode = 'showing';
672
- } else {
673
- sub.mode = 'hidden';
674
- }
675
- }
676
- },
677
- });
678
- });
679
-
680
- menuItems.push(
681
- {
682
- title: 'Subtitles',
683
- getActiveIndex: () => {
684
- const subs = this.videojs.textTracks();
685
- for (let i = 0; i < subs.length; i++) {
686
- const sub = subs[i];
687
- if (sub.mode === 'showing') {
688
- return i + 1;
689
- }
690
- }
691
-
692
- return 0;
693
- },
694
- items: subtitleMenuItems,
695
- },
696
- );
697
- }
698
-
699
- if (menuItems.length > 0) {
700
- const target = this.videojs.el_;
701
-
702
- this.menu = new Menu({
703
- target,
704
- items: menuItems,
705
- onOpen: () => {
706
- !this.controlsBelowPlayer && this.hideControls();
707
- },
708
- onClose: () => {
709
- !this.controlsBelowPlayer && this.videojs.controls(true);
710
- },
711
- });
712
-
713
-
714
- this.videoEl.parentElement.classList.add('has-vdt-menu');
715
-
716
- this.addButtonToControlBar({
717
- onClick: () => {
718
- this.menu.toggle();
719
- },
720
- componentName: 'SettingsMenuButton',
721
- className: 'vdt-settings-menu-button',
722
- title: 'Settings',
723
- });
724
- } else {
725
-
726
-
727
- }
728
- }
729
-
730
- hideControls() {
731
- this.videojs.userActive(false);
732
- this.videojs.controls(false);
733
- this.videojs.fluid(true);
734
-
735
- this.videoEl.parentElement.classList.remove('vjs-user-active');
736
- this.videojs.userActive(false);
737
- }
738
-
739
- showControls() {
740
- this.videojs.fluid(!this.controlsBelowPlayer);
741
- this.videojs.controls(true);
742
- this.videojs.userActive(true);
743
- }
744
-
745
- toggleControls() {
746
- if (this.videojs.controls()) {
747
- this.hideControls();
748
- } else {
749
- this.showControls();
750
- }
751
- }
752
-
753
- onHotkeyPressed(key) {
754
- if (key !== 'h' && this.help.state.active) {
755
- this.help.hide();
756
- }
757
- }
758
-
759
-
760
- triggerHotkey(key) {
761
- mousetrap.trigger(key);
762
- }
763
-
764
- toStart() {
765
- this.videojs.currentTime(0);
766
- }
767
-
768
- toEnd() {
769
- this.videojs.currentTime(this.videojs.duration());
770
- }
771
-
772
- replay() {
773
- this.toStart();
774
- this.videojs.play();
775
- }
776
-
777
- play() {
778
- this.videojs.play();
779
- }
780
-
781
- pause() {
782
- !this.videojs.paused() && this.videojs.pause();
783
- }
784
-
785
- togglePlayback() {
786
- if (this.videojs.paused()) {
787
- this.play();
788
- this.videojs.hasStarted_ && this.osd.feedback(constants.osd.play);
789
- } else {
790
- this.pause();
791
- this.osd.feedback(constants.osd.pause);
792
- }
793
- }
794
-
795
- destroy() {
796
- this.videojs.paused(true);
797
- this.rafID && cancelAnimationFrame(this.rafID);
798
- this.videojs.dispose();
799
- this.unbindHotKeys();
800
- this.seekBar && this.seekBar.destroy();
801
- }
802
-
803
- get container() {
804
- return this.videoEl.parentElement;
805
- }
806
-
807
- set onDark(bool) {
808
- if (bool) {
809
- this.container.classList.add('on-dark');
810
- } else {
811
- this.container.classList.remove('on-dark');
812
- }
813
-
814
- if (this.seekBar) {
815
- this.seekBar.onDark = bool;
816
- }
817
- }
818
-
819
- get onDark() {
820
- return this.container.classList.contains('on-dark');
821
- }
822
-
823
- set controlsBelowPlayer(bool) {
824
- if (this.videojs.controls()) {
825
- if (bool) {
826
- this.container.classList.add('controls-below-player');
827
- this.videojs.fluid(false);
828
- } else {
829
- this.container.classList.remove('controls-below-player');
830
- this.videojs.fluid(true);
831
- }
832
- }
833
- }
834
-
835
- get controlsBelowPlayer() {
836
- return this.container.classList.contains('controls-below-player');
837
- }
838
-
839
- get smpte() {
840
- const currentSecond = this.videojs.currentTime();
841
- return this.timeConverter.secondsFromStartToSMPTE(currentSecond);
842
- }
843
-
844
- set smpte(smpte) {
845
- const currentSecond = this.videojs.currentTime();
846
- return this.timeConverter.secondsFromStartToSMPTE(currentSecond);
847
- }
848
-
849
- set src({ src, type = 'video/mp4', label = null }) {
850
- const currentTime = this.videojs.currentTime();
851
-
852
- const source = this.props.sources.find((aSource) => (aSource.src === src));
853
-
854
-
855
- const onReady = () => {
856
- let initdone = false;
857
-
858
- this.videojs.on('loadedmetadata', () => {
859
- this.videojs.currentTime(currentTime);
860
- });
861
-
862
-
863
-
864
- this.videojs.on('canplaythrough', () => {
865
- if (!initdone) {
866
- this.videojs.currentTime(currentTime);
867
- initdone = true;
868
- this.videojs.play();
869
- }
870
- });
871
- };
872
-
873
- if (source && typeof souce === 'Array' && source.length > 0) {
874
-
875
- this.videojs.addClass('vjs-waiting');
876
- this.videojs.src({
877
- ...source[0],
878
- });
879
- onReady();
880
- } else {
881
- this.videojs.addClass('vjs-waiting');
882
- this.videojs.src(this.addSrc(src, type, label));
883
- onReady();
884
- }
885
- }
886
-
887
- get src() {
888
- return this.videojs.src();
889
- }
890
-
891
- addSrc(src, type, label) {
892
- const newSource = {
893
- src,
894
- type,
895
- label,
896
- };
897
- const index = this.props.sources.push(newSource) - 1;
898
-
899
- return this.props.sources[index];
900
- }
901
-
902
- removeSrc(url) {
903
-
904
- }
905
-
906
- set controls(bool) {
907
- if (bool) {
908
- this.showControls();
909
- } else {
910
- this.hideControls();
911
- }
912
- }
913
-
914
- get percentLoaded() {
915
- const r = this.videojs.buffered();
916
-
917
- const percentLoaded = (r.end(0) / this.videojs.duration()) * 100;
918
- return percentLoaded;
919
- }
920
- }
921
-
922
-
923
-
924
- const button = videojs.prototype.constructor.getComponent('Button');
925
-
926
- button.prototype.handleKeyDown = function (e) {
927
- if (e.keyCode === 32) {
928
- e.preventDefault();
929
- }
930
- };
931
- videojs.prototype.constructor.registerComponent('Button', button);
932
-
933
-
934
- const subsButton = videojs.prototype.constructor.getComponent('SubsCapsButton');
935
- class CustomSubsCapsButton extends subsButton {
936
- constructor(player, options = {}) {
937
- super(player, options);
938
- this.menuButton_.off('mouseenter');
939
- this.menuButton_.off('mouseleave');
940
- }
941
- }
942
-
943
- videojs.prototype.constructor.registerComponent('SubsCapsButton', CustomSubsCapsButton);