shaka-player 3.1.0 → 3.1.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/AUTHORS +8 -2
- package/CHANGELOG.md +209 -0
- package/CONTRIBUTORS +10 -3
- package/README.md +3 -0
- package/build/apps.py +2 -2
- package/build/check.py +2 -2
- package/build/conformance.textproto +0 -9
- package/build/generateExterns.js +1 -1
- package/build/misspellings.txt +1 -0
- package/build/shakaBuildHelpers.py +6 -5
- package/build/subprocessWindowsPatch.py +103 -0
- package/demo/common/asset.js +11 -0
- package/demo/common/assets.js +1 -1
- package/demo/common/message_ids.js +5 -0
- package/demo/config.js +2 -1
- package/demo/custom.js +84 -3
- package/demo/demo.less +13 -1
- package/demo/demo_utils.js +1 -0
- package/demo/input.js +31 -12
- package/demo/input_container.js +24 -1
- package/demo/locales/en.json +6 -1
- package/demo/locales/source.json +20 -0
- package/demo/main.js +5 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +99 -91
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +99 -91
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +9 -9
- package/dist/locales.js +36 -34
- package/dist/receiver.compiled.debug.js +74 -70
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +74 -70
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +165 -9
- package/dist/shaka-player.compiled.debug.d.ts +165 -9
- package/dist/shaka-player.compiled.debug.externs.js +179 -11
- package/dist/shaka-player.compiled.debug.js +367 -339
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +179 -11
- package/dist/shaka-player.compiled.js +818 -807
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +165 -9
- package/dist/shaka-player.ui.debug.d.ts +165 -9
- package/dist/shaka-player.ui.debug.externs.js +181 -13
- package/dist/shaka-player.ui.debug.js +459 -429
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +181 -13
- package/dist/shaka-player.ui.js +973 -961
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/faq.md +25 -0
- package/docs/tutorials/index.json +2 -2
- package/docs/tutorials/upgrade-v3.md +38 -0
- package/docs/tutorials/upgrade.md +3 -3
- package/externs/ima.js +4 -0
- package/externs/media_capabilities.js +16 -0
- package/externs/shaka/ads.js +2 -0
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/player.js +6 -0
- package/karma.conf.js +1 -0
- package/lib/abr/simple_abr_manager.js +1 -1
- package/lib/ads/ad_manager.js +29 -11
- package/lib/ads/client_side_ad_manager.js +76 -86
- package/lib/ads/server_side_ad_manager.js +26 -11
- package/lib/cast/cast_proxy.js +3 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cea/sei_processor.js +24 -17
- package/lib/dash/dash_parser.js +107 -4
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +45 -15
- package/lib/dependencies/all.js +15 -15
- package/lib/hls/hls_parser.js +46 -18
- package/lib/media/closed_caption_parser.js +3 -1
- package/lib/media/content_workarounds.js +18 -0
- package/lib/media/drm_engine.js +20 -1
- package/lib/media/gap_jumping_controller.js +8 -4
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +3 -1
- package/lib/media/segment_index.js +38 -12
- package/lib/media/segment_reference.js +8 -0
- package/lib/media/streaming_engine.js +30 -21
- package/lib/net/http_fetch_plugin.js +2 -2
- package/lib/net/networking_engine.js +3 -2
- package/lib/offline/storage.js +4 -0
- package/lib/player.js +113 -56
- package/lib/polyfill/encryption_scheme.js +2 -0
- package/lib/polyfill/fullscreen.js +2 -0
- package/lib/polyfill/mathround.js +2 -0
- package/lib/polyfill/media_capabilities.js +62 -23
- package/lib/polyfill/mediasource.js +8 -0
- package/lib/polyfill/orientation.js +3 -1
- package/lib/polyfill/patchedmediakeys_apple.js +6 -4
- package/lib/polyfill/patchedmediakeys_ms.js +6 -4
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +6 -4
- package/lib/polyfill/pip_webkit.js +2 -0
- package/lib/polyfill/storage_estimate.js +2 -0
- package/lib/polyfill/video_play_promise.js +2 -0
- package/lib/polyfill/videoplaybackquality.js +2 -0
- package/lib/polyfill/vttcue.js +2 -0
- package/lib/text/cue.js +11 -0
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +52 -30
- package/lib/text/ui_text_displayer.js +255 -82
- package/lib/text/vtt_text_parser.js +4 -2
- package/lib/util/error.js +1 -4
- package/lib/util/fake_event.js +53 -7
- package/lib/util/mime_utils.js +33 -0
- package/lib/util/mp4_box_parsers.js +1 -1
- package/lib/util/mp4_parser.js +14 -0
- package/lib/util/networking.js +1 -1
- package/lib/util/periods.js +132 -37
- package/lib/util/platform.js +13 -1
- package/lib/util/stream_utils.js +46 -7
- package/package.json +3 -3
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_receiver_integration.js +1 -1
- package/test/cast/cast_utils_unit.js +1 -1
- package/test/cea/mp4_cea_parser_unit.js +26 -0
- package/test/dash/dash_parser_live_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +187 -1
- package/test/dash/dash_parser_segment_template_unit.js +3 -3
- package/test/demo/demo_unit.js +0 -1
- package/test/hls/hls_parser_unit.js +45 -1
- package/test/media/closed_caption_parser_unit.js +20 -0
- package/test/media/drm_engine_unit.js +59 -3
- package/test/media/playhead_unit.js +27 -1
- package/test/media/presentation_timeline_unit.js +19 -0
- package/test/media/segment_index_unit.js +76 -3
- package/test/media/streaming_engine_unit.js +3 -3
- package/test/player_integration.js +38 -0
- package/test/player_unit.js +125 -6
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/assets/empty_caption_video_init.mp4 +0 -0
- package/test/test/assets/empty_caption_video_segment.mp4 +0 -0
- package/test/test/util/fake_ad_manager.js +4 -1
- package/test/test/util/simple_fakes.js +5 -3
- package/test/test/util/waiter.js +36 -2
- package/test/text/ttml_text_parser_unit.js +55 -0
- package/test/text/ui_text_displayer_unit.js +95 -18
- package/test/text/vtt_text_parser_unit.js +17 -1
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +52 -1
- package/test/ui/ui_unit.js +4 -0
- package/test/util/mp4_box_parsers_unit.js +28 -0
- package/test/util/periods_unit.js +190 -2
- package/test/util/stream_utils_unit.js +56 -5
- package/ui/airplay_button.js +5 -0
- package/ui/big_play_button.js +10 -0
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +9 -7
- package/ui/less/containers.less +10 -5
- package/ui/locales/en.json +1 -0
- package/ui/locales/ru.json +6 -6
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +28 -51
- package/ui/pip_button.js +2 -3
- package/ui/play_button.js +10 -10
- package/ui/small_play_button.js +12 -0
- package/ui/ui.js +1 -1
- package/docs/tutorials/upgrade-v2-4.md +0 -481
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
goog.require('shaka.test.UiUtils');
|
|
8
7
|
goog.require('shaka.test.Util');
|
|
9
8
|
goog.require('shaka.text.Cue');
|
|
10
9
|
goog.require('shaka.text.UITextDisplayer');
|
|
@@ -51,8 +50,7 @@ describe('UITextDisplayer', () => {
|
|
|
51
50
|
/** @type {!HTMLElement} */ (document.createElement('div'));
|
|
52
51
|
videoContainer.style.height = `${videoContainerHeight}px`;
|
|
53
52
|
document.body.appendChild(videoContainer);
|
|
54
|
-
video = shaka.test.
|
|
55
|
-
videoContainer.appendChild(video);
|
|
53
|
+
video = new shaka.test.FakeVideo();
|
|
56
54
|
});
|
|
57
55
|
|
|
58
56
|
beforeEach(() => {
|
|
@@ -86,19 +84,16 @@ describe('UITextDisplayer', () => {
|
|
|
86
84
|
// Wait until updateCaptions_() gets called.
|
|
87
85
|
await shaka.test.Util.delay(0.5);
|
|
88
86
|
|
|
89
|
-
const textContainer =
|
|
90
|
-
|
|
91
|
-
const captions = textContainer.querySelector('span');
|
|
87
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
88
|
+
const captions = textContainer.querySelector('div');
|
|
92
89
|
const cssObj = parseCssText(captions.style.cssText);
|
|
93
90
|
|
|
94
91
|
const expectCssObj = {
|
|
95
92
|
'color': 'green',
|
|
96
|
-
'background-color': 'black',
|
|
97
93
|
'direction': 'ltr',
|
|
98
94
|
'font-size': '10px',
|
|
99
95
|
'font-style': 'normal',
|
|
100
96
|
'font-weight': 400,
|
|
101
|
-
'line-height': 2,
|
|
102
97
|
'text-align': 'center',
|
|
103
98
|
};
|
|
104
99
|
|
|
@@ -115,6 +110,8 @@ describe('UITextDisplayer', () => {
|
|
|
115
110
|
}
|
|
116
111
|
|
|
117
112
|
expect(cssObj).toEqual(jasmine.objectContaining(expectCssObj));
|
|
113
|
+
expect(parseCssText(textContainer.querySelector('span').style.cssText))
|
|
114
|
+
.toEqual(jasmine.objectContaining({'background-color': 'black'}));
|
|
118
115
|
});
|
|
119
116
|
|
|
120
117
|
it('correctly displays styles for nested cues', async () => {
|
|
@@ -138,14 +135,13 @@ describe('UITextDisplayer', () => {
|
|
|
138
135
|
await shaka.test.Util.delay(0.5);
|
|
139
136
|
|
|
140
137
|
// Verify styles applied to the nested cues.
|
|
141
|
-
const textContainer =
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
139
|
+
const captions =
|
|
140
|
+
textContainer.querySelector('span:not(.shaka-text-wrapper)');
|
|
144
141
|
const cssObj = parseCssText(captions.style.cssText);
|
|
145
142
|
|
|
146
143
|
const expectCssObj = {
|
|
147
144
|
'color': 'green',
|
|
148
|
-
'background-color': 'black',
|
|
149
145
|
'font-size': '10px',
|
|
150
146
|
'font-style': 'normal',
|
|
151
147
|
'font-weight': 400,
|
|
@@ -165,6 +161,8 @@ describe('UITextDisplayer', () => {
|
|
|
165
161
|
}
|
|
166
162
|
|
|
167
163
|
expect(cssObj).toEqual(jasmine.objectContaining(expectCssObj));
|
|
164
|
+
expect(parseCssText(captions.querySelector('span').style.cssText))
|
|
165
|
+
.toEqual(jasmine.objectContaining({'background-color': 'black'}));
|
|
168
166
|
});
|
|
169
167
|
|
|
170
168
|
it('correctly displays styles for cellResolution units', async () => {
|
|
@@ -191,9 +189,8 @@ describe('UITextDisplayer', () => {
|
|
|
191
189
|
// style.
|
|
192
190
|
const expectedLinePadding = '11.25px';
|
|
193
191
|
|
|
194
|
-
const textContainer =
|
|
195
|
-
|
|
196
|
-
const captions = textContainer.querySelector('span');
|
|
192
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
193
|
+
const captions = textContainer.querySelector('div');
|
|
197
194
|
const cssObj = parseCssText(captions.style.cssText);
|
|
198
195
|
expect(cssObj).toEqual(
|
|
199
196
|
jasmine.objectContaining({
|
|
@@ -221,9 +218,8 @@ describe('UITextDisplayer', () => {
|
|
|
221
218
|
// videoContainerHeight=450px and tts:fontSize="90%" on the default style.
|
|
222
219
|
const expectedFontSize = '27px';
|
|
223
220
|
|
|
224
|
-
const textContainer =
|
|
225
|
-
|
|
226
|
-
const captions = textContainer.querySelector('span');
|
|
221
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
222
|
+
const captions = textContainer.querySelector('div');
|
|
227
223
|
const cssObj = parseCssText(captions.style.cssText);
|
|
228
224
|
expect(cssObj).toEqual(
|
|
229
225
|
jasmine.objectContaining({'font-size': expectedFontSize}));
|
|
@@ -316,4 +312,85 @@ describe('UITextDisplayer', () => {
|
|
|
316
312
|
// duplicates.
|
|
317
313
|
expect(captions.length).toBe(3);
|
|
318
314
|
});
|
|
315
|
+
|
|
316
|
+
it('hides currently displayed cue when removed', async () => {
|
|
317
|
+
const cue = new shaka.text.Cue(0, 50, 'One');
|
|
318
|
+
textDisplayer.setTextVisibility(true);
|
|
319
|
+
textDisplayer.append([cue]);
|
|
320
|
+
video.currentTime = 10;
|
|
321
|
+
await shaka.test.Util.delay(0.5);
|
|
322
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
323
|
+
|
|
324
|
+
let cueElements = textContainer.querySelectorAll('div');
|
|
325
|
+
expect(cueElements.length).toBe(1);
|
|
326
|
+
expect(cueElements[0].textContent).toBe('One');
|
|
327
|
+
|
|
328
|
+
textDisplayer.remove(0, 100);
|
|
329
|
+
|
|
330
|
+
cueElements = textContainer.querySelectorAll('div');
|
|
331
|
+
expect(cueElements.length).toBe(0);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it('hides and shows nested cues at appropriate times', async () => {
|
|
335
|
+
const parentCue1 = new shaka.text.Cue(0, 100, '');
|
|
336
|
+
const cue1 = new shaka.text.Cue(0, 50, 'One');
|
|
337
|
+
parentCue1.nestedCues.push(cue1);
|
|
338
|
+
const cue2 = new shaka.text.Cue(25, 75, 'Two');
|
|
339
|
+
parentCue1.nestedCues.push(cue2);
|
|
340
|
+
const cue3 = new shaka.text.Cue(50, 100, 'Three');
|
|
341
|
+
parentCue1.nestedCues.push(cue3);
|
|
342
|
+
|
|
343
|
+
const parentCue2 = new shaka.text.Cue(90, 190, '');
|
|
344
|
+
const cue4 = new shaka.text.Cue(90, 130, 'Four');
|
|
345
|
+
parentCue2.nestedCues.push(cue4);
|
|
346
|
+
|
|
347
|
+
textDisplayer.setTextVisibility(true);
|
|
348
|
+
textDisplayer.append([parentCue1, parentCue2]);
|
|
349
|
+
|
|
350
|
+
video.currentTime = 10;
|
|
351
|
+
await shaka.test.Util.delay(0.5);
|
|
352
|
+
/** @type {Element} */
|
|
353
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
354
|
+
let parentCueElements = textContainer.querySelectorAll('div');
|
|
355
|
+
|
|
356
|
+
expect(parentCueElements.length).toBe(1);
|
|
357
|
+
expect(parentCueElements[0].textContent).toBe('One');
|
|
358
|
+
|
|
359
|
+
video.currentTime = 35;
|
|
360
|
+
await shaka.test.Util.delay(0.5);
|
|
361
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
362
|
+
expect(parentCueElements.length).toBe(1);
|
|
363
|
+
expect(parentCueElements[0].textContent).toBe('OneTwo');
|
|
364
|
+
|
|
365
|
+
video.currentTime = 60;
|
|
366
|
+
await shaka.test.Util.delay(0.5);
|
|
367
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
368
|
+
expect(parentCueElements.length).toBe(1);
|
|
369
|
+
expect(parentCueElements[0].textContent).toBe('TwoThree');
|
|
370
|
+
|
|
371
|
+
video.currentTime = 85;
|
|
372
|
+
await shaka.test.Util.delay(0.5);
|
|
373
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
374
|
+
expect(parentCueElements.length).toBe(1);
|
|
375
|
+
expect(parentCueElements[0].textContent).toBe('Three');
|
|
376
|
+
|
|
377
|
+
video.currentTime = 95;
|
|
378
|
+
await shaka.test.Util.delay(0.5);
|
|
379
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
380
|
+
expect(parentCueElements.length).toBe(2);
|
|
381
|
+
expect(parentCueElements[0].textContent).toBe('Three');
|
|
382
|
+
expect(parentCueElements[1].textContent).toBe('Four');
|
|
383
|
+
|
|
384
|
+
video.currentTime = 105;
|
|
385
|
+
await shaka.test.Util.delay(0.5);
|
|
386
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
387
|
+
expect(parentCueElements.length).toBe(1);
|
|
388
|
+
expect(parentCueElements[0].textContent).toBe('Four');
|
|
389
|
+
|
|
390
|
+
video.currentTime = 150;
|
|
391
|
+
await shaka.test.Util.delay(0.5);
|
|
392
|
+
parentCueElements = textContainer.querySelectorAll('div');
|
|
393
|
+
expect(parentCueElements.length).toBe(1);
|
|
394
|
+
expect(parentCueElements[0].textContent).toBe('');
|
|
395
|
+
});
|
|
319
396
|
});
|
|
@@ -924,6 +924,18 @@ describe('VttTextParser', () => {
|
|
|
924
924
|
payload: '<c.lime><b>Parse fail 2</c></b>',
|
|
925
925
|
nestedCues: [],
|
|
926
926
|
},
|
|
927
|
+
{
|
|
928
|
+
startTime: 100,
|
|
929
|
+
endTime: 110,
|
|
930
|
+
payload: '<c.lime>forward slash 1/2 in text</c>',
|
|
931
|
+
nestedCues: [],
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
startTime: 110,
|
|
935
|
+
endTime: 120,
|
|
936
|
+
payload: '<c.lime>less or more < > in text</c>',
|
|
937
|
+
nestedCues: [],
|
|
938
|
+
},
|
|
927
939
|
],
|
|
928
940
|
'WEBVTT\n\n' +
|
|
929
941
|
'00:00:20.000 --> 00:00:40.000\n' +
|
|
@@ -939,7 +951,11 @@ describe('VttTextParser', () => {
|
|
|
939
951
|
'00:01:20.000 --> 00:01:30.000\n' +
|
|
940
952
|
'<b><c.lime>Parse fail 1</b></c>\n\n' +
|
|
941
953
|
'00:01:30.000 --> 00:01:40.000\n' +
|
|
942
|
-
'<c.lime><b>Parse fail 2</c></b
|
|
954
|
+
'<c.lime><b>Parse fail 2</c></b>\n\n' +
|
|
955
|
+
'00:01:40.000 --> 00:01:50.000\n' +
|
|
956
|
+
'<c.lime>forward slash 1/2 in text</c>\n\n' +
|
|
957
|
+
'00:01:50.000 --> 00:02:00.000\n' +
|
|
958
|
+
'<c.lime>less or more < > in text</c>',
|
|
943
959
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
944
960
|
});
|
|
945
961
|
|
|
@@ -198,7 +198,7 @@ describe('Localization', () => {
|
|
|
198
198
|
localization.changeLocale([ELVISH_WOODLAND]);
|
|
199
199
|
|
|
200
200
|
expect(events.length).toBe(1);
|
|
201
|
-
expect(events[0]
|
|
201
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
|
|
202
202
|
});
|
|
203
203
|
|
|
204
204
|
|
|
@@ -214,23 +214,23 @@ describe('Localization', () => {
|
|
|
214
214
|
localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
215
215
|
|
|
216
216
|
expect(events.length).toBe(1);
|
|
217
|
-
expect(events[0]
|
|
217
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
218
218
|
|
|
219
219
|
// We should see an event telling us that dwarfish is still missing.
|
|
220
220
|
localization.insert(ELVISH_WOODLAND, new Map());
|
|
221
221
|
localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
222
222
|
|
|
223
223
|
expect(events.length).toBe(2);
|
|
224
|
-
expect(events[0]
|
|
225
|
-
expect(events[1]
|
|
224
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
225
|
+
expect(events[1]['locales']).toEqual([DWARFISH_NORTH]);
|
|
226
226
|
|
|
227
227
|
// There should be no more events now that we added the last language.
|
|
228
228
|
localization.insert(DWARFISH_NORTH, new Map());
|
|
229
229
|
localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
230
230
|
|
|
231
231
|
expect(events.length).toBe(2);
|
|
232
|
-
expect(events[0]
|
|
233
|
-
expect(events[1]
|
|
232
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
233
|
+
expect(events[1]['locales']).toEqual([DWARFISH_NORTH]);
|
|
234
234
|
});
|
|
235
235
|
});
|
|
236
236
|
|
|
@@ -373,8 +373,8 @@ describe('Localization', () => {
|
|
|
373
373
|
// it was in the fallback (HALFLING) but not our preferred language
|
|
374
374
|
// (EVLISH).
|
|
375
375
|
expect(events.length).toBe(1);
|
|
376
|
-
expect(events[0]
|
|
377
|
-
expect(events[0]
|
|
376
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
|
|
377
|
+
expect(events[0]['missing']).toEqual(['hello']);
|
|
378
378
|
});
|
|
379
379
|
|
|
380
380
|
it('fires when key/value is missing from preferred but found in base',
|
|
@@ -400,8 +400,8 @@ describe('Localization', () => {
|
|
|
400
400
|
// because it was in the base (ELVISH) but not our preferred language
|
|
401
401
|
// (EVLISH_WOODLAND).
|
|
402
402
|
expect(events.length).toBe(1);
|
|
403
|
-
expect(events[0]
|
|
404
|
-
expect(events[0]
|
|
403
|
+
expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
|
|
404
|
+
expect(events[0]['missing']).toEqual(['Best Wishes']);
|
|
405
405
|
});
|
|
406
406
|
|
|
407
407
|
it('fires when key/value is missing from preferred but found in sibling',
|
|
@@ -427,8 +427,8 @@ describe('Localization', () => {
|
|
|
427
427
|
// understand" because it was in a sibling locale (HALFLING_SHIRE)
|
|
428
428
|
// but not our preferred language (HALFLING_COMMON).
|
|
429
429
|
expect(events.length).toBe(1);
|
|
430
|
-
expect(events[0]
|
|
431
|
-
expect(events[0]
|
|
430
|
+
expect(events[0]['locales']).toEqual([HALFLING_COMMON]);
|
|
431
|
+
expect(events[0]['missing']).toEqual(['Do you understand']);
|
|
432
432
|
});
|
|
433
433
|
|
|
434
434
|
it('fires when key/value is missing from some preferred languages',
|
|
@@ -454,8 +454,9 @@ describe('Localization', () => {
|
|
|
454
454
|
|
|
455
455
|
// There should have no missing localization events.
|
|
456
456
|
expect(events.length).toBe(1);
|
|
457
|
-
expect(events[0]
|
|
458
|
-
|
|
457
|
+
expect(events[0]['locales']).toEqual(
|
|
458
|
+
[ELVISH_WOODLAND, DWARFISH_NORTH]);
|
|
459
|
+
expect(events[0]['missing']).toEqual(['may your forge burn bright']);
|
|
459
460
|
});
|
|
460
461
|
});
|
|
461
462
|
|
|
@@ -141,7 +141,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
141
141
|
cue.region.id = '1';
|
|
142
142
|
// Position the cue *explicitly* at the bottom of the screen.
|
|
143
143
|
cue.region.viewportAnchorX = 0; // %
|
|
144
|
-
cue.region.viewportAnchorY =
|
|
144
|
+
cue.region.viewportAnchorY = 90; // %
|
|
145
|
+
cue.region.width = 100; // %
|
|
146
|
+
cue.region.height = 10; // %
|
|
145
147
|
textDisplayer.append([cue]);
|
|
146
148
|
|
|
147
149
|
await checkScreenshot('ui', 'cue-with-controls');
|
|
@@ -299,6 +301,31 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
299
301
|
await checkScreenshot(prefix, 'two-nested-cues');
|
|
300
302
|
});
|
|
301
303
|
|
|
304
|
+
// Distinct from "newline" test above, which has a literal \n character in
|
|
305
|
+
// the text payload. This uses a nested "lineBreak" cue, which is what you
|
|
306
|
+
// get with <br> in TTML.
|
|
307
|
+
it('nested cues with linebreak', async () => {
|
|
308
|
+
const cue = new shaka.text.Cue(0, 1, '');
|
|
309
|
+
cue.nestedCues = [
|
|
310
|
+
new shaka.text.Cue(0, 1, 'Captain\'s log,'),
|
|
311
|
+
shaka.text.Cue.lineBreak(0, 1),
|
|
312
|
+
new shaka.text.Cue(0, 1, 'stardate 41636.9'),
|
|
313
|
+
];
|
|
314
|
+
textDisplayer.append([cue]);
|
|
315
|
+
|
|
316
|
+
await checkScreenshot(prefix, 'nested-cues-with-linebreak');
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Regression test for #3600
|
|
320
|
+
it('cue positioning', async () => {
|
|
321
|
+
const cue = new shaka.text.Cue(0, 1, 'Text');
|
|
322
|
+
cue.line = 10;
|
|
323
|
+
cue.lineInterpretation = shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
324
|
+
textDisplayer.append([cue]);
|
|
325
|
+
|
|
326
|
+
await checkScreenshot(prefix, 'cue-position');
|
|
327
|
+
});
|
|
328
|
+
|
|
302
329
|
// Regression test for #2157 and #2584
|
|
303
330
|
it('region positioning', async () => {
|
|
304
331
|
const nestedCue = new shaka.text.Cue(
|
|
@@ -316,6 +343,30 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
|
|
|
316
343
|
await checkScreenshot(prefix, 'region-position');
|
|
317
344
|
});
|
|
318
345
|
|
|
346
|
+
// Regression test for #3379, in which the displayAlign was not respected,
|
|
347
|
+
// placing text at the top of the region instead of the bottom.
|
|
348
|
+
it('region with display alignment', async () => {
|
|
349
|
+
const cue = new shaka.text.Cue(0, 1, '');
|
|
350
|
+
|
|
351
|
+
cue.region.id = '1';
|
|
352
|
+
cue.region.viewportAnchorX = 10;
|
|
353
|
+
cue.region.viewportAnchorY = 10;
|
|
354
|
+
cue.region.width = 80;
|
|
355
|
+
cue.region.height = 80;
|
|
356
|
+
|
|
357
|
+
cue.positionAlign = shaka.text.Cue.positionAlign.CENTER;
|
|
358
|
+
cue.lineAlign = shaka.text.Cue.lineAlign.CENTER;
|
|
359
|
+
cue.displayAlign = shaka.text.Cue.displayAlign.AFTER;
|
|
360
|
+
|
|
361
|
+
cue.nestedCues = [
|
|
362
|
+
// For those who don't speak Unicode, \xbf is an upside down "?".
|
|
363
|
+
new shaka.text.Cue(0, 1, '\xbfBien?'),
|
|
364
|
+
];
|
|
365
|
+
textDisplayer.append([cue]);
|
|
366
|
+
|
|
367
|
+
await checkScreenshot(prefix, 'region-with-display-alignment');
|
|
368
|
+
});
|
|
369
|
+
|
|
319
370
|
// Regression test for #2188
|
|
320
371
|
it('bitmap-based cues', async () => {
|
|
321
372
|
const cue = new shaka.text.Cue(0, 1, '');
|
package/test/ui/ui_unit.js
CHANGED
|
@@ -196,6 +196,10 @@ describe('UI', () => {
|
|
|
196
196
|
});
|
|
197
197
|
|
|
198
198
|
it('goes into fullscreen on double click', async () => {
|
|
199
|
+
if (!document.fullscreenEnabled) {
|
|
200
|
+
pending('This test requires fullscreen support, which is unavailable.');
|
|
201
|
+
}
|
|
202
|
+
|
|
199
203
|
const config = {
|
|
200
204
|
controlPanelElements: [
|
|
201
205
|
'overflow_menu',
|
|
@@ -149,4 +149,32 @@ describe('Mp4BoxParsers', () => {
|
|
|
149
149
|
expect(defaultSampleDuration).toBe(expectedDefaultSampleDuration);
|
|
150
150
|
expect(baseMediaDecodeTime).toBe(expectedBaseMediaDecodeTime);
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Test on parsing an incomplete TKHD V1 box, since the parser doesn't
|
|
155
|
+
* parse the other fields
|
|
156
|
+
*
|
|
157
|
+
* Explanation on the Uint8Array:
|
|
158
|
+
* [
|
|
159
|
+
* <creation_time, 8 bytes>,
|
|
160
|
+
* <modification_time, 8 bytes>,
|
|
161
|
+
* <track_id, 4 bytes>
|
|
162
|
+
* ]
|
|
163
|
+
*
|
|
164
|
+
* Time is a 32B integer expressed in seconds since Jan 1, 1904, 0000 UTC
|
|
165
|
+
*
|
|
166
|
+
*/
|
|
167
|
+
it('parses TKHD v1 box', () => {
|
|
168
|
+
const tkhdBox = new Uint8Array([
|
|
169
|
+
0x00, 0x00, 0x00, 0x00, 0xDC, 0xBF, 0x0F, 0xD7, // Creation time
|
|
170
|
+
0x00, 0x00, 0x00, 0x00, 0xDC, 0xBF, 0x0F, 0xD7, // Modification time
|
|
171
|
+
0x00, 0x00, 0x00, 0x01, // Track ID
|
|
172
|
+
// Remaining fields are not processed in parseTKHD()
|
|
173
|
+
]);
|
|
174
|
+
const reader = new shaka.util.DataViewReader(
|
|
175
|
+
tkhdBox, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
176
|
+
const parsedTkhd = shaka.util.Mp4BoxParsers
|
|
177
|
+
.parseTKHD(reader, /* version= */ 1);
|
|
178
|
+
expect(parsedTkhd.trackId).toBe(1);
|
|
179
|
+
});
|
|
152
180
|
});
|