@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
@@ -1,253 +0,0 @@
1
-
2
- const timeCodeNodeNames = [
3
- 'hours',
4
- 'minutes',
5
- 'seconds',
6
- 'frame',
7
- ];
8
-
9
- export default class TimeCodeDisplay {
10
- constructor(props) {
11
- this.props = props;
12
-
13
- this.state = {
14
- selectedNode: null,
15
- };
16
-
17
- const classNames = [
18
- 'vdt-timecode',
19
- 'vjs-time-control',
20
- (!(this.props.onInput)) ? 'duration' : '', // if no input capability, assume it's a duration timecode
21
- ];
22
- this.container = document.createElement('div');
23
- this.container.className = classNames.join(' ');
24
-
25
- this.nodeNames = [].concat(timeCodeNodeNames);
26
- this.nodes = {};
27
-
28
- this.nodeNames.forEach((nodeName, index) => {
29
- const node = document.createElement('input');
30
- node.className = nodeName;
31
- node.tabIndex = -1;
32
-
33
- if (this.props.onInput) {
34
- node.maxLength = 2;
35
-
36
- node.onfocus = (e) => {
37
- this.handleInputFocus(e, nodeName);
38
- };
39
-
40
- node.onblur = (e) => {
41
- this.handleInputBlur(e, nodeName);
42
- };
43
-
44
- node.onmouseup = (e) => {
45
- e.preventDefault();
46
- e.currentTarget.select();
47
- };
48
-
49
- node.onkeydown = (e) => {
50
- this.handleTimeCodeInput(e, nodeName);
51
- };
52
-
53
- node.onkeyup = (e) => {
54
- this.handleTimeCodeInputOnKeyUp(e, nodeName);
55
- };
56
- } else {
57
- node.readOnly = true;
58
- }
59
-
60
- this.nodes[nodeName] = node;
61
-
62
-
63
- const colon = document.createElement('span');
64
- colon.innerHTML = ':';
65
-
66
-
67
- this.container.appendChild(node);
68
- (index !== this.nodeNames.length - 1) && this.container.appendChild(colon);
69
- });
70
-
71
- if (this.props.target) {
72
- if (this.props.appendAfter) {
73
- this.props.target.parentNode.insertBefore(this.container, this.props.target.nextSibling);
74
- } else {
75
- this.props.target.appendChild(this.container);
76
- }
77
-
78
-
79
- this.reset();
80
- } else {
81
-
82
- console.error(`Unable to instantiate a new ${this.constructor.name} without target DOM node`);
83
- }
84
- }
85
-
86
- update(valuesObj) {
87
- const startCount = this.nodeNames.length - 1;
88
- let i;
89
- for (i = startCount; i > -1; i--) {
90
- const key = this.nodeNames[i];
91
-
92
- if (typeof valuesObj[key] !== 'undefined' && (valuesObj[key] !== parseInt(this.nodes[key].value, 10)) && key !== this.state.selectedNode) {
93
- const str = valuesObj[key].toString();
94
- this.nodes[key].value = this.toDigitPairStr(str);
95
- }
96
- }
97
- }
98
-
99
- reset() {
100
- this.update({
101
- hours: 0,
102
- minutes: 0,
103
- seconds: 0,
104
- frame: 0,
105
- });
106
- }
107
-
108
- handleInputFocus(e, nodeName) {
109
- this.state.selectedNode = nodeName;
110
- this.nodes[nodeName].select();
111
- this.props.onInputFocus && this.props.onInputFocus(nodeName);
112
- }
113
-
114
- handleInputBlur(e, nodeName) {
115
- this.state.selectedNode = null;
116
- this.props.onInputBlur && this.props.onInputBlur(nodeName);
117
- }
118
-
119
- sanitize(input) {
120
- const output = input.replace(/[^0-9]/g, '');
121
- return output;
122
- }
123
-
124
- toDigitPairStr(strValue) {
125
- return (strValue.length < 2) ? `0${strValue}` : strValue;
126
- }
127
-
128
- handleTimeCodeInput(e, nodeName) {
129
- const nodeIndex = this.nodeNames.indexOf(nodeName);
130
-
131
- switch (e.code) {
132
- case 'Enter':
133
- this.checkAndNormalizeAllInputs();
134
-
135
- this.props.onInput && this.props.onInput(e, nodeName, {
136
- hours: this.hours,
137
- minutes: this.minutes,
138
- seconds: this.seconds,
139
- frame: this.frame,
140
- });
141
-
142
- this[nodeName] = e.currentTarget.value;
143
- e.currentTarget.blur();
144
- break;
145
- case 'Tab':
146
- e.preventDefault();
147
-
148
-
149
- if (!e.shiftKey) {
150
- if ((nodeIndex + 1) <= (this.nodeNames.length - 1)) {
151
- this.nodes[this.nodeNames[nodeIndex + 1]].focus();
152
- } else {
153
- this.nodes[this.nodeNames[0]].focus();
154
- }
155
- } else if ((nodeIndex - 1) >= 0) {
156
- this.nodes[this.nodeNames[nodeIndex - 1]].focus();
157
- } else {
158
- this.nodes[this.nodeNames[this.nodeNames.length - 1]].focus();
159
- }
160
- break;
161
- default:
162
- break;
163
- }
164
- }
165
-
166
- handleTimeCodeInputOnKeyUp(e, nodeName) {
167
- if (this.nodes[nodeName].value.length === 2 && !isNaN(e.key)) {
168
- const nodeIndex = this.nodeNames.indexOf(nodeName);
169
-
170
- if ((nodeIndex + 1) <= (this.nodeNames.length - 1)) {
171
- this.nodes[this.nodeNames[nodeIndex + 1]].focus();
172
- }
173
- }
174
- }
175
-
176
- checkAndNormalizeAllInputs() {
177
- this.nodeNames.forEach((nodeName) => {
178
- if (this.nodes[nodeName].value.length < 1) {
179
- this.nodes[nodeName].value = '00';
180
- }
181
-
182
-
183
- this.nodes[nodeName].value = this.toDigitPairStr(this.sanitize(this.nodes[nodeName].value));
184
- });
185
- }
186
-
187
-
188
-
189
- set frame(val) {
190
- this.nodes.frame.value = this.toDigitPairStr(val);
191
- }
192
-
193
- get frame() {
194
- return parseInt(this.nodes.frame.value, 10);
195
- }
196
-
197
- set seconds(val) {
198
- this.nodes.seconds.value = this.toDigitPairStr(val);
199
- }
200
-
201
- get seconds() {
202
- return parseInt(this.nodes.seconds.value, 10);
203
- }
204
-
205
- set minutes(val) {
206
- this.nodes.minutes.value = this.toDigitPairStr(val);
207
- }
208
-
209
- get minutes() {
210
- return parseInt(this.nodes.minutes.value, 10);
211
- }
212
-
213
- set hours(val) {
214
- this.nodes.hours.value = this.toDigitPairStr(val);
215
- }
216
-
217
- get hours() {
218
- return parseInt(this.nodes.hours.value, 10);
219
- }
220
-
221
- getFormatted(key) {
222
- return this.toDigitPairStr(this[key].toString());
223
- }
224
-
225
- get smpte() {
226
- return {
227
- hours: this.hours,
228
- minutes: this.minutes,
229
- seconds: this.seconds,
230
- frame: this.frame,
231
- };
232
- }
233
-
234
- set spmte(o) {
235
- this.update(o);
236
- }
237
-
238
- get smpteString() {
239
- return `${this.getFormatted('hours')}:${this.getFormatted('minutes')}:${this.getFormatted('seconds')}:${this.getFormatted('frame')}`;
240
- }
241
-
242
- set external(bool) {
243
- if (bool) {
244
- this.container.classList.add('external');
245
- } else {
246
- this.container.classList.remove('external');
247
- }
248
- }
249
-
250
- get external() {
251
- return (this.container.classList.contains('external'));
252
- }
253
- }
@@ -1,66 +0,0 @@
1
-
2
-
3
- class VideoTime {
4
- constructor(props) {
5
- if (props.frameRate === undefined) {
6
- delete this;
7
- throw new Error('No "frameRate" option provided, refer to docs.');
8
- } else {
9
- this.props = props;
10
- }
11
- }
12
-
13
- secondsToFramesFromStart(seconds) {
14
- let frame = seconds * this.props.frameRate;
15
- frame = Math.round(frame);
16
- return frame;
17
- }
18
-
19
- currentTimeToFramesFromStart(currentTime) {
20
- return this.secondsToFramesFromStart(currentTime);
21
- }
22
-
23
- secondsToFrame(seconds) {
24
- let frame = this.secondsToFramesFromStart(seconds) % this.props.frameRate;
25
- frame = Math.round(frame);
26
- return frame;
27
- }
28
-
29
- currentFrame(currentTime) {
30
- return Math.round(this.secondsToFrame(currentTime));
31
- }
32
-
33
- frameToCurrentTimeFromStart(frame) {
34
- return frame / this.props.frameRate;
35
- }
36
-
37
- smpteToCurrentTimeFromStart(values) {
38
- return (
39
- values.hours * 3600
40
- + values.minutes * 60
41
- + values.seconds
42
- + values.frame / this.props.frameRate
43
- );
44
- }
45
-
46
- secondsFromStartToSMPTE(secondsFromStart) {
47
- let secondsFS = secondsFromStart;
48
- const hours = Math.floor(secondsFS / 3600);
49
- const minutesWithoutHours = secondsFS / 60 - 60 * hours;
50
-
51
- secondsFS %= 3600;
52
-
53
- const minutes = Math.floor(minutesWithoutHours);
54
- const seconds = Math.floor(secondsFS % 60);
55
- const frame = this.secondsToFrame(secondsFS);
56
-
57
- return {
58
- hours,
59
- minutes,
60
- seconds,
61
- frame,
62
- };
63
- }
64
- }
65
-
66
- export default VideoTime;
package/log.js DELETED
@@ -1,24 +0,0 @@
1
- /* eslint-disable import/no-extraneous-dependencies */
2
- /* eslint-disable no-console */
3
- require('colors');
4
-
5
- const log = {
6
- progress: (str) => {
7
- console.log(`[ OK ] - ${str}`.yellow);
8
- },
9
- change: (str) => {
10
- console.log(`[ OH ] - ${str}`.cyan);
11
- },
12
- success: (str) => {
13
- console.log(`[ OK ] - ${str}`.green);
14
- },
15
- fail: (str) => {
16
- console.log(`[ FAIL ] - ${str}`.red);
17
- process.exit(); // steps are inder-dependent, so fail gracefully
18
- },
19
- clear: () => {
20
- process.stdout.write('\x1BC'); // clear console
21
- },
22
- };
23
-
24
- module.exports = log;
@@ -1,24 +0,0 @@
1
- /* eslint import/no-extraneous-dependencies: "off" */
2
- import { packageInfo } from './constants';
3
- import pkgJson from '../package.json';
4
- import playerReadme from '../README.md';
5
-
6
- export const readme = () => playerReadme;
7
-
8
- export const liveDemo = () => ({ src: 'https://vdt-js-player.netlify.app/?live_demo=true' });
9
-
10
- export const changelog = () => {
11
- let mdChangeLog = '# Changelog\n';
12
- Object.keys(pkgJson.changelog).reverse().forEach((changelogKey) => {
13
- mdChangeLog += `## ${changelogKey}:\n\n`;
14
- pkgJson.changelog[changelogKey].forEach((entry) => {
15
- mdChangeLog += `- ${entry}\n`;
16
- });
17
- });
18
-
19
- return mdChangeLog;
20
- };
21
-
22
- export default {
23
- title: `${packageInfo.name}/Introduction`,
24
- };
@@ -1,6 +0,0 @@
1
- /* eslint import/no-extraneous-dependencies: "off" */
2
- import { packageInfo } from './constants';
3
-
4
- export default {
5
- title: `${packageInfo.name}/ExternalControls`,
6
- };
@@ -1,6 +0,0 @@
1
- /* eslint import/no-extraneous-dependencies: "off" */
2
- import { packageInfo } from './constants';
3
-
4
- export default {
5
- title: `${packageInfo.name}/HelpOverlay`,
6
- };
@@ -1,47 +0,0 @@
1
- ## Menu Class Methods
2
-
3
- Menu is initialized at `player.menu`, so you can access
4
- the Menu class instance methods via `player.menu.methodName()`.
5
-
6
- <br />
7
- <table>
8
- <thead>
9
- <tr>
10
- <th>Method</th>
11
- <th>Description</th>
12
- <th>Associated hotkey</th>
13
- </tr>
14
- </thead>
15
- <tbody>
16
- <tr>
17
- <td>.open()</td>
18
- <td>Open menu</td>
19
- <td>N</td>
20
- </tr>
21
- <tr>
22
- <td>.close()</td>
23
- <td>Close menu</td>
24
- <td>ESC, N</td>
25
- </tr>
26
- <tr>
27
- <td>.toggle()</td>
28
- <td>Toggle open / close</td>
29
- <td>N</td>
30
- </tr>
31
- <tr>
32
- <td>.up()</td>
33
- <td>Go up to main level</td>
34
- <td></td>
35
- </tr>
36
- <tr>
37
- <td>.render()</td>
38
- <td>Update selected items in main level</td>
39
- <td></td>
40
- </tr>
41
- <tr>
42
- <td>.opened</td>
43
- <td>Getter property (bool) - use this to get the state of menu</td>
44
- <td></td>
45
- </tr>
46
- </tbody>
47
- </table>
@@ -1,108 +0,0 @@
1
- # Player Class Methods
2
-
3
- <table>
4
- <thead>
5
- <tr>
6
- <th>Method</th>
7
- <th>Description</th>
8
- <th>Associated hotkey</th>
9
- </tr>
10
- </thead>
11
- <tbody>
12
- <tr>
13
- <td>.togglePlayback()</td>
14
- <td>toggle Play / Pause</td>
15
- <td>Space, K</td>
16
- </tr>
17
- <tr>
18
- <td>.pause()</td>
19
- <td>Pause</td>
20
- <td></td>
21
- </tr>
22
- <tr>
23
- <td>.play()</td>
24
- <td>Play</td>
25
- <td></td>
26
- </tr>
27
- <tr>
28
- <td>.volumeUp()</td>
29
- <td>Increase playback volume</td>
30
- <td>Arrow up</td>
31
- </tr>
32
- <tr>
33
- <td>.volumeDown()</td>
34
- <td>Decrease playback volume</td>
35
- <td>Arrow down</td>
36
- </tr>
37
- <tr>
38
- <td>.toggleMute()</td>
39
- <td>Mute / Unmute audio</td>
40
- <td>M</td>
41
- </tr>
42
- <tr>
43
- <td>.toggleFullscreen()</td>
44
- <td>Toggle fullscreen</td>
45
- <td>F</td>
46
- </tr>
47
- <tr>
48
- <td>.jumpForward()</td>
49
- <td>Jump 10 seconds forward</td>
50
- <td>L</td>
51
- </tr>
52
- <tr>
53
- <td>.jumpBackward()</td>
54
- <td>Jump 10 seconds backward</td>
55
- <td>J</td>
56
- </tr>
57
- <tr>
58
- <td>.frameForward()</td>
59
- <td>Navigate to next frame</td>
60
- <td>Arrow right</td>
61
- </tr>
62
- <tr>
63
- <td>.frameBackward()</td>
64
- <td>Navigate to previous frame</td>
65
- <td>Arrow left</td>
66
- </tr>
67
- <tr>
68
- <td>.toggleSubs()</td>
69
- <td>Toggle subtitles on / off if any</td>
70
- <td>C</td>
71
- </tr>
72
- <tr>
73
- <td>.disableSubs()</td>
74
- <td>Turn subtitles off</td>
75
- <td></td>
76
- </tr>
77
- <tr>
78
- <td>.enableSubs()</td>
79
- <td>Turn subtitles on</td>
80
- <td></td>
81
- </tr>
82
- <tr>
83
- <td>.volume</td>
84
- <td>Returns current volume level (0-1)</td>
85
- <td></td>
86
- </tr>
87
- <tr>
88
- <td>.volume = 0.345</td>
89
- <td>Sets volume level (0-1)</td>
90
- <td></td>
91
- </tr>
92
- <tr>
93
- <td>.toStart()</td>
94
- <td>Navigate to start of the video</td>
95
- <td></td>
96
- </tr>
97
- <tr>
98
- <td>.toEnd()</td>
99
- <td>Navigate to end of the video</td>
100
- <td></td>
101
- </tr>
102
- <tr>
103
- <td>.destroy()</td>
104
- <td>Deconstructor</td>
105
- <td></td>
106
- </tr>
107
- </tbody>
108
- </table>
@@ -1,14 +0,0 @@
1
- /* eslint import/no-extraneous-dependencies: "off" */
2
- import { packageInfo } from './constants';
3
- import exampleMd from './player.example.md';
4
- import menuExampleMd from './menu.example.md';
5
- import menuClassMethodsMd from './menu.classMethods.md';
6
- import methodsMd from './player.classMethods.md';
7
-
8
- export default {
9
- title: `${packageInfo.name}/Player`,
10
- };
11
-
12
- export const exampleUsage = () => exampleMd;
13
- export const classMethods = () => methodsMd;
14
- export const menuAPI = ()=> menuExampleMd+menuClassMethodsMd;
@@ -1,8 +0,0 @@
1
- /* eslint import/no-extraneous-dependencies: "off" */
2
- import { packageInfo } from './constants';
3
- import exampleMd from './player.example.md';
4
- import methodsMd from './player.classMethods.md';
5
-
6
- export default {
7
- title: `${packageInfo.name}/SeekBar`,
8
- };
package/tmp/player.css DELETED
@@ -1 +0,0 @@
1
- button,input,select,textarea,video{outline:none}.video-js .vjs-menu-item,button:focus{outline:initial}.video-js{max-width:100%;overflow:hidden}.video-js.init{height:0!important;display:none}.video-js video{transform:translateZ(0);-webkit-transform:translateZ(0);display:block}.video-js .vjs-poster{background-size:cover}.video-js .vjs-control-bar{height:50px;padding-top:6px;display:flex;background:-moz-linear-gradient(top,transparent 0,transparent 15%,rgba(0,0,0,.3) 100%);background:-webkit-linear-gradient(top,transparent,transparent 15%,rgba(0,0,0,.3));background:linear-gradient(180deg,transparent 0,transparent 15%,rgba(0,0,0,.3));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#4d000000",GradientType=0);transform:translateZ(0);-webkit-transform:translateZ(0);z-index:2}.video-js .vjs-control-bar .vdt-seekbar-wrapper{top:0;left:0;height:10px;width:100%;position:absolute;margin:0 auto}.video-js .vjs-big-play-button{font-size:90px;border:0;background-color:transparent;text-shadow:1px 2px 40px rgba(0,0,0,.4);z-index:2}.video-js .vjs-big-play-button .vjs-icon-placeholder:before{padding-top:5px}.video-js:hover .vjs-big-play-button,.video-js:hover .vjs-big-play-button:focus{background-color:transparent}.video-js .vjs-progress-control{top:0;left:0;position:absolute;display:block;width:100%;height:10px}.video-js .vjs-progress-control .vjs-load-progress{background:hsla(0,0%,100%,.2)}.video-js .vjs-progress-control .vjs-play-progress .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-play-progress .vjs-time-tooltip{display:none}.video-js .vjs-time-control.duration,.video-js .vjs-time-control.vjs-duration{margin-right:auto}.video-js .vdt-screenshot-button .vjs-icon-placeholder,.video-js .vjs-subs-caps-button .vjs-icon-placeholder{opacity:.6}.video-js.has-vdt-menu .vjs-subs-caps-button{display:none}.video-js.subtitles-active .vjs-subs-caps-button .vjs-icon-placeholder{opacity:1}.video-js .vjs-control{font-size:14px}.video-js .vjs-play-progress.vjs-slider-bar{background-color:red}.video-js .vjs-current-time,.video-js .vjs-no-flex .vjs-current-time,.video-js .vjs-time-control{display:block}.video-js .vjs-time-control{font-size:14px;padding:0;min-width:14px;text-align:center}.video-js .vjs-volume-panel,.video-js .vjs-volume-panel .vjs-mute-control{width:3em}.video-js .vjs-menu-button-popup .vjs-menu{bottom:20px}.video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:rgba(28,28,28,.9);border-radius:7px}.video-js .vjs-menu-button-popup .vjs-menu li.vjs-menu-item:focus:not(.vjs-selected){background-color:transparent}.video-js .vjs-menu-button-popup .vjs-menu li.vjs-menu-item:hover:not(.vjs-selected){background-color:hsla(0,0%,100%,.2)}.video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-item-text{color:#fff}.video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-item.vjs-selected .vjs-menu-item-text{color:#333}.video-js .vdt-player-osd{pointer-events:none;position:absolute;top:0;left:0;height:100%;width:100%;opacity:0;z-index:4;-webkit-transform:translateZ(0) scale3d(.5,.5,.5);-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0) scale3d(.5,.5,.5);transition:all .2s ease-out}.video-js .vdt-player-osd.active{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}.video-js .vdt-player-osd table{width:100%;height:100%}.video-js .vdt-player-osd table td{vertical-align:middle;text-align:center}.video-js .vdt-player-osd table td .osd-feedback-icon:before{font-family:VideoJS;content:"\f101";font-size:50px;padding:15px;display:inline-block;height:80px;width:80px;text-align:center;background:rgba(0,0,0,.2);border-radius:100%}.video-js .vdt-player-osd table td .pause:before{content:"\f103"}.video-js .vdt-player-osd table td .volchange.high:before{content:"\f107"}.video-js .vdt-player-osd table td .volchange.mid:before{content:"\f106"}.video-js .vdt-player-osd table td .volchange.low:before{content:"\f105"}.video-js .vdt-player-osd table td .mute:before,.video-js .vdt-player-osd table td .volchange.null:before{content:"\f104"}.video-js .vdt-player-osd table td .unmute:before{content:"\f107"}.video-js .vdt-player-osd table td .backward-jump:before,.video-js .vdt-player-osd table td .forward-jump:before{content:"\f101\f101";letter-spacing:-38px;padding-left:0;padding-right:34px}.video-js .vdt-player-osd table td .backward-jump:before{-webkit-transform:scaleX(-1);transform:scaleX(-1)}@keyframes vjs-spinner-fade{0%{border-top-color:hsla(0,0%,100%,.6)}35%{border-top-color:#fff}to{border-top-color:hsla(0,0%,100%,.6)}}.video-js .vjs-loading-spinner{margin:-40px 0 0 -40px;opacity:.85;border:5px solid hsla(0,0%,100%,.7);width:80px;height:80px;border-radius:100px;z-index:5}.video-js .vjs-loading-spinner:after,.video-js .vjs-loading-spinner:before{margin:-5px}.video-js .vjs-text-track-display,.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:0;transition:transform .3s ease-out;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.video-js .vjs-text-track-display>div,.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display>div{display:table;width:100%;height:100%;margin:0!important}.video-js .vjs-text-track-display .vjs-text-track-cue,.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display .vjs-text-track-cue{width:100%!important;bottom:0!important;top:auto!important;left:auto!important;right:auto!important;font-size:18px!important;height:auto!important;padding-bottom:1.5%;display:table-cell}.video-js .vjs-text-track-display .vjs-text-track-cue>div,.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display .vjs-text-track-cue>div{padding:2px 4px;line-height:1.25;border-radius:2px}.video-js.vjs-fullscreen .vjs-text-track-display .vjs-text-track-cue,.video-js.vjs-user-inactive.vjs-playing.vjs-fullscreen .vjs-text-track-display .vjs-text-track-cue{-webkit-backface-visibility:hidden;backface-visibility:hidden;font-size:24px!important}.video-js.vjs-controls-enabled.vjs-user-active .vjs-control-bar,.video-js.vjs-has-started.vjs-user-inactive.vjs-paused .vjs-control-bar,.video-js.vjs-has-started.vjs-user-inactive.vjs-playing:not(.vjs-fullscreen) .vjs-control-bar,.video-jsdiv .vjs-control-bar{opacity:1}.video-js.vjs-has-started.vjs-user-inactive.vjs-playing:not(.controls-below-player) .vjs-control-bar,.video-js:not(.controls-below-player) .vjs-control-bar{-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translate3d(0,50px,0);transition:transform .3s ease-in-out}.video-js.vjs-controls-enabled.vjs-user-active:not(.controls-below-player) .vjs-control-bar,.video-js.vjs-has-started.vjs-user-inactive.vjs-paused:not(.controls-below-player) .vjs-control-bar{transform:translateZ(0);-webkit-transform:translateZ(0)}.video-js.vjs-controls-enabled.vjs-user-active:not(.controls-below-player):not(.vjs-controls-disabled) .vjs-text-track-display,.video-js.vjs-has-started.vjs-user-inactive.vjs-paused:not(.controls-below-player):not(.vjs-controls-disabled) .vjs-text-track-display{transform:translate3d(0,-50px,0)}.video-js .vdt-timecode{display:inline;font-family:"monospace",sans-serif;margin-left:20px}.video-js .vdt-timecode input,.video-js .vdt-timecode span{font-size:16px}.video-js .vdt-timecode span{text-align:center;display:inline-block}.video-js .vdt-timecode input{display:inline-block;width:auto;border:0;background:transparent;color:inherit;width:21px}@media (max-width:640px){.video-js .vdt-timecode{flex-grow:3}}.video-js .vdt-timecode.duration{margin-left:0;margin-right:auto}.video-js .vdt-timecode.duration span{cursor:default}.video-js .vdt-timecode.duration:before{content:"/";display:inline-block;margin:0 5px;font-size:16px}@media (max-width:640px){.video-js .vdt-timecode.duration{display:none}}.video-js .vdt-cinema-button,.video-js .vdt-screenshot-button,.video-js .vdt-settings-menu-button{cursor:pointer}.video-js .vdt-cinema-button:after,.video-js .vdt-screenshot-button:after,.video-js .vdt-settings-menu-button:after{content:"\f10b";font-family:VideoJS;font-size:22px}.video-js .vdt-cinema-button:active,.video-js .vdt-cinema-button:focus,.video-js .vdt-screenshot-button:active,.video-js .vdt-screenshot-button:focus,.video-js .vdt-settings-menu-button:active,.video-js .vdt-settings-menu-button:focus{opacity:.6}.video-js .vdt-cinema-button:after{content:"\f10a"}.video-js .vdt-settings-menu-button:after{content:"\f110"}.video-js .vdt-help-overlay,.video-js .vdt-waveform-visual{position:absolute;top:0;left:0;background:#888;height:100%;width:100%;display:none;background:#88bfe8;background:-moz-linear-gradient(top,#88bfe8 0,#71a1c4 100%);background:-webkit-linear-gradient(top,#88bfe8,#71a1c4);background:linear-gradient(180deg,#88bfe8 0,#71a1c4);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#88bfe8",endColorstr="#71a1c4",GradientType=0)}.video-js .vdt-help-overlay canvas,.video-js .vdt-waveform-visual canvas{height:100%;width:100%}.video-js.vjs-has-started .vdt-waveform-visual{display:block}.video-js .vdt-help-overlay{font-size:15px;background:transparent;z-index:2;transition:opacity 1s ease-in-out;opacity:0;padding-bottom:12px}.video-js .vdt-help-overlay>table{height:100%;margin:0 auto}.video-js .vdt-help-overlay>table td.vdt-help-contents table{border-radius:7px;max-height:400px;-webkit-backdrop-filter:blur(10px);background:rgba(0,0,0,.6)}.video-js .vdt-help-overlay>table td.vdt-help-contents table td{padding:6px}.video-js .vdt-help-overlay>table td.vdt-help-contents table td:nth-child(2),.video-js .vdt-help-overlay>table td.vdt-help-contents table td td:nth-child(4){padding:4px 9px}.video-js .vdt-help-overlay>table td.vdt-help-contents table td:nth-child(2){padding-right:32px}.video-js .vdt-help-overlay>table td.vdt-help-contents table td:first-child div,.video-js .vdt-help-overlay>table td.vdt-help-contents table td:nth-child(3) div{text-align:center;padding:3px;border:1px solid #fff;border-radius:2px;background:hsla(0,0%,100%,.1);font-size:13px;min-width:21px}.video-js .vdt-help-overlay>table td.vdt-help-contents table td:first-child{padding-left:16px}.video-js .vdt-help-overlay>table td.vdt-help-contents table td:last-child{padding-right:16px}.video-js .vdt-help-overlay>table td.vdt-help-contents table tr:first-child td{padding-top:16px}.video-js .vdt-help-overlay>table td.vdt-help-contents table tr:last-child td{padding-bottom:16px}.video-js .vdt-help-overlay>table td{vertical-align:middle}.video-js .vdt-help-overlay.active{display:block;opacity:1}.video-js.controls-below-player:not(.vjs-controls-disabled).vjs-fullscreen .vjs-text-track-display,.video-js.controls-below-player:not(.vjs-controls-disabled).vjs-fullscreen.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:60px}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled){overflow:visible;width:auto;height:auto;background-color:transparent;margin-bottom:70px}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) video{position:relative}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-control-bar{transform:translate3d(0,60px,0);transition:all .3s ease-in-out;background:transparent}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-control-bar .vdt-timecode:not(.vjs-menu-item-text),.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-control-bar .vjs-button:not(.vjs-menu-item-text){color:#333}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled).on-dark .vjs-control-bar .vdt-timecode:not(.vjs-menu-item-text),.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled).on-dark .vjs-control-bar .vjs-button:not(.vjs-menu-item-text){color:#efefef}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-progress-holder{margin:0 auto}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-menu{bottom:35px}.video-js.controls-below-player:not(.vjs-fullscreen):not(.vjs-controls-disabled) .vjs-poster{height:auto}.video-js .vjs-picture-in-picture-control,.video-js .vjs-play-progress .vjs-time-tooltip,.video-js .vjs-play-progress:before,.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltips,.video-js .vjs-remaining-time{display:none}