@vidispine/vdt-videojs 23.1.0 → 23.2.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.
@@ -1,318 +0,0 @@
1
- import { classNames, colors } from './constants';
2
- import { reactiveSetters } from './helpers';
3
-
4
- const buttonNames = Object.freeze({
5
- play: 'play-pause',
6
- start: 'start',
7
- fb: 'frame-backward',
8
- ff: 'frame-forward',
9
- end: 'end',
10
- });
11
-
12
- const buttons = [
13
- // order matters
14
- buttonNames.start,
15
- buttonNames.fb,
16
- buttonNames.play,
17
- buttonNames.ff,
18
- buttonNames.end,
19
- ];
20
-
21
- /*
22
- Since this could possibly be used in a
23
- context without the player and vice versa -
24
- will try and make it as self-contained
25
- as possible, currently utilizing
26
- shadow DOM (style encapsulation as main reason),
27
- https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM
28
- BEWARE - IE < Edge is unsupported
29
- */
30
-
31
- const CSS = `
32
- .vdt-external-controls{
33
- display: flex;
34
- justify-content: center;
35
- align-items: center;
36
- }
37
-
38
- .control{
39
- flex: 1;
40
- flex-grow: 1;
41
- height: 100%;
42
- align-contents: center;
43
- align-self: center;
44
- text-align: center;
45
- vertical-align: middle;
46
- cursor: pointer;
47
- user-select: none;
48
- height: 20px;
49
- padding-top: 10px;
50
- padding-bottom: 10px;
51
- }
52
-
53
- .control .icon{
54
- display: inline-block;
55
- height: 20px;
56
- white-space: nowrap;
57
- opacity: .9;
58
- }
59
-
60
- .control:hover .icon{ opacity: 1; }
61
-
62
- .control .icon:before{
63
- opacity: 1;
64
- flex: 1;
65
- align-self: center;
66
- content: " ";
67
- display: inline-block;
68
- margin: 0 auto;
69
-
70
- /* triangles */
71
- width: 0;
72
- height: 0;
73
- border-style: solid;
74
- border-width: 16px 0 16px 23px;
75
- border-color: transparent transparent transparent ${colors.gray};
76
- }
77
-
78
- .vdt-external-controls.${classNames.onDark} .control .icon:before{
79
- border-color: transparent transparent transparent ${colors.light};
80
- }
81
-
82
- /* specific buttons */
83
-
84
- .control.${buttonNames.start},
85
- .control.${buttonNames.end}{
86
- height: 20px;
87
- }
88
-
89
- .control.${buttonNames.play}{
90
- height: 30px;
91
- padding-top: 0px;
92
- padding-bottom: 0px;
93
- }
94
-
95
- .control.${buttonNames.play} .icon{
96
- height: 30px;
97
- }
98
-
99
- .control.${buttonNames.ff} .icon:before,
100
- .control.${buttonNames.fb} .icon:before,
101
- .control.${buttonNames.end} .icon:before,
102
- .control.${buttonNames.start} .icon:before{
103
- border-width: 10px 0 10px 16px;
104
- }
105
-
106
- .control.${buttonNames.fb} .icon,
107
- .control.${buttonNames.start}{
108
- transform: rotate(180deg);
109
- }
110
-
111
- .control.${buttonNames.end} .icon:after,
112
- .control.${buttonNames.start} .icon:after{
113
- content: " ";
114
- width: 4px;
115
- height: 20px;
116
- display: inline-block;
117
- background: ${colors.gray};
118
- }
119
-
120
- .vdt-external-controls.${classNames.onDark} .control.${buttonNames.end} .icon:after,
121
- .vdt-external-controls.${classNames.onDark} .control.${buttonNames.start} .icon:after{
122
- background: ${colors.light};
123
- }
124
-
125
- /* stateful styles */
126
- .control.${buttonNames.play}.playing .icon:before{
127
- height: 30px;
128
- width: 6px;
129
- border-width: 0px 8px 0px 8px;
130
- border-color: transparent ${colors.gray} transparent ${colors.gray};
131
- }
132
-
133
- .vdt-external-controls.${classNames.onDark} .control.${buttonNames.play}.playing .icon:before{
134
- border-color: transparent ${colors.light} transparent ${colors.light};
135
- }
136
-
137
- .vdt-external-controls.${classNames.loading} .control.${buttonNames.play}{
138
- border-color: transparent #f00 transparent #f00;
139
- }
140
- `;
141
-
142
- class ExternalControls {
143
- constructor(props) {
144
- this.props = props;
145
- reactiveSetters.apply(this);
146
-
147
- this.state = {
148
- playing: false,
149
- onDark: false,
150
- loading: false,
151
- };
152
-
153
- this.shadowRoot = document.createElement('div'); // will attach shadow here, after appending to target
154
- this.shadowRoot.className = 'vdt-external-controls-wrapper';
155
- this.container = document.createElement('div');
156
- this.container.className = 'vdt-external-controls';
157
-
158
- if (this.props.target) {
159
- this.props.target.appendChild(this.shadowRoot);
160
- this.shadow = this.shadowRoot.attachShadow({ mode: 'open' });
161
- // attach styles
162
- this.style = document.createElement('style');
163
- this.style.type = 'text/css';
164
- this.style.appendChild(document.createTextNode(CSS));
165
- this.shadow.appendChild(this.style);
166
-
167
- // attach container to shadow root
168
- this.shadow.appendChild(this.container);
169
- }
170
-
171
- this.handleNewProps(props);
172
- this.bindEvents();
173
- this.draw();
174
- }
175
-
176
- draw() {
177
- this.buttons = {}; // map of html nodes for DOM manipulations
178
- const excludes = this.props.excludes || [];
179
-
180
- buttons.forEach((buttonName) => {
181
- if (excludes.indexOf(buttonName) < 0) {
182
- const btn = document.createElement('div');
183
- btn.className = `control ${buttonName}`;
184
- btn.innerHTML = '<span class="icon"></span>';
185
-
186
- btn.onclick = () => {
187
- this.handlePress(buttonName);
188
- };
189
-
190
- this.buttons[buttonName] = btn;
191
- this.container.appendChild(btn);
192
- }
193
- });
194
- }
195
-
196
- /*
197
- bind to play / pause / stop and other events,
198
- so that controls reflect the player state
199
- */
200
- bindEvents() {
201
- if (this.props.player && this.props.player.videojs) {
202
- const { player } = this.props;
203
-
204
- player.videojs.on('play', () => {
205
- this.playing = true;
206
- });
207
-
208
- player.videojs.on('pause', () => {
209
- this.playing = false;
210
- });
211
-
212
- player.videojs.on('stop', () => {
213
- this.playing = false;
214
- });
215
- }
216
- }
217
-
218
- handlePress(buttonName) {
219
- if (this.props.player) {
220
- // control a vdt player instance directly
221
- const { player } = this.props;
222
- if (player.osd) player.osd.disable(); // temporarily disable OSD
223
-
224
- switch (buttonName) {
225
- case buttonNames.start:
226
- player.toStart();
227
- break;
228
- case buttonNames.fb:
229
- player.triggerHotkey('left');
230
- break;
231
- case buttonNames.play:
232
- player.triggerHotkey('k'); // TODO - triggering hotkeys has a side effect - OSD will give feedback
233
- break;
234
- case buttonNames.ff:
235
- player.triggerHotkey('right');
236
- break;
237
- case buttonNames.end:
238
- player.toEnd();
239
- break;
240
- default:
241
- // do nothing
242
- break;
243
- }
244
-
245
- if (player.osd) player.osd.enable(); // re-enable OSD
246
- } else {
247
- switch (buttonName) {
248
- case buttonNames.start:
249
- if (this.props.onPrev) this.props.onPrev();
250
- break;
251
- case buttonNames.fb:
252
- if (this.props.onFB) this.props.onFB();
253
- break;
254
- case buttonNames.play:
255
- if (this.playing) {
256
- if (this.props.onPause) this.props.onPause();
257
- } else if (this.props.onPlay) this.props.onPlay();
258
- break;
259
- case buttonNames.ff:
260
- if (this.props.onFF) this.props.onFF();
261
- break;
262
- case buttonNames.end:
263
- if (this.props.onNext) this.props.onNext();
264
- break;
265
- default:
266
- // do nothing
267
- break;
268
- }
269
- }
270
- }
271
-
272
- // setters and getters for state
273
- set playing(bool) {
274
- if (bool) {
275
- this.state.playing = true;
276
- this.buttons[buttonNames.play].classList.add('playing');
277
- } else {
278
- this.state.playing = false;
279
- this.buttons[buttonNames.play].classList.remove('playing');
280
- }
281
- }
282
-
283
- get playing() {
284
- return this.state.playing;
285
- }
286
-
287
- set onDark(bool) {
288
- if (bool) {
289
- this.state.onDark = true;
290
- this.container.classList.add(classNames.onDark);
291
- } else {
292
- this.state.onDark = false;
293
- this.container.classList.remove(classNames.onDark);
294
- }
295
- }
296
-
297
- get onDark() {
298
- return this.container.classList.contains(classNames.onDark);
299
- }
300
-
301
- set loading(bool) {
302
- if (bool) {
303
- this.state.loading = true;
304
- this.container.classList.add(classNames.loading);
305
- } else {
306
- this.state.loading = false;
307
- this.container.classList.remove(classNames.loading);
308
- }
309
- }
310
-
311
- get loading() {
312
- return this.state.loading;
313
- }
314
- }
315
-
316
- ExternalControls.buttonNames = buttonNames;
317
-
318
- export default ExternalControls;
@@ -1,110 +0,0 @@
1
- import mousetrap from 'mousetrap';
2
-
3
- export default class HelpOverlay {
4
- constructor(props) {
5
- this.props = props;
6
-
7
- this.state = {
8
- active: this.props.active || false,
9
- };
10
-
11
- this.container = document.createElement('div');
12
- this.container.className = 'vdt-help-overlay';
13
- this.container.innerHTML = '';
14
- this.container.onclick = () => {
15
- this.hide();
16
- };
17
-
18
- if (this.props.target) this.props.target.appendChild(this.container);
19
-
20
- this.draw();
21
- }
22
-
23
- draw() {
24
- // draws keyboard controls
25
- let tableRowMarkup = ''; // will insert a DOM string here
26
- const rows = [
27
- ['⎵', 'Play / Pause'],
28
- ['⇧', 'Increase volume '],
29
- ['⇩', 'Decrease volume'],
30
- ['⇨', 'Step frame forward'],
31
- ['⇦', 'Step frame backward'],
32
- ['M', 'Mute / Unmute'],
33
-
34
- ['J', 'Seek 10 seconds backward'],
35
- ['K', 'Play / Pause'],
36
- ['L', 'Seek 10 seconds forward'],
37
- ['C', 'Toggle subtitles'],
38
- ['N', 'Toggle settings menu'],
39
- ['H', 'Toggle this help overlay'],
40
- ];
41
-
42
- // split the data for 2 columns
43
- const halfpointIndex = Math.round(rows.length / 2);
44
- const columns = [rows.slice(0, halfpointIndex), rows.slice(halfpointIndex, rows.length)];
45
-
46
- // table will niceley auto adjust td's according to length
47
- for (let i = 0; i < halfpointIndex; i += 1) {
48
- tableRowMarkup += `
49
- <tr>
50
- <td><div>${columns[0][i][0]}</div></td>
51
- <td>- ${columns[0][i][1]}</td>
52
-
53
- <td>${columns[1][i] ? `<div>${columns[1][i][0]}</div>` : ''}</td>
54
- <td>${columns[1][i] ? `- ${columns[1][i][1]}` : ''}</td>
55
- </tr>
56
- `;
57
- }
58
-
59
- /*
60
- insert table row markup in the table;
61
- note that there are two tables going
62
- on here - one is for vertically centering the
63
- content of help overlay (the other table)
64
- */
65
-
66
- this.container.innerHTML = `
67
- <table>
68
- <tbody>
69
- <tr>
70
- <td class="vdt-help-contents">
71
- <table><tbody>${tableRowMarkup}</tbody></table>
72
- </td>
73
- </tr>
74
- </tbody>
75
- </table>
76
- `;
77
- }
78
-
79
- show() {
80
- if (!this.state.active) {
81
- this.container.classList.add('active');
82
- this.state.active = true;
83
-
84
- mousetrap.bind('esc', () => {
85
- this.hide();
86
- });
87
-
88
- if (this.props.onToggle) this.props.onToggle(true);
89
- }
90
- }
91
-
92
- hide() {
93
- if (this.state.active) {
94
- this.container.classList.remove('active');
95
- this.state.active = false;
96
-
97
- mousetrap.unbind('esc');
98
-
99
- if (this.props.onToggle) this.props.onToggle(false);
100
- }
101
- }
102
-
103
- toggle() {
104
- if (this.state.active) {
105
- this.hide();
106
- } else {
107
- this.show();
108
- }
109
- }
110
- }
package/src/helpers.js DELETED
@@ -1,39 +0,0 @@
1
- export function truncate(input, len) {
2
- if (input.length > len) return `${input.substring(0, len)}...`;
3
- return input;
4
- }
5
-
6
- /*
7
- Make certain component props React-ive
8
- by being able to call respective component .handleNewProps()
9
- method in react wrappers
10
- */
11
- export function reactiveSetters() {
12
- // will try to find a matching setter in context
13
- // TODO - switch to for loop for more efficient updates
14
- function handleNewProps(props) {
15
- if (typeof props === 'object') {
16
- const keys = Object.getOwnPropertyNames(props);
17
- const proto = Object.getPrototypeOf(this);
18
- keys.forEach((key) => {
19
- // check for own setters / getters
20
- const descriptor = Object.getOwnPropertyDescriptor(proto, key);
21
-
22
- if (descriptor && descriptor.set) {
23
- // if a setter is defined, apply the prop
24
- this[key] = props[key];
25
- }
26
- });
27
- }
28
- }
29
-
30
- // extends a context with handleNewProps method
31
- this.handleNewProps = handleNewProps;
32
- }
33
-
34
- // an elegant way to prevent xss attacks
35
- export function sanitize(str) {
36
- const temp = document.createElement('div');
37
- temp.textContent = str;
38
- return temp.innerHTML;
39
- }
package/src/index.js DELETED
@@ -1,7 +0,0 @@
1
- import ExternalControls from './externalControls';
2
- import Player from './player';
3
- import SeekBar from './seekBar';
4
- import TimeCodeDisplay from './timeCodeDisplay';
5
- import VideoTime from './videoTime';
6
-
7
- export { TimeCodeDisplay, ExternalControls, SeekBar, Player, VideoTime };
@@ -1,52 +0,0 @@
1
- import { Meta } from '@storybook/addon-docs';
2
-
3
- import { docsParameters } from '@vidispine/vdt-storybook';
4
-
5
- import pkgJson from '../package.json';
6
-
7
- <Meta title="vdt-videojs/Overview" parameters={docsParameters} />
8
-
9
- export const changelogMd = () => {
10
- let mdChangeLog = '';
11
- Object.keys(pkgJson.changelog)
12
- .reverse()
13
- .forEach((changelogKey) => {
14
- mdChangeLog += `### ${changelogKey}:\n\n`;
15
- pkgJson.changelog[changelogKey].forEach((entry) => {
16
- mdChangeLog += `- ${entry}\n`;
17
- });
18
- });
19
- return mdChangeLog;
20
- };
21
-
22
- # Overview
23
-
24
- ```
25
- ┌───────────┐ ┌───────┐
26
- │ vdt-react ---------------- ( hooks, providers, wrappers ) --> │ │
27
- └───────────┘ │ │
28
- ┌─────────┐ │ │
29
- │ vdt-api ------------------------- ( API js Promises ) ------> │ │
30
- └─────────┘ │ │
31
- ┌────────────────┐ │ │
32
- │ vdt-materialui -- (Customized Material UI React library) ---> │ │
33
- └────────────────┘ │ Your │
34
- ┌─── player components ──┐ │ SPA │
35
- │┌───────────────────────┐ │ │
36
- open-source player packages --> ││ vdt-videojs-react ---> │ │
37
- │└───────────────────────┘ │ │
38
- ┌─────────────┐ │┌───────────────────────┐ │ │
39
- │ vdt-videojs ------------------> ││ vdt-videojs-vue (?) ---> │ │
40
- └─────────────┘ │└───────────────────────┘ └───────┘
41
- (pure js) └ wrapped for frameworks ┘
42
-
43
- ```
44
-
45
- vdt-videojs sets out to build a pure javascript video player on top of [video.js](https://videojs.com) and delivers more features with a "familiar" user interface / experience. There is an every-so-often manually deployed [live demo here](https://vdt-js-player.netlify.app/).
46
-
47
- vdt-videojs is written in ES6 Javascript and has minimal dependencies; It's wrapable for supported frameworks.
48
-
49
- Additionally vdt-videojs package exports other pure js components closely related to Player (SeekBar, TimeCodeDisplay, ExternalControls and others) for
50
- use with react / other frameworks within their respective wrappers.
51
-
52
- See the [vdt-videojs-react](./?path=/story/vdt-videojs-react-videoplayer--basic) package for use with React.
@@ -1,53 +0,0 @@
1
- import { Meta } from '@storybook/addon-docs';
2
-
3
- import { docsParameters } from '@vidispine/vdt-storybook';
4
-
5
- <Meta title="vdt-videojs/Player Menu/Class Methods" parameters={docsParameters} />
6
-
7
- ## Class Methods
8
-
9
- Menu is initialized at `player.menu`, so you can access
10
- the Menu class instance methods via `player.menu.methodName()`.
11
-
12
- <br />
13
- <table>
14
- <thead>
15
- <tr>
16
- <th>Method</th>
17
- <th>Description</th>
18
- <th>Associated hotkey</th>
19
- </tr>
20
- </thead>
21
- <tbody>
22
- <tr>
23
- <td>.open()</td>
24
- <td>Open menu</td>
25
- <td>N</td>
26
- </tr>
27
- <tr>
28
- <td>.close()</td>
29
- <td>Close menu</td>
30
- <td>ESC, N</td>
31
- </tr>
32
- <tr>
33
- <td>.toggle()</td>
34
- <td>Toggle open / close</td>
35
- <td>N</td>
36
- </tr>
37
- <tr>
38
- <td>.up()</td>
39
- <td>Go up to main level</td>
40
- <td />
41
- </tr>
42
- <tr>
43
- <td>.render()</td>
44
- <td>Update selected items in main level</td>
45
- <td />
46
- </tr>
47
- <tr>
48
- <td>.opened</td>
49
- <td>Getter property (bool) - use this to get the state of menu</td>
50
- <td />
51
- </tr>
52
- </tbody>
53
- </table>