shaka-player 3.3.16 → 3.3.18

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.
Files changed (68) hide show
  1. package/.github/workflows/build-and-test.yaml +4 -4
  2. package/.github/workflows/demo-version-index.yaml +6 -0
  3. package/.github/workflows/selenium-lab-tests.yaml +72 -11
  4. package/.github/workflows/update-screenshots.yaml +142 -0
  5. package/CHANGELOG.md +38 -0
  6. package/demo/common/asset.js +15 -0
  7. package/demo/common/assets.js +4 -2
  8. package/demo/common/message_ids.js +1 -0
  9. package/demo/custom.js +19 -0
  10. package/demo/locales/en.json +1 -0
  11. package/demo/locales/source.json +4 -0
  12. package/demo/main.js +14 -0
  13. package/dist/demo.compiled.debug.js +146 -144
  14. package/dist/demo.compiled.debug.map +3 -3
  15. package/dist/demo.compiled.js +146 -144
  16. package/dist/demo.compiled.map +3 -3
  17. package/dist/deps.js +1 -1
  18. package/dist/locales.js +28 -28
  19. package/dist/receiver.compiled.debug.js +15 -15
  20. package/dist/receiver.compiled.debug.map +2 -2
  21. package/dist/receiver.compiled.js +15 -15
  22. package/dist/receiver.compiled.map +2 -2
  23. package/dist/shaka-player.compiled.d.ts +12 -0
  24. package/dist/shaka-player.compiled.debug.d.ts +12 -0
  25. package/dist/shaka-player.compiled.debug.externs.js +4 -0
  26. package/dist/shaka-player.compiled.debug.js +105 -100
  27. package/dist/shaka-player.compiled.debug.map +3 -3
  28. package/dist/shaka-player.compiled.externs.js +4 -0
  29. package/dist/shaka-player.compiled.js +296 -292
  30. package/dist/shaka-player.compiled.map +3 -3
  31. package/dist/shaka-player.ui.d.ts +12 -0
  32. package/dist/shaka-player.ui.debug.d.ts +12 -0
  33. package/dist/shaka-player.ui.debug.externs.js +4 -0
  34. package/dist/shaka-player.ui.debug.js +119 -114
  35. package/dist/shaka-player.ui.debug.map +3 -3
  36. package/dist/shaka-player.ui.externs.js +4 -0
  37. package/dist/shaka-player.ui.js +311 -307
  38. package/dist/shaka-player.ui.map +3 -3
  39. package/docs/tutorials/errors.md +94 -0
  40. package/docs/tutorials/index.json +2 -0
  41. package/docs/tutorials/widevine-service-certs.md +45 -0
  42. package/externs/ima.js +9 -0
  43. package/externs/shaka/text.js +7 -0
  44. package/lib/ads/client_side_ad_manager.js +6 -3
  45. package/lib/dash/segment_template.js +17 -5
  46. package/lib/hls/hls_parser.js +3 -1
  47. package/lib/media/transmuxer.js +13 -7
  48. package/lib/media/video_wrapper.js +3 -3
  49. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  50. package/lib/player.js +3 -1
  51. package/lib/polyfill/media_capabilities.js +3 -8
  52. package/lib/polyfill/mediasource.js +7 -2
  53. package/lib/text/cue.js +6 -0
  54. package/lib/text/ui_text_displayer.js +2 -5
  55. package/lib/text/vtt_text_parser.js +257 -93
  56. package/lib/util/mime_utils.js +1 -1
  57. package/lib/util/platform.js +8 -0
  58. package/lib/util/stream_utils.js +26 -14
  59. package/package.json +1 -1
  60. package/support.html +1 -0
  61. package/test/dash/dash_parser_manifest_unit.js +0 -36
  62. package/test/polyfill/media_capabilities_unit.js +20 -22
  63. package/test/test/util/layout_tests.js +433 -0
  64. package/test/test/util/util.js +0 -120
  65. package/test/{ui → text}/text_displayer_layout_unit.js +59 -235
  66. package/test/text/ui_text_displayer_unit.js +2 -4
  67. package/test/text/vtt_text_parser_unit.js +151 -6
  68. package/test/text/web_vtt_layout_integration.js +525 -0
@@ -0,0 +1,525 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
8
+ /** @type {shaka.test.TextLayoutTests} */
9
+ let helper;
10
+
11
+ describe('using UI', () => {
12
+ beforeAll(async () => {
13
+ helper = new shaka.test.DomTextLayoutTests('webvtt-ui');
14
+
15
+ await helper.beforeAll();
16
+ });
17
+
18
+ beforeEach(async () => {
19
+ await helper.beforeEach();
20
+ });
21
+
22
+ afterEach(async () => {
23
+ await helper.afterEach();
24
+ });
25
+
26
+ afterAll(async () => {
27
+ await helper.afterAll();
28
+ });
29
+
30
+ defineTests();
31
+ });
32
+
33
+ describe('using browser-native rendering', () => {
34
+ beforeAll(async () => {
35
+ helper = new shaka.test.NativeTextLayoutTests('webvtt-native');
36
+
37
+ await helper.beforeAll();
38
+ });
39
+
40
+ beforeEach(async () => {
41
+ await helper.beforeEach();
42
+ });
43
+
44
+ afterEach(async () => {
45
+ await helper.afterEach();
46
+ });
47
+
48
+ afterAll(async () => {
49
+ await helper.afterAll();
50
+ });
51
+
52
+ defineTests();
53
+ });
54
+
55
+ function defineTests() {
56
+ // The initial set of tests here were a subset of the official test suite:
57
+ // https://github.com/web-platform-tests/wpt/tree/master/webvtt/rendering/cues-with-video/processing-model
58
+
59
+ it('align center', async () => {
60
+ parseAndDisplay([
61
+ 'WEBVTT\n',
62
+ '\n',
63
+ '00:00:00.000 --> 00:00:05.000 align:center\n',
64
+ 'This is a test\n',
65
+ ].join(''));
66
+
67
+ await helper.checkScreenshot('align-center');
68
+ });
69
+
70
+ // FIXME: UI version is slightly wrong: black background should hug text
71
+ it('align center long', async () => {
72
+ parseAndDisplay([
73
+ 'WEBVTT\n',
74
+ '\n',
75
+ '00:00:00.000 --> 00:00:05.000 align:center\n',
76
+ 'This is a test subtitle that most likely will span over several ',
77
+ 'rows since it is a pretty long cue with a lot of text.\n',
78
+ ].join(''));
79
+
80
+ await helper.checkScreenshot('align-center-long');
81
+ });
82
+
83
+ it('align center position 50%', async () => {
84
+ parseAndDisplay([
85
+ 'WEBVTT\n',
86
+ '\n',
87
+ '00:00:00.000 --> 00:00:05.000 align:center position:50%\n',
88
+ 'This is a test\n',
89
+ ].join(''));
90
+
91
+ await helper.checkScreenshot('align-center-position-50');
92
+ });
93
+
94
+ // FIXME: UI version is wrong: not positioned on the right
95
+ it('align center position 90%', async () => {
96
+ parseAndDisplay([
97
+ 'WEBVTT\n',
98
+ '\n',
99
+ '00:00:00.000 --> 00:00:05.000 align:center position:90%\n',
100
+ 'This is a test\n',
101
+ ].join(''));
102
+
103
+ await helper.checkScreenshot('align-center-position-90');
104
+ });
105
+
106
+ // FIXME: UI version is wrong: not positioned on the left
107
+ it('align center position 10%', async () => {
108
+ parseAndDisplay([
109
+ 'WEBVTT\n',
110
+ '\n',
111
+ '00:00:00.000 --> 00:00:05.000 align:center position:10%\n',
112
+ 'This is a test\n',
113
+ ].join(''));
114
+
115
+ await helper.checkScreenshot('align-center-position-10');
116
+ });
117
+
118
+ // FIXME: UI version is wrong: not positioned on the left
119
+ it('align center position 10% size 10%', async () => {
120
+ parseAndDisplay([
121
+ 'WEBVTT\n',
122
+ '\n',
123
+ '00:00:00.000 --> 00:00:05.000 align:center position:10% size:10%\n',
124
+ 'This is a test\n',
125
+ ].join(''));
126
+
127
+ await helper.checkScreenshot('align-center-position-10-size-10');
128
+ });
129
+
130
+ // FIXME: UI version is wrong: not positioned on the right
131
+ it('align end', async () => {
132
+ parseAndDisplay([
133
+ 'WEBVTT\n',
134
+ '\n',
135
+ '00:00:00.000 --> 00:00:05.000 align:end\n',
136
+ 'This is a test\n',
137
+ ].join(''));
138
+
139
+ await helper.checkScreenshot('align-end');
140
+ });
141
+
142
+ // FIXME: UI version is slightly wrong: black background should hug text
143
+ it('align end long', async () => {
144
+ parseAndDisplay([
145
+ 'WEBVTT\n',
146
+ '\n',
147
+ '00:00:00.000 --> 00:00:05.000 align:end\n',
148
+ 'This is a test subtitle that most likely will span over several ',
149
+ 'rows since it is a pretty long cue with a lot of text.\n',
150
+ ].join(''));
151
+
152
+ await helper.checkScreenshot('align-end-long');
153
+ });
154
+
155
+ // FIXME: UI version is wrong: not positioned on the left
156
+ it('align start', async () => {
157
+ parseAndDisplay([
158
+ 'WEBVTT\n',
159
+ '\n',
160
+ '00:00:00.000 --> 00:00:05.000 align:start\n',
161
+ 'This is a test\n',
162
+ ].join(''));
163
+
164
+ await helper.checkScreenshot('align-start');
165
+ });
166
+
167
+ // FIXME: UI version is slightly wrong: black background should hug text
168
+ it('align start long', async () => {
169
+ parseAndDisplay([
170
+ 'WEBVTT\n',
171
+ '\n',
172
+ '00:00:00.000 --> 00:00:05.000 align:start\n',
173
+ 'This is a test subtitle that most likely will span over several ',
174
+ 'rows since it is a pretty long cue with a lot of text.\n',
175
+ ].join(''));
176
+
177
+ await helper.checkScreenshot('align-start-long');
178
+ });
179
+
180
+ // FIXME: both versions are wrong, top-left corner should be centered
181
+ it('align with position and line', async () => {
182
+ parseAndDisplay([
183
+ 'WEBVTT\n',
184
+ '\n',
185
+ '00:00:00.000 --> 00:00:05.000 ', // continued on next line
186
+ 'align:start position:50%,line-left line:50%,start\n',
187
+ 'This is a test\n',
188
+ ].join(''));
189
+
190
+ await helper.checkScreenshot('align-position-line');
191
+ });
192
+
193
+ it('size 50%', async () => {
194
+ parseAndDisplay([
195
+ 'WEBVTT\n',
196
+ '\n',
197
+ '00:00:00.000 --> 00:00:05.000 size:50%\n',
198
+ 'This is a test subtitle that should wrap no matter what\n',
199
+ ].join(''));
200
+
201
+ await helper.checkScreenshot('size-50');
202
+ });
203
+
204
+ // FIXME: UI version is wrong: not positioned by line
205
+ it('line -2', async () => {
206
+ parseAndDisplay([
207
+ 'WEBVTT\n',
208
+ '\n',
209
+ '00:00:00.000 --> 00:00:05.000 line:-2\n',
210
+ 'This is a test\n',
211
+ ].join(''));
212
+
213
+ await helper.checkScreenshot('line-negative-2');
214
+ });
215
+
216
+ // FIXME: UI version is wrong: not positioned by line
217
+ it('line 0', async () => {
218
+ parseAndDisplay([
219
+ 'WEBVTT\n',
220
+ '\n',
221
+ '00:00:00.000 --> 00:00:05.000 line:0\n',
222
+ 'This is a test\n',
223
+ ].join(''));
224
+
225
+ await helper.checkScreenshot('line-0');
226
+ });
227
+
228
+ // FIXME: UI version is wrong: not positioned by line
229
+ it('line 1', async () => {
230
+ parseAndDisplay([
231
+ 'WEBVTT\n',
232
+ '\n',
233
+ '00:00:00.000 --> 00:00:05.000 line:1\n',
234
+ 'This is a test\n',
235
+ ].join(''));
236
+
237
+ await helper.checkScreenshot('line-1');
238
+ });
239
+
240
+ it('line 50%', async () => {
241
+ parseAndDisplay([
242
+ 'WEBVTT\n',
243
+ '\n',
244
+ '00:00:00.000 --> 00:00:05.000 line:50%\n',
245
+ 'This is a test\n',
246
+ ].join(''));
247
+
248
+ await helper.checkScreenshot('line-50');
249
+ });
250
+
251
+ // Regression case for http://b/259121343
252
+ // The top center of the cue box should be 85% from the top and
253
+ // horizontally centered.
254
+ // NOTE: The native version is wrong on Chrome and Edge due to layout bugs
255
+ // in Chrome. https://crbug.com/1411464
256
+ it('align to bottom center with restricted size', async () => {
257
+ parseAndDisplay([
258
+ 'WEBVTT\n',
259
+ '\n',
260
+ '00:00:00.000 --> 00:00:05.000 ', // continued on next line
261
+ 'line:85% position:50% size:63%\n',
262
+ 'This is a test\n',
263
+ ].join(''));
264
+
265
+ await helper.checkScreenshot('line-85-position-50-size-63');
266
+ });
267
+
268
+ it('bold long', async () => {
269
+ parseAndDisplay([
270
+ 'WEBVTT\n',
271
+ '\n',
272
+ '00:00:00.000 --> 00:00:05.000 align:start\n',
273
+ '<b>This is a test subtitle that most likely will span over several ',
274
+ 'rows since it is a pretty long cue with a lot of text.</b>\n',
275
+ ].join(''));
276
+
277
+ await helper.checkScreenshot('bold-long');
278
+ });
279
+
280
+ it('italic long', async () => {
281
+ parseAndDisplay([
282
+ 'WEBVTT\n',
283
+ '\n',
284
+ '00:00:00.000 --> 00:00:05.000 align:start\n',
285
+ '<i>This is a test subtitle that most likely will span over several ',
286
+ 'rows since it is a pretty long cue with a lot of text.</i>\n',
287
+ ].join(''));
288
+
289
+ await helper.checkScreenshot('italic-long');
290
+ });
291
+
292
+ it('underline long', async () => {
293
+ parseAndDisplay([
294
+ 'WEBVTT\n',
295
+ '\n',
296
+ '00:00:00.000 --> 00:00:05.000 align:start\n',
297
+ '<u>This is a test subtitle that most likely will span over several ',
298
+ 'rows since it is a pretty long cue with a lot of text.</u>\n',
299
+ ].join(''));
300
+
301
+ await helper.checkScreenshot('underline-long');
302
+ });
303
+
304
+ it('escaped entities', async () => {
305
+ parseAndDisplay([
306
+ 'WEBVTT\n',
307
+ '\n',
308
+ '00:00:00.000 --> 00:00:05.000\n',
309
+ 'Here are the escaped entities: &amp; &lt; &gt; &lrm; &rlm; &nbsp;\n',
310
+ ].join(''));
311
+
312
+ await helper.checkScreenshot('escaped-entities');
313
+ });
314
+
315
+ it('white spaces', async () => {
316
+ parseAndDisplay([
317
+ 'WEBVTT\n',
318
+ '\n',
319
+ '00:00:00.000 --> 00:00:05.000\n',
320
+ // eslint-disable-next-line no-tabs
321
+ 'A A A A A A\n',
322
+ ].join(''));
323
+
324
+ await helper.checkScreenshot('white-spaces');
325
+ });
326
+
327
+ it('embedded styles', async () => {
328
+ parseAndDisplay([
329
+ 'WEBVTT\n',
330
+ '\n',
331
+ 'STYLE\n',
332
+ '*|*::cue(b) {\n',
333
+ ' background: blue;\n',
334
+ '}\n',
335
+ '|*::cue(i) {\n',
336
+ ' color: blue;\n',
337
+ '}\n',
338
+ '::cue(i) {\n',
339
+ ' background: white;\n',
340
+ '}\n',
341
+ '*::cue(b) {\n',
342
+ ' color: white;\n',
343
+ '}\n',
344
+ '::cue {\n',
345
+ ' font-size: 30px;\n',
346
+ '}\n',
347
+ '\n',
348
+ '00:00:00.000 --> 00:00:05.000\n',
349
+ 'This <i>is</i> a <b>test</b> subtitle\n',
350
+ ].join(''));
351
+
352
+ await helper.checkScreenshot('embedded-styles');
353
+ });
354
+
355
+ it('voices', async () => {
356
+ parseAndDisplay([
357
+ 'WEBVTT\n',
358
+ '\n',
359
+ '00:00:00.000 --> 00:00:05.000\n',
360
+ 'This is a <v foo>test subtitle</v>, <v bar>test subtitle</v>\n',
361
+ ].join(''));
362
+
363
+ await helper.checkScreenshot('voices');
364
+ });
365
+
366
+ it('voices with styles', async () => {
367
+ parseAndDisplay([
368
+ 'WEBVTT\n',
369
+ '\n',
370
+ 'STYLE\n',
371
+ '::cue(v[voice=foo]) {\n',
372
+ ' background: blue;\n',
373
+ '}\n',
374
+ '::cue(v[voice=bar]) {\n',
375
+ ' background: red;\n',
376
+ '}\n',
377
+ '\n',
378
+ '00:00:00.000 --> 00:00:05.000\n',
379
+ 'This is a <v foo>test subtitle</v>, <v bar>test subtitle</v>\n',
380
+ ].join(''));
381
+
382
+ await helper.checkScreenshot('voices-with-styles');
383
+ });
384
+
385
+ it('classes', async () => {
386
+ parseAndDisplay([
387
+ 'WEBVTT\n',
388
+ '\n',
389
+ '00:00:00.000 --> 00:00:05.000\n',
390
+ 'This is a <c.foo>test subtitle</c>, <c.bar>test subtitle</c>\n',
391
+ ].join(''));
392
+
393
+ await helper.checkScreenshot('classes');
394
+ });
395
+
396
+ it('classes with styles', async () => {
397
+ parseAndDisplay([
398
+ 'WEBVTT\n',
399
+ '\n',
400
+ 'STYLE\n',
401
+ '::cue(.foo) {\n',
402
+ ' background: blue;\n',
403
+ '}\n',
404
+ '::cue(.bar) {\n',
405
+ ' background: red;\n',
406
+ '}\n',
407
+ '\n',
408
+ '00:00:00.000 --> 00:00:05.000\n',
409
+ 'This is a <c.foo>test subtitle</c>, <c.bar>test subtitle</c>\n',
410
+ ].join(''));
411
+
412
+ await helper.checkScreenshot('classes-with-styles');
413
+ });
414
+
415
+ // FIXME: regions not supported
416
+ it('region without anchors', async () => {
417
+ parseAndDisplay([
418
+ 'WEBVTT\n',
419
+ '\n',
420
+ 'REGION\n',
421
+ 'id:1\n',
422
+ '\n',
423
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
424
+ 'This is a test subtitle\n',
425
+ ].join(''));
426
+
427
+ await helper.checkScreenshot('region-no-anchors');
428
+ });
429
+
430
+ // FIXME: regions not supported
431
+ it('region anchored at top center', async () => {
432
+ parseAndDisplay([
433
+ 'WEBVTT\n',
434
+ '\n',
435
+ 'REGION\n',
436
+ 'id:1\n',
437
+ 'regionanchor:50%,0%\n',
438
+ 'viewportanchor:50%,0%\n',
439
+ 'width:100%\n',
440
+ '\n',
441
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
442
+ 'This is a test subtitle\n',
443
+ ].join(''));
444
+
445
+ await helper.checkScreenshot('region-anchor-top-center');
446
+ });
447
+
448
+ // FIXME: regions not supported
449
+ it('region anchored at top left', async () => {
450
+ parseAndDisplay([
451
+ 'WEBVTT\n',
452
+ '\n',
453
+ 'REGION\n',
454
+ 'id:1\n',
455
+ 'regionanchor:0%,0%\n',
456
+ 'viewportanchor:0%,0%\n',
457
+ 'width:100%\n',
458
+ '\n',
459
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
460
+ 'This is a test subtitle\n',
461
+ ].join(''));
462
+
463
+ await helper.checkScreenshot('region-anchor-top-left');
464
+ });
465
+
466
+ // FIXME: regions not supported
467
+ it('region with complex anchors', async () => {
468
+ parseAndDisplay([
469
+ 'WEBVTT\n',
470
+ '\n',
471
+ 'REGION\n',
472
+ 'id:1\n',
473
+ 'regionanchor:0%,100%\n',
474
+ 'viewportanchor:50%,50%\n',
475
+ 'width:30%\n',
476
+ '\n',
477
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
478
+ 'This is a test subtitle\n',
479
+ ].join(''));
480
+
481
+ await helper.checkScreenshot('region-complex-anchors');
482
+ });
483
+
484
+ // FIXME: regions not supported
485
+ it('region 2 lines scroll up', async () => {
486
+ parseAndDisplay([
487
+ 'WEBVTT\n',
488
+ '\n',
489
+ 'REGION\n',
490
+ 'id:1\n',
491
+ 'regionanchor:50%,0%\n',
492
+ 'viewportanchor:50%,0%\n',
493
+ 'width:100%\n',
494
+ 'lines:2\n',
495
+ 'scroll:up\n',
496
+ '\n',
497
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
498
+ 'This is a first test subtitle\n',
499
+ '\n',
500
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
501
+ 'This is a second test subtitle\n',
502
+ '\n',
503
+ '00:00:00.000 --> 00:00:05.000 region:1\n',
504
+ 'This is a third test subtitle\n',
505
+ ].join(''));
506
+
507
+ await helper.checkScreenshot('region-2-lines-scroll-up');
508
+ });
509
+ }
510
+
511
+ /** @param {string} text */
512
+ function parseAndDisplay(text) {
513
+ const data =
514
+ shaka.util.BufferUtils.toUint8(shaka.util.StringUtils.toUTF8(text));
515
+ const time = {
516
+ periodStart: 0,
517
+ segmentStart: 0,
518
+ segmentEnd: 100,
519
+ vttOffset: 0,
520
+ };
521
+ const textParser = new shaka.text.VttTextParser();
522
+ const cues = textParser.parseMedia(data, time);
523
+ helper.textDisplayer.append(cues);
524
+ }
525
+ });