shaka-player 4.3.9 → 4.4.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/workflows/build-and-test.yaml +11 -18
- package/.github/workflows/compute-incremental-coverage.py +3 -0
- package/.github/workflows/release-please.yaml +7 -0
- package/.github/workflows/selenium-lab-tests.yaml +45 -10
- package/AUTHORS +9 -0
- package/CHANGELOG.md +295 -190
- package/CONTRIBUTORS +8 -0
- package/LICENSE +32 -0
- package/README.md +63 -10
- package/demo/autoTemplate.txt +40 -5
- package/demo/close_button.js +11 -0
- package/demo/common/asset.js +13 -1
- package/demo/common/assets.js +112 -28
- package/demo/common/message_ids.js +25 -1
- package/demo/config.js +69 -10
- package/demo/customWarning.txt +2 -2
- package/demo/index.html +3 -1
- package/demo/locales/en.json +26 -2
- package/demo/locales/source.json +105 -9
- package/demo/main.js +57 -9
- package/demo/search.js +3 -1
- package/demo/service_worker.js +3 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +132 -118
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +132 -118
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +46 -28
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +60 -52
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +60 -52
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.externs.js +1188 -616
- package/dist/shaka-player.compiled.debug.js +1046 -700
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1188 -616
- package/dist/shaka-player.compiled.js +1094 -933
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +677 -392
- package/dist/shaka-player.ui.debug.d.ts +677 -392
- package/dist/shaka-player.ui.debug.externs.js +1023 -451
- package/dist/shaka-player.ui.debug.js +1101 -738
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1023 -451
- package/dist/shaka-player.ui.js +1244 -1071
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +15 -1
- package/docs/tutorials/application-level-redirects.md +1 -1
- package/docs/tutorials/config.md +9 -5
- package/docs/tutorials/drm-config.md +61 -0
- package/docs/tutorials/fairplay.md +19 -4
- package/docs/tutorials/license-server-auth.md +4 -4
- package/docs/tutorials/license-wrapping.md +2 -2
- package/docs/tutorials/ui-customization.md +7 -3
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/ima.js +123 -2
- package/externs/isoboxer.js +217 -0
- package/externs/mediakeys.js +18 -0
- package/externs/mux.js +1 -105
- package/externs/pictureinpicture.js +48 -0
- package/externs/shaka/ads.js +61 -1
- package/externs/shaka/cea.js +110 -0
- package/externs/shaka/codecs.js +32 -0
- package/externs/shaka/manifest.js +101 -1
- package/externs/shaka/manifest_parser.js +0 -10
- package/externs/shaka/net.js +36 -7
- package/externs/shaka/offline.js +8 -1
- package/externs/shaka/player.js +220 -21
- package/externs/shaka/text.js +1 -382
- package/externs/shaka/transmuxer.js +59 -0
- package/karma.conf.js +15 -0
- package/lib/abr/simple_abr_manager.js +6 -3
- package/lib/ads/ad_manager.js +60 -2
- package/lib/ads/client_side_ad.js +86 -0
- package/lib/ads/client_side_ad_manager.js +93 -5
- package/lib/ads/server_side_ad.js +86 -0
- package/lib/ads/server_side_ad_manager.js +13 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/cea608_data_channel.js +24 -14
- package/lib/cea/cea608_memory.js +5 -2
- package/lib/cea/cea708_service.js +8 -9
- package/lib/cea/cea708_window.js +1 -2
- package/lib/cea/cea_decoder.js +23 -6
- package/lib/cea/cea_utils.js +25 -2
- package/lib/cea/dummy_caption_decoder.js +21 -0
- package/lib/cea/dummy_cea_parser.js +1 -3
- package/lib/cea/mp4_cea_parser.js +15 -10
- package/lib/cea/ts_cea_parser.js +69 -0
- package/lib/dash/content_protection.js +32 -2
- package/lib/dash/dash_parser.js +93 -31
- package/lib/dash/mpd_utils.js +6 -25
- package/lib/dash/segment_base.js +12 -14
- package/lib/dash/segment_list.js +10 -6
- package/lib/dash/segment_template.js +349 -32
- package/lib/dependencies/all.js +8 -0
- package/lib/hls/hls_classes.js +33 -8
- package/lib/hls/hls_parser.js +805 -191
- package/lib/hls/manifest_text_parser.js +4 -14
- package/lib/media/adaptation_set_criteria.js +43 -3
- package/lib/media/closed_caption_parser.js +74 -12
- package/lib/media/drm_engine.js +189 -49
- package/lib/media/gap_jumping_controller.js +1 -1
- package/lib/media/manifest_parser.js +34 -0
- package/lib/media/media_source_capabilities.js +10 -0
- package/lib/media/media_source_engine.js +475 -231
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +62 -0
- package/lib/media/segment_index.js +50 -14
- package/lib/media/segment_prefetch.js +277 -0
- package/lib/media/segment_reference.js +70 -4
- package/lib/media/streaming_engine.js +258 -81
- package/lib/media/video_wrapper.js +15 -7
- package/lib/mss/content_protection.js +353 -0
- package/lib/mss/mss_parser.js +1081 -0
- package/lib/net/networking_engine.js +60 -10
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +6 -0
- package/lib/offline/storage.js +2 -4
- package/lib/player.js +309 -105
- package/lib/polyfill/media_capabilities.js +43 -3
- package/lib/polyfill/patchedmediakeys_apple.js +5 -0
- package/lib/polyfill/patchedmediakeys_nop.js +5 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
- package/lib/text/cue.js +208 -130
- package/lib/text/lrc_text_parser.js +2 -2
- package/lib/text/mp4_vtt_parser.js +2 -2
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +2 -1
- package/lib/text/srt_text_parser.js +9 -1
- package/lib/text/ssa_text_parser.js +2 -2
- package/lib/text/text_engine.js +3 -21
- package/lib/text/text_utils.js +71 -20
- package/lib/text/ui_text_displayer.js +14 -14
- package/lib/text/vtt_text_parser.js +22 -14
- package/lib/transmuxer/aac_transmuxer.js +224 -0
- package/lib/transmuxer/ac3.js +142 -0
- package/lib/transmuxer/ac3_transmuxer.js +212 -0
- package/lib/transmuxer/adts.js +232 -0
- package/lib/transmuxer/ec3.js +103 -0
- package/lib/transmuxer/ec3_transmuxer.js +212 -0
- package/lib/transmuxer/h264.js +324 -0
- package/lib/transmuxer/mp3_transmuxer.js +204 -0
- package/lib/transmuxer/mpeg_audio.js +196 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
- package/lib/transmuxer/mss_transmuxer.js +389 -0
- package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
- package/lib/transmuxer/transmuxer_engine.js +161 -0
- package/lib/transmuxer/ts_transmuxer.js +738 -0
- package/lib/util/cmcd_manager.js +131 -71
- package/lib/util/error.js +62 -26
- package/lib/util/exp_golomb.js +220 -0
- package/lib/util/fairplay_utils.js +64 -13
- package/lib/util/id3_utils.js +56 -3
- package/lib/util/language_utils.js +11 -8
- package/lib/util/manifest_parser_utils.js +3 -0
- package/lib/util/mime_utils.js +44 -7
- package/lib/util/mp4_box_parsers.js +233 -5
- package/lib/util/mp4_generator.js +1381 -0
- package/lib/util/periods.js +40 -34
- package/lib/util/platform.js +25 -3
- package/lib/util/player_configuration.js +38 -1
- package/lib/util/stream_utils.js +138 -27
- package/lib/util/text_parser.js +1 -1
- package/lib/util/ts_parser.js +470 -47
- package/lib/util/xml_utils.js +16 -3
- package/maintained-branches.md +2 -2
- package/package.json +4 -2
- package/roadmap.md +21 -6
- package/shaka-player.uncompiled.js +18 -0
- package/test/abr/simple_abr_manager_unit.js +32 -4
- package/test/ads/ad_manager_unit.js +18 -2
- package/test/cast/cast_utils_unit.js +7 -2
- package/test/cea/cea608_memory_unit.js +24 -0
- package/test/cea/cea_decoder_unit.js +33 -0
- package/test/dash/dash_parser_content_protection_unit.js +93 -3
- package/test/dash/dash_parser_live_unit.js +56 -13
- package/test/dash/dash_parser_manifest_unit.js +70 -2
- package/test/dash/dash_parser_segment_base_unit.js +14 -9
- package/test/dash/dash_parser_segment_template_unit.js +286 -6
- package/test/demo/demo_unit.js +5 -1
- package/test/hls/hls_live_unit.js +188 -28
- package/test/hls/hls_parser_unit.js +250 -109
- package/test/hls/manifest_text_parser_unit.js +18 -13
- package/test/media/adaptation_set_criteria_unit.js +46 -14
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/drm_engine_integration.js +11 -8
- package/test/media/drm_engine_unit.js +220 -7
- package/test/media/media_source_engine_integration.js +122 -38
- package/test/media/media_source_engine_unit.js +133 -153
- package/test/media/playhead_unit.js +3 -0
- package/test/media/presentation_timeline_unit.js +51 -0
- package/test/media/segment_index_unit.js +52 -0
- package/test/media/segment_prefetch_unit.js +243 -0
- package/test/media/streaming_engine_integration.js +9 -3
- package/test/media/streaming_engine_unit.js +440 -59
- package/test/mss/mss_parser_content_protection_unit.js +49 -0
- package/test/mss/mss_parser_unit.js +472 -0
- package/test/mss/mss_player_integration.js +123 -0
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/storage_integration.js +6 -1
- package/test/player_integration.js +4 -1
- package/test/player_unit.js +386 -133
- package/test/polyfill/media_capabilities_unit.js +18 -0
- package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
- package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
- package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
- package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
- package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
- package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
- package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
- package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
- package/test/test/boot.js +7 -2
- package/test/test/util/fake_ad.js +99 -0
- package/test/test/util/fake_ad_manager.js +7 -1
- package/test/test/util/fake_networking_engine.js +41 -14
- package/test/test/util/fake_segment_prefetch.js +81 -0
- package/test/test/util/manifest_generator.js +19 -5
- package/test/test/util/mss_parser_util.js +115 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +12 -3
- package/test/test/util/streaming_engine_util.js +14 -4
- package/test/test/util/ttml_utils.js +2 -2
- package/test/test/util/ui_utils.js +5 -1
- package/test/text/cue_integration.js +1 -1
- package/test/text/srt_text_parser_unit.js +78 -0
- package/test/text/text_engine_unit.js +17 -8
- package/test/text/ui_text_displayer_unit.js +4 -4
- package/test/text/vtt_text_parser_unit.js +59 -40
- package/test/text/web_vtt_generator_unit.js +9 -3
- package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
- package/test/transmuxer/transmuxer_engine_integration.js +60 -0
- package/test/transmuxer/transmuxer_integration.js +296 -0
- package/test/util/cmcd_manager_unit.js +162 -13
- package/test/util/language_utils_unit.js +9 -2
- package/test/util/mp4_box_parsers_unit.js +39 -4
- package/test/util/periods_unit.js +34 -26
- package/test/util/stream_utils_unit.js +60 -107
- package/ui/controls.js +19 -1
- package/ui/controls.less +1 -0
- package/ui/externs/ui.js +13 -3
- package/ui/language_utils.js +15 -0
- package/ui/less/thumbnails.less +26 -0
- package/ui/locales/oc.json +42 -0
- package/ui/pip_button.js +83 -2
- package/ui/range_element.js +15 -0
- package/ui/resolution_selection.js +9 -2
- package/ui/seek_bar.js +230 -1
- package/ui/ui.js +5 -0
- package/lib/cea/i_caption_decoder.js +0 -51
- package/lib/cea/i_cea_parser.js +0 -68
|
@@ -66,8 +66,6 @@ describe('HlsParser live', () => {
|
|
|
66
66
|
|
|
67
67
|
config = shaka.util.PlayerConfiguration.createDefault().manifest;
|
|
68
68
|
playerInterface = {
|
|
69
|
-
modifyManifestRequest: (request, manifestInfo) => {},
|
|
70
|
-
modifySegmentRequest: (request, segmentInfo) => {},
|
|
71
69
|
filter: () => Promise.resolve(),
|
|
72
70
|
makeTextStreamsForClosedCaptions: (manifest) => {},
|
|
73
71
|
networkingEngine: fakeNetEngine,
|
|
@@ -90,6 +88,15 @@ describe('HlsParser live', () => {
|
|
|
90
88
|
parser.stop();
|
|
91
89
|
});
|
|
92
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Gets a spy on the function that sets the update period.
|
|
93
|
+
* @return {!jasmine.Spy}
|
|
94
|
+
* @suppress {accessControls}
|
|
95
|
+
*/
|
|
96
|
+
function updateTickSpy() {
|
|
97
|
+
return spyOn(parser.updatePlaylistTimer_, 'tickAfter');
|
|
98
|
+
}
|
|
99
|
+
|
|
93
100
|
/**
|
|
94
101
|
* Trigger a manifest update.
|
|
95
102
|
* @suppress {accessControls}
|
|
@@ -334,6 +341,34 @@ describe('HlsParser live', () => {
|
|
|
334
341
|
expect(notifySegmentsSpy).toHaveBeenCalled();
|
|
335
342
|
});
|
|
336
343
|
|
|
344
|
+
it('fatal error on manifest update request failure when ' +
|
|
345
|
+
'raiseFatalErrorOnManifestUpdateRequestFailure is true', async () => {
|
|
346
|
+
const manifestConfig =
|
|
347
|
+
shaka.util.PlayerConfiguration.createDefault().manifest;
|
|
348
|
+
manifestConfig.raiseFatalErrorOnManifestUpdateRequestFailure = true;
|
|
349
|
+
parser.configure(manifestConfig);
|
|
350
|
+
|
|
351
|
+
const updateTick = updateTickSpy();
|
|
352
|
+
|
|
353
|
+
await testInitialManifest(master, media);
|
|
354
|
+
expect(updateTick).toHaveBeenCalledTimes(1);
|
|
355
|
+
|
|
356
|
+
/** @type {!jasmine.Spy} */
|
|
357
|
+
const onError = jasmine.createSpy('onError');
|
|
358
|
+
playerInterface.onError = shaka.test.Util.spyFunc(onError);
|
|
359
|
+
|
|
360
|
+
const error = new shaka.util.Error(
|
|
361
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
362
|
+
shaka.util.Error.Category.NETWORK,
|
|
363
|
+
shaka.util.Error.Code.BAD_HTTP_STATUS);
|
|
364
|
+
const operation = shaka.util.AbortableOperation.failed(error);
|
|
365
|
+
fakeNetEngine.request.and.returnValue(operation);
|
|
366
|
+
|
|
367
|
+
await delayForUpdatePeriod();
|
|
368
|
+
expect(onError).toHaveBeenCalledWith(error);
|
|
369
|
+
expect(updateTick).toHaveBeenCalledTimes(1);
|
|
370
|
+
});
|
|
371
|
+
|
|
337
372
|
it('converts to VOD only after all playlists end', async () => {
|
|
338
373
|
const master = [
|
|
339
374
|
'#EXTM3U\n',
|
|
@@ -373,9 +408,13 @@ describe('HlsParser live', () => {
|
|
|
373
408
|
manifest, mediaWithAdditionalSegment + '#EXT-X-ENDLIST\n');
|
|
374
409
|
|
|
375
410
|
// We saw one request for the video playlist, which signalled "ENDLIST".
|
|
411
|
+
const type =
|
|
412
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST;
|
|
413
|
+
|
|
376
414
|
fakeNetEngine.expectRequest(
|
|
377
415
|
'test:/video',
|
|
378
|
-
shaka.net.NetworkingEngine.RequestType.MANIFEST
|
|
416
|
+
shaka.net.NetworkingEngine.RequestType.MANIFEST,
|
|
417
|
+
{type});
|
|
379
418
|
expect(manifest.presentationTimeline.isLive()).toBe(false);
|
|
380
419
|
|
|
381
420
|
fakeNetEngine.request.calls.reset();
|
|
@@ -505,6 +544,24 @@ describe('HlsParser live', () => {
|
|
|
505
544
|
expect(manifest.presentationTimeline.getDelay()).toBe(15);
|
|
506
545
|
});
|
|
507
546
|
|
|
547
|
+
it('sets presentation delay if defined', async () => {
|
|
548
|
+
const media = [
|
|
549
|
+
'#EXTM3U\n',
|
|
550
|
+
'#EXT-X-SERVER-CONTROL:HOLD-BACK=2\n',
|
|
551
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
552
|
+
'#EXT-X-PART-INF:PART-TARGET=0.5\n',
|
|
553
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
554
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
555
|
+
'#EXTINF:2,\n',
|
|
556
|
+
'main.mp4\n',
|
|
557
|
+
].join('');
|
|
558
|
+
|
|
559
|
+
const manifest = await testInitialManifest(master, media);
|
|
560
|
+
// Presentation delay should be the value of 'HOLD-BACK' if not
|
|
561
|
+
// configured.
|
|
562
|
+
expect(manifest.presentationTimeline.getDelay()).toBe(2);
|
|
563
|
+
});
|
|
564
|
+
|
|
508
565
|
it('sets presentation delay for low latency mode', async () => {
|
|
509
566
|
const mediaWithLowLatency = [
|
|
510
567
|
'#EXTM3U\n',
|
|
@@ -577,44 +634,44 @@ describe('HlsParser live', () => {
|
|
|
577
634
|
'#EXTM3U\n',
|
|
578
635
|
'#EXT-X-TARGETDURATION:5\n',
|
|
579
636
|
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
580
|
-
'#EXT-X-MAP:URI="init.mp4"
|
|
637
|
+
'#EXT-X-MAP:URI="init.mp4"\n',
|
|
581
638
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
582
639
|
// ref includes partialRef, partialRef2
|
|
583
640
|
// partialRef
|
|
584
|
-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",
|
|
641
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
|
|
585
642
|
// partialRef2
|
|
586
|
-
'#EXT-X-PART:DURATION=2,URI="partial2.mp4",
|
|
643
|
+
'#EXT-X-PART:DURATION=2,URI="partial2.mp4",INDEPENDENT=YES\n',
|
|
587
644
|
'#EXTINF:4,\n',
|
|
588
645
|
'main.mp4\n',
|
|
589
646
|
// ref2 includes partialRef3, preloadRef
|
|
590
647
|
// partialRef3
|
|
591
|
-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",
|
|
648
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
|
|
592
649
|
// preloadRef
|
|
593
|
-
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"
|
|
594
|
-
'BYTERANGE-LENGTH=210\n',
|
|
650
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"\n',
|
|
595
651
|
].join('');
|
|
596
652
|
|
|
597
653
|
const partialRef = makeReference(
|
|
598
654
|
'test:/partial.mp4', 0, 2, /* syncTime= */ null,
|
|
599
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
655
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
|
|
600
656
|
|
|
601
657
|
const partialRef2 = makeReference(
|
|
602
658
|
'test:/partial2.mp4', 2, 4, /* syncTime= */ null,
|
|
603
|
-
/* baseUri= */ '', /* startByte= */
|
|
659
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
|
|
604
660
|
|
|
605
661
|
const ref = makeReference(
|
|
606
662
|
'test:/main.mp4', 0, 4, /* syncTime= */ null,
|
|
607
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
663
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
608
664
|
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
609
665
|
|
|
610
666
|
const partialRef3 = makeReference(
|
|
611
667
|
'test:/partial.mp4', 4, 6, /* syncTime= */ null,
|
|
612
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
668
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
|
|
613
669
|
|
|
614
670
|
const preloadRef = makeReference(
|
|
615
671
|
'test:/partial.mp4', 6, 7.5, /* syncTime= */ null,
|
|
616
|
-
/* baseUri= */ '', /* startByte= */
|
|
672
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
|
|
617
673
|
preloadRef.markAsPreload();
|
|
674
|
+
preloadRef.markAsNonIndependent();
|
|
618
675
|
|
|
619
676
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
620
677
|
const ref2 = makeReference(
|
|
@@ -625,6 +682,85 @@ describe('HlsParser live', () => {
|
|
|
625
682
|
await testInitialManifest(master, mediaWithPartialSegments, [ref, ref2]);
|
|
626
683
|
});
|
|
627
684
|
|
|
685
|
+
it('parses streams with partial and preload hinted segments and BYTERANGE', async () => { // eslint-disable-line max-len
|
|
686
|
+
playerInterface.isLowLatencyMode = () => true;
|
|
687
|
+
const mediaWithPartialSegments = [
|
|
688
|
+
'#EXTM3U\n',
|
|
689
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
690
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
691
|
+
'#EXT-X-MAP:URI="init.mp4"\n',
|
|
692
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
693
|
+
// ref includes partialRef, partialRef2
|
|
694
|
+
// partialRef
|
|
695
|
+
'#EXT-X-PART:DURATION=2,URI="ref1.mp4",BYTERANGE=200@0,',
|
|
696
|
+
'INDEPENDENT=YES\n',
|
|
697
|
+
// partialRef2
|
|
698
|
+
'#EXT-X-PART:DURATION=2,URI="ref1.mp4",BYTERANGE=230@200,',
|
|
699
|
+
'INDEPENDENT=YES\n',
|
|
700
|
+
'#EXTINF:4,\n',
|
|
701
|
+
'ref1.mp4\n',
|
|
702
|
+
// ref2 includes partialRef3, preloadRef
|
|
703
|
+
// partialRef3
|
|
704
|
+
'#EXT-X-PART:DURATION=2,URI="ref2.mp4",BYTERANGE=210@0,',
|
|
705
|
+
'INDEPENDENT=YES\n',
|
|
706
|
+
// preloadRef
|
|
707
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="ref2.mp4",BYTERANGE-START=210,',
|
|
708
|
+
'BYTERANGE-LENGTH=210\n',
|
|
709
|
+
].join('');
|
|
710
|
+
|
|
711
|
+
// If ReadableStream is defined we can apply some optimizations
|
|
712
|
+
if (window.ReadableStream) {
|
|
713
|
+
const ref = makeReference(
|
|
714
|
+
'test:/ref1.mp4', 0, 4, /* syncTime= */ null,
|
|
715
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
716
|
+
/* timestampOffset= */ 0);
|
|
717
|
+
ref.markAsByterangeOptimization();
|
|
718
|
+
|
|
719
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
720
|
+
const ref2 = makeReference(
|
|
721
|
+
'test:/ref2.mp4', 4, 7.5, /* syncTime= */ null,
|
|
722
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
723
|
+
/* timestampOffset= */ 0);
|
|
724
|
+
ref2.markAsByterangeOptimization();
|
|
725
|
+
ref2.markAsPreload();
|
|
726
|
+
|
|
727
|
+
await testInitialManifest(master, mediaWithPartialSegments,
|
|
728
|
+
[ref, ref2]);
|
|
729
|
+
} else {
|
|
730
|
+
const partialRef = makeReference(
|
|
731
|
+
'test:/ref1.mp4', 0, 2, /* syncTime= */ null,
|
|
732
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 199);
|
|
733
|
+
|
|
734
|
+
const partialRef2 = makeReference(
|
|
735
|
+
'test:/ref1.mp4', 2, 4, /* syncTime= */ null,
|
|
736
|
+
/* baseUri= */ '', /* startByte= */ 200, /* endByte= */ 429);
|
|
737
|
+
|
|
738
|
+
const ref = makeReference(
|
|
739
|
+
'test:/ref1.mp4', 0, 4, /* syncTime= */ null,
|
|
740
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
741
|
+
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
742
|
+
|
|
743
|
+
const partialRef3 = makeReference(
|
|
744
|
+
'test:/ref2.mp4', 4, 6, /* syncTime= */ null,
|
|
745
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
746
|
+
|
|
747
|
+
const preloadRef = makeReference(
|
|
748
|
+
'test:/ref2.mp4', 6, 7.5, /* syncTime= */ null,
|
|
749
|
+
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ 419);
|
|
750
|
+
preloadRef.markAsPreload();
|
|
751
|
+
preloadRef.markAsNonIndependent();
|
|
752
|
+
|
|
753
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
754
|
+
const ref2 = makeReference(
|
|
755
|
+
'', 4, 7.5, /* syncTime= */ null,
|
|
756
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 419,
|
|
757
|
+
/* timestampOffset= */ 0, [partialRef3, preloadRef]);
|
|
758
|
+
|
|
759
|
+
await testInitialManifest(master, mediaWithPartialSegments,
|
|
760
|
+
[ref, ref2]);
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
|
|
628
764
|
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
629
765
|
it('ignores preload hinted segments without target duration', async () => {
|
|
630
766
|
playerInterface.isLowLatencyMode = () => true;
|
|
@@ -640,9 +776,9 @@ describe('HlsParser live', () => {
|
|
|
640
776
|
'main.mp4\n',
|
|
641
777
|
// ref2 includes partialRef, but not preloadRef
|
|
642
778
|
// partialRef
|
|
643
|
-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",
|
|
779
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
|
|
644
780
|
// preloadRef
|
|
645
|
-
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"
|
|
781
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"\n',
|
|
646
782
|
].join('');
|
|
647
783
|
|
|
648
784
|
const ref = makeReference(
|
|
@@ -652,12 +788,12 @@ describe('HlsParser live', () => {
|
|
|
652
788
|
|
|
653
789
|
const partialRef = makeReference(
|
|
654
790
|
'test:/partial.mp4', 4, 6, /* syncTime= */ null,
|
|
655
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
791
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
|
|
656
792
|
|
|
657
793
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
658
794
|
const ref2 = makeReference(
|
|
659
795
|
'', 4, 6, /* syncTime= */ null,
|
|
660
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
796
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
661
797
|
/* timestampOffset= */ 0, [partialRef]);
|
|
662
798
|
|
|
663
799
|
await testInitialManifest(master, mediaWithPartialSegments, [ref, ref2]);
|
|
@@ -843,9 +979,12 @@ describe('HlsParser live', () => {
|
|
|
843
979
|
// Only one request was made, and it was for the playlist.
|
|
844
980
|
// No segment requests were needed to get the start time.
|
|
845
981
|
expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
|
|
982
|
+
const type =
|
|
983
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST;
|
|
846
984
|
fakeNetEngine.expectRequest(
|
|
847
985
|
'test:/video',
|
|
848
|
-
shaka.net.NetworkingEngine.RequestType.MANIFEST
|
|
986
|
+
shaka.net.NetworkingEngine.RequestType.MANIFEST,
|
|
987
|
+
{type});
|
|
849
988
|
});
|
|
850
989
|
|
|
851
990
|
it('request playlist delta updates to skip segments', async () => {
|
|
@@ -855,39 +994,60 @@ describe('HlsParser live', () => {
|
|
|
855
994
|
'#EXT-X-TARGETDURATION:5\n',
|
|
856
995
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
857
996
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
858
|
-
'#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=60.0
|
|
997
|
+
'#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
|
|
859
998
|
'#EXTINF:2,\n',
|
|
860
|
-
'
|
|
999
|
+
'main0.mp4\n',
|
|
861
1000
|
'#EXTINF:2,\n',
|
|
862
|
-
'
|
|
1001
|
+
'main1.mp4\n',
|
|
863
1002
|
].join('');
|
|
864
1003
|
|
|
865
|
-
const
|
|
1004
|
+
const mediaWithSkippedSegments1 = [
|
|
866
1005
|
'#EXTM3U\n',
|
|
867
1006
|
'#EXT-X-TARGETDURATION:5\n',
|
|
868
1007
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
869
|
-
'#EXT-X-MEDIA-SEQUENCE:
|
|
870
|
-
'#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=60.0
|
|
1008
|
+
'#EXT-X-MEDIA-SEQUENCE:1\n',
|
|
1009
|
+
'#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
|
|
871
1010
|
'#EXT-X-SKIP:SKIPPED-SEGMENTS=1\n',
|
|
872
1011
|
'#EXTINF:2,\n',
|
|
873
1012
|
'main2.mp4\n',
|
|
1013
|
+
].join('');
|
|
1014
|
+
|
|
1015
|
+
const mediaWithSkippedSegments2 = [
|
|
1016
|
+
'#EXTM3U\n',
|
|
1017
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
1018
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
1019
|
+
'#EXT-X-MEDIA-SEQUENCE:2\n',
|
|
1020
|
+
'#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
|
|
1021
|
+
'#EXT-X-SKIP:SKIPPED-SEGMENTS=1\n',
|
|
874
1022
|
'#EXTINF:2,\n',
|
|
875
1023
|
'main3.mp4\n',
|
|
876
1024
|
].join('');
|
|
877
1025
|
|
|
878
1026
|
fakeNetEngine.setResponseText(
|
|
879
|
-
'test:/video?_HLS_skip=YES',
|
|
1027
|
+
'test:/video?_HLS_msn=2&_HLS_skip=YES', mediaWithSkippedSegments1);
|
|
1028
|
+
|
|
1029
|
+
fakeNetEngine.setResponseText(
|
|
1030
|
+
'test:/video?_HLS_msn=3&_HLS_skip=YES', mediaWithSkippedSegments2);
|
|
880
1031
|
|
|
881
1032
|
playerInterface.isLowLatencyMode = () => true;
|
|
882
1033
|
|
|
883
1034
|
await testInitialManifest(master, mediaWithDeltaUpdates);
|
|
884
1035
|
|
|
885
1036
|
fakeNetEngine.request.calls.reset();
|
|
1037
|
+
|
|
886
1038
|
await delayForUpdatePeriod();
|
|
1039
|
+
fakeNetEngine.expectRequest(
|
|
1040
|
+
'test:/video?_HLS_msn=2&_HLS_skip=YES',
|
|
1041
|
+
shaka.net.NetworkingEngine.RequestType.MANIFEST,
|
|
1042
|
+
{type:
|
|
1043
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST});
|
|
887
1044
|
|
|
1045
|
+
await delayForUpdatePeriod();
|
|
888
1046
|
fakeNetEngine.expectRequest(
|
|
889
|
-
'test:/video?_HLS_skip=YES',
|
|
890
|
-
shaka.net.NetworkingEngine.RequestType.MANIFEST
|
|
1047
|
+
'test:/video?_HLS_msn=3&_HLS_skip=YES',
|
|
1048
|
+
shaka.net.NetworkingEngine.RequestType.MANIFEST,
|
|
1049
|
+
{type:
|
|
1050
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST});
|
|
891
1051
|
});
|
|
892
1052
|
|
|
893
1053
|
it('skips older segments', async () => {
|