@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.
- package/README.md +4 -4
- package/deprecated-app/README.md +21 -0
- package/{demo.html → deprecated-app/index.html} +1 -1
- package/{demo.js → deprecated-app/index.js} +69 -41
- package/{samples → deprecated-app/samples}/birds-es.vvt +0 -0
- package/{samples → deprecated-app/samples}/birds.vvt +0 -0
- package/{tests.js → deprecated-app/tests.js} +87 -54
- package/{lib/style.css → dist/index.css} +755 -55
- package/dist/index.es.js +2099 -0
- package/dist/index.js +2112 -0
- package/dist/index.umd.js +2115 -0
- package/package.json +29 -85
- package/rollup.config.js +54 -0
- package/src/constants.js +1 -1
- package/src/externalControls.js +14 -18
- package/src/helpOverlay.js +12 -16
- package/src/helpers.js +3 -3
- package/src/index.js +3 -9
- package/src/index.stories.mdx +59 -0
- package/src/menu.api.stories.mdx +59 -0
- package/src/menu.js +23 -19
- package/src/{menu.example.md → menu.usage.stories.mdx} +31 -21
- package/src/osd.js +24 -18
- package/src/player.api.stories.mdx +120 -0
- package/src/player.js +157 -108
- package/src/player.scss +2 -0
- package/src/{player.example.md → player.usage.stories.mdx} +18 -8
- package/src/seekBar.js +85 -48
- package/src/timeCodeDisplay.js +39 -31
- package/src/videoTime.js +4 -4
- package/build.js +0 -233
- package/lib/index.cjs.js +0 -3240
- package/lib/index.esm.js +0 -3227
- package/lib/index.umd.js +0 -3243
- package/lib/package.json +0 -13
- package/lib/src/constants.js +0 -51
- package/lib/src/externalControls.js +0 -307
- package/lib/src/helpOverlay.js +0 -106
- package/lib/src/helpers.js +0 -34
- package/lib/src/index.js +0 -13
- package/lib/src/menu.js +0 -365
- package/lib/src/osd.js +0 -91
- package/lib/src/player.js +0 -943
- package/lib/src/seekBar.js +0 -833
- package/lib/src/timeCodeDisplay.js +0 -253
- package/lib/src/videoTime.js +0 -66
- package/log.js +0 -24
- package/src/_index.stories.js +0 -24
- package/src/externalControls.stories.js +0 -6
- package/src/helpOverlay.stories.js +0 -6
- package/src/menu.classMethods.md +0 -47
- package/src/player.classMethods.md +0 -108
- package/src/player.stories.js +0 -14
- package/src/seekBar.stories.js +0 -8
- package/tmp/player.css +0 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
│┌───────────────────────┐ │ │
|
|
15
15
|
open-source player packages --> ││ vdt-videojs-react ---> │ │
|
|
16
16
|
│└───────────────────────┘ │ │
|
|
17
|
-
┌─────────────┐ │┌───────────────────────┐ │ │
|
|
17
|
+
┌─────────────┐ │┌───────────────────────┐ │ │
|
|
18
18
|
│ vdt-videojs ------------------> ││ vdt-videojs-vue (?) ---> │ │
|
|
19
19
|
└─────────────┘ │└───────────────────────┘ └───────┘
|
|
20
20
|
(pure js) └ wrapped for frameworks ┘
|
|
@@ -30,7 +30,6 @@ use with react / other frameworks within their respective wrappers.
|
|
|
30
30
|
|
|
31
31
|
See the [vdt-videojs-react docs](https://vidispine.github.io/vdt/?path=/story/vdt-videojs-react-videoplayer--basic) for use with React.
|
|
32
32
|
|
|
33
|
-
|
|
34
33
|
# Get started with development
|
|
35
34
|
|
|
36
35
|
`cd` into `vdt-videojs` directory and run
|
|
@@ -40,16 +39,17 @@ npm i
|
|
|
40
39
|
npm run start
|
|
41
40
|
|
|
42
41
|
```
|
|
42
|
+
|
|
43
43
|
Edit the code in `./src/` directory and observe changes at [localhost:2222](localhost:2222) (should auto-open)
|
|
44
44
|
|
|
45
45
|
<br />
|
|
46
46
|
|
|
47
47
|
# Building for distribution
|
|
48
48
|
|
|
49
|
-
|
|
50
49
|
```
|
|
51
50
|
npm run build
|
|
52
51
|
```
|
|
52
|
+
|
|
53
53
|
Outputs CSS and comment stripped ES6 javascript;
|
|
54
54
|
Addittionally outputs CJS, EMS and UMD bundles.
|
|
55
55
|
|
|
@@ -58,6 +58,7 @@ You can also use
|
|
|
58
58
|
```
|
|
59
59
|
npm run build:watch
|
|
60
60
|
```
|
|
61
|
+
|
|
61
62
|
this will output to `/lib/` directory for development needs while working with other packages on the fly.
|
|
62
63
|
|
|
63
64
|
<br />
|
|
@@ -70,4 +71,3 @@ this will output to `/lib/` directory for development needs while working with o
|
|
|
70
71
|
- Fast forward / Fast backward functionality
|
|
71
72
|
- Result view improvements
|
|
72
73
|
- Suggested videos after video playback has ended
|
|
73
|
-
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Demo/Test app for videojs
|
|
2
|
+
|
|
3
|
+
This folder contain a parcel v1 app used to demo and tests for videojs in the browser
|
|
4
|
+
|
|
5
|
+
It is disabled due to parcel v1 deprecation and since we're using rollup to build all libraries.
|
|
6
|
+
We should strive to demo in storybook and write tests we can use in an automated test pipeline instead.
|
|
7
|
+
|
|
8
|
+
## Temporarily enable it by adding this to package.json
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"devDependency": {
|
|
13
|
+
"parcel-bundler": "^1.12.5"
|
|
14
|
+
//...
|
|
15
|
+
},
|
|
16
|
+
"script": {
|
|
17
|
+
"start": "rm -rf ./deprecated-app/build && rm -rf ./.cache && parcel ./deprecated-app/index.html --no-source-maps --no-hmr -p 3002 --open --out-dir ./deprecated-app/build"
|
|
18
|
+
//...
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
@@ -1,32 +1,22 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
/* eslint-disable no-multi-assign */
|
|
3
|
-
/* eslint-disable no-alert */
|
|
4
|
-
|
|
5
2
|
import 'video.js/dist/video-js.css';
|
|
6
|
-
import '
|
|
3
|
+
import '../dist/index.css';
|
|
7
4
|
|
|
8
5
|
// example import for pure js use
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
ExternalControls,
|
|
12
|
-
SeekBar,
|
|
13
|
-
TimeCodeDisplay,
|
|
14
|
-
} from './src';
|
|
6
|
+
import pkgJson from '../package.json'; // for version codes and other useful info
|
|
7
|
+
import { Player, ExternalControls, SeekBar, TimeCodeDisplay } from '../src/index';
|
|
15
8
|
|
|
16
|
-
// subtitles - imports return file urls (hased file output in parcel packager)
|
|
17
|
-
import subtitleTestFile from './samples/birds.vvt';
|
|
18
9
|
import subtitleTestFile2 from './samples/birds-es.vvt';
|
|
19
|
-
|
|
10
|
+
import subtitleTestFile from './samples/birds.vvt';
|
|
20
11
|
// simple smokescreen tests
|
|
21
|
-
import
|
|
22
|
-
|
|
12
|
+
import runTests, { log } from './tests';
|
|
13
|
+
|
|
14
|
+
// subtitles - imports return file urls (hased file output in parcel packager)
|
|
23
15
|
|
|
24
16
|
const urlParams = new URLSearchParams(window.location.search);
|
|
25
17
|
const liveDemoMode = urlParams.get('live_demo') === 'true';
|
|
26
18
|
|
|
27
|
-
const bodyClassName = [
|
|
28
|
-
(liveDemoMode) ? 'live-demo' : '',
|
|
29
|
-
].join(' ');
|
|
19
|
+
const bodyClassName = [liveDemoMode ? 'live-demo' : ''].join(' ');
|
|
30
20
|
if (bodyClassName.length > 0) document.getElementsByTagName('body')[0].className += bodyClassName;
|
|
31
21
|
|
|
32
22
|
document.title = `${pkgJson.name} - ${pkgJson.version}`;
|
|
@@ -60,12 +50,12 @@ function makeButtonBox(buttons) {
|
|
|
60
50
|
}
|
|
61
51
|
|
|
62
52
|
// test data
|
|
63
|
-
const testData = [
|
|
53
|
+
const testData = [
|
|
54
|
+
// bunch of videos for variety, different aspect ratios and bitrates
|
|
64
55
|
{
|
|
65
|
-
sources: [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
posterUrl: 'https://www.nationalgeographic.com/content/dam/news/2016/11/09/birds-plastic/birds-plastic.jpg',
|
|
56
|
+
sources: [{ src: '//vjs.zencdn.net/v/oceans.mp4', type: 'video/mp4', label: 'Birds video' }],
|
|
57
|
+
posterUrl:
|
|
58
|
+
'https://www.nationalgeographic.com/content/dam/news/2016/11/09/birds-plastic/birds-plastic.jpg',
|
|
69
59
|
subtitles: [
|
|
70
60
|
{
|
|
71
61
|
src: subtitleTestFile,
|
|
@@ -78,12 +68,17 @@ const testData = [ // bunch of videos for variety, different aspect ratios and b
|
|
|
78
68
|
label: 'Spanish',
|
|
79
69
|
},
|
|
80
70
|
{
|
|
81
|
-
src: new Blob(
|
|
71
|
+
src: new Blob(
|
|
72
|
+
[
|
|
73
|
+
'WEBVTT\n\n\n00:00:00.500 --> 00:00:03.500 line:0%\nFuglene...\n\n00:00:03.800 --> 00:00:05.800 line:0%\nDe flyver og dykker i havet.\n\n00:00:06.000 --> 00:00:07.000 line:0%\nOg nu...\n\n00:00:07.200 --> 00:00:08.000 position:58% line:0%\nFuglene fester.\n\n00:00:08.200 --> 00:00:10.000 line:0%\nYumm, elskede fisk!\n\n00:00:10.100 --> 00:00:12.000 line:0%\nFiskene har masser af næringsstoffer i sig.\n\n00:00:12.000 --> 00:00:13.200 line:0%\nHvad hvis fisken kan føle smerter?\n\n00:00:13.200 --> 00:00:14.500 position:61% line:0%\nDet er en tanke.\n\n00:00:14.522 --> 00:00:16.900 line:0%\nTaler fisk engelsk?\n\n00:00:16.950 --> 00:00:18.200 line:0%\nGulp gulp gl gllllp ...\n\n00:00:18.300 --> 00:00:20.200 line:0%\nVi er nødt til at stoppe den useriøse fisk.\n\n00:00:20.333 --> 00:00:25.333 line:0%\nSwoosh swooosh; dykke eller dø\n\n00:00:26.000 --> 00:00:28.240 line:0%\nDet ser sammen.\n\n00:00:28.951 --> 00:00:30.785 line:0%\nHar du !!!\n\n00:00:30.900 --> 00:00:32.000 line:0%\nO-åh, de store fisker kommer.\n\n00:00:33.200 --> 00:00:36.044 line:0%\n"Vi vil afslutte dig"\n\n00:00:36.800 --> 00:00:42.547 line:0%\nOK, jeg skal hoppe, HVALE dette har ikke gået dårligere end det er; Tjek denne lange undertekstlinie!',
|
|
74
|
+
],
|
|
75
|
+
{ type: 'text/plain' },
|
|
76
|
+
),
|
|
82
77
|
lang: 'dk',
|
|
83
78
|
label: 'Danish',
|
|
84
79
|
},
|
|
85
80
|
],
|
|
86
|
-
frameRate:
|
|
81
|
+
frameRate: 24000 / 1001,
|
|
87
82
|
},
|
|
88
83
|
/*
|
|
89
84
|
{ // has multiple in-band audio tracks
|
|
@@ -143,15 +138,18 @@ const testData = [ // bunch of videos for variety, different aspect ratios and b
|
|
|
143
138
|
let onDark = true;
|
|
144
139
|
function setupLightSwitch() {
|
|
145
140
|
function applyBg() {
|
|
146
|
-
document.getElementsByTagName('html')[0].className =
|
|
141
|
+
document.getElementsByTagName('html')[0].className = onDark ? 'dark' : 'light';
|
|
147
142
|
}
|
|
148
143
|
|
|
149
144
|
function lightSwitch() {
|
|
150
145
|
onDark = !onDark;
|
|
151
146
|
|
|
152
147
|
applyBg();
|
|
148
|
+
// eslint-disable-next-line no-use-before-define
|
|
153
149
|
player.onDark = onDark;
|
|
150
|
+
// eslint-disable-next-line no-undef
|
|
154
151
|
controls.onDark = onDark;
|
|
152
|
+
// eslint-disable-next-line no-use-before-define
|
|
155
153
|
seekbar.onDark = onDark;
|
|
156
154
|
}
|
|
157
155
|
|
|
@@ -161,6 +159,7 @@ function setupLightSwitch() {
|
|
|
161
159
|
logoSwitch.className = 'vdt-lightswitch';
|
|
162
160
|
logoSwitch.onclick = lightSwitch;
|
|
163
161
|
|
|
162
|
+
// eslint-disable-next-line no-use-before-define
|
|
164
163
|
target.appendChild(logoSwitch);
|
|
165
164
|
}
|
|
166
165
|
|
|
@@ -173,10 +172,12 @@ setupLightSwitch();
|
|
|
173
172
|
const menuItems = [
|
|
174
173
|
{
|
|
175
174
|
title: 'Example 1',
|
|
176
|
-
getActiveIndex: (subitems) => {
|
|
175
|
+
getActiveIndex: (subitems) => {
|
|
176
|
+
// predicate method for determining active index
|
|
177
177
|
let activeIndex = 0;
|
|
178
178
|
|
|
179
179
|
subitems.forEach((item, index) => {
|
|
180
|
+
// eslint-disable-next-line no-use-before-define
|
|
180
181
|
if (item.src === player.src) {
|
|
181
182
|
activeIndex = index;
|
|
182
183
|
}
|
|
@@ -204,11 +205,16 @@ const menuItems = [
|
|
|
204
205
|
},
|
|
205
206
|
];
|
|
206
207
|
|
|
207
|
-
|
|
208
|
+
// eslint-disable-next-line no-multi-assign
|
|
209
|
+
const player = (window.player = new Player({
|
|
208
210
|
target,
|
|
209
211
|
sources: [
|
|
210
212
|
...testData[randIndex].sources,
|
|
211
|
-
{
|
|
213
|
+
{
|
|
214
|
+
src: '//commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4',
|
|
215
|
+
type: 'video/mp4',
|
|
216
|
+
label: 'Blender video',
|
|
217
|
+
},
|
|
212
218
|
],
|
|
213
219
|
posterUrl: testData[randIndex].posterUrl, // optional
|
|
214
220
|
subtitles: testData[randIndex].subtitles, // array of external subtitle URLs
|
|
@@ -218,10 +224,12 @@ const player = window.player = new Player({
|
|
|
218
224
|
onDark,
|
|
219
225
|
timecode: true, // optional, default -> false
|
|
220
226
|
// color: '#e84393', // optional, default -> YT red
|
|
221
|
-
onReady: () => {
|
|
227
|
+
onReady: () => {
|
|
228
|
+
// called after player has been initialized
|
|
222
229
|
console.log('player ready!');
|
|
223
230
|
},
|
|
224
|
-
onScreenshot: (currentTime) => {
|
|
231
|
+
onScreenshot: (currentTime) => {
|
|
232
|
+
// optional - will show a screenshot button in control bar
|
|
225
233
|
console.log(currentTime);
|
|
226
234
|
},
|
|
227
235
|
// additional menu items
|
|
@@ -237,7 +245,7 @@ const player = window.player = new Player({
|
|
|
237
245
|
console.log(`Out point was set - ${seconds}`);
|
|
238
246
|
},
|
|
239
247
|
},
|
|
240
|
-
});
|
|
248
|
+
}));
|
|
241
249
|
target.appendChild(makeLabel('player.js'));
|
|
242
250
|
|
|
243
251
|
const playerApiTestButtons = [
|
|
@@ -318,7 +326,8 @@ const playerApiTestButtons = [
|
|
|
318
326
|
target.appendChild(makeButtonBox(playerApiTestButtons));
|
|
319
327
|
|
|
320
328
|
// seekbar
|
|
321
|
-
|
|
329
|
+
// eslint-disable-next-line no-multi-assign
|
|
330
|
+
const seekbar = (window.seekbar = new SeekBar({
|
|
322
331
|
target,
|
|
323
332
|
player,
|
|
324
333
|
onRegionClick: (region) => {
|
|
@@ -327,7 +336,7 @@ const seekbar = window.seekbar = new SeekBar({
|
|
|
327
336
|
onDark,
|
|
328
337
|
// in: 13.00,
|
|
329
338
|
// out: 33.00,
|
|
330
|
-
});
|
|
339
|
+
}));
|
|
331
340
|
target.appendChild(makeLabel('seekBar.js'));
|
|
332
341
|
|
|
333
342
|
// buttons for various seekbar api tests
|
|
@@ -348,6 +357,7 @@ const seekbarApiTestButtons = [
|
|
|
348
357
|
{
|
|
349
358
|
title: 'Get In&Out',
|
|
350
359
|
method: () => {
|
|
360
|
+
// eslint-disable-next-line no-alert
|
|
351
361
|
alert(`In point is set at ${seekbar.in} seconds\nOut point is set at ${seekbar.out} seconds`);
|
|
352
362
|
},
|
|
353
363
|
},
|
|
@@ -374,16 +384,30 @@ const seekbarApiTestButtons = [
|
|
|
374
384
|
method: () => {
|
|
375
385
|
seekbar.regions = [
|
|
376
386
|
new SeekBar.Region({
|
|
377
|
-
in: 9.7597499,
|
|
387
|
+
in: 9.7597499,
|
|
388
|
+
out: 14,
|
|
389
|
+
title: 'Birds',
|
|
390
|
+
annotation:
|
|
391
|
+
'Birds are a group of feathered theropod dinosaurs, and constitute the only living dinosaurs.',
|
|
378
392
|
}),
|
|
379
393
|
new SeekBar.Region({
|
|
380
|
-
in: 1,
|
|
394
|
+
in: 1,
|
|
395
|
+
out: 2.8,
|
|
396
|
+
title: 'Cool!',
|
|
397
|
+
annotation: 'Lorem ipsum sit dolor atmet my friend...',
|
|
381
398
|
}),
|
|
382
399
|
new SeekBar.Region({
|
|
383
|
-
in: 28,
|
|
400
|
+
in: 28,
|
|
401
|
+
out: 29,
|
|
402
|
+
title: 'Dinosaurs',
|
|
403
|
+
annotation:
|
|
404
|
+
'Based on fossil and biological evidence, most scientists accept that birds are a specialised subgroup of theropod dinosaurs.',
|
|
384
405
|
}),
|
|
385
406
|
new SeekBar.Region({
|
|
386
|
-
in: 40,
|
|
407
|
+
in: 40,
|
|
408
|
+
out: 43,
|
|
409
|
+
title: 'Right aligned',
|
|
410
|
+
annotation: 'This annotation is right aligned with end of region for fitment. ',
|
|
387
411
|
}),
|
|
388
412
|
];
|
|
389
413
|
},
|
|
@@ -471,13 +495,17 @@ toDoTarget.appendChild(description);
|
|
|
471
495
|
const progressBar = document.createElement('div');
|
|
472
496
|
progressBar.className = 'progress-bar';
|
|
473
497
|
const percent = (toDoos.filter((todo) => todo[1]).length / toDoos.length) * 100;
|
|
474
|
-
progressBar.innerHTML = `<div class="fill" style="width: ${percent}%">${percent.toFixed(
|
|
498
|
+
progressBar.innerHTML = `<div class="fill" style="width: ${percent}%">${percent.toFixed(
|
|
499
|
+
2,
|
|
500
|
+
)} %</div>`;
|
|
475
501
|
toDoTarget.appendChild(progressBar);
|
|
476
502
|
|
|
477
503
|
toDoos.forEach((todo, index) => {
|
|
478
504
|
const checkItem = document.createElement('div');
|
|
479
505
|
checkItem.innerHTML = `
|
|
480
|
-
<span class="to-do"><input type="checkbox" onclick="return false" name="${todo}-${index}" ${
|
|
506
|
+
<span class="to-do"><input type="checkbox" onclick="return false" name="${todo}-${index}" ${
|
|
507
|
+
todo[1] ? 'checked' : ''
|
|
508
|
+
}> ${todo[0]}</span><br />
|
|
481
509
|
`;
|
|
482
510
|
|
|
483
511
|
toDoTarget.appendChild(checkItem);
|
|
@@ -489,7 +517,7 @@ runTestsDiv.className = 'tests';
|
|
|
489
517
|
runTestsDiv.innerHTML = '<center><button>Run in-browser tests</button></center';
|
|
490
518
|
|
|
491
519
|
runTestsDiv.getElementsByTagName('button')[0].onclick = () => {
|
|
492
|
-
|
|
520
|
+
runTests();
|
|
493
521
|
};
|
|
494
522
|
|
|
495
523
|
const testLog = document.createElement('div'); // drop in test log directly into player DOM for demo
|
|
File without changes
|
|
File without changes
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-undef */
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
/* eslint-disable no-unused-expressions */
|
|
4
|
-
/* eslint-disable max-len */
|
|
5
|
-
|
|
6
3
|
import mousetrap from 'mousetrap';
|
|
7
|
-
|
|
4
|
+
|
|
5
|
+
import constants from '../src/constants';
|
|
8
6
|
|
|
9
7
|
// use this to keep logs sane
|
|
10
|
-
function logMiddleware(output, type = '') {
|
|
8
|
+
function logMiddleware(output, type = '') {
|
|
9
|
+
// use log events for extra decoupled needs
|
|
11
10
|
const evt = new Event('log', {
|
|
12
11
|
bubbles: true,
|
|
13
12
|
cancelable: false,
|
|
@@ -57,13 +56,15 @@ function getIntInRange(min, max) {
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
async function pressKeys(keysArr) {
|
|
60
|
-
return new Promise((resolve) => {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
// press like a very fast monkey, max 300ms-ish speed
|
|
61
61
|
keysArr.forEach((key, index) => {
|
|
62
62
|
setTimeout(() => {
|
|
63
63
|
// play key
|
|
64
64
|
mousetrap.trigger(key);
|
|
65
65
|
|
|
66
|
-
if (index === keysArr.length - 1) {
|
|
66
|
+
if (index === keysArr.length - 1) {
|
|
67
|
+
// last keystroke
|
|
67
68
|
resolve();
|
|
68
69
|
}
|
|
69
70
|
}, 100 * index + getIntInRange(150, 250));
|
|
@@ -72,7 +73,9 @@ async function pressKeys(keysArr) {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
async function sleep(milis = 50) {
|
|
75
|
-
return new Promise((r) =>
|
|
76
|
+
return new Promise((r) => {
|
|
77
|
+
setTimeout(r, milis);
|
|
78
|
+
});
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
async function waitForSeek() {
|
|
@@ -84,8 +87,10 @@ async function waitForSeek() {
|
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
return new Promise((resolve) => {
|
|
87
|
-
setTimeout(() => {
|
|
88
|
-
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
// wait for 'seeking' to start
|
|
92
|
+
checkIntervalInstance = setInterval(() => {
|
|
93
|
+
// check every x ms
|
|
89
94
|
if (!isSeeking()) {
|
|
90
95
|
clearInterval(checkIntervalInstance);
|
|
91
96
|
resolve(true);
|
|
@@ -110,23 +115,24 @@ const tests = {
|
|
|
110
115
|
hours: 1,
|
|
111
116
|
});
|
|
112
117
|
|
|
113
|
-
const timeCodeAssertion1 =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
);
|
|
118
|
+
const timeCodeAssertion1 =
|
|
119
|
+
player.timeCode.frame === 21 &&
|
|
120
|
+
player.timeCode.seconds === 22 &&
|
|
121
|
+
player.timeCode.minutes === 23 &&
|
|
122
|
+
player.timeCode.hours === 1;
|
|
119
123
|
assert(timeCodeAssertion1, 'Numbers with pure timeCode.update(...) method match');
|
|
120
124
|
|
|
121
125
|
player.videojs.currentTime(0);
|
|
122
126
|
await waitForSeek();
|
|
123
|
-
const timeCodeAssertion2 =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
const timeCodeAssertion2 =
|
|
128
|
+
player.timeCode.frame === 0 &&
|
|
129
|
+
player.timeCode.seconds === 0 &&
|
|
130
|
+
player.timeCode.minutes === 0 &&
|
|
131
|
+
player.timeCode.hours === 0;
|
|
132
|
+
assert(
|
|
133
|
+
timeCodeAssertion2,
|
|
134
|
+
'Timecode reacted to player time update, everything should be zeroed out',
|
|
128
135
|
);
|
|
129
|
-
assert(timeCodeAssertion2, 'Timecode reacted to player time update, everything should be zeroed out');
|
|
130
136
|
|
|
131
137
|
let i = 1;
|
|
132
138
|
const times = 22;
|
|
@@ -140,12 +146,18 @@ const tests = {
|
|
|
140
146
|
}
|
|
141
147
|
});
|
|
142
148
|
await waitForSeek();
|
|
143
|
-
assert(
|
|
149
|
+
assert(
|
|
150
|
+
player.timeCode.frame === times,
|
|
151
|
+
'Timecode reacted to frameForward, should be 22nd frame',
|
|
152
|
+
);
|
|
144
153
|
|
|
145
154
|
await sleep(); // sleep
|
|
146
155
|
player.videojs.currentTime(13);
|
|
147
156
|
await waitForSeek();
|
|
148
|
-
assert(
|
|
157
|
+
assert(
|
|
158
|
+
player.timeCode.seconds === 13 && player.timeCode.minutes === 0,
|
|
159
|
+
'Timecode reacted to player time update, seconds should be 13',
|
|
160
|
+
);
|
|
149
161
|
|
|
150
162
|
log.progress('Done with timeCodeDisplay tests');
|
|
151
163
|
},
|
|
@@ -156,16 +168,16 @@ const tests = {
|
|
|
156
168
|
log.title('Testing hotkeys');
|
|
157
169
|
|
|
158
170
|
await pressKeys(['space']);
|
|
159
|
-
assert(
|
|
171
|
+
assert(!player.videojs.paused(), 'Space key starts player');
|
|
160
172
|
|
|
161
173
|
await pressKeys(['space']);
|
|
162
|
-
assert(
|
|
174
|
+
assert(player.videojs.paused(), 'Space key pauses player');
|
|
163
175
|
|
|
164
176
|
await pressKeys(['k']);
|
|
165
|
-
assert(
|
|
177
|
+
assert(!player.videojs.paused(), 'K key starts player');
|
|
166
178
|
|
|
167
179
|
await pressKeys(['k']);
|
|
168
|
-
assert(
|
|
180
|
+
assert(player.videojs.paused(), 'K key pauses player');
|
|
169
181
|
|
|
170
182
|
await sleep();
|
|
171
183
|
|
|
@@ -173,7 +185,11 @@ const tests = {
|
|
|
173
185
|
await pressKeys(['l', 'l']);
|
|
174
186
|
await waitForSeek();
|
|
175
187
|
const secAfterJumpForward = Math.round(player.videojs.currentTime());
|
|
176
|
-
assert(
|
|
188
|
+
assert(
|
|
189
|
+
// eslint-disable-next-line import/no-named-as-default-member
|
|
190
|
+
secAfterJumpForward - secBeforeJumpForward >= constants.defaults.jumpSeconds * 2,
|
|
191
|
+
'Jump forward with L key works',
|
|
192
|
+
);
|
|
177
193
|
|
|
178
194
|
await sleep();
|
|
179
195
|
await pressKeys(['l']);
|
|
@@ -183,7 +199,11 @@ const tests = {
|
|
|
183
199
|
await pressKeys(['j', 'j']);
|
|
184
200
|
await waitForSeek();
|
|
185
201
|
const secAfterJumpBackward = Math.round(player.videojs.currentTime());
|
|
186
|
-
assert(
|
|
202
|
+
assert(
|
|
203
|
+
// eslint-disable-next-line import/no-named-as-default-member
|
|
204
|
+
secBeforeJumpBackward - secAfterJumpBackward >= constants.defaults.jumpSeconds * 2,
|
|
205
|
+
'Jump backward with J key works',
|
|
206
|
+
);
|
|
187
207
|
|
|
188
208
|
await sleep(100);
|
|
189
209
|
|
|
@@ -191,34 +211,37 @@ const tests = {
|
|
|
191
211
|
await pressKeys(['right']);
|
|
192
212
|
await waitForSeek();
|
|
193
213
|
const frameAfterFF = player.timeConverter.currentFrame(player.videojs.currentTime());
|
|
194
|
-
assert(
|
|
214
|
+
assert(frameAfterFF === frameBeforeFF + 1, '→ Frame forward with right arrow key works');
|
|
195
215
|
|
|
196
216
|
const frameBeforeFB = player.timeConverter.currentFrame(player.videojs.currentTime());
|
|
197
217
|
await pressKeys(['left']);
|
|
198
218
|
await waitForSeek();
|
|
199
219
|
const frameAfterFB = player.timeConverter.currentFrame(player.videojs.currentTime());
|
|
200
|
-
assert(
|
|
220
|
+
assert(frameAfterFB === frameBeforeFB - 1, '← Frame backward with left arrow key works');
|
|
201
221
|
|
|
202
|
-
player.volume = 1.
|
|
222
|
+
player.volume = 1.0;
|
|
203
223
|
await pressKeys(['down', 'down', 'down', 'down']);
|
|
204
|
-
assert(
|
|
224
|
+
assert(player.volume < 0.8, '↓ Volume adjustment with down arrow works');
|
|
205
225
|
|
|
206
226
|
player.volume = 0.2;
|
|
207
227
|
await pressKeys(['up', 'up', 'up', 'up', 'up', 'up', 'up', 'up']);
|
|
208
|
-
assert(
|
|
228
|
+
assert(player.volume > 0.8, '↑ Volume adjustment with up arrow works');
|
|
209
229
|
|
|
210
230
|
await pressKeys(['m']);
|
|
211
|
-
assert(
|
|
231
|
+
assert(player.volume === 0, 'Mute with m key works');
|
|
212
232
|
|
|
213
233
|
await pressKeys(['m']);
|
|
214
|
-
assert(
|
|
234
|
+
assert(player.volume > 0, 'Unmute with m key works');
|
|
215
235
|
|
|
216
236
|
log.progress('Done with hotkey tests');
|
|
217
237
|
},
|
|
218
238
|
seekBar: () => {
|
|
219
239
|
seekbar.regions = [
|
|
220
240
|
new seekbar.Region({
|
|
221
|
-
in: 1,
|
|
241
|
+
in: 1,
|
|
242
|
+
out: 2.8,
|
|
243
|
+
title: 'Cool!',
|
|
244
|
+
annotation: 'Lorem ipsum sit dolor atmet my friend...',
|
|
222
245
|
}),
|
|
223
246
|
new seekbar.Region({ in: 12, out: 16 }),
|
|
224
247
|
new seekbar.Region({ in: 22, out: 28 }),
|
|
@@ -227,13 +250,24 @@ const tests = {
|
|
|
227
250
|
setTimeout(() => {
|
|
228
251
|
seekbar.regions = [
|
|
229
252
|
new seekbar.Region({
|
|
230
|
-
in: 9.7597499,
|
|
253
|
+
in: 9.7597499,
|
|
254
|
+
out: 14,
|
|
255
|
+
title: 'Birds',
|
|
256
|
+
annotation:
|
|
257
|
+
'Birds are a group of feathered theropod dinosaurs, and constitute the only living dinosaurs.',
|
|
231
258
|
}),
|
|
232
259
|
new seekbar.Region({
|
|
233
|
-
in: 1,
|
|
260
|
+
in: 1,
|
|
261
|
+
out: 2.8,
|
|
262
|
+
title: 'Cool!',
|
|
263
|
+
annotation: 'Lorem ipsum sit dolor atmet my friend...',
|
|
234
264
|
}),
|
|
235
265
|
new seekbar.Region({
|
|
236
|
-
in: 18,
|
|
266
|
+
in: 18,
|
|
267
|
+
out: 22,
|
|
268
|
+
title: 'Dinosaurs',
|
|
269
|
+
annotation:
|
|
270
|
+
'Based on fossil and biological evidence, most scientists accept that birds are a specialised subgroup of theropod dinosaurs.',
|
|
237
271
|
}),
|
|
238
272
|
];
|
|
239
273
|
}, 1500);
|
|
@@ -241,10 +275,7 @@ const tests = {
|
|
|
241
275
|
testInFrameMenu: async () => {
|
|
242
276
|
// reduces repeat code for assertions
|
|
243
277
|
function isMenuOpen() {
|
|
244
|
-
return (
|
|
245
|
-
player.menu.state.opened
|
|
246
|
-
&& player.menu.menuContainer.classList.contains('open')
|
|
247
|
-
);
|
|
278
|
+
return player.menu.state.opened && player.menu.menuContainer.classList.contains('open');
|
|
248
279
|
}
|
|
249
280
|
|
|
250
281
|
log.title('Testing in frame menu');
|
|
@@ -256,13 +287,13 @@ const tests = {
|
|
|
256
287
|
|
|
257
288
|
await pressKeys(['n']);
|
|
258
289
|
await sleep(400);
|
|
259
|
-
assert(
|
|
290
|
+
assert(!isMenuOpen(), 'Menu state is closed upon second N key toggle');
|
|
260
291
|
|
|
261
292
|
await pressKeys(['n']);
|
|
262
293
|
await sleep(400);
|
|
263
294
|
await pressKeys(['esc']);
|
|
264
295
|
await sleep(400);
|
|
265
|
-
assert(
|
|
296
|
+
assert(!isMenuOpen(), 'Menu state is closed after pressing the ESC key');
|
|
266
297
|
|
|
267
298
|
const menuButtonEl = document.getElementsByClassName('vdt-settings-menu-button')[0];
|
|
268
299
|
menuButtonEl.click();
|
|
@@ -271,13 +302,13 @@ const tests = {
|
|
|
271
302
|
|
|
272
303
|
menuButtonEl.click();
|
|
273
304
|
await sleep(400);
|
|
274
|
-
assert(
|
|
305
|
+
assert(!isMenuOpen(), 'Menu state is closed upon second click event invocation on menu btn');
|
|
275
306
|
|
|
276
307
|
menuButtonEl.click();
|
|
277
308
|
await sleep(400);
|
|
278
309
|
player.container.click();
|
|
279
310
|
await sleep(400);
|
|
280
|
-
assert(
|
|
311
|
+
assert(!isMenuOpen(), 'Menu is being closed upon clicking outside the menu area when open');
|
|
281
312
|
|
|
282
313
|
log.progress('Testing video source switching and subtitles selection capability');
|
|
283
314
|
|
|
@@ -286,24 +317,26 @@ const tests = {
|
|
|
286
317
|
await sleep(400);
|
|
287
318
|
|
|
288
319
|
// find the sources menu item and click it
|
|
289
|
-
const sourcesMenuItem = player.menu.state.items.find(
|
|
290
|
-
|
|
320
|
+
const sourcesMenuItem = player.menu.state.items.find(
|
|
321
|
+
(menuItem) => menuItem.props.title.toLowerCase().indexOf('sources') > -1,
|
|
322
|
+
);
|
|
323
|
+
if (sourcesMenuItem) sourcesMenuItem.container.click();
|
|
291
324
|
await sleep(400);
|
|
292
325
|
|
|
293
326
|
// find a subitem that's not the selected one currently and click it
|
|
294
|
-
const altSrcMenuItem = player.menu.state.subItems.find((menuItem) => !
|
|
327
|
+
const altSrcMenuItem = player.menu.state.subItems.find((menuItem) => !menuItem.props.selected);
|
|
295
328
|
|
|
296
329
|
// avoid sound on playback of the other video src
|
|
297
330
|
const playerVolBefore = player.volume;
|
|
298
331
|
player.volume = 0;
|
|
299
332
|
|
|
300
|
-
altSrcMenuItem
|
|
333
|
+
if (altSrcMenuItem) altSrcMenuItem.container.click();
|
|
301
334
|
await waitForSeek();
|
|
302
335
|
sleep();
|
|
303
336
|
player.pause();
|
|
304
337
|
|
|
305
338
|
const videoSrcAfterSwitch = player.videojs.src().toString();
|
|
306
|
-
assert(
|
|
339
|
+
assert(videoSrcBeforeSwitch !== videoSrcAfterSwitch, 'Video source was changed successfully');
|
|
307
340
|
player.volume = playerVolBefore;
|
|
308
341
|
|
|
309
342
|
// TODO - test subtitles selection
|