@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.
@@ -126,7 +126,6 @@ export declare class ClosedCaptions extends UICorePlugin {
126
126
  private renderIcon;
127
127
  private clampPopup;
128
128
  private mount;
129
- private get shouldKeepVisible();
130
129
  private clickaway;
131
130
  }
132
131
  //# sourceMappingURL=ClosedCaptions.d.ts.map
@@ -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;IAOtB,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,KAAK,iBAAiB,GAE5B;IAED,OAAO,CAAC,SAAS,CAA+C;CACjE"}
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
- if (this.shouldKeepVisible) {
340
- this.core.getPlugin('media_control').setKeepVisible(keepVisible);
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 consist of timestamp records followed by a thumbnail area
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 parseSRT from 'parse-srt';
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 consist of timestamp records followed by a thumbnail area
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(parseSRT(vtt), spriteSheet);
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.21",
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
- "parse-srt": "^1.0.0-alpha"
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
- if (this.shouldKeepVisible) {
452
- this.core.getPlugin('media_control').setKeepVisible(keepVisible)
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 parseSRT, { type ParsedSRT } from 'parse-srt'
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 consist of timestamp records followed by a thumbnail area
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: ParsedSRT[],
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(parseSRT(vtt), spriteSheet)
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
- describe('Thumbnails', () => {
21
- let core: any
22
- let mediaControl: any
23
- let thumbnails: Thumbnails
24
- beforeEach(() => {
25
- core = createMockCore({
26
- thumbnails: {
27
- backdropHeight: 100,
28
- spotlightHeight: 100,
29
- sprite: 'https://example.com/sprite.png',
30
- vtt: `
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
- mediaControl = createMockMediaControl(core)
42
- core.getPlugin.mockImplementation((name) => {
43
- switch (name) {
44
- case 'media_control':
45
- return mediaControl
46
- }
47
- });
48
- thumbnails = new Thumbnails(core)
49
- })
50
- describe('loading', () => {
51
- beforeEach(async () => {
52
- core.emit(Events.CORE_READY)
53
- await new Promise(resolve => setTimeout(resolve, 1))
54
- })
55
- it('should render', () => {
56
- expect(thumbnails.$el.html()).toMatchSnapshot()
57
- })
58
- it('should mount along with media controls', () => {
59
- expect(core.$el.find('.scrub-thumbnails')).toHaveLength(1)
60
- })
61
- it('should load image dimensions', () => {
62
- expect(loadImageDimensions).toHaveBeenCalledWith('https://example.com/sprite.png')
63
- })
64
- it('should parse sprite sheet and create thumbnails', () => {
65
- const thumbs = thumbnails.$el.find('#thumbnails-carousel .thumbnail-container')
66
- expect(thumbs).toHaveLength(2)
67
- })
68
- it('should hide', () => {
69
- expect(thumbnails.$el.hasClass('hidden')).toBe(true)
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 show thumbnails', () => {
82
- expect(thumbnails.$el.hasClass('hidden')).toBe(false)
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 show the matching spotlight thumbnail', () => {
85
- expect(thumbnails.$el.find('#thumbnails-spotlight .thumbnail-container').css('background-position')).toBe('-100px 0px')
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(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url(&quot;https://example.com/sprite.png&quot;); 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(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url(&quot;https://example.com/sprite.png&quot;); 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(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url(&quot;https://example.com/sprite.png&quot;); 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(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url(&quot;https://example.com/sprite.png&quot;); 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(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: 0px 0px;"></div><div class="thumbnail-container" style="width: 100px; height: 100px; background-image: url(&quot;https://example.com/sprite.png&quot;); background-size: 600px 900px; background-position: -100px 0px;"></div></div>