shaka-player 4.5.0 → 4.6.0
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/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/AUTHORS +2 -0
- package/CHANGELOG.md +98 -0
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +38 -32
- package/demo/common/asset.js +11 -17
- package/demo/common/assets.js +117 -11
- package/demo/config.js +28 -1
- package/demo/custom.js +52 -38
- package/demo/main.js +11 -3
- package/demo/search.js +7 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +133 -124
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +133 -124
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +20 -18
- package/dist/locales.js +35 -31
- package/dist/receiver.compiled.debug.js +58 -50
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +58 -50
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.externs.js +162 -77
- package/dist/shaka-player.compiled.debug.js +786 -736
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +162 -77
- package/dist/shaka-player.compiled.js +1154 -1121
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +491 -437
- package/dist/shaka-player.ui.debug.d.ts +491 -437
- package/dist/shaka-player.ui.debug.externs.js +167 -77
- package/dist/shaka-player.ui.debug.js +877 -811
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +167 -77
- package/dist/shaka-player.ui.js +1362 -1318
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +54 -0
- package/docs/tutorials/basic-usage.md +2 -1
- package/docs/tutorials/errors.md +2 -1
- package/docs/tutorials/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +13 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/managedmediasource.js +24 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +21 -5
- package/externs/shaka/manifest_parser.js +17 -0
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +9 -2
- package/externs/shaka/player.js +53 -7
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/lib/abr/simple_abr_manager.js +25 -8
- package/lib/ads/media_tailor_ad_manager.js +14 -3
- package/lib/cast/cast_receiver.js +1 -1
- package/lib/cea/cea_decoder.js +28 -0
- package/lib/cea/dummy_caption_decoder.js +5 -0
- package/lib/dash/dash_parser.js +249 -83
- package/lib/dash/mpd_utils.js +52 -31
- package/lib/dash/segment_base.js +4 -5
- package/lib/dash/segment_list.js +5 -4
- package/lib/dash/segment_template.js +83 -26
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +761 -649
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/media/adaptation_set.js +20 -13
- package/lib/media/adaptation_set_criteria.js +70 -18
- package/lib/media/closed_caption_parser.js +13 -0
- package/lib/media/content_workarounds.js +6 -0
- package/lib/media/drm_engine.js +8 -13
- package/lib/media/manifest_parser.js +8 -113
- package/lib/media/media_source_capabilities.js +10 -3
- package/lib/media/media_source_engine.js +75 -21
- package/lib/media/play_rate_controller.js +8 -38
- package/lib/media/presentation_timeline.js +7 -1
- package/lib/media/quality_observer.js +1 -1
- package/lib/media/segment_index.js +5 -5
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +67 -1
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +41 -21
- package/lib/mss/mss_parser.js +18 -2
- package/lib/net/networking_engine.js +66 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
- package/lib/offline/manifest_converter.js +2 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +11 -7
- package/lib/player.js +993 -1502
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/mp4_ttml_parser.js +2 -2
- package/lib/text/srt_text_parser.js +2 -2
- package/lib/text/stub_text_displayer.js +51 -0
- package/lib/text/text_engine.js +3 -2
- package/lib/text/ttml_text_parser.js +28 -5
- package/lib/text/ui_text_displayer.js +4 -0
- package/lib/text/vtt_text_parser.js +7 -2
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -1
- package/lib/transmuxer/ec3_transmuxer.js +1 -1
- package/lib/transmuxer/h264.js +5 -4
- package/lib/transmuxer/h265.js +5 -4
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +1 -1
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +33 -13
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +2 -6
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +5 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +2 -4
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +154 -179
- package/lib/util/platform.js +4 -3
- package/lib/util/player_configuration.js +35 -6
- package/lib/util/stream_utils.js +105 -98
- package/lib/util/ts_parser.js +124 -73
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +2 -2
- package/package.json +1 -1
- package/roadmap.md +15 -5
- package/shaka-player.uncompiled.js +0 -1
- package/test/abr/simple_abr_manager_unit.js +33 -33
- package/test/ads/ad_manager_unit.js +3 -2
- package/test/cast/cast_receiver_integration.js +3 -4
- package/test/cast/cast_utils_unit.js +2 -0
- package/test/cea/cea_decoder_unit.js +7 -0
- package/test/codec_switching/codec_switching_integration.js +2 -1
- package/test/dash/dash_parser_integration.js +2 -1
- package/test/dash/dash_parser_live_unit.js +0 -19
- package/test/dash/dash_parser_manifest_unit.js +494 -2
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/hls/hls_live_unit.js +12 -3
- package/test/hls/hls_parser_unit.js +377 -27
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +172 -21
- package/test/media/adaptation_set_unit.js +1 -0
- package/test/media/content_workarounds_unit.js +1 -1
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/media_source_engine_unit.js +1 -1
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +2 -1
- package/test/mss/mss_player_integration.js +3 -2
- package/test/net/networking_engine_unit.js +3 -3
- package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +21 -9
- package/test/player_external.js +4 -2
- package/test/player_integration.js +15 -4
- package/test/player_load_graph_integration.js +47 -151
- package/test/player_src_equals_external.js +1 -0
- package/test/player_src_equals_integration.js +71 -4
- package/test/player_unit.js +80 -27
- package/test/test/util/fake_media_source_engine.js +5 -0
- package/test/test/util/fake_networking_engine.js +9 -1
- package/test/test/util/fake_segment_prefetch.js +3 -0
- package/test/test/util/manifest_generator.js +4 -0
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +3 -0
- package/test/test/util/test_scheme.js +6 -0
- package/test/test/util/ui_utils.js +4 -3
- package/test/text/mp4_ttml_parser_unit.js +4 -4
- package/test/text/srt_text_parser_unit.js +1 -1
- package/test/text/text_displayer_layout_unit.js +1 -1
- package/test/text/text_engine_unit.js +6 -0
- package/test/text/ttml_text_parser_unit.js +33 -2
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +33 -3
- package/test/ui/ad_ui_unit.js +2 -2
- package/test/ui/ui_customization_unit.js +17 -16
- package/test/ui/ui_integration.js +30 -20
- package/test/ui/ui_unit.js +25 -19
- package/test/util/buffer_utils_unit.js +1 -1
- package/test/util/content_steering_manager_unit.js +427 -0
- package/test/util/id3_utils_unit.js +52 -0
- package/test/util/stream_utils_unit.js +17 -113
- package/test/util/ts_parser_unit.js +3 -3
- package/third_party/closure-uri/uri.js +13 -1
- package/ui/audio_language_selection.js +9 -2
- package/ui/externs/ui.js +17 -2
- package/ui/language_utils.js +43 -8
- package/ui/less/range_elements.less +33 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/es-419.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +10 -0
- package/ui/remote_button.js +3 -1
- package/ui/resolution_selection.js +47 -10
- package/ui/seek_bar.js +296 -3
- package/ui/text_selection.js +2 -1
- package/ui/ui.js +6 -2
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -47
- package/lib/routing/walker.js +0 -587
- package/test/routing/walker_unit.js +0 -505
package/test/player_unit.js
CHANGED
|
@@ -48,7 +48,7 @@ describe('Player', () => {
|
|
|
48
48
|
/** @type {!shaka.test.FakeVideo} */
|
|
49
49
|
let video;
|
|
50
50
|
|
|
51
|
-
beforeEach(() => {
|
|
51
|
+
beforeEach(async () => {
|
|
52
52
|
// By default, errors are a failure.
|
|
53
53
|
logErrorSpy = jasmine.createSpy('shaka.log.error');
|
|
54
54
|
logErrorSpy.calls.reset();
|
|
@@ -124,6 +124,7 @@ describe('Player', () => {
|
|
|
124
124
|
open: jasmine.createSpy('open').and.returnValue(Promise.resolve()),
|
|
125
125
|
destroy:
|
|
126
126
|
jasmine.createSpy('destroy').and.returnValue(Promise.resolve()),
|
|
127
|
+
setTextDisplayer: jasmine.createSpy('setTextDisplayer'),
|
|
127
128
|
setUseEmbeddedText: jasmine.createSpy('setUseEmbeddedText'),
|
|
128
129
|
getUseEmbeddedText: jasmine.createSpy('getUseEmbeddedText'),
|
|
129
130
|
setSegmentRelativeVttTiming:
|
|
@@ -151,7 +152,8 @@ describe('Player', () => {
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
video = new shaka.test.FakeVideo(20);
|
|
154
|
-
player = new shaka.Player(
|
|
155
|
+
player = new shaka.Player(null, dependencyInjector);
|
|
156
|
+
await player.attach(video);
|
|
155
157
|
player.configure({
|
|
156
158
|
// Ensures we don't get a warning about missing preference.
|
|
157
159
|
preferredAudioLanguage: 'en',
|
|
@@ -170,6 +172,7 @@ describe('Player', () => {
|
|
|
170
172
|
try {
|
|
171
173
|
await player.destroy();
|
|
172
174
|
} finally {
|
|
175
|
+
player.releaseAllMutexes();
|
|
173
176
|
shaka.log.error = originalLogError;
|
|
174
177
|
shaka.log.alwaysError = originalLogError;
|
|
175
178
|
shaka.log.warning = originalLogWarn;
|
|
@@ -234,31 +237,6 @@ describe('Player', () => {
|
|
|
234
237
|
expect(mediaSourceEngine.destroy).toHaveBeenCalled();
|
|
235
238
|
expect(drmEngine.destroy).toHaveBeenCalled();
|
|
236
239
|
});
|
|
237
|
-
|
|
238
|
-
// TODO(vaage): Re-enable once the parser is integrated into the load graph
|
|
239
|
-
// better.
|
|
240
|
-
xit('destroys parser first when interrupting load', async () => {
|
|
241
|
-
const p = shaka.test.Util.shortDelay();
|
|
242
|
-
/** @type {!shaka.test.FakeManifestParser} */
|
|
243
|
-
const parser = new shaka.test.FakeManifestParser(manifest);
|
|
244
|
-
parser.start.and.returnValue(p);
|
|
245
|
-
parser.stop.and.callFake(() => {
|
|
246
|
-
expect(abrManager.stop).not.toHaveBeenCalled();
|
|
247
|
-
expect(abrManager.release).not.toHaveBeenCalled();
|
|
248
|
-
expect(networkingEngine.destroy).not.toHaveBeenCalled();
|
|
249
|
-
});
|
|
250
|
-
shaka.media.ManifestParser.registerParserByMime(
|
|
251
|
-
fakeMimeType, () => parser);
|
|
252
|
-
|
|
253
|
-
const load = player.load(fakeManifestUri, 0, fakeMimeType);
|
|
254
|
-
await shaka.test.Util.shortDelay();
|
|
255
|
-
await player.destroy();
|
|
256
|
-
expect(abrManager.stop).toHaveBeenCalled();
|
|
257
|
-
expect(abrManager.release).toHaveBeenCalled();
|
|
258
|
-
expect(networkingEngine.destroy).toHaveBeenCalled();
|
|
259
|
-
expect(parser.stop).toHaveBeenCalled();
|
|
260
|
-
await expectAsync(load).toBeRejected();
|
|
261
|
-
});
|
|
262
240
|
});
|
|
263
241
|
|
|
264
242
|
describe('load/unload', () => {
|
|
@@ -1503,6 +1481,7 @@ describe('Player', () => {
|
|
|
1503
1481
|
frameRate: 1000000 / 42000,
|
|
1504
1482
|
pixelAspectRatio: '59:54',
|
|
1505
1483
|
hdr: null,
|
|
1484
|
+
videoLayout: null,
|
|
1506
1485
|
mimeType: 'video/mp4',
|
|
1507
1486
|
audioMimeType: 'audio/mp4',
|
|
1508
1487
|
videoMimeType: 'video/mp4',
|
|
@@ -1541,6 +1520,7 @@ describe('Player', () => {
|
|
|
1541
1520
|
frameRate: 24,
|
|
1542
1521
|
pixelAspectRatio: '59:54',
|
|
1543
1522
|
hdr: null,
|
|
1523
|
+
videoLayout: null,
|
|
1544
1524
|
mimeType: 'video/mp4',
|
|
1545
1525
|
audioMimeType: 'audio/mp4',
|
|
1546
1526
|
videoMimeType: 'video/mp4',
|
|
@@ -1579,6 +1559,7 @@ describe('Player', () => {
|
|
|
1579
1559
|
frameRate: 1000000 / 42000,
|
|
1580
1560
|
pixelAspectRatio: '59:54',
|
|
1581
1561
|
hdr: null,
|
|
1562
|
+
videoLayout: null,
|
|
1582
1563
|
mimeType: 'video/mp4',
|
|
1583
1564
|
audioMimeType: 'audio/mp4',
|
|
1584
1565
|
videoMimeType: 'video/mp4',
|
|
@@ -1617,6 +1598,7 @@ describe('Player', () => {
|
|
|
1617
1598
|
frameRate: 24,
|
|
1618
1599
|
pixelAspectRatio: '59:54',
|
|
1619
1600
|
hdr: null,
|
|
1601
|
+
videoLayout: null,
|
|
1620
1602
|
mimeType: 'video/mp4',
|
|
1621
1603
|
audioMimeType: 'audio/mp4',
|
|
1622
1604
|
videoMimeType: 'video/mp4',
|
|
@@ -1655,6 +1637,7 @@ describe('Player', () => {
|
|
|
1655
1637
|
frameRate: 1000000 / 42000,
|
|
1656
1638
|
pixelAspectRatio: '59:54',
|
|
1657
1639
|
hdr: null,
|
|
1640
|
+
videoLayout: null,
|
|
1658
1641
|
mimeType: 'video/mp4',
|
|
1659
1642
|
audioMimeType: 'audio/mp4',
|
|
1660
1643
|
videoMimeType: 'video/mp4',
|
|
@@ -1693,6 +1676,7 @@ describe('Player', () => {
|
|
|
1693
1676
|
frameRate: 24,
|
|
1694
1677
|
pixelAspectRatio: '59:54',
|
|
1695
1678
|
hdr: null,
|
|
1679
|
+
videoLayout: null,
|
|
1696
1680
|
mimeType: 'video/mp4',
|
|
1697
1681
|
audioMimeType: 'audio/mp4',
|
|
1698
1682
|
videoMimeType: 'video/mp4',
|
|
@@ -1731,6 +1715,7 @@ describe('Player', () => {
|
|
|
1731
1715
|
frameRate: 1000000 / 42000,
|
|
1732
1716
|
pixelAspectRatio: '59:54',
|
|
1733
1717
|
hdr: null,
|
|
1718
|
+
videoLayout: null,
|
|
1734
1719
|
mimeType: 'video/mp4',
|
|
1735
1720
|
audioMimeType: 'audio/mp4',
|
|
1736
1721
|
videoMimeType: 'video/mp4',
|
|
@@ -1769,6 +1754,7 @@ describe('Player', () => {
|
|
|
1769
1754
|
frameRate: 24,
|
|
1770
1755
|
pixelAspectRatio: '59:54',
|
|
1771
1756
|
hdr: null,
|
|
1757
|
+
videoLayout: null,
|
|
1772
1758
|
mimeType: 'video/mp4',
|
|
1773
1759
|
audioMimeType: 'audio/mp4',
|
|
1774
1760
|
videoMimeType: 'video/mp4',
|
|
@@ -1826,6 +1812,7 @@ describe('Player', () => {
|
|
|
1826
1812
|
frameRate: null,
|
|
1827
1813
|
pixelAspectRatio: null,
|
|
1828
1814
|
hdr: null,
|
|
1815
|
+
videoLayout: null,
|
|
1829
1816
|
videoId: null,
|
|
1830
1817
|
audioId: null,
|
|
1831
1818
|
originalAudioId: null,
|
|
@@ -1864,6 +1851,7 @@ describe('Player', () => {
|
|
|
1864
1851
|
frameRate: null,
|
|
1865
1852
|
pixelAspectRatio: null,
|
|
1866
1853
|
hdr: null,
|
|
1854
|
+
videoLayout: null,
|
|
1867
1855
|
videoId: null,
|
|
1868
1856
|
audioId: null,
|
|
1869
1857
|
originalAudioId: null,
|
|
@@ -1902,6 +1890,7 @@ describe('Player', () => {
|
|
|
1902
1890
|
frameRate: null,
|
|
1903
1891
|
pixelAspectRatio: null,
|
|
1904
1892
|
hdr: null,
|
|
1893
|
+
videoLayout: null,
|
|
1905
1894
|
videoId: null,
|
|
1906
1895
|
audioId: null,
|
|
1907
1896
|
originalAudioId: null,
|
|
@@ -1943,6 +1932,7 @@ describe('Player', () => {
|
|
|
1943
1932
|
frameRate: null,
|
|
1944
1933
|
pixelAspectRatio: null,
|
|
1945
1934
|
hdr: null,
|
|
1935
|
+
videoLayout: null,
|
|
1946
1936
|
videoId: null,
|
|
1947
1937
|
audioId: null,
|
|
1948
1938
|
originalAudioId: null,
|
|
@@ -4179,6 +4169,69 @@ describe('Player', () => {
|
|
|
4179
4169
|
expect(thumbnail8.duration).toBe(10);
|
|
4180
4170
|
});
|
|
4181
4171
|
});
|
|
4172
|
+
|
|
4173
|
+
describe('getAllThumbnails', () => {
|
|
4174
|
+
it('returns all thumbnails', async () => {
|
|
4175
|
+
const uris = () => ['thumbnail'];
|
|
4176
|
+
const ref = new shaka.media.SegmentReference(
|
|
4177
|
+
0, 60, uris, 0, null, null, 0, 0, Infinity, [],
|
|
4178
|
+
);
|
|
4179
|
+
const index = new shaka.media.SegmentIndex([ref]);
|
|
4180
|
+
|
|
4181
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
4182
|
+
manifest.addVariant(0, (variant) => {
|
|
4183
|
+
variant.addVideo(1);
|
|
4184
|
+
});
|
|
4185
|
+
manifest.addImageStream(5, (stream) => {
|
|
4186
|
+
stream.originalId = 'thumbnail';
|
|
4187
|
+
stream.width = 200;
|
|
4188
|
+
stream.height = 150;
|
|
4189
|
+
stream.mimeType = 'image/jpeg';
|
|
4190
|
+
stream.tilesLayout = '2x3';
|
|
4191
|
+
stream.segmentIndex = index;
|
|
4192
|
+
});
|
|
4193
|
+
});
|
|
4194
|
+
|
|
4195
|
+
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
4196
|
+
|
|
4197
|
+
expect(player.getImageTracks()[0].width).toBe(100);
|
|
4198
|
+
expect(player.getImageTracks()[0].height).toBe(50);
|
|
4199
|
+
const thumbnails = await player.getAllThumbnails(5);
|
|
4200
|
+
expect(thumbnails.length).toBe(6);
|
|
4201
|
+
expect(thumbnails[0]).toEqual(jasmine.objectContaining({
|
|
4202
|
+
imageHeight: 150,
|
|
4203
|
+
imageWidth: 200,
|
|
4204
|
+
positionX: 0,
|
|
4205
|
+
positionY: 0,
|
|
4206
|
+
width: 100,
|
|
4207
|
+
height: 50,
|
|
4208
|
+
}));
|
|
4209
|
+
expect(thumbnails[1]).toEqual(jasmine.objectContaining({
|
|
4210
|
+
imageHeight: 150,
|
|
4211
|
+
imageWidth: 200,
|
|
4212
|
+
positionX: 100,
|
|
4213
|
+
positionY: 0,
|
|
4214
|
+
width: 100,
|
|
4215
|
+
height: 50,
|
|
4216
|
+
}));
|
|
4217
|
+
expect(thumbnails[2]).toEqual(jasmine.objectContaining({
|
|
4218
|
+
imageHeight: 150,
|
|
4219
|
+
imageWidth: 200,
|
|
4220
|
+
positionX: 0,
|
|
4221
|
+
positionY: 50,
|
|
4222
|
+
width: 100,
|
|
4223
|
+
height: 50,
|
|
4224
|
+
}));
|
|
4225
|
+
expect(thumbnails[5]).toEqual(jasmine.objectContaining({
|
|
4226
|
+
imageHeight: 150,
|
|
4227
|
+
imageWidth: 200,
|
|
4228
|
+
positionX: 100,
|
|
4229
|
+
positionY: 100,
|
|
4230
|
+
width: 100,
|
|
4231
|
+
height: 50,
|
|
4232
|
+
}));
|
|
4233
|
+
});
|
|
4234
|
+
});
|
|
4182
4235
|
});
|
|
4183
4236
|
|
|
4184
4237
|
describe('config streaming.startAtSegmentBoundary', () => {
|
|
@@ -49,6 +49,9 @@ shaka.test.FakeNetworkingEngine = class {
|
|
|
49
49
|
/** @type {!jasmine.Spy} */
|
|
50
50
|
this.setForceHTTPS = jasmine.createSpy('setForceHTTPS').and.stub();
|
|
51
51
|
|
|
52
|
+
/** @private {number} */
|
|
53
|
+
this.maxUris_ = 1;
|
|
54
|
+
|
|
52
55
|
// The prototype has already been applied; create spies for the
|
|
53
56
|
// methods but still call it by default.
|
|
54
57
|
spyOn(this, 'destroy').and.callThrough();
|
|
@@ -67,7 +70,7 @@ shaka.test.FakeNetworkingEngine = class {
|
|
|
67
70
|
*/
|
|
68
71
|
requestImpl_(type, request) {
|
|
69
72
|
expect(request).toBeTruthy();
|
|
70
|
-
expect(request.uris.length).
|
|
73
|
+
expect(request.uris.length).toBeLessThanOrEqual(this.maxUris_);
|
|
71
74
|
|
|
72
75
|
const requestedUri = request.uris[0];
|
|
73
76
|
|
|
@@ -288,6 +291,11 @@ shaka.test.FakeNetworkingEngine = class {
|
|
|
288
291
|
return this;
|
|
289
292
|
}
|
|
290
293
|
|
|
294
|
+
setMaxUris(maxUris) {
|
|
295
|
+
this.maxUris_ = maxUris;
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
|
|
291
299
|
/**
|
|
292
300
|
* Expects that a request for the given segment has occurred.
|
|
293
301
|
*
|
|
@@ -556,11 +556,15 @@ shaka.test.ManifestGenerator.Stream = class {
|
|
|
556
556
|
/** @type {(string|undefined)} */
|
|
557
557
|
this.hdr = undefined;
|
|
558
558
|
/** @type {(string|undefined)} */
|
|
559
|
+
this.videoLayout = undefined;
|
|
560
|
+
/** @type {(string|undefined)} */
|
|
559
561
|
this.tilesLayout = undefined;
|
|
560
562
|
/** @type {?shaka.media.ManifestParser.AccessibilityPurpose} */
|
|
561
563
|
this.accessibilityPurpose;
|
|
562
564
|
/** @type {boolean} */
|
|
563
565
|
this.external = false;
|
|
566
|
+
/** @type {boolean} */
|
|
567
|
+
this.fastSwitching = false;
|
|
564
568
|
}
|
|
565
569
|
|
|
566
570
|
/** @type {shaka.extern.Stream} */
|
|
@@ -42,7 +42,7 @@ shaka.test.ManifestParser = class {
|
|
|
42
42
|
/**
|
|
43
43
|
* Creates a segment reference using a relative URI.
|
|
44
44
|
*
|
|
45
|
-
* @param {string} uri A relative URI to http://example.com
|
|
45
|
+
* @param {string|Array.<string>} uri A relative URI to http://example.com
|
|
46
46
|
* @param {number} start
|
|
47
47
|
* @param {number} end
|
|
48
48
|
* @param {string=} baseUri
|
|
@@ -57,7 +57,19 @@ shaka.test.ManifestParser = class {
|
|
|
57
57
|
static makeReference(uri, start, end, baseUri = '',
|
|
58
58
|
startByte = 0, endByte = null, timestampOffset = 0,
|
|
59
59
|
partialReferences = [], tilesLayout = '', syncTime = null) {
|
|
60
|
-
const getUris = () =>
|
|
60
|
+
const getUris = () => {
|
|
61
|
+
const uris = [];
|
|
62
|
+
if (uri instanceof Array) {
|
|
63
|
+
for (const url of uri) {
|
|
64
|
+
if (url.length) {
|
|
65
|
+
uris.push(baseUri + url);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} else if (uri.length) {
|
|
69
|
+
uris.push(baseUri + uri);
|
|
70
|
+
}
|
|
71
|
+
return uris;
|
|
72
|
+
};
|
|
61
73
|
|
|
62
74
|
// If a test wants to verify these, they can be set explicitly after
|
|
63
75
|
// makeReference is called.
|
|
@@ -529,7 +529,7 @@ shaka.test.FakeTransmuxer = class {
|
|
|
529
529
|
jasmine.createSpy('transmux').and.returnValue(Promise.resolve(output));
|
|
530
530
|
|
|
531
531
|
/** @type {!jasmine.Spy} */
|
|
532
|
-
this.
|
|
533
|
-
jasmine.createSpy('
|
|
532
|
+
this.getOriginalMimeType =
|
|
533
|
+
jasmine.createSpy('getOriginalMimeType').and.returnValue('mimeType');
|
|
534
534
|
}
|
|
535
535
|
};
|
|
@@ -417,6 +417,7 @@ shaka.test.StreamingEngineUtil = class {
|
|
|
417
417
|
spatialAudio: false,
|
|
418
418
|
accessibilityPurpose: null,
|
|
419
419
|
external: false,
|
|
420
|
+
fastSwitching: false,
|
|
420
421
|
};
|
|
421
422
|
}
|
|
422
423
|
|
|
@@ -459,6 +460,7 @@ shaka.test.StreamingEngineUtil = class {
|
|
|
459
460
|
spatialAudio: false,
|
|
460
461
|
accessibilityPurpose: null,
|
|
461
462
|
external: false,
|
|
463
|
+
fastSwitching: false,
|
|
462
464
|
};
|
|
463
465
|
}
|
|
464
466
|
|
|
@@ -498,6 +500,7 @@ shaka.test.StreamingEngineUtil = class {
|
|
|
498
500
|
spatialAudio: false,
|
|
499
501
|
accessibilityPurpose: null,
|
|
500
502
|
external: false,
|
|
503
|
+
fastSwitching: false,
|
|
501
504
|
};
|
|
502
505
|
}
|
|
503
506
|
};
|
|
@@ -9,10 +9,11 @@ shaka.test.UiUtils = class {
|
|
|
9
9
|
* @param {!HTMLElement} videoContainer
|
|
10
10
|
* @param {!HTMLMediaElement} video
|
|
11
11
|
* @param {!Object=} config
|
|
12
|
-
* @return {!shaka.ui.Overlay}
|
|
12
|
+
* @return {!Promise.<!shaka.ui.Overlay>}
|
|
13
13
|
*/
|
|
14
|
-
static createUIThroughAPI(videoContainer, video, config) {
|
|
15
|
-
const player = new shaka.Player(
|
|
14
|
+
static async createUIThroughAPI(videoContainer, video, config) {
|
|
15
|
+
const player = new shaka.Player();
|
|
16
|
+
await player.attach(video);
|
|
16
17
|
// Create UI
|
|
17
18
|
config = config || {};
|
|
18
19
|
const ui = new shaka.ui.Overlay(player, videoContainer, video);
|
|
@@ -43,7 +43,7 @@ describe('Mp4TtmlParser', () => {
|
|
|
43
43
|
parser.parseInit(ttmlInitSegment);
|
|
44
44
|
const time =
|
|
45
45
|
{periodStart: 0, segmentStart: 0, segmentEnd: 60, vttOffset: 0};
|
|
46
|
-
const ret = parser.parseMedia(ttmlSegmentMultipleMDAT, time);
|
|
46
|
+
const ret = parser.parseMedia(ttmlSegmentMultipleMDAT, time, null);
|
|
47
47
|
// Bodies.
|
|
48
48
|
expect(ret.length).toBe(2);
|
|
49
49
|
// Divs.
|
|
@@ -63,10 +63,10 @@ describe('Mp4TtmlParser', () => {
|
|
|
63
63
|
const parser = new shaka.text.Mp4TtmlParser();
|
|
64
64
|
parser.parseInit(ttmlInitSegment);
|
|
65
65
|
|
|
66
|
-
const ret1 = parser.parseMedia(ttmlSegment, time1);
|
|
66
|
+
const ret1 = parser.parseMedia(ttmlSegment, time1, null);
|
|
67
67
|
expect(ret1.length).toBeGreaterThan(0);
|
|
68
68
|
|
|
69
|
-
const ret2 = parser.parseMedia(ttmlSegment, time2);
|
|
69
|
+
const ret2 = parser.parseMedia(ttmlSegment, time2, null);
|
|
70
70
|
expect(ret2.length).toBeGreaterThan(0);
|
|
71
71
|
|
|
72
72
|
expect(ret2[0].startTime).toBe(ret1[0].startTime + 7);
|
|
@@ -164,7 +164,7 @@ describe('Mp4TtmlParser', () => {
|
|
|
164
164
|
parser.parseInit(ttmlInitSegment);
|
|
165
165
|
const time =
|
|
166
166
|
{periodStart: 0, segmentStart: 0, segmentEnd: 60, vttOffset: 0};
|
|
167
|
-
const result = parser.parseMedia(ttmlSegment, time);
|
|
167
|
+
const result = parser.parseMedia(ttmlSegment, time, null);
|
|
168
168
|
shaka.test.TtmlUtils.verifyHelper(
|
|
169
169
|
cues, result, {startTime: 23, endTime: 53.5});
|
|
170
170
|
});
|
|
@@ -149,7 +149,7 @@ describe('SrtTextParser', () => {
|
|
|
149
149
|
const data = BufferUtils.toUint8(StringUtils.toUTF8(text));
|
|
150
150
|
|
|
151
151
|
const parser = new shaka.text.SrtTextParser();
|
|
152
|
-
const result = parser.parseMedia(data, time);
|
|
152
|
+
const result = parser.parseMedia(data, time, null);
|
|
153
153
|
|
|
154
154
|
const expected = cues.map((cue) => {
|
|
155
155
|
if (cue.nestedCues) {
|
|
@@ -37,7 +37,7 @@ filterDescribe('Cue layout', shaka.test.TextLayoutTests.supported, () => {
|
|
|
37
37
|
// Set up UI controls. The video element is in a paused state by
|
|
38
38
|
// default, so the controls should be shown. The video is not in the
|
|
39
39
|
// DOM and is purely temporary.
|
|
40
|
-
const player = new shaka.Player(
|
|
40
|
+
const player = new shaka.Player();
|
|
41
41
|
ui = new shaka.ui.Overlay(
|
|
42
42
|
player, /** @type {!HTMLElement} */(helper.videoContainer),
|
|
43
43
|
shaka.test.UiUtils.createVideoElement());
|
|
@@ -105,6 +105,7 @@ describe('TextEngine', () => {
|
|
|
105
105
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
106
106
|
dummyData,
|
|
107
107
|
{periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0},
|
|
108
|
+
undefined,
|
|
108
109
|
]);
|
|
109
110
|
|
|
110
111
|
expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([
|
|
@@ -120,6 +121,7 @@ describe('TextEngine', () => {
|
|
|
120
121
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
121
122
|
dummyData,
|
|
122
123
|
{periodStart: 0, segmentStart: 3, segmentEnd: 5, vttOffset: 0},
|
|
124
|
+
undefined,
|
|
123
125
|
]);
|
|
124
126
|
|
|
125
127
|
expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([
|
|
@@ -272,6 +274,7 @@ describe('TextEngine', () => {
|
|
|
272
274
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
273
275
|
dummyData,
|
|
274
276
|
{periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0},
|
|
277
|
+
undefined,
|
|
275
278
|
]);
|
|
276
279
|
expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([
|
|
277
280
|
[
|
|
@@ -286,6 +289,7 @@ describe('TextEngine', () => {
|
|
|
286
289
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
287
290
|
dummyData,
|
|
288
291
|
{periodStart: 4, segmentStart: 4, segmentEnd: 7, vttOffset: 4},
|
|
292
|
+
undefined,
|
|
289
293
|
]);
|
|
290
294
|
expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([
|
|
291
295
|
[
|
|
@@ -316,6 +320,7 @@ describe('TextEngine', () => {
|
|
|
316
320
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
317
321
|
dummyData,
|
|
318
322
|
{periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0},
|
|
323
|
+
undefined,
|
|
319
324
|
]);
|
|
320
325
|
|
|
321
326
|
textEngine.setTimestampOffset(8);
|
|
@@ -325,6 +330,7 @@ describe('TextEngine', () => {
|
|
|
325
330
|
expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([
|
|
326
331
|
dummyData,
|
|
327
332
|
{periodStart: 8, segmentStart: 4, segmentEnd: 7, vttOffset: 4},
|
|
333
|
+
undefined,
|
|
328
334
|
]);
|
|
329
335
|
});
|
|
330
336
|
});
|
|
@@ -1263,6 +1263,35 @@ describe('TtmlTextParser', () => {
|
|
|
1263
1263
|
});
|
|
1264
1264
|
});
|
|
1265
1265
|
|
|
1266
|
+
it('supports smpte:backgroundImage attribute with url', () => {
|
|
1267
|
+
verifyHelper(
|
|
1268
|
+
[
|
|
1269
|
+
{
|
|
1270
|
+
startTime: 62.05,
|
|
1271
|
+
endTime: 3723.2,
|
|
1272
|
+
payload: '',
|
|
1273
|
+
},
|
|
1274
|
+
],
|
|
1275
|
+
'<tt ' +
|
|
1276
|
+
'xmlns:ttm="http://www.w3.org/ns/ttml#metadata" ' +
|
|
1277
|
+
'xmlns:smpte="http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt">' +
|
|
1278
|
+
'<metadata>' +
|
|
1279
|
+
'<smpte:image imageType="PNG" encoding="Base64" xml:id="img_0">' +
|
|
1280
|
+
'base64EncodedImage</smpte:image>' +
|
|
1281
|
+
'</metadata>' +
|
|
1282
|
+
'<body><div smpte:backgroundImage="img_0.png">' +
|
|
1283
|
+
'<p begin="01:02.05" end="01:02:03.200"></p>' +
|
|
1284
|
+
'</div></body></tt>',
|
|
1285
|
+
{periodStart: 0, segmentStart: 60, segmentEnd: 3730, vttOffset: 0},
|
|
1286
|
+
{startTime: 62.05, endTime: 3723.2},
|
|
1287
|
+
{
|
|
1288
|
+
startTime: 62.05,
|
|
1289
|
+
endTime: 3723.2,
|
|
1290
|
+
backgroundImage: 'foo://bar/img_0.png',
|
|
1291
|
+
isContainer: false,
|
|
1292
|
+
});
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1266
1295
|
it('supports smpte:backgroundImage attribute in div element', () => {
|
|
1267
1296
|
verifyHelper(
|
|
1268
1297
|
[],
|
|
@@ -2112,7 +2141,8 @@ describe('TtmlTextParser', () => {
|
|
|
2112
2141
|
function verifyHelper(cues, text, time, bodyProperties, divProperties) {
|
|
2113
2142
|
const data =
|
|
2114
2143
|
shaka.util.BufferUtils.toUint8(shaka.util.StringUtils.toUTF8(text));
|
|
2115
|
-
const result = new shaka.text.TtmlTextParser()
|
|
2144
|
+
const result = new shaka.text.TtmlTextParser()
|
|
2145
|
+
.parseMedia(data, time, 'foo://bar');
|
|
2116
2146
|
shaka.test.TtmlUtils.verifyHelper(
|
|
2117
2147
|
cues, result, bodyProperties, divProperties);
|
|
2118
2148
|
}
|
|
@@ -2139,7 +2169,8 @@ describe('TtmlTextParser', () => {
|
|
|
2139
2169
|
expect(() => {
|
|
2140
2170
|
new shaka.text.TtmlTextParser().parseMedia(
|
|
2141
2171
|
shaka.util.BufferUtils.toUint8(data),
|
|
2142
|
-
{periodStart: 0, segmentStart: 0, segmentEnd: 10, vttOffset: 0}
|
|
2172
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 10, vttOffset: 0},
|
|
2173
|
+
'foo://bar');
|
|
2143
2174
|
}).toThrow(error);
|
|
2144
2175
|
}
|
|
2145
2176
|
});
|
|
@@ -56,5 +56,14 @@ describe('TransmuxerEngine', () => {
|
|
|
56
56
|
ContentType.VIDEO, 'video/MP2T; codecs="avc1.420001"'))
|
|
57
57
|
.toBe('video/mp4; codecs="avc1.420001"');
|
|
58
58
|
});
|
|
59
|
+
|
|
60
|
+
it('converts legacy avc1 codec strings', () => {
|
|
61
|
+
expect(convertCodecs(
|
|
62
|
+
ContentType.VIDEO, 'video/mp2t; codecs="avc1.100.42"'))
|
|
63
|
+
.toBe('video/mp4; codecs="avc1.64002a"');
|
|
64
|
+
expect(convertCodecs(
|
|
65
|
+
ContentType.VIDEO, 'video/mp2t; codecs="avc1.66.1"'))
|
|
66
|
+
.toBe('video/mp4; codecs="avc1.420001"');
|
|
67
|
+
});
|
|
59
68
|
});
|
|
60
69
|
});
|
|
@@ -4,7 +4,36 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* For unknown reasons, these tests fail in the test labs for Edge on Windows,
|
|
9
|
+
* in ways that do not seem to be unrelated to transmuxers.
|
|
10
|
+
* Practical testing has not found any sign that playback is actually broken in
|
|
11
|
+
* Edge, so these tests are disabled on Edge for the time being.
|
|
12
|
+
* TODO(#5834): Remove this filter once the tests are fixed.
|
|
13
|
+
* @return {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function checkNoBrokenEdge() {
|
|
16
|
+
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
17
|
+
if (shaka.util.Platform.isWindows() && shaka.util.Platform.isEdge() &&
|
|
18
|
+
chromeVersion && chromeVersion <= 118) {
|
|
19
|
+
// When the tests fail, it's due to the manifest parser failing to find a
|
|
20
|
+
// factory. Attempt to find a factory first, to avoid filtering the tests
|
|
21
|
+
// when running in a non-broken Edge environment.
|
|
22
|
+
const uri = 'fakeuri.m3u8';
|
|
23
|
+
const mimeType = 'application/x-mpegurl';
|
|
24
|
+
/* eslint-disable no-restricted-syntax */
|
|
25
|
+
try {
|
|
26
|
+
shaka.media.ManifestParser.getFactory(uri, mimeType);
|
|
27
|
+
return true;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
/* eslint-enable no-restricted-syntax */
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
filterDescribe('Transmuxer Player', checkNoBrokenEdge, () => {
|
|
8
37
|
const Util = shaka.test.Util;
|
|
9
38
|
|
|
10
39
|
/** @type {!jasmine.Spy} */
|
|
@@ -73,7 +102,8 @@ describe('Transmuxer Player', () => {
|
|
|
73
102
|
|
|
74
103
|
beforeEach(async () => {
|
|
75
104
|
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
76
|
-
player = new compiledShaka.Player(
|
|
105
|
+
player = new compiledShaka.Player();
|
|
106
|
+
await player.attach(video);
|
|
77
107
|
|
|
78
108
|
player.configure('mediaSource.forceTransmux', true);
|
|
79
109
|
player.configure('streaming.useNativeHlsOnSafari', false);
|
|
@@ -161,7 +191,7 @@ describe('Transmuxer Player', () => {
|
|
|
161
191
|
pending('Codec EC-3 is not supported by the platform.');
|
|
162
192
|
}
|
|
163
193
|
|
|
164
|
-
await player.load('/base/test/test/assets/hls-raw-
|
|
194
|
+
await player.load('/base/test/test/assets/hls-raw-ec3/prog_index.m3u8');
|
|
165
195
|
await video.play();
|
|
166
196
|
expect(player.isLive()).toBe(false);
|
|
167
197
|
|
package/test/ui/ad_ui_unit.js
CHANGED
|
@@ -25,14 +25,14 @@ describe('Ad UI', () => {
|
|
|
25
25
|
shaka.Player.setAdManagerFactory(() => new shaka.test.FakeAdManager());
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
beforeEach(() => {
|
|
28
|
+
beforeEach(async () => {
|
|
29
29
|
container =
|
|
30
30
|
/** @type {!HTMLElement} */ (document.createElement('div'));
|
|
31
31
|
document.body.appendChild(container);
|
|
32
32
|
|
|
33
33
|
video = shaka.test.UiUtils.createVideoElement();
|
|
34
34
|
container.appendChild(video);
|
|
35
|
-
UiUtils.createUIThroughAPI(container, video);
|
|
35
|
+
await UiUtils.createUIThroughAPI(container, video);
|
|
36
36
|
adManager = video['ui'].getControls().getPlayer().getAdManager();
|
|
37
37
|
});
|
|
38
38
|
|