shaka-player 4.3.3 → 4.3.4
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/.github/workflows/selenium-lab-tests.yaml +22 -0
- package/CHANGELOG.md +17 -0
- package/dist/deps.js +3 -2
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.debug.js +89 -84
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.js +649 -646
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.debug.js +101 -96
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +756 -753
- package/dist/shaka-player.ui.map +4 -4
- package/lib/dash/segment_template.js +17 -5
- package/lib/hls/hls_parser.js +6 -1
- package/lib/player.js +1 -1
- package/lib/polyfill/media_capabilities.js +4 -1
- package/lib/text/simple_text_displayer.js +2 -64
- package/lib/text/text_utils.js +88 -0
- package/lib/text/ui_text_displayer.js +0 -5
- package/lib/text/vtt_text_parser.js +224 -97
- package/lib/text/web_vtt_generator.js +2 -64
- package/lib/util/platform.js +8 -0
- package/package.json +1 -1
- package/support.html +1 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -36
- package/test/test/util/layout_tests.js +433 -0
- package/test/test/util/util.js +0 -120
- package/test/{ui → text}/text_displayer_layout_unit.js +59 -235
- package/test/text/ui_text_displayer_unit.js +2 -4
- package/test/text/vtt_text_parser_unit.js +114 -8
- package/test/text/web_vtt_layout_integration.js +528 -0
|
@@ -4,98 +4,30 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const UiUtils = shaka.test.UiUtils;
|
|
11
|
-
const Util = shaka.test.Util;
|
|
12
|
-
|
|
13
|
-
/** @type {!shaka.extern.TextDisplayer} */
|
|
14
|
-
let textDisplayer;
|
|
15
|
-
/**
|
|
16
|
-
* The video container or other element which is used for the screenshot.
|
|
17
|
-
* @type {!HTMLElement}
|
|
18
|
-
*/
|
|
19
|
-
let videoContainer;
|
|
20
|
-
/**
|
|
21
|
-
* Awaited before each screenshot, and can vary by test suite.
|
|
22
|
-
* @type {function(number):!Promise}
|
|
23
|
-
*/
|
|
24
|
-
let beforeScreenshot;
|
|
25
|
-
|
|
26
|
-
// A minimum similarity score for screenshots, between 0 and 1.
|
|
27
|
-
const minSimilarity = 0.95;
|
|
28
|
-
|
|
29
|
-
const originalCast = window.chrome && window.chrome.cast;
|
|
30
|
-
|
|
7
|
+
filterDescribe('Cue layout', shaka.test.TextLayoutTests.supported, () => {
|
|
8
|
+
/** @type {shaka.test.TextLayoutTests} */
|
|
9
|
+
let helper;
|
|
31
10
|
|
|
32
11
|
describe('using UI', () => {
|
|
33
|
-
/** @type {!HTMLLinkElement} */
|
|
34
|
-
let cssLink;
|
|
35
|
-
/** @type {!shaka.test.FakeVideo} */
|
|
36
|
-
let mockVideo;
|
|
37
|
-
|
|
38
|
-
function createTextDisplayer() {
|
|
39
|
-
textDisplayer = new shaka.text.UITextDisplayer(
|
|
40
|
-
/** @type {!HTMLMediaElement} */(mockVideo),
|
|
41
|
-
videoContainer);
|
|
42
|
-
textDisplayer.setTextVisibility(true);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
12
|
beforeAll(async () => {
|
|
46
|
-
|
|
47
|
-
if (window.chrome) {
|
|
48
|
-
window.chrome['cast'] = null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Add css file
|
|
52
|
-
cssLink = /** @type {!HTMLLinkElement} */(document.createElement('link'));
|
|
53
|
-
await UiUtils.setupCSS(cssLink);
|
|
54
|
-
|
|
55
|
-
// There's no actual video inside this container, but subtitles will be
|
|
56
|
-
// positioned within this space.
|
|
57
|
-
videoContainer = /** @type {!HTMLElement} */(
|
|
58
|
-
document.createElement('div'));
|
|
59
|
-
document.body.appendChild(videoContainer);
|
|
60
|
-
|
|
61
|
-
positionElementForScreenshot(videoContainer);
|
|
13
|
+
helper = new shaka.test.DomTextLayoutTests('text-displayer-ui');
|
|
62
14
|
|
|
63
|
-
|
|
64
|
-
// this explicitly, since we don't instantiate controls in all of the
|
|
65
|
-
// tests.
|
|
66
|
-
videoContainer.classList.add('shaka-video-container');
|
|
67
|
-
|
|
68
|
-
await Util.waitForFont('Roboto');
|
|
69
|
-
|
|
70
|
-
// eslint-disable-next-line require-await
|
|
71
|
-
beforeScreenshot = async (time) => {
|
|
72
|
-
// Set the faked time.
|
|
73
|
-
mockVideo.currentTime = time;
|
|
74
|
-
|
|
75
|
-
// Trigger the display update logic to notice the time change by
|
|
76
|
-
// appending an empty array.
|
|
77
|
-
textDisplayer.append([]);
|
|
78
|
-
};
|
|
15
|
+
await helper.beforeAll();
|
|
79
16
|
});
|
|
80
17
|
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
|
|
83
|
-
createTextDisplayer();
|
|
18
|
+
beforeEach(async () => {
|
|
19
|
+
await helper.beforeEach();
|
|
84
20
|
});
|
|
85
21
|
|
|
86
22
|
afterEach(async () => {
|
|
87
|
-
await
|
|
23
|
+
await helper.afterEach();
|
|
88
24
|
});
|
|
89
25
|
|
|
90
|
-
afterAll(() => {
|
|
91
|
-
|
|
92
|
-
document.head.removeChild(cssLink);
|
|
93
|
-
if (window.chrome) {
|
|
94
|
-
window.chrome['cast'] = originalCast;
|
|
95
|
-
}
|
|
26
|
+
afterAll(async () => {
|
|
27
|
+
await helper.afterAll();
|
|
96
28
|
});
|
|
97
29
|
|
|
98
|
-
defineTests(
|
|
30
|
+
defineTests();
|
|
99
31
|
|
|
100
32
|
// This test is unique to the UI.
|
|
101
33
|
it('moves cues to avoid controls', async () => {
|
|
@@ -107,7 +39,8 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
107
39
|
// DOM and is purely temporary.
|
|
108
40
|
const player = new shaka.Player(null);
|
|
109
41
|
ui = new shaka.ui.Overlay(
|
|
110
|
-
player,
|
|
42
|
+
player, /** @type {!HTMLElement} */(helper.videoContainer),
|
|
43
|
+
shaka.test.UiUtils.createVideoElement());
|
|
111
44
|
// Turn off every part of the UI that we can, so that the screenshot is
|
|
112
45
|
// less likey to change because of something unrelated to text
|
|
113
46
|
// rendering.
|
|
@@ -119,8 +52,8 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
119
52
|
// Recreate the text displayer so that the text container comes after
|
|
120
53
|
// the controls (as it does in production). This is important for the
|
|
121
54
|
// CSS that moves the cues above the controls when they are shown.
|
|
122
|
-
await textDisplayer.destroy();
|
|
123
|
-
|
|
55
|
+
await helper.textDisplayer.destroy();
|
|
56
|
+
helper.recreateTextDisplayer();
|
|
124
57
|
|
|
125
58
|
const cue = new shaka.text.Cue(
|
|
126
59
|
0, 1, 'Captain\'s log, stardate 41636.9');
|
|
@@ -130,133 +63,61 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
130
63
|
cue.region.viewportAnchorY = 90; // %
|
|
131
64
|
cue.region.width = 100; // %
|
|
132
65
|
cue.region.height = 10; // %
|
|
133
|
-
textDisplayer.append([cue]);
|
|
66
|
+
helper.textDisplayer.append([cue]);
|
|
134
67
|
|
|
135
|
-
await checkScreenshot('
|
|
68
|
+
await helper.checkScreenshot('cue-with-controls');
|
|
136
69
|
} finally {
|
|
137
70
|
await ui.destroy();
|
|
138
71
|
}
|
|
139
72
|
});
|
|
140
73
|
});
|
|
141
74
|
|
|
142
|
-
|
|
143
75
|
describe('using browser-native rendering', () => {
|
|
144
|
-
/** @type {!HTMLVideoElement} */
|
|
145
|
-
let video;
|
|
146
|
-
|
|
147
76
|
beforeAll(async () => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// button overlayed if this isn't set.
|
|
152
|
-
video.disableRemotePlayback = true;
|
|
153
|
-
|
|
154
|
-
document.body.appendChild(video);
|
|
155
|
-
|
|
156
|
-
positionElementForScreenshot(video);
|
|
157
|
-
|
|
158
|
-
const eventManager = new shaka.util.EventManager();
|
|
159
|
-
const waiter = new shaka.test.Waiter(eventManager);
|
|
160
|
-
const canPlay = waiter.failOnTimeout(false).timeoutAfter(10)
|
|
161
|
-
.waitForEvent(video, 'canplay');
|
|
162
|
-
|
|
163
|
-
// Video content is required to show native subtitles. This is a small
|
|
164
|
-
// green frame.
|
|
165
|
-
video.src = '/base/test/test/assets/green-pixel.mp4';
|
|
166
|
-
await canPlay;
|
|
167
|
-
expect(video.duration).toBeGreaterThan(0);
|
|
168
|
-
expect(video.videoWidth).toBeGreaterThan(0);
|
|
169
|
-
|
|
170
|
-
// There is no actual container. Screenshots will be taken of the video
|
|
171
|
-
// element itself.
|
|
172
|
-
videoContainer = video;
|
|
173
|
-
|
|
174
|
-
// On Firefox, Safari, and legacy Edge, the video must be played a little
|
|
175
|
-
// _after_ appending cues in order to consistently show subtitles
|
|
176
|
-
// natively on the video element.
|
|
177
|
-
beforeScreenshot = async (time) => {
|
|
178
|
-
// Seek to the beginning so that we can reasonably wait for movement
|
|
179
|
-
// after playing below. If somehow the playhead ends up at the end of
|
|
180
|
-
// the video, we should seek back before we play.
|
|
181
|
-
video.currentTime = 0;
|
|
182
|
-
|
|
183
|
-
// The video must be played a little now, after the cues were appended,
|
|
184
|
-
// but before the screenshot.
|
|
185
|
-
video.playbackRate = 1;
|
|
186
|
-
video.play();
|
|
187
|
-
await waiter.failOnTimeout(false).timeoutAfter(5)
|
|
188
|
-
.waitForMovement(video);
|
|
189
|
-
video.pause();
|
|
190
|
-
|
|
191
|
-
// Seek to a time when cues should be showing.
|
|
192
|
-
video.currentTime = time;
|
|
193
|
-
// Get into a playing state, but without movement.
|
|
194
|
-
video.playbackRate = 0;
|
|
195
|
-
video.play();
|
|
196
|
-
|
|
197
|
-
// Add a short delay to ensure that the system has caught up and that
|
|
198
|
-
// native text displayers have been updated by the browser.
|
|
199
|
-
await Util.delay(0.1);
|
|
200
|
-
};
|
|
77
|
+
helper = new shaka.test.NativeTextLayoutTests('text-displayer-native');
|
|
78
|
+
|
|
79
|
+
await helper.beforeAll();
|
|
201
80
|
});
|
|
202
81
|
|
|
203
|
-
beforeEach(() => {
|
|
204
|
-
|
|
205
|
-
textDisplayer.setTextVisibility(true);
|
|
82
|
+
beforeEach(async () => {
|
|
83
|
+
await helper.beforeEach();
|
|
206
84
|
});
|
|
207
85
|
|
|
208
86
|
afterEach(async () => {
|
|
209
|
-
await
|
|
87
|
+
await helper.afterEach();
|
|
210
88
|
});
|
|
211
89
|
|
|
212
|
-
afterAll(() => {
|
|
213
|
-
|
|
90
|
+
afterAll(async () => {
|
|
91
|
+
await helper.afterAll();
|
|
214
92
|
});
|
|
215
93
|
|
|
216
|
-
defineTests(
|
|
94
|
+
defineTests();
|
|
217
95
|
});
|
|
218
96
|
|
|
219
|
-
|
|
220
|
-
/** @param {string} prefix Prepended to screenshot names */
|
|
221
|
-
function defineTests(prefix) {
|
|
222
|
-
// Due to a Safari implementation bug, the browser only does the correct
|
|
223
|
-
// thing for "end-time-edge-case" on Safari 16+. Skip the tests on earlier
|
|
224
|
-
// versions.
|
|
225
|
-
const safariVersion = shaka.util.Platform.safariVersion();
|
|
226
|
-
if (prefix == 'native' && safariVersion && safariVersion < 16) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Due to updates in the rendering and/or default styles in Chrome, the
|
|
231
|
-
// screenshots for native rendering only match in Chrome 106+.
|
|
232
|
-
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
233
|
-
if (prefix == 'native' && chromeVersion && chromeVersion < 106) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
97
|
+
function defineTests() {
|
|
237
98
|
it('basic cue', async () => {
|
|
238
|
-
textDisplayer.append([
|
|
99
|
+
helper.textDisplayer.append([
|
|
239
100
|
new shaka.text.Cue(0, 1, 'Captain\'s log, stardate 41636.9'),
|
|
240
101
|
]);
|
|
241
102
|
|
|
242
|
-
await checkScreenshot(
|
|
103
|
+
await helper.checkScreenshot('basic-cue');
|
|
243
104
|
});
|
|
244
105
|
|
|
245
106
|
it('cue with newline', async () => {
|
|
246
|
-
textDisplayer.append([
|
|
107
|
+
helper.textDisplayer.append([
|
|
247
108
|
new shaka.text.Cue(0, 1, 'Captain\'s log,\nstardate 41636.9'),
|
|
248
109
|
]);
|
|
249
110
|
|
|
250
|
-
await checkScreenshot(
|
|
111
|
+
await helper.checkScreenshot('cue-with-newline');
|
|
251
112
|
});
|
|
252
113
|
|
|
253
114
|
it('two basic cues', async () => {
|
|
254
|
-
textDisplayer.append([
|
|
115
|
+
helper.textDisplayer.append([
|
|
255
116
|
new shaka.text.Cue(0, 1, 'Captain\'s log,'),
|
|
256
117
|
new shaka.text.Cue(0, 1, 'stardate 41636.9'),
|
|
257
118
|
]);
|
|
258
119
|
|
|
259
|
-
await checkScreenshot(
|
|
120
|
+
await helper.checkScreenshot('two-basic-cues');
|
|
260
121
|
});
|
|
261
122
|
|
|
262
123
|
// Regression test for #2497
|
|
@@ -265,14 +126,14 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
265
126
|
// In reality, this occurs when a VTT cue crossed a segment boundary and
|
|
266
127
|
// appears in more than one segment. So we must simulate this with two
|
|
267
128
|
// calls to append().
|
|
268
|
-
textDisplayer.append([
|
|
129
|
+
helper.textDisplayer.append([
|
|
269
130
|
new shaka.text.Cue(0, 1, 'Captain\'s log, stardate 41636.9'),
|
|
270
131
|
]);
|
|
271
|
-
textDisplayer.append([
|
|
132
|
+
helper.textDisplayer.append([
|
|
272
133
|
new shaka.text.Cue(0, 1, 'Captain\'s log, stardate 41636.9'),
|
|
273
134
|
]);
|
|
274
135
|
|
|
275
|
-
await checkScreenshot(
|
|
136
|
+
await helper.checkScreenshot('duplicate-cues');
|
|
276
137
|
});
|
|
277
138
|
|
|
278
139
|
// Regression test for #3151
|
|
@@ -283,15 +144,15 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
283
144
|
// through the UI & DOM, we can always get the timing right.
|
|
284
145
|
it('cues ending exactly now', async () => {
|
|
285
146
|
// At time exactly 1, this cue should _not_ be displayed any more.
|
|
286
|
-
textDisplayer.append([
|
|
147
|
+
helper.textDisplayer.append([
|
|
287
148
|
new shaka.text.Cue(0, 1, 'This cue is over and gone.'),
|
|
288
149
|
]);
|
|
289
150
|
// At time exactly 1, this cue should _just_ be starting.
|
|
290
|
-
textDisplayer.append([
|
|
151
|
+
helper.textDisplayer.append([
|
|
291
152
|
new shaka.text.Cue(1, 2, 'This cue is just starting.'),
|
|
292
153
|
]);
|
|
293
154
|
|
|
294
|
-
await checkScreenshot(
|
|
155
|
+
await helper.checkScreenshot('end-time-edge-case', /* time= */ 1);
|
|
295
156
|
});
|
|
296
157
|
|
|
297
158
|
// Regression test for #2524
|
|
@@ -301,9 +162,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
301
162
|
new shaka.text.Cue(0, 1, 'Captain\'s log, '),
|
|
302
163
|
new shaka.text.Cue(0, 1, 'stardate 41636.9'),
|
|
303
164
|
];
|
|
304
|
-
textDisplayer.append([cue]);
|
|
165
|
+
helper.textDisplayer.append([cue]);
|
|
305
166
|
|
|
306
|
-
await checkScreenshot(
|
|
167
|
+
await helper.checkScreenshot('two-nested-cues');
|
|
307
168
|
});
|
|
308
169
|
|
|
309
170
|
// Distinct from "newline" test above, which has a literal \n character in
|
|
@@ -316,9 +177,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
316
177
|
shaka.text.Cue.lineBreak(0, 1),
|
|
317
178
|
new shaka.text.Cue(0, 1, 'stardate 41636.9'),
|
|
318
179
|
];
|
|
319
|
-
textDisplayer.append([cue]);
|
|
180
|
+
helper.textDisplayer.append([cue]);
|
|
320
181
|
|
|
321
|
-
await checkScreenshot(
|
|
182
|
+
await helper.checkScreenshot('nested-cues-with-linebreak');
|
|
322
183
|
});
|
|
323
184
|
|
|
324
185
|
// Regression test for #3600
|
|
@@ -326,9 +187,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
326
187
|
const cue = new shaka.text.Cue(0, 1, 'Text');
|
|
327
188
|
cue.line = 10;
|
|
328
189
|
cue.lineInterpretation = shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
329
|
-
textDisplayer.append([cue]);
|
|
190
|
+
helper.textDisplayer.append([cue]);
|
|
330
191
|
|
|
331
|
-
await checkScreenshot(
|
|
192
|
+
await helper.checkScreenshot('cue-position');
|
|
332
193
|
});
|
|
333
194
|
|
|
334
195
|
// Regression test for #2157 and #2584
|
|
@@ -343,9 +204,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
343
204
|
cue.region.width = 30; // %
|
|
344
205
|
cue.region.height = 65; // %
|
|
345
206
|
cue.nestedCues = [nestedCue];
|
|
346
|
-
textDisplayer.append([cue]);
|
|
207
|
+
helper.textDisplayer.append([cue]);
|
|
347
208
|
|
|
348
|
-
await checkScreenshot(
|
|
209
|
+
await helper.checkScreenshot('region-position');
|
|
349
210
|
});
|
|
350
211
|
|
|
351
212
|
// Regression test for #3379, in which the displayAlign was not respected,
|
|
@@ -367,9 +228,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
367
228
|
// For those who don't speak Unicode, \xbf is an upside down "?".
|
|
368
229
|
new shaka.text.Cue(0, 1, '\xbfBien?'),
|
|
369
230
|
];
|
|
370
|
-
textDisplayer.append([cue]);
|
|
231
|
+
helper.textDisplayer.append([cue]);
|
|
371
232
|
|
|
372
|
-
await checkScreenshot(
|
|
233
|
+
await helper.checkScreenshot('region-with-display-alignment');
|
|
373
234
|
});
|
|
374
235
|
|
|
375
236
|
// Regression test for #2188
|
|
@@ -381,9 +242,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
381
242
|
cue.region.viewportAnchorY = 10; // %
|
|
382
243
|
// eslint-disable-next-line max-len
|
|
383
244
|
cue.backgroundImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAA8BAMAAABMVCNvAAAAElBMVEX9/vtRldU+uUv6vAnvNjWzvsvH461AAAABvUlEQVRIx7WWwY6CMBRFYQb2Nhn22sS9o5m9icy+aPn/X5lS6r221gfTxLsC0pN7XovE6j1p9d6UcB/apYTUU/YlhT7bArCwUocUg9sCsMxVF7i2Pwd3+v93/Ty5uEbZtVVd+nacphw08oJzMUmhzxWgyYHDBHbRo9sMHmVX5bOJTENyrq0rMjB1EUG61ipMBtBEYM41qakVXLk3eVdyagMQrqNB47ProO4hGCbu+/4MMHUlp6J2F8c58pR3bRVj/B1cm94nB2IlatSDq53BW8Z1i4UEed3PueQqhxTkA781L10JBb2aNwAvGdddAj66NhKon0C6onHZtXKhKxolVx46XbtyUHLdRaaxqyXISoBxYfQOftFVBPnZuSfrSpCFcBXAYwp2HlrtSrBi1BrXlFt2RSEGXOn6DRCc6EpQgYMoXGWQIbLsSpCizAOIABQ4yZVgV2VAwfXlgPJvi6DJgnUGvMEUA0qgBTh6cOCAsmsD8LdDIQYUKiuA50FdBwy4DFqAtXCCDMAGYEtOCDYBrgYfFfn/G0ALsAInVgYruIaHnQSxcroKI1ZrU9/PuQmmq9OO43xhhUI5jR3lBX8x/RKsZNOu/wAAAABJRU5ErkJggg==';
|
|
384
|
-
textDisplayer.append([cue]);
|
|
245
|
+
helper.textDisplayer.append([cue]);
|
|
385
246
|
|
|
386
|
-
await checkScreenshot(
|
|
247
|
+
await helper.checkScreenshot('bitmap-cue');
|
|
387
248
|
});
|
|
388
249
|
|
|
389
250
|
// Used to be a regression test for #2623, but that should have been fixed
|
|
@@ -405,9 +266,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
405
266
|
cue.nestedCues[2].backgroundColor = 'yellow';
|
|
406
267
|
cue.backgroundColor = 'purple';
|
|
407
268
|
|
|
408
|
-
textDisplayer.append([cue]);
|
|
269
|
+
helper.textDisplayer.append([cue]);
|
|
409
270
|
|
|
410
|
-
await checkScreenshot(
|
|
271
|
+
await helper.checkScreenshot('nested-cue-bg');
|
|
411
272
|
});
|
|
412
273
|
|
|
413
274
|
it('colors background for flat cues', async () => {
|
|
@@ -415,9 +276,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
415
276
|
// This is shown.
|
|
416
277
|
cue.backgroundColor = 'purple';
|
|
417
278
|
|
|
418
|
-
textDisplayer.append([cue]);
|
|
279
|
+
helper.textDisplayer.append([cue]);
|
|
419
280
|
|
|
420
|
-
await checkScreenshot(
|
|
281
|
+
await helper.checkScreenshot('flat-cue-bg');
|
|
421
282
|
});
|
|
422
283
|
|
|
423
284
|
// https://github.com/shaka-project/shaka-player/issues/2761
|
|
@@ -440,9 +301,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
440
301
|
]),
|
|
441
302
|
]);
|
|
442
303
|
|
|
443
|
-
textDisplayer.append([cue]);
|
|
304
|
+
helper.textDisplayer.append([cue]);
|
|
444
305
|
|
|
445
|
-
await checkScreenshot(
|
|
306
|
+
await helper.checkScreenshot('deeply-nested-cues');
|
|
446
307
|
});
|
|
447
308
|
|
|
448
309
|
// Regression test for #4567, in which "end" line alignment for VTT was
|
|
@@ -454,46 +315,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
454
315
|
cue.lineInterpretation = shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
455
316
|
cue.lineAlign = shaka.text.Cue.lineAlign.END;
|
|
456
317
|
|
|
457
|
-
textDisplayer.append([cue]);
|
|
318
|
+
helper.textDisplayer.append([cue]);
|
|
458
319
|
|
|
459
|
-
await checkScreenshot(
|
|
320
|
+
await helper.checkScreenshot('line-alignment');
|
|
460
321
|
});
|
|
461
322
|
}
|
|
462
|
-
|
|
463
|
-
/** @param {!HTMLElement} element */
|
|
464
|
-
function positionElementForScreenshot(element) {
|
|
465
|
-
// The element we screenshot will be 16:9 and small.
|
|
466
|
-
element.style.width = '320px';
|
|
467
|
-
element.style.height = '180px';
|
|
468
|
-
|
|
469
|
-
// The background is green so we can better see the background color of
|
|
470
|
-
// the text spans within the subtitles, and so it is easier to identify
|
|
471
|
-
// cropping issues.
|
|
472
|
-
element.style.backgroundColor = 'green';
|
|
473
|
-
|
|
474
|
-
// Make sure the element is in the top-left corner of the iframe that
|
|
475
|
-
// contains the tests.
|
|
476
|
-
element.style.top = '0';
|
|
477
|
-
element.style.left = '0';
|
|
478
|
-
element.style.position = 'fixed';
|
|
479
|
-
element.style.margin = '0';
|
|
480
|
-
element.style.padding = '0';
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* @param {string} prefix A prefix added to the screenshot name with a hyphen
|
|
485
|
-
* to provide context.
|
|
486
|
-
* @param {string} baseName The base name of the screenshot.
|
|
487
|
-
* @param {number=} time The time to seek to in the screenshot. Defaults to
|
|
488
|
-
* 0.1, when most of our tests will be showing cues (timed 0-1).
|
|
489
|
-
* @return {!Promise}
|
|
490
|
-
*/
|
|
491
|
-
async function checkScreenshot(prefix, baseName, time=0.1) {
|
|
492
|
-
await beforeScreenshot(time);
|
|
493
|
-
|
|
494
|
-
return Util.checkScreenshot(
|
|
495
|
-
/* element= */ videoContainer,
|
|
496
|
-
prefix + '-' + baseName,
|
|
497
|
-
minSimilarity);
|
|
498
|
-
}
|
|
499
323
|
});
|
|
@@ -338,15 +338,13 @@ describe('UITextDisplayer', () => {
|
|
|
338
338
|
it('hides and shows nested cues at appropriate times', () => {
|
|
339
339
|
const parentCue1 = new shaka.text.Cue(0, 100, '');
|
|
340
340
|
const cue1 = new shaka.text.Cue(0, 50, 'One');
|
|
341
|
-
parentCue1.nestedCues.push(cue1);
|
|
342
341
|
const cue2 = new shaka.text.Cue(25, 75, 'Two');
|
|
343
|
-
parentCue1.nestedCues.push(cue2);
|
|
344
342
|
const cue3 = new shaka.text.Cue(50, 100, 'Three');
|
|
345
|
-
parentCue1.nestedCues
|
|
343
|
+
parentCue1.nestedCues = [cue1, cue2, cue3];
|
|
346
344
|
|
|
347
345
|
const parentCue2 = new shaka.text.Cue(90, 190, '');
|
|
348
346
|
const cue4 = new shaka.text.Cue(90, 130, 'Four');
|
|
349
|
-
parentCue2.nestedCues
|
|
347
|
+
parentCue2.nestedCues = [cue4];
|
|
350
348
|
|
|
351
349
|
textDisplayer.setTextVisibility(true);
|
|
352
350
|
textDisplayer.append([parentCue1, parentCue2]);
|
|
@@ -852,11 +852,11 @@ describe('VttTextParser', () => {
|
|
|
852
852
|
it('support escaped html payload', () => {
|
|
853
853
|
verifyHelper(
|
|
854
854
|
[
|
|
855
|
-
{startTime: 20.1, endTime: 40.505, payload: '"Test & 1"'},
|
|
855
|
+
{startTime: 20.1, endTime: 40.505, payload: '"Test & 1"\u{a0}'},
|
|
856
856
|
],
|
|
857
857
|
'WEBVTT\n\n' +
|
|
858
858
|
'00:00:20.100 --> 00:00:40.505\n' +
|
|
859
|
-
'"Test & 1"',
|
|
859
|
+
'"Test & 1" ',
|
|
860
860
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
861
861
|
});
|
|
862
862
|
|
|
@@ -997,25 +997,32 @@ describe('VttTextParser', () => {
|
|
|
997
997
|
{
|
|
998
998
|
startTime: 80,
|
|
999
999
|
endTime: 90,
|
|
1000
|
-
payload: '<b><c.lime>Parse fail 1</b></c>',
|
|
1000
|
+
payload: '<b><c.lime>Parse fail 1</b></c.lime>',
|
|
1001
1001
|
nestedCues: [],
|
|
1002
1002
|
},
|
|
1003
1003
|
{
|
|
1004
1004
|
startTime: 90,
|
|
1005
1005
|
endTime: 100,
|
|
1006
|
-
payload: '<c.lime><b>Parse fail 2</c></b>',
|
|
1006
|
+
payload: '<c.lime><b>Parse fail 2</c.lime></b>',
|
|
1007
1007
|
nestedCues: [],
|
|
1008
1008
|
},
|
|
1009
1009
|
{
|
|
1010
1010
|
startTime: 100,
|
|
1011
1011
|
endTime: 110,
|
|
1012
|
-
payload: '
|
|
1013
|
-
nestedCues: [
|
|
1012
|
+
payload: '',
|
|
1013
|
+
nestedCues: [
|
|
1014
|
+
{
|
|
1015
|
+
startTime: 100,
|
|
1016
|
+
endTime: 110,
|
|
1017
|
+
payload: 'forward slash 1/2 in text',
|
|
1018
|
+
color: '#0F0',
|
|
1019
|
+
},
|
|
1020
|
+
],
|
|
1014
1021
|
},
|
|
1015
1022
|
{
|
|
1016
1023
|
startTime: 110,
|
|
1017
1024
|
endTime: 120,
|
|
1018
|
-
payload: '<c.lime>less or more < > in text</c>',
|
|
1025
|
+
payload: '<c.lime>less or more < > in text</c.lime>',
|
|
1019
1026
|
nestedCues: [],
|
|
1020
1027
|
},
|
|
1021
1028
|
],
|
|
@@ -1067,6 +1074,53 @@ describe('VttTextParser', () => {
|
|
|
1067
1074
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1068
1075
|
});
|
|
1069
1076
|
|
|
1077
|
+
it('supports voice style blocks', () => {
|
|
1078
|
+
verifyHelper(
|
|
1079
|
+
[
|
|
1080
|
+
{
|
|
1081
|
+
startTime: 20,
|
|
1082
|
+
endTime: 40,
|
|
1083
|
+
payload: '',
|
|
1084
|
+
nestedCues: [
|
|
1085
|
+
{
|
|
1086
|
+
startTime: 20,
|
|
1087
|
+
endTime: 40,
|
|
1088
|
+
payload: 'Test',
|
|
1089
|
+
color: 'cyan',
|
|
1090
|
+
},
|
|
1091
|
+
],
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
startTime: 40,
|
|
1095
|
+
endTime: 50,
|
|
1096
|
+
payload: '',
|
|
1097
|
+
nestedCues: [
|
|
1098
|
+
{
|
|
1099
|
+
startTime: 40,
|
|
1100
|
+
endTime: 50,
|
|
1101
|
+
payload: 'Test',
|
|
1102
|
+
color: 'red',
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
startTime: 40,
|
|
1106
|
+
endTime: 50,
|
|
1107
|
+
payload: '2',
|
|
1108
|
+
fontStyle: Cue.fontStyle.ITALIC,
|
|
1109
|
+
},
|
|
1110
|
+
],
|
|
1111
|
+
},
|
|
1112
|
+
],
|
|
1113
|
+
'WEBVTT\n\n' +
|
|
1114
|
+
'STYLE\n' +
|
|
1115
|
+
'::cue(v[voice="Shaka"]) { color: cyan; }\n' +
|
|
1116
|
+
'::cue(v[voice=ShakaBis]) { color: red; }\n\n' +
|
|
1117
|
+
'00:00:20.000 --> 00:00:40.000\n' +
|
|
1118
|
+
'<v Shaka>Test\n\n' +
|
|
1119
|
+
'00:00:40.000 --> 00:00:50.000\n' +
|
|
1120
|
+
'<v ShakaBis>Test</v><i>2</i>',
|
|
1121
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1070
1124
|
it('supports default color overriding', () => {
|
|
1071
1125
|
verifyHelper(
|
|
1072
1126
|
[
|
|
@@ -1087,12 +1141,64 @@ describe('VttTextParser', () => {
|
|
|
1087
1141
|
],
|
|
1088
1142
|
'WEBVTT\n\n' +
|
|
1089
1143
|
'STYLE\n' +
|
|
1090
|
-
'::cue(bg_blue) { font-size: 10px; background-color: #FF0 }\n\n' +
|
|
1144
|
+
'::cue(.bg_blue) { font-size: 10px; background-color: #FF0 }\n\n' +
|
|
1091
1145
|
'00:00:10.000 --> 00:00:20.000\n' +
|
|
1092
1146
|
'<c.red.bg_blue>Example 1</c>\n\n',
|
|
1093
1147
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1094
1148
|
});
|
|
1095
1149
|
|
|
1150
|
+
// https://github.com/shaka-project/shaka-player/issues/4479
|
|
1151
|
+
it('keep styles when there are line breaks', () => {
|
|
1152
|
+
verifyHelper(
|
|
1153
|
+
[
|
|
1154
|
+
{
|
|
1155
|
+
startTime: 10, endTime: 20,
|
|
1156
|
+
payload: '',
|
|
1157
|
+
nestedCues: [
|
|
1158
|
+
{
|
|
1159
|
+
startTime: 10,
|
|
1160
|
+
endTime: 20,
|
|
1161
|
+
payload: '1',
|
|
1162
|
+
color: '#F0F',
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
startTime: 10,
|
|
1166
|
+
endTime: 20,
|
|
1167
|
+
payload: '',
|
|
1168
|
+
lineBreak: true,
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
startTime: 10,
|
|
1172
|
+
endTime: 20,
|
|
1173
|
+
payload: '2',
|
|
1174
|
+
color: '#F0F',
|
|
1175
|
+
fontStyle: Cue.fontStyle.ITALIC,
|
|
1176
|
+
},
|
|
1177
|
+
],
|
|
1178
|
+
},
|
|
1179
|
+
],
|
|
1180
|
+
'WEBVTT\n\n' +
|
|
1181
|
+
'00:00:10.000 --> 00:00:20.000\n' +
|
|
1182
|
+
'<c.magenta>1</c><br/><c.magenta><i>2</i></c>\n\n',
|
|
1183
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
it('does not fail on REGION blocks', () => {
|
|
1187
|
+
verifyHelper(
|
|
1188
|
+
[
|
|
1189
|
+
{
|
|
1190
|
+
startTime: 10, endTime: 20,
|
|
1191
|
+
payload: 'test',
|
|
1192
|
+
},
|
|
1193
|
+
],
|
|
1194
|
+
'WEBVTT\n\n' +
|
|
1195
|
+
'REGION\n' +
|
|
1196
|
+
'id:1\n\n' +
|
|
1197
|
+
'00:00:10.000 --> 00:00:20.000\n' +
|
|
1198
|
+
'test\n\n',
|
|
1199
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1096
1202
|
/**
|
|
1097
1203
|
* @param {!Array} cues
|
|
1098
1204
|
* @param {string} text
|