@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.
- package/dist/index.css +1 -456
- package/dist/index.js +1915 -342
- package/dist/index.umd.cjs +460 -0
- package/package.json +24 -22
- package/deprecated-app/README.md +0 -21
- package/deprecated-app/index.html +0 -298
- package/deprecated-app/index.js +0 -614
- package/deprecated-app/samples/birds-es.vvt +0 -53
- package/deprecated-app/samples/birds.vvt +0 -53
- package/deprecated-app/tests.js +0 -365
- package/dist/index.es.js +0 -335
- package/dist/index.umd.js +0 -351
- package/rollup.config.js +0 -58
- package/screenshot.png +0 -0
- package/src/constants.js +0 -51
- package/src/externalControls.js +0 -318
- package/src/helpOverlay.js +0 -110
- package/src/helpers.js +0 -39
- package/src/index.js +0 -7
- package/src/index.stories.mdx +0 -52
- package/src/menu.api.stories.mdx +0 -53
- package/src/menu.js +0 -373
- package/src/menu.usage.stories.mdx +0 -78
- package/src/osd.js +0 -105
- package/src/player.api.stories.mdx +0 -114
- package/src/player.js +0 -1029
- package/src/player.scss +0 -604
- package/src/player.usage.stories.mdx +0 -62
- package/src/seekBar.js +0 -904
- package/src/timeCodeDisplay.js +0 -274
- package/src/videoTime.js +0 -66
package/src/timeCodeDisplay.js
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-restricted-globals */
|
|
2
|
-
/* eslint-disable class-methods-use-this */
|
|
3
|
-
/* eslint-disable no-plusplus */
|
|
4
|
-
/* eslint-disable no-unused-expressions */
|
|
5
|
-
|
|
6
|
-
const timeCodeNodeNames = ['hours', 'minutes', 'seconds', 'frame'];
|
|
7
|
-
|
|
8
|
-
export default class TimeCodeDisplay {
|
|
9
|
-
// displays and renders smpte timecodes
|
|
10
|
-
constructor(props) {
|
|
11
|
-
this.props = props;
|
|
12
|
-
|
|
13
|
-
this.state = {
|
|
14
|
-
selectedNode: null, // avoid updating values in a selected node
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const classNames = [
|
|
18
|
-
'vdt-timecode',
|
|
19
|
-
'vjs-time-control', // will apply default videojs style to the whole container, centers things vertically
|
|
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); // used internally
|
|
26
|
-
this.nodes = {}; // store sub-element nodes for mapped access here
|
|
27
|
-
|
|
28
|
-
this.nodeNames.forEach((nodeName, index) => {
|
|
29
|
-
const node = document.createElement('input');
|
|
30
|
-
node.className = nodeName;
|
|
31
|
-
node.tabIndex = -1; // prevent default Tab behaviour for cycling inputs
|
|
32
|
-
|
|
33
|
-
if (this.props.onInput) {
|
|
34
|
-
// optional input capabilities
|
|
35
|
-
node.maxLength = 2;
|
|
36
|
-
|
|
37
|
-
node.onfocus = (e) => {
|
|
38
|
-
this.handleInputFocus(e, nodeName);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
node.onblur = (e) => {
|
|
42
|
-
this.handleInputBlur(e, nodeName);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
node.onmouseup = (e) => {
|
|
46
|
-
e.preventDefault();
|
|
47
|
-
e.currentTarget.select();
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
node.onkeydown = (e) => {
|
|
51
|
-
this.handleTimeCodeInput(e, nodeName);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
node.onkeyup = (e) => {
|
|
55
|
-
this.handleTimeCodeInputOnKeyUp(e, nodeName);
|
|
56
|
-
};
|
|
57
|
-
} else {
|
|
58
|
-
node.readOnly = true; // display-only timecode
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.nodes[nodeName] = node;
|
|
62
|
-
|
|
63
|
-
const colon = document.createElement('span');
|
|
64
|
-
colon.innerHTML = ':';
|
|
65
|
-
|
|
66
|
-
this.container.appendChild(node);
|
|
67
|
-
index !== this.nodeNames.length - 1 && this.container.appendChild(colon);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
if (this.props.target) {
|
|
71
|
-
if (this.props.appendAfter) {
|
|
72
|
-
// so it's possible to append after volume control, for example
|
|
73
|
-
this.props.target.parentNode.insertBefore(this.container, this.props.target.nextSibling);
|
|
74
|
-
} else {
|
|
75
|
-
this.props.target.appendChild(this.container);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// start at 0 values for now, if player will "remember" playback position, revisit this
|
|
79
|
-
this.reset();
|
|
80
|
-
} else {
|
|
81
|
-
// eslint-disable-next-line no-console
|
|
82
|
-
console.error(`Unable to instantiate a new ${this.constructor.name} without target DOM node`); // no joy
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
update(valuesObj) {
|
|
87
|
-
// Object.keys and array.forEach are too slow, classic for is faster
|
|
88
|
-
const startCount = this.nodeNames.length - 1;
|
|
89
|
-
let i;
|
|
90
|
-
for (i = startCount; i > -1; i--) {
|
|
91
|
-
// updates follow frame -> seconds -> minutes -> hours order
|
|
92
|
-
const key = this.nodeNames[i];
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
typeof valuesObj[key] !== 'undefined' &&
|
|
96
|
-
valuesObj[key] !== parseInt(this.nodes[key].value, 10) &&
|
|
97
|
-
key !== this.state.selectedNode
|
|
98
|
-
) {
|
|
99
|
-
// re-render node if value is defineed and is different from current value
|
|
100
|
-
const str = valuesObj[key].toString();
|
|
101
|
-
this.nodes[key].value = this.toDigitPairStr(str);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
reset() {
|
|
107
|
-
this.update({
|
|
108
|
-
hours: 0,
|
|
109
|
-
minutes: 0,
|
|
110
|
-
seconds: 0,
|
|
111
|
-
frame: 0,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
handleInputFocus(e, nodeName) {
|
|
116
|
-
this.state.selectedNode = nodeName; // prevent updates on this input
|
|
117
|
-
this.nodes[nodeName].select();
|
|
118
|
-
this.props.onInputFocus && this.props.onInputFocus(nodeName);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
handleInputBlur(e, nodeName) {
|
|
122
|
-
this.state.selectedNode = null; // allow updates on this input
|
|
123
|
-
this.props.onInputBlur && this.props.onInputBlur(nodeName);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
sanitize(input) {
|
|
127
|
-
const output = input.replace(/[^0-9]/g, '');
|
|
128
|
-
return output;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
toDigitPairStr(strValue) {
|
|
132
|
-
return strValue.length < 2 ? `0${strValue}` : strValue;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
handleTimeCodeInput(e, nodeName) {
|
|
136
|
-
const nodeIndex = this.nodeNames.indexOf(nodeName);
|
|
137
|
-
|
|
138
|
-
switch (e.code) {
|
|
139
|
-
case 'Enter': // do work before submitting input
|
|
140
|
-
this.checkAndNormalizeAllInputs();
|
|
141
|
-
|
|
142
|
-
this.props.onInput &&
|
|
143
|
-
this.props.onInput(e, nodeName, {
|
|
144
|
-
hours: this.hours,
|
|
145
|
-
minutes: this.minutes,
|
|
146
|
-
seconds: this.seconds,
|
|
147
|
-
frame: this.frame,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
this[nodeName] = e.currentTarget.value;
|
|
151
|
-
e.currentTarget.blur(); // done
|
|
152
|
-
break;
|
|
153
|
-
case 'Tab': // custom tab behaviour
|
|
154
|
-
e.preventDefault();
|
|
155
|
-
|
|
156
|
-
// tab trough inputs in a loop fashion
|
|
157
|
-
if (!e.shiftKey) {
|
|
158
|
-
if (nodeIndex + 1 <= this.nodeNames.length - 1) {
|
|
159
|
-
this.nodes[this.nodeNames[nodeIndex + 1]].focus(); // focus next
|
|
160
|
-
} else {
|
|
161
|
-
this.nodes[this.nodeNames[0]].focus(); // focus first
|
|
162
|
-
}
|
|
163
|
-
} else if (nodeIndex - 1 >= 0) {
|
|
164
|
-
this.nodes[this.nodeNames[nodeIndex - 1]].focus(); // focus previous
|
|
165
|
-
} else {
|
|
166
|
-
this.nodes[this.nodeNames[this.nodeNames.length - 1]].focus(); // focus last
|
|
167
|
-
}
|
|
168
|
-
break;
|
|
169
|
-
default:
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
handleTimeCodeInputOnKeyUp(e, nodeName) {
|
|
175
|
-
/*
|
|
176
|
-
cycle to next input if this one is done being populated,
|
|
177
|
-
has to happen onkeyup, since the timecode is already populated
|
|
178
|
-
with valid values most of the time, keydown would always trigger
|
|
179
|
-
false positive length check.
|
|
180
|
-
|
|
181
|
-
Also check if the input is a number (!isNaN),
|
|
182
|
-
to prevent double-triggering Tab key or other logic
|
|
183
|
-
*/
|
|
184
|
-
if (this.nodes[nodeName].value.length === 2 && !isNaN(e.key)) {
|
|
185
|
-
const nodeIndex = this.nodeNames.indexOf(nodeName); // determine position in timecode
|
|
186
|
-
|
|
187
|
-
if (nodeIndex + 1 <= this.nodeNames.length - 1) {
|
|
188
|
-
// check bounds
|
|
189
|
-
this.nodes[this.nodeNames[nodeIndex + 1]].focus(); // focus next
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
checkAndNormalizeAllInputs() {
|
|
195
|
-
this.nodeNames.forEach((nodeName) => {
|
|
196
|
-
if (this.nodes[nodeName].value.length < 1) {
|
|
197
|
-
// somebody left the input blank
|
|
198
|
-
this.nodes[nodeName].value = '00';
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// make sure displayed timecode stays consistent after input and before time-based updates
|
|
202
|
-
this.nodes[nodeName].value = this.toDigitPairStr(this.sanitize(this.nodes[nodeName].value));
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// setters and getters
|
|
207
|
-
|
|
208
|
-
set frame(val) {
|
|
209
|
-
this.nodes.frame.value = this.toDigitPairStr(val);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
get frame() {
|
|
213
|
-
return parseInt(this.nodes.frame.value, 10);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
set seconds(val) {
|
|
217
|
-
this.nodes.seconds.value = this.toDigitPairStr(val);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
get seconds() {
|
|
221
|
-
return parseInt(this.nodes.seconds.value, 10);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
set minutes(val) {
|
|
225
|
-
this.nodes.minutes.value = this.toDigitPairStr(val);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
get minutes() {
|
|
229
|
-
return parseInt(this.nodes.minutes.value, 10);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
set hours(val) {
|
|
233
|
-
this.nodes.hours.value = this.toDigitPairStr(val);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
get hours() {
|
|
237
|
-
return parseInt(this.nodes.hours.value, 10);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
getFormatted(key) {
|
|
241
|
-
return this.toDigitPairStr(this[key].toString());
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
get smpte() {
|
|
245
|
-
return {
|
|
246
|
-
hours: this.hours,
|
|
247
|
-
minutes: this.minutes,
|
|
248
|
-
seconds: this.seconds,
|
|
249
|
-
frame: this.frame,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
set smpte(o) {
|
|
254
|
-
this.update(o);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
get smpteString() {
|
|
258
|
-
return `${this.getFormatted('hours')}:${this.getFormatted('minutes')}:${this.getFormatted(
|
|
259
|
-
'seconds',
|
|
260
|
-
)}:${this.getFormatted('frame')}`;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
set external(bool) {
|
|
264
|
-
if (bool) {
|
|
265
|
-
this.container.classList.add('external');
|
|
266
|
-
} else {
|
|
267
|
-
this.container.classList.remove('external');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
get external() {
|
|
272
|
-
return this.container.classList.contains('external');
|
|
273
|
-
}
|
|
274
|
-
}
|
package/src/videoTime.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// TODO - move this to @vidispine/vdt-js when finalized and use as dependency
|
|
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; // we're on this frame, could be for example 23.45
|
|
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; // in seconds from start
|
|
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
|
-
// eslint-disable-next-line no-param-reassign
|
|
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;
|