@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/src/player.js CHANGED
@@ -1,12 +1,5 @@
1
- /* eslint-disable no-param-reassign */
2
- /* eslint-disable no-case-declarations */
3
1
  /* eslint-disable no-underscore-dangle */
4
- /* eslint-disable no-unused-expressions */
5
- /* eslint-disable max-classes-per-file */
6
- /* eslint-disable no-plusplus */
7
- /* eslint-disable prefer-rest-params */
8
2
  /* eslint-disable import/no-named-as-default-member */
9
-
10
3
  /*
11
4
  Eslint rules disabled for lines like these:
12
5
 
@@ -14,20 +7,21 @@ this.props.target && this.props.target.appendChild(this.videoEl); //validity che
14
7
  document.getElementsByClassName('vjs-volume-panel')[0] //rule asks for destructuring
15
8
  this.videojs.hasStarted_ //dangling underscore produced by video.js in this case
16
9
  */
17
- import videojs from 'video.js/dist/alt/video.core.min';
10
+ // eslint-disable-next-line max-classes-per-file
18
11
  import mousetrap from 'mousetrap';
12
+ import videojs from 'video.js/dist/alt/video.core.min';
19
13
 
20
14
  import constants from './constants';
21
15
  import { reactiveSetters } from './helpers';
22
-
23
- import OSD from './osd';
24
- import TimeCodeDisplay from './timeCodeDisplay';
25
16
  import HelpOverlay from './helpOverlay';
26
17
  import Menu from './menu';
18
+ import OSD from './osd';
27
19
  import SeekBar from './seekBar';
28
-
20
+ import TimeCodeDisplay from './timeCodeDisplay';
29
21
  import VideoTime from './videoTime';
30
22
 
23
+ import './player.scss';
24
+
31
25
  const correctMimeTypes = {
32
26
  'audio/x-aac': 'audio/aac',
33
27
  };
@@ -38,11 +32,12 @@ export default class Player {
38
32
  this.props = props; // save props
39
33
  reactiveSetters.apply(this); // ability to handle new props via setters
40
34
 
41
- const classNames = [ // add conditional css classes here for the whole container
35
+ const classNames = [
36
+ // add conditional css classes here for the whole container
42
37
  'video-js',
43
38
  'vjs-big-play-centered',
44
- (this.props.posterUrl) ? constants.classNames.poster : '',
45
- (this.props.subtitles && this.props.subtitles.length > 0) ? constants.classNames.subtitles : '',
39
+ this.props.posterUrl ? constants.classNames.poster : '',
40
+ this.props.subtitles && this.props.subtitles.length > 0 ? constants.classNames.subtitles : '',
46
41
  'init', // make player height 0 while no metadata for video size available with css
47
42
  ];
48
43
 
@@ -70,7 +65,7 @@ export default class Player {
70
65
  if (this.props.sources) {
71
66
  // sort mp4 at the top
72
67
  if (this.props.sources.length > 1) {
73
- this.props.sources.sort((a) => ((a.type.indexOf('mp4') > 0) ? 1 : -1));
68
+ this.props.sources.sort((a) => (a.type.indexOf('mp4') > 0 ? 1 : -1));
74
69
  }
75
70
 
76
71
  // construct <source> els
@@ -80,21 +75,20 @@ export default class Player {
80
75
  aSource.type = sanitizeMimeType(source.type);
81
76
  this.videoEl.appendChild(aSource);
82
77
  });
83
- }// handle else with err later
78
+ } // handle else with err later
84
79
 
85
- this.videoEl.onloadedmetadata = () => { // read-only duration timecode
80
+ this.videoEl.onloadedmetadata = () => {
81
+ // read-only duration timecode
86
82
  if (this.durationTimeCode) {
87
83
  this.setDurationTimeCode();
88
84
  }
89
85
 
90
- this.videojs.el_.classList.remove('init');
86
+ if (this.videojs.el_) this.videojs.el_.classList.remove('init');
91
87
  };
92
88
 
93
89
  // if video has not loaded by now, show the player w/ errors
94
90
  setTimeout(() => {
95
- if (this.videojs.el_) {
96
- this.videojs.el_.classList.remove('init');
97
- }
91
+ if (this.videojs.el_) this.videojs.el_.classList.remove('init');
98
92
  }, 2000);
99
93
 
100
94
  // attach subtitle tracks (these should come in last in the <video /> node)
@@ -117,14 +111,13 @@ export default class Player {
117
111
  }
118
112
 
119
113
  // attach to dom and construct videojs player
120
- if (this.props.target) {
121
- this.props.target && this.props.target.appendChild(this.videoEl);
122
- }
114
+ if (this.props.target) this.props.target.appendChild(this.videoEl);
123
115
 
124
- const showDefaultTimeDisplay = (this.props.timecode !== true);
125
- const controlsEnabled = (this.props.controls !== false);
116
+ const showDefaultTimeDisplay = this.props.timecode !== true;
117
+ const controlsEnabled = this.props.controls !== false;
126
118
  const options = this.props.options || {};
127
119
 
120
+ // eslint-disable-next-line new-cap
128
121
  this.videojs = new videojs('vdt-video', {
129
122
  responsive: true,
130
123
  fluid: true,
@@ -136,7 +129,9 @@ export default class Player {
136
129
  durationDisplay: showDefaultTimeDisplay,
137
130
  currentTimeDisplay: showDefaultTimeDisplay,
138
131
  },
139
- inactivityTimeout: (this.audioOnly) ? constants.defaults.audioInactivityTimeout : constants.defaults.inactivityTimeout,
132
+ inactivityTimeout: this.audioOnly
133
+ ? constants.defaults.audioInactivityTimeout
134
+ : constants.defaults.inactivityTimeout,
140
135
  preload: 'auto',
141
136
  captionsButton: false,
142
137
  subsCapsButton: false,
@@ -155,7 +150,7 @@ export default class Player {
155
150
  });
156
151
 
157
152
  // set the poster
158
- this.props.posterUrl && this.videojs.poster(this.props.posterUrl);
153
+ if (this.props.posterUrl) this.videojs.poster(this.props.posterUrl);
159
154
 
160
155
  // set other props that are passed
161
156
  this.handleNewProps(this.props);
@@ -164,7 +159,7 @@ export default class Player {
164
159
  this.videojs.ready(() => {
165
160
  this.bindHotkeys();
166
161
  this.bindEvents();
167
- this.props.onReady && this.props.onReady(this.videojs);
162
+ if (this.props.onReady) this.props.onReady(this.videojs);
168
163
 
169
164
  this.restoreSettings();
170
165
  this.setupTimeCode();
@@ -193,14 +188,14 @@ export default class Player {
193
188
  // show & hide markers when controls hide
194
189
  this.videojs.on('userinactive', () => {
195
190
  if (!this.controlsBelowPlayer) {
196
- this.seekBar && this.seekBar.hideMarkers();
191
+ if (this.seekBar) this.seekBar.hideMarkers?.();
197
192
  } else {
198
- this.seekBar && this.seekBar.showMarkers();
193
+ this.seekBar?.showMarkers?.();
199
194
  }
200
195
  });
201
196
 
202
197
  this.videojs.on('useractive', () => {
203
- this.seekBar && this.seekBar.showMarkers();
198
+ if (this.seekBar) this.seekBar.showMarkers();
204
199
  });
205
200
  }
206
201
  }
@@ -230,10 +225,13 @@ export default class Player {
230
225
  },
231
226
  };
232
227
 
233
- if (externalTimecodeInstance !== null) { // setting up an external playback timecode
228
+ if (externalTimecodeInstance !== null) {
229
+ // setting up an external playback timecode
230
+ // eslint-disable-next-line no-param-reassign
234
231
  externalTimecodeInstance.props = Object.assign(externalTimecodeInstance.props, props);
235
232
  this.externalTimecodes.playback.push(externalTimecodeInstance);
236
- } else if (this.props.timecode === true) { // player uses timecode
233
+ } else if (this.props.timecode === true) {
234
+ // player uses timecode
237
235
  // construct an in-frame timecode, if controls are enabled
238
236
  if (this.props.controls !== false) {
239
237
  const target = document.getElementsByClassName('vjs-volume-panel')[0];
@@ -260,11 +258,12 @@ export default class Player {
260
258
  }
261
259
  }
262
260
 
263
- updateTimeCode() { // HH:MM:SS (the usual)
261
+ updateTimeCode() {
262
+ // HH:MM:SS (the usual)
264
263
  const currentSecond = this.videojs.currentTime();
265
264
  const props = this.timeConverter.secondsFromStartToSMPTE(currentSecond);
266
265
 
267
- this.timeCode && this.timeCode.update(props);
266
+ if (this.timeCode) this.timeCode.update(props);
268
267
 
269
268
  if (this.externalTimecodes.playback.length > 0) {
270
269
  this.externalTimecodes.playback.forEach((timecode) => {
@@ -273,10 +272,11 @@ export default class Player {
273
272
  }
274
273
  }
275
274
 
276
- updateTimeCodeFrame() { // update the frame in this second -> 00:00:00:XX
275
+ updateTimeCodeFrame() {
276
+ // update the frame in this second -> 00:00:00:XX
277
277
  const frame = this.timeConverter.currentFrame(this.videojs.currentTime()); // -> :XX
278
278
 
279
- this.timeCode && this.timeCode.update({ frame }); // TODO - figure out a way to drop frames
279
+ if (this.timeCode) this.timeCode.update({ frame }); // TODO - figure out a way to drop frames
280
280
 
281
281
  if (this.externalTimecodes.playback.length > 0) {
282
282
  this.externalTimecodes.playback.forEach((timecode) => {
@@ -286,11 +286,14 @@ export default class Player {
286
286
 
287
287
  // recursive invocation if still playing
288
288
  if (!this.videojs.paused()) {
289
- this.rafID = requestAnimationFrame(() => { this.updateTimeCodeFrame(); });
289
+ this.rafID = requestAnimationFrame(() => {
290
+ this.updateTimeCodeFrame();
291
+ });
290
292
  }
291
293
  }
292
294
 
293
- setDurationTimeCode() { // happens once
295
+ setDurationTimeCode() {
296
+ // happens once
294
297
  const durationInSeconds = this.videojs.duration();
295
298
  const props = this.timeConverter.secondsFromStartToSMPTE(durationInSeconds);
296
299
  props.frame = this.timeConverter.secondsToFrame(durationInSeconds);
@@ -299,26 +302,27 @@ export default class Player {
299
302
  this.durationTimeCode.container.classList.add('duration');
300
303
  }
301
304
 
302
- bindHotkeys() { // keyboard shortcuts
305
+ bindHotkeys() {
306
+ // keyboard shortcuts
303
307
  this.bindings = [
304
308
  {
305
309
  key: ['space', 'k'],
306
310
  method: (e) => {
307
311
  // prevents page scroll on space, just like YT
308
- (e.preventDefault) && e.preventDefault();
312
+ if (e.preventDefault) e.preventDefault();
309
313
  this.togglePlayback();
310
314
  },
311
315
  },
312
316
  {
313
317
  key: 'j',
314
318
  method: () => {
315
- this.videojs.hasStarted_ && this.jumpBackward();
319
+ if (this.videojs.hasStarted_) this.jumpBackward();
316
320
  },
317
321
  },
318
322
  {
319
323
  key: 'l',
320
324
  method: () => {
321
- this.videojs.hasStarted_ && this.jumpForward();
325
+ if (this.videojs.hasStarted_) this.jumpForward();
322
326
  },
323
327
  },
324
328
  {
@@ -348,14 +352,14 @@ export default class Player {
348
352
  {
349
353
  key: 'up',
350
354
  method: (e) => {
351
- e.preventDefault && e.preventDefault(); // prevent page scroll
355
+ if (e.preventDefault) e.preventDefault(); // prevent page scroll
352
356
  this.volumeUp();
353
357
  },
354
358
  },
355
359
  {
356
360
  key: 'down',
357
361
  method: (e) => {
358
- e.preventDefault && e.preventDefault(); // prevent page scroll
362
+ if (e.preventDefault) e.preventDefault(); // prevent page scroll
359
363
  this.volumeDown();
360
364
  },
361
365
  },
@@ -368,7 +372,7 @@ export default class Player {
368
372
  {
369
373
  key: 'n',
370
374
  method: () => {
371
- this.menu && this.menu.toggle();
375
+ if (this.menu) this.menu.toggle();
372
376
  },
373
377
  },
374
378
  ];
@@ -392,22 +396,26 @@ export default class Player {
392
396
  }
393
397
 
394
398
  unbindHotKeys() {
395
- this.bindings && this.bindings.forEach((binding) => {
396
- mousetrap.unbind(binding.key);
397
- });
399
+ if (this.bindings)
400
+ this.bindings.forEach((binding) => {
401
+ mousetrap.unbind(binding.key);
402
+ });
398
403
  }
399
404
 
400
405
  bindEvents() {
401
- this.videojs.on('volumechange', () => { // persist volume changes
406
+ this.videojs.on('volumechange', () => {
407
+ // persist volume changes
402
408
  this.persistSetting(constants.settings.volume, this.volume);
403
409
  });
404
410
 
405
- this.videojs.textTracks().on('change', () => { // determine subtitles state
411
+ this.videojs.textTracks().on('change', () => {
412
+ // determine subtitles state
406
413
  const tracks = this.videojs.textTracks().tracks_;
407
- const selected = tracks.filter((track) => (track.mode === 'showing'));
414
+ const selected = tracks.filter((track) => track.mode === 'showing');
408
415
  const areAnyTxtTracksActive = selected.length > 0; // -> true if any text tracks are showing
409
416
 
410
- if (areAnyTxtTracksActive) { // update container with appropriate className
417
+ if (areAnyTxtTracksActive) {
418
+ // update container with appropriate className
411
419
  this.videojs.el_.classList.add(constants.classNames.subtitlesActive);
412
420
  this.persistSetting(constants.settings.subs, true);
413
421
  this.persistSetting(constants.settings.subLang, selected[0].language);
@@ -446,7 +454,8 @@ export default class Player {
446
454
  }
447
455
  }
448
456
 
449
- seek(secs) { // relative to current playback time
457
+ seek(secs) {
458
+ // relative to current playback time
450
459
  let time = this.videojs.currentTime() + secs;
451
460
 
452
461
  if (time < 0) {
@@ -457,7 +466,7 @@ export default class Player {
457
466
  }
458
467
 
459
468
  seekTo(sec) {
460
- !this.videojs.hasStarted() && this.videojs.hasStarted(true);
469
+ if (!this.videojs.hasStarted()) this.videojs.hasStarted(true);
461
470
  this.videojs.currentTime(sec);
462
471
  }
463
472
 
@@ -492,9 +501,12 @@ export default class Player {
492
501
  return frame; // we're on this frame, could be for example 23.45
493
502
  }
494
503
 
495
- doEsothericWork() { // non critical parts, that are nice to have
496
- if (this.props.color) { // change the seekbar color from props
497
- document.getElementsByClassName('vjs-play-progress')[0].style.backgroundColor = this.props.color;
504
+ doEsothericWork() {
505
+ // non critical parts, that are nice to have
506
+ if (this.props.color) {
507
+ // change the seekbar color from props
508
+ document.getElementsByClassName('vjs-play-progress')[0].style.backgroundColor =
509
+ this.props.color;
498
510
  }
499
511
 
500
512
  // feedback gizmo, mainly for feedback on hotkey-presses
@@ -548,7 +560,8 @@ export default class Player {
548
560
  });
549
561
  }
550
562
 
551
- restoreSettings() { // restore settings, like volume level or language track
563
+ restoreSettings() {
564
+ // restore settings, like volume level or language track
552
565
  // get values from storage
553
566
  const volume = localStorage.getItem(constants.settings.volume);
554
567
  const subsEnabled = localStorage.getItem(constants.settings.subs);
@@ -557,15 +570,16 @@ export default class Player {
557
570
  // values vs default behaviours in a neatly readable map
558
571
  this.settings = {
559
572
  // avoid .99999999 and other float pecularities in js
560
- [constants.settings.volume]: (volume !== null) ? Math.round(volume * 100) / 100 : 1,
561
- [constants.settings.subLang]: (subLang !== null) ? subLang : 'en',
562
- [constants.settings.subs]: (subsEnabled !== null) ? JSON.parse(subsEnabled) : false,
573
+ [constants.settings.volume]: volume !== null ? Math.round(volume * 100) / 100 : 1,
574
+ [constants.settings.subLang]: subLang !== null ? subLang : 'en',
575
+ [constants.settings.subs]: subsEnabled !== null ? JSON.parse(subsEnabled) : false,
563
576
  };
564
577
 
565
578
  // apply values (settings)
566
579
  this.volume = this.settings[constants.settings.volume]; // volume
567
580
 
568
- if (this.settings[constants.settings.subs]) { // subtitles
581
+ if (this.settings[constants.settings.subs]) {
582
+ // subtitles
569
583
  this.enableSubs();
570
584
  }
571
585
  }
@@ -578,7 +592,7 @@ export default class Player {
578
592
  enableSubs() {
579
593
  const subs = this.videojs.textTracks();
580
594
 
581
- for (let i = 0; i < subs.length; i++) {
595
+ for (let i = 0; i < subs.length; i += 1) {
582
596
  const sub = subs[i];
583
597
  if (sub.language === this.settings[constants.settings.subLang]) {
584
598
  sub.mode = 'showing';
@@ -591,15 +605,19 @@ export default class Player {
591
605
  disableSubs() {
592
606
  const subs = this.videojs.textTracks();
593
607
 
594
- for (let i = 0; i < subs.length; i++) {
608
+ for (let i = 0; i < subs.length; i += 1) {
595
609
  const sub = subs[i];
596
610
  sub.mode = 'hidden';
597
611
  }
598
612
  }
599
613
 
600
614
  toggleSubs() {
601
- if (this.videojs.textTracks().length > 0) { // check if subtitles exist
602
- if (this.videojs.textTracks().tracks_.filter((track) => (track.mode === 'showing')).length > 0) { // a certain subtitle track is enabled
615
+ if (this.videojs.textTracks().length > 0) {
616
+ // check if subtitles exist
617
+ if (
618
+ this.videojs.textTracks().tracks_.filter((track) => track.mode === 'showing').length > 0
619
+ ) {
620
+ // a certain subtitle track is enabled
603
621
  this.disableSubs();
604
622
  } else {
605
623
  this.enableSubs();
@@ -620,12 +638,15 @@ export default class Player {
620
638
  const CustomButton = videojs.extend(Button, {
621
639
  /* eslint-disable func-names, object-shorthand */
622
640
  constructor: function () {
641
+ // eslint-disable-next-line prefer-rest-params
623
642
  Button.apply(this, arguments);
624
- options.className && this.el_.classList.add(options.className);
625
- if (options.title) { this.el_.title = options.title; }
643
+ if (options.className) this.el_.classList.add(options.className);
644
+ if (options.title) {
645
+ this.el_.title = options.title;
646
+ }
626
647
  },
627
648
  handleClick: () => {
628
- options.onClick && options.onClick();
649
+ if (options.onClick) options.onClick();
629
650
  },
630
651
  });
631
652
 
@@ -650,7 +671,8 @@ export default class Player {
650
671
  setupMenu() {
651
672
  const menuItems = this.props.menuItems || [];
652
673
  const sourcesMenuItems = [];
653
- if (this.props.sources.length > 1) { // show only if more than 1 source
674
+ if (this.props.sources.length > 1) {
675
+ // show only if more than 1 source
654
676
  this.props.sources.forEach((source) => {
655
677
  if (source.label) {
656
678
  sourcesMenuItems.push({
@@ -665,8 +687,12 @@ export default class Player {
665
687
  menuItems.push({
666
688
  title: 'Sources',
667
689
  getActiveIndex: () => {
668
- const matchingSource = this.props.sources.find((source) => (source.src === this.videojs.src()));
669
- return sourcesMenuItems.indexOf(sourcesMenuItems.find((menuItem) => (menuItem.title === matchingSource.label)));
690
+ const matchingSource = this.props.sources.find(
691
+ (source) => source.src === this.videojs.src(),
692
+ );
693
+ return sourcesMenuItems.indexOf(
694
+ sourcesMenuItems.find((menuItem) => menuItem.title === matchingSource.label),
695
+ );
670
696
  },
671
697
  items: sourcesMenuItems,
672
698
  });
@@ -675,12 +701,14 @@ export default class Player {
675
701
  // subtitles
676
702
  if (this.props.subtitles && this.props.subtitles.length > 0) {
677
703
  // off option for subs
678
- const subtitleMenuItems = [{
679
- title: 'Off',
680
- onClick: () => {
681
- this.disableSubs();
704
+ const subtitleMenuItems = [
705
+ {
706
+ title: 'Off',
707
+ onClick: () => {
708
+ this.disableSubs();
709
+ },
682
710
  },
683
- }];
711
+ ];
684
712
 
685
713
  // quick toggle in the control bar
686
714
  // this.addButtonToControlBar({
@@ -697,7 +725,7 @@ export default class Player {
697
725
  title: subtitle.label,
698
726
  onClick: () => {
699
727
  const subs = this.videojs.textTracks();
700
- for (let i = 0; i < subs.length; i++) {
728
+ for (let i = 0; i < subs.length; i += 1) {
701
729
  const sub = subs[i];
702
730
  if (i === index) {
703
731
  sub.mode = 'showing';
@@ -709,23 +737,21 @@ export default class Player {
709
737
  });
710
738
  });
711
739
 
712
- menuItems.push(
713
- {
714
- title: 'Subtitles',
715
- getActiveIndex: () => {
716
- const subs = this.videojs.textTracks();
717
- for (let i = 0; i < subs.length; i++) {
718
- const sub = subs[i];
719
- if (sub.mode === 'showing') {
720
- return i + 1; // offset "off" option
721
- }
740
+ menuItems.push({
741
+ title: 'Subtitles',
742
+ getActiveIndex: () => {
743
+ const subs = this.videojs.textTracks();
744
+ for (let i = 0; i < subs.length; i += 1) {
745
+ const sub = subs[i];
746
+ if (sub.mode === 'showing') {
747
+ return i + 1; // offset "off" option
722
748
  }
749
+ }
723
750
 
724
- return 0; // if none are showing, then probably "off"
725
- },
726
- items: subtitleMenuItems,
751
+ return 0; // if none are showing, then probably "off"
727
752
  },
728
- );
753
+ items: subtitleMenuItems,
754
+ });
729
755
  }
730
756
 
731
757
  if (menuItems.length > 0) {
@@ -735,10 +761,10 @@ export default class Player {
735
761
  target,
736
762
  items: menuItems,
737
763
  onOpen: () => {
738
- !this.controlsBelowPlayer && this.hideControls();
764
+ if (!this.controlsBelowPlayer) this.hideControls();
739
765
  },
740
766
  onClose: () => {
741
- !this.controlsBelowPlayer && this.videojs.controls(true);
767
+ if (!this.controlsBelowPlayer) this.videojs.controls(true);
742
768
  },
743
769
  });
744
770
 
@@ -755,7 +781,6 @@ export default class Player {
755
781
  });
756
782
  } else {
757
783
  // no menu items, no menu
758
-
759
784
  }
760
785
  }
761
786
 
@@ -811,25 +836,47 @@ export default class Player {
811
836
  }
812
837
 
813
838
  pause() {
814
- !this.videojs.paused() && this.videojs.pause();
839
+ if (!this.videojs.paused()) this.videojs.pause();
815
840
  }
816
841
 
817
842
  togglePlayback() {
818
843
  if (this.videojs.paused()) {
819
844
  this.play();
820
- this.videojs.hasStarted_ && this.osd.feedback(constants.osd.play);
845
+ if (this.videojs.hasStarted_) this.osd.feedback(constants.osd.play);
821
846
  } else {
822
847
  this.pause();
823
848
  this.osd.feedback(constants.osd.pause);
824
849
  }
825
850
  }
826
851
 
827
- destroy() { // clean up
852
+ // TODO: Check that this works, I took what was in timeCodeDisplay.js
853
+ updateSmpte(valuesObj) {
854
+ // Object.keys and array.forEach are too slow, classic for is faster
855
+ const startCount = this.nodeNames.length - 1;
856
+ let i;
857
+ for (i = startCount; i > -1; i -= 1) {
858
+ // updates follow frame -> seconds -> minutes -> hours order
859
+ const key = this.nodeNames[i];
860
+
861
+ if (
862
+ typeof valuesObj[key] !== 'undefined' &&
863
+ valuesObj[key] !== parseInt(this.nodes[key].value, 10) &&
864
+ key !== this.state.selectedNode
865
+ ) {
866
+ // re-render node if value is defineed and is different from current value
867
+ const str = valuesObj[key].toString();
868
+ this.nodes[key].value = this.toDigitPairStr(str);
869
+ }
870
+ }
871
+ }
872
+
873
+ destroy() {
874
+ // clean up
828
875
  this.videojs.paused(true);
829
- this.rafID && cancelAnimationFrame(this.rafID);
876
+ if (this.rafID) cancelAnimationFrame(this.rafID);
830
877
  this.videojs.dispose();
831
878
  this.unbindHotKeys();
832
- this.seekBar && this.seekBar.destroy();
879
+ if (this.seekBar) this.seekBar.destroy();
833
880
  }
834
881
 
835
882
  get container() {
@@ -873,15 +920,16 @@ export default class Player {
873
920
  return this.timeConverter.secondsFromStartToSMPTE(currentSecond);
874
921
  }
875
922
 
876
- set smpte(smpte) {
877
- const currentSecond = this.videojs.currentTime();
878
- return this.timeConverter.secondsFromStartToSMPTE(currentSecond);
923
+ set smpte(o) {
924
+ // TODO: Verify that this works.
925
+ // Prior to this it used the getter as setter here...
926
+ this.updateSmpte(o);
879
927
  }
880
928
 
881
929
  set src({ src, type = 'video/mp4', label = null }) {
882
930
  const currentTime = this.videojs.currentTime();
883
931
  // iterate trough sources, find existing matches
884
- const source = this.props.sources.find((aSource) => (aSource.src === src));
932
+ const source = this.props.sources.find((aSource) => aSource.src === src);
885
933
  // if no match try adding source
886
934
 
887
935
  const onReady = () => {
@@ -902,7 +950,7 @@ export default class Player {
902
950
  });
903
951
  };
904
952
 
905
- if (source && typeof souce === 'Array' && source.length > 0) {
953
+ if (source && Array.isArray(source) && source.length > 0) {
906
954
  // TODO - if(source.length > 1) - try one by one until a successful load happens
907
955
  this.videojs.addClass('vjs-waiting');
908
956
  this.videojs.src({
@@ -931,6 +979,7 @@ export default class Player {
931
979
  return this.props.sources[index];
932
980
  }
933
981
 
982
+ // eslint-disable-next-line class-methods-use-this, no-unused-vars
934
983
  removeSrc(url) {
935
984
  // should remove all url matching sources
936
985
  }
package/src/player.scss CHANGED
@@ -1,3 +1,5 @@
1
+ @import '~video.js/src/css/video-js.scss';
2
+
1
3
  $red: #f00;
2
4
  $dark-translucent: rgba(28,28,28,0.9);
3
5
  $dark-gray: #333;
@@ -1,4 +1,16 @@
1
- # Player Example Usage
1
+ import { Meta } from '@storybook/addon-docs';
2
+
3
+ <Meta
4
+ title="vdt-videojs/Player/Example usage"
5
+ parameters={{
6
+ viewMode: 'docs',
7
+ previewTabs: {
8
+ canvas: { hidden: true },
9
+ },
10
+ }}
11
+ />
12
+
13
+ ## Example Usage
2
14
 
3
15
  `import { Player } from '@vidispine/vdt-videojs'`
4
16
 
@@ -7,12 +19,12 @@ Here's an example how to use the Player class in a pure js way in your project:
7
19
  ```
8
20
  const playerReference = new Player({
9
21
  target: document.getElementById('player-node'), //HTML mount point
10
-
22
+
11
23
  sources: [
12
24
  { src: 'https://some.domain/video-file.mp4', type: 'video/mp4'},
13
25
  { src: 'https://some.domain/video-file.webm', type: 'video/webm'}
14
26
  ],
15
-
27
+
16
28
  posterUrl: 'https://some.domain/poster-image.jpg', //optional
17
29
  color: '#e84393', //optional - replaces primary color
18
30
 
@@ -34,14 +46,14 @@ const playerReference = new Player({
34
46
  label: 'Danish'
35
47
  }
36
48
  ],
37
-
49
+
38
50
  timecode: false, //optional - replaces time display with SMPTE timecode
39
51
  frameRate: (24000/1001), //optional - use together with timecode option
40
-
52
+
41
53
  onReady: ()=>{ //optional
42
54
  // invoke methods after player has done initializing
43
55
  },
44
-
56
+
45
57
  /*
46
58
  optional - will add a screenshot button to player
47
59
  control bar and invoke method callback on click with player's
@@ -53,5 +65,3 @@ const playerReference = new Player({
53
65
  })
54
66
 
55
67
  ```
56
-
57
- See the [vdt-videojs-react](/?path=/story/vdt-videojs-react-videoplayer--basic) package for use with React.