@gcorevideo/player 2.28.21 → 2.28.22
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/core.js +1 -1
- package/dist/index.css +190 -190
- package/dist/index.embed.js +2718 -194
- package/dist/index.js +2719 -195
- package/lib/plugins/subtitles/ClosedCaptions.d.ts +0 -1
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +2 -7
- package/lib/plugins/thumbnails/Thumbnails.d.ts +1 -1
- package/lib/plugins/thumbnails/Thumbnails.js +23 -3
- package/package.json +3 -2
- package/src/plugins/subtitles/ClosedCaptions.ts +2 -8
- package/src/plugins/thumbnails/Thumbnails.ts +35 -4
- package/src/plugins/thumbnails/__tests__/Thumbnails.test.ts +108 -53
- package/src/plugins/thumbnails/__tests__/__snapshots__/Thumbnails.test.ts.snap +37 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/plugins/typings/parse-srt.d.ts +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,sCAAsC,CAAA;AAiB7C;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,IAAI,CAAQ;IAEpB,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,MAAM,CAAsB;IAEpC,OAAO,CAAC,KAAK,CAA2B;IAExC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAyB;IAEhE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAE3D;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED,OAAO,KAAK,mBAAmB,GAK9B;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,kBAAkB;IAmD1B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,iBAAiB;IAqBzB;;OAEG;IACH,IAAI;IAcJ;;OAEG;IACH,IAAI;IAiBJ,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACM,MAAM;IA4Bf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,yBAAyB;IAejC,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,sCAAsC,CAAA;AAiB7C;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,IAAI,CAAQ;IAEpB,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,MAAM,CAAsB;IAEpC,OAAO,CAAC,KAAK,CAA2B;IAExC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAyB;IAEhE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAE3D;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED,OAAO,KAAK,mBAAmB,GAK9B;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,kBAAkB;IAmD1B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,iBAAiB;IAqBzB;;OAEG;IACH,IAAI;IAcJ;;OAEG;IACH,IAAI;IAiBJ,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACM,MAAM;IA4Bf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,yBAAyB;IAejC,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,SAAS,CAA+C;CACjE"}
|
|
@@ -336,10 +336,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
336
336
|
this.setKeepVisible(this.open);
|
|
337
337
|
}
|
|
338
338
|
setKeepVisible(keepVisible) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
this.clickaway(keepVisible ? this.core.activeContainer.$el[0] : null);
|
|
342
|
-
}
|
|
339
|
+
this.core.getPlugin('media_control').setKeepVisible(keepVisible);
|
|
340
|
+
this.clickaway(keepVisible ? this.core.activeContainer.$el[0] : null);
|
|
343
341
|
}
|
|
344
342
|
itemElement(id) {
|
|
345
343
|
// TODO fix semantically
|
|
@@ -414,8 +412,5 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
414
412
|
mediaControl.slot('cc', this.$el);
|
|
415
413
|
}
|
|
416
414
|
}
|
|
417
|
-
get shouldKeepVisible() {
|
|
418
|
-
return !!this.options.cc?.keepVisible;
|
|
419
|
-
}
|
|
420
415
|
clickaway = mediaControlClickaway(() => this.hideMenu());
|
|
421
416
|
}
|
|
@@ -32,7 +32,7 @@ export interface ThumbnailsPluginSettings {
|
|
|
32
32
|
* @public
|
|
33
33
|
* @remarks
|
|
34
34
|
* The plugin needs specially crafted VTT file with a thumbnail sprite sheet to work.
|
|
35
|
-
* The VTT
|
|
35
|
+
* The VTT cues refer to a thumbnail, an area within the sprite sheet, to associate with a time span.
|
|
36
36
|
*
|
|
37
37
|
* Configuration options - {@link ThumbnailsPluginSettings}
|
|
38
38
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UICorePlugin, Events, template, $, } from '@clappr/core';
|
|
2
2
|
import { trace } from '@gcorevideo/utils';
|
|
3
|
-
import
|
|
3
|
+
import { WebVTT } from 'videojs-vtt.js';
|
|
4
4
|
import assert from 'assert';
|
|
5
5
|
import { CLAPPR_VERSION } from '../../build.js';
|
|
6
6
|
import pluginHtml from '../../../assets/thumbnails/scrub-thumbnails.ejs';
|
|
@@ -12,7 +12,7 @@ const T = 'plugins.thumbnails';
|
|
|
12
12
|
* @public
|
|
13
13
|
* @remarks
|
|
14
14
|
* The plugin needs specially crafted VTT file with a thumbnail sprite sheet to work.
|
|
15
|
-
* The VTT
|
|
15
|
+
* The VTT cues refer to a thumbnail, an area within the sprite sheet, to associate with a time span.
|
|
16
16
|
*
|
|
17
17
|
* Configuration options - {@link ThumbnailsPluginSettings}
|
|
18
18
|
*
|
|
@@ -129,7 +129,7 @@ export class Thumbnails extends UICorePlugin {
|
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
const { sprite: spriteSheet, vtt } = this.options.thumbnails;
|
|
132
|
-
this.thumbs = this.buildSpriteConfig(
|
|
132
|
+
this.thumbs = this.buildSpriteConfig(parseVTT(vtt), spriteSheet);
|
|
133
133
|
if (!this.thumbs.length) {
|
|
134
134
|
trace(`${T} failed to parse the sprite sheet`);
|
|
135
135
|
this.destroy();
|
|
@@ -358,3 +358,23 @@ export class Thumbnails extends UICorePlugin {
|
|
|
358
358
|
return this;
|
|
359
359
|
}
|
|
360
360
|
}
|
|
361
|
+
function parseVTT(vtt) {
|
|
362
|
+
const correctedVTT = vtt.startsWith('WEBVTT') ? vtt : 'WEBVTT\n\n' + vtt;
|
|
363
|
+
const parser = new WebVTT.Parser(window);
|
|
364
|
+
const cues = [];
|
|
365
|
+
parser.oncue = (cue) => {
|
|
366
|
+
cues.push({
|
|
367
|
+
id: cue.id,
|
|
368
|
+
start: cue.startTime,
|
|
369
|
+
end: cue.endTime,
|
|
370
|
+
text: cue.text
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
// TextEncoder is available in all modern browsers and Node >=v11
|
|
374
|
+
const uint8Array = typeof TextEncoder !== 'undefined'
|
|
375
|
+
? new TextEncoder().encode(correctedVTT)
|
|
376
|
+
: Buffer.from(correctedVTT, 'utf-8');
|
|
377
|
+
parser.parse(uint8Array);
|
|
378
|
+
parser.flush();
|
|
379
|
+
return cues;
|
|
380
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gcorevideo/player",
|
|
3
|
-
"version": "2.28.
|
|
3
|
+
"version": "2.28.22",
|
|
4
4
|
"description": "Gcore JavaScript video player",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@types/mousetrap": "^1.6.15",
|
|
45
45
|
"@types/node": "^22.10.1",
|
|
46
46
|
"@types/sinonjs__fake-timers": "^8.1.5",
|
|
47
|
+
"@types/videojs-vtt.js": "^0.15.3",
|
|
47
48
|
"assert": "^2.1.0",
|
|
48
49
|
"eventemitter3": "^5.0.1",
|
|
49
50
|
"happy-dom": "^20.0.8",
|
|
@@ -64,6 +65,6 @@
|
|
|
64
65
|
"hls.js": "^1.5.17",
|
|
65
66
|
"human-format": "^1.2.1",
|
|
66
67
|
"mousetrap": "^1.6.5",
|
|
67
|
-
"
|
|
68
|
+
"videojs-vtt.js": "^0.15.5"
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -448,10 +448,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
private setKeepVisible(keepVisible: boolean) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
this.clickaway(keepVisible ? this.core.activeContainer.$el[0] : null)
|
|
454
|
-
}
|
|
451
|
+
this.core.getPlugin('media_control').setKeepVisible(keepVisible)
|
|
452
|
+
this.clickaway(keepVisible ? this.core.activeContainer.$el[0] : null)
|
|
455
453
|
}
|
|
456
454
|
|
|
457
455
|
private itemElement(id: number): ZeptoResult {
|
|
@@ -543,9 +541,5 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
543
541
|
}
|
|
544
542
|
}
|
|
545
543
|
|
|
546
|
-
private get shouldKeepVisible() {
|
|
547
|
-
return !!this.options.cc?.keepVisible
|
|
548
|
-
}
|
|
549
|
-
|
|
550
544
|
private clickaway = mediaControlClickaway(() => this.hideMenu())
|
|
551
545
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Core,
|
|
8
8
|
} from '@clappr/core'
|
|
9
9
|
import { trace } from '@gcorevideo/utils'
|
|
10
|
-
import
|
|
10
|
+
import { WebVTT } from 'videojs-vtt.js'
|
|
11
11
|
import assert from 'assert'
|
|
12
12
|
|
|
13
13
|
import { TimeValue } from '../../playback.types.js'
|
|
@@ -67,7 +67,7 @@ const T = 'plugins.thumbnails'
|
|
|
67
67
|
* @public
|
|
68
68
|
* @remarks
|
|
69
69
|
* The plugin needs specially crafted VTT file with a thumbnail sprite sheet to work.
|
|
70
|
-
* The VTT
|
|
70
|
+
* The VTT cues refer to a thumbnail, an area within the sprite sheet, to associate with a time span.
|
|
71
71
|
*
|
|
72
72
|
* Configuration options - {@link ThumbnailsPluginSettings}
|
|
73
73
|
*
|
|
@@ -152,7 +152,7 @@ export class Thumbnails extends UICorePlugin {
|
|
|
152
152
|
* startTime- The time (in seconds) that the first thumbnail represents. (defaults to 0)
|
|
153
153
|
*/
|
|
154
154
|
private buildSpriteConfig(
|
|
155
|
-
vtt:
|
|
155
|
+
vtt: ParsedVTT[],
|
|
156
156
|
baseUrl: string,
|
|
157
157
|
): ThumbnailDesc[] {
|
|
158
158
|
const thumbs: ThumbnailDesc[] = []
|
|
@@ -216,7 +216,7 @@ export class Thumbnails extends UICorePlugin {
|
|
|
216
216
|
return
|
|
217
217
|
}
|
|
218
218
|
const { sprite: spriteSheet, vtt } = this.options.thumbnails
|
|
219
|
-
this.thumbs = this.buildSpriteConfig(
|
|
219
|
+
this.thumbs = this.buildSpriteConfig(parseVTT(vtt), spriteSheet)
|
|
220
220
|
if (!this.thumbs.length) {
|
|
221
221
|
trace(`${T} failed to parse the sprite sheet`)
|
|
222
222
|
this.destroy()
|
|
@@ -521,3 +521,34 @@ export class Thumbnails extends UICorePlugin {
|
|
|
521
521
|
return this
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
+
|
|
525
|
+
type ParsedVTT = {
|
|
526
|
+
id: string;
|
|
527
|
+
start: number;
|
|
528
|
+
end: number;
|
|
529
|
+
text: string;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
function parseVTT(vtt: string): ParsedVTT[] {
|
|
534
|
+
const correctedVTT = vtt.startsWith('WEBVTT') ? vtt : 'WEBVTT\n\n' + vtt;
|
|
535
|
+
const parser = new WebVTT.Parser(window);
|
|
536
|
+
const cues: ParsedVTT[] = [];
|
|
537
|
+
(parser as any).oncue = (cue: any) => {
|
|
538
|
+
cues.push({
|
|
539
|
+
id: cue.id,
|
|
540
|
+
start: cue.startTime,
|
|
541
|
+
end: cue.endTime,
|
|
542
|
+
text: cue.text
|
|
543
|
+
});
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
// TextEncoder is available in all modern browsers and Node >=v11
|
|
547
|
+
const uint8Array = typeof TextEncoder !== 'undefined'
|
|
548
|
+
? new TextEncoder().encode(correctedVTT)
|
|
549
|
+
: Buffer.from(correctedVTT, 'utf-8');
|
|
550
|
+
parser.parse(uint8Array as any);
|
|
551
|
+
parser.flush();
|
|
552
|
+
|
|
553
|
+
return cues;
|
|
554
|
+
}
|
|
@@ -17,17 +17,17 @@ vi.mock('../utils.ts', () => ({
|
|
|
17
17
|
loadImageDimensions: vi.fn().mockResolvedValue({ width: 600, height: 900 }),
|
|
18
18
|
}))
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
const baselineVTT = `1
|
|
21
|
+
00:00:00.000 --> 00:00:01.000
|
|
22
|
+
sprite.png#xywh=0,0,100,100
|
|
23
|
+
|
|
24
|
+
2
|
|
25
|
+
00:00:01.000 --> 00:00:02.000
|
|
26
|
+
sprite.png#xywh=100,0,100,100
|
|
27
|
+
`
|
|
28
|
+
|
|
29
|
+
const headerfulVTT = `WEBVTT
|
|
30
|
+
|
|
31
31
|
1
|
|
32
32
|
00:00:00.000 --> 00:00:01.000
|
|
33
33
|
sprite.png#xywh=0,0,100,100
|
|
@@ -35,54 +35,109 @@ sprite.png#xywh=0,0,100,100
|
|
|
35
35
|
2
|
|
36
36
|
00:00:01.000 --> 00:00:02.000
|
|
37
37
|
sprite.png#xywh=100,0,100,100
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
38
|
+
`
|
|
39
|
+
|
|
40
|
+
const blockfulVTT = `WEBVTT
|
|
41
|
+
|
|
42
|
+
STYLE
|
|
43
|
+
.cue { font-weight: bold; }
|
|
44
|
+
|
|
45
|
+
1
|
|
46
|
+
00:00:00.000 --> 00:00:01.000
|
|
47
|
+
sprite.png#xywh=0,0,100,100
|
|
48
|
+
|
|
49
|
+
NOTE
|
|
50
|
+
This is a note
|
|
51
|
+
|
|
52
|
+
2 - This is fancy cue ID
|
|
53
|
+
00:00:01.000 --> 00:00:02.000
|
|
54
|
+
sprite.png#xywh=100,0,100,100
|
|
55
|
+
`
|
|
56
|
+
|
|
57
|
+
const idlessVTT = `WEBVTT
|
|
58
|
+
|
|
59
|
+
00:00:00.000 --> 00:00:01.000
|
|
60
|
+
sprite.png#xywh=0,0,100,100
|
|
61
|
+
|
|
62
|
+
00:00:01.000 --> 00:00:02.000
|
|
63
|
+
sprite.png#xywh=100,0,100,100
|
|
64
|
+
`
|
|
65
|
+
|
|
66
|
+
const richcueVTT = `WEBVTT
|
|
67
|
+
|
|
68
|
+
00:00:00.000 --> 00:00:01.000 align:start size:100%
|
|
69
|
+
sprite.png#xywh=0,0,100,100
|
|
70
|
+
|
|
71
|
+
00:00:01.000 --> 00:00:02.000 align:center size:100%
|
|
72
|
+
sprite.png#xywh=100,0,100,100
|
|
73
|
+
`
|
|
74
|
+
|
|
75
|
+
describe('Thumbnails', () => {
|
|
76
|
+
let core: any
|
|
77
|
+
let mediaControl: any
|
|
78
|
+
let thumbnails: Thumbnails
|
|
79
|
+
describe.each([
|
|
80
|
+
['baseline VTT', baselineVTT],
|
|
81
|
+
['VTT where cues are without ids', idlessVTT],
|
|
82
|
+
['VTT with a WebVTT header', headerfulVTT],
|
|
83
|
+
['VTT with NOTE and STYLE blocks', blockfulVTT],
|
|
84
|
+
['VTT where cues have settings', richcueVTT],
|
|
85
|
+
])('%s', (name, vtt) => {
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
core = createMockCore({
|
|
88
|
+
thumbnails: {
|
|
89
|
+
backdropHeight: 100,
|
|
90
|
+
spotlightHeight: 100,
|
|
91
|
+
sprite: 'https://example.com/sprite.png',
|
|
92
|
+
vtt,
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
mediaControl = createMockMediaControl(core)
|
|
96
|
+
core.getPlugin.mockImplementation((name) => {
|
|
97
|
+
switch (name) {
|
|
98
|
+
case 'media_control':
|
|
99
|
+
return mediaControl
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
thumbnails = new Thumbnails(core)
|
|
70
103
|
})
|
|
71
|
-
|
|
72
|
-
describe('update', () => {
|
|
73
|
-
describe('when mouse pointer is over the scrubber', () => {
|
|
104
|
+
describe('loading', () => {
|
|
74
105
|
beforeEach(async () => {
|
|
75
106
|
core.emit(Events.CORE_READY)
|
|
76
107
|
await new Promise(resolve => setTimeout(resolve, 1))
|
|
77
|
-
mediaControl.container.getDuration.mockReturnValue(5)
|
|
78
|
-
vi.spyOn(thumbnails.$el, 'width').mockReturnValue(300)
|
|
79
|
-
mediaControl.trigger(Events.MEDIACONTROL_MOUSEMOVE_SEEKBAR, {}, 0.5)
|
|
80
108
|
})
|
|
81
|
-
it('should
|
|
82
|
-
expect(thumbnails.$el.
|
|
109
|
+
it('should render', () => {
|
|
110
|
+
expect(thumbnails.$el.html()).toMatchSnapshot()
|
|
111
|
+
})
|
|
112
|
+
it('should mount along with media controls', () => {
|
|
113
|
+
expect(core.$el.find('.scrub-thumbnails')).toHaveLength(1)
|
|
114
|
+
})
|
|
115
|
+
it('should load image dimensions', () => {
|
|
116
|
+
expect(loadImageDimensions).toHaveBeenCalledWith('https://example.com/sprite.png')
|
|
83
117
|
})
|
|
84
|
-
it('should
|
|
85
|
-
|
|
118
|
+
it('should parse sprite sheet and create thumbnails', () => {
|
|
119
|
+
const thumbs = thumbnails.$el.find('#thumbnails-carousel .thumbnail-container')
|
|
120
|
+
expect(thumbs).toHaveLength(2)
|
|
121
|
+
})
|
|
122
|
+
it('should hide', () => {
|
|
123
|
+
expect(thumbnails.$el.hasClass('hidden')).toBe(true)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
describe('update', () => {
|
|
127
|
+
describe('when mouse pointer is over the scrubber', () => {
|
|
128
|
+
beforeEach(async () => {
|
|
129
|
+
core.emit(Events.CORE_READY)
|
|
130
|
+
await new Promise(resolve => setTimeout(resolve, 1))
|
|
131
|
+
mediaControl.container.getDuration.mockReturnValue(5)
|
|
132
|
+
vi.spyOn(thumbnails.$el, 'width').mockReturnValue(300)
|
|
133
|
+
mediaControl.trigger(Events.MEDIACONTROL_MOUSEMOVE_SEEKBAR, {}, 0.5)
|
|
134
|
+
})
|
|
135
|
+
it('should show thumbnails', () => {
|
|
136
|
+
expect(thumbnails.$el.hasClass('hidden')).toBe(false)
|
|
137
|
+
})
|
|
138
|
+
it('should show the matching spotlight thumbnail', () => {
|
|
139
|
+
expect(thumbnails.$el.find('#thumbnails-spotlight .thumbnail-container').css('background-position')).toBe('-100px 0px')
|
|
140
|
+
})
|
|
86
141
|
})
|
|
87
142
|
})
|
|
88
143
|
})
|
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`Thumbnails > loading > should render 1`] = `
|
|
3
|
+
exports[`Thumbnails > VTT where cues are without ids > loading > should render 1`] = `
|
|
4
|
+
"<div class="thumbnails-text" id="thumbnails-text"></div>
|
|
5
|
+
<div class="backdrop" id="thumbnails-backdrop" style="height: 100px;">
|
|
6
|
+
<div class="carousel" id="thumbnails-carousel"><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: -100px 0px;"></div></div>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="spotlight" id="thumbnails-spotlight" style="height: 100px;"></div>
|
|
9
|
+
"
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
exports[`Thumbnails > VTT where cues have settings > loading > should render 1`] = `
|
|
13
|
+
"<div class="thumbnails-text" id="thumbnails-text"></div>
|
|
14
|
+
<div class="backdrop" id="thumbnails-backdrop" style="height: 100px;">
|
|
15
|
+
<div class="carousel" id="thumbnails-carousel"><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: -100px 0px;"></div></div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="spotlight" id="thumbnails-spotlight" style="height: 100px;"></div>
|
|
18
|
+
"
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
exports[`Thumbnails > VTT with NOTE and STYLE blocks > loading > should render 1`] = `
|
|
22
|
+
"<div class="thumbnails-text" id="thumbnails-text"></div>
|
|
23
|
+
<div class="backdrop" id="thumbnails-backdrop" style="height: 100px;">
|
|
24
|
+
<div class="carousel" id="thumbnails-carousel"><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: -100px 0px;"></div></div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="spotlight" id="thumbnails-spotlight" style="height: 100px;"></div>
|
|
27
|
+
"
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
exports[`Thumbnails > VTT with a WebVTT header > loading > should render 1`] = `
|
|
31
|
+
"<div class="thumbnails-text" id="thumbnails-text"></div>
|
|
32
|
+
<div class="backdrop" id="thumbnails-backdrop" style="height: 100px;">
|
|
33
|
+
<div class="carousel" id="thumbnails-carousel"><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: -100px 0px;"></div></div>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="spotlight" id="thumbnails-spotlight" style="height: 100px;"></div>
|
|
36
|
+
"
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
exports[`Thumbnails > baseline VTT > loading > should render 1`] = `
|
|
4
40
|
"<div class="thumbnails-text" id="thumbnails-text"></div>
|
|
5
41
|
<div class="backdrop" id="thumbnails-backdrop" style="height: 100px;">
|
|
6
42
|
<div class="carousel" id="thumbnails-carousel"><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url("https://example.com/sprite.png"); background-size: 600px 900px; background-position: -100px 0px;"></div></div>
|