shaka-player 4.3.10 → 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/release-please.yaml +7 -0
- package/AUTHORS +9 -0
- package/CHANGELOG.md +295 -200
- 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 +53 -3
- 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 +52 -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 +124 -112
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +124 -112
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +46 -28
- package/dist/locales.js +28 -28
- package/dist/receiver.compiled.debug.js +52 -46
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +52 -46
- 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 +1045 -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 +1100 -739
- 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 +13 -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 +79 -3
- 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 +17 -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 +3 -1
- 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_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/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 +11 -1
- 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 +223 -0
- package/ui/ui.js +5 -0
- package/lib/cea/i_caption_decoder.js +0 -51
- package/lib/cea/i_cea_parser.js +0 -68
|
@@ -76,6 +76,8 @@ describe('StreamingEngine', () => {
|
|
|
76
76
|
let beforeAppendSegment;
|
|
77
77
|
/** @type {!jasmine.Spy} */
|
|
78
78
|
let onMetadata;
|
|
79
|
+
/** @type {!jasmine.Spy} */
|
|
80
|
+
let disableStream;
|
|
79
81
|
|
|
80
82
|
/** @type {function(function(), number)} */
|
|
81
83
|
let realSetTimeout;
|
|
@@ -437,6 +439,8 @@ describe('StreamingEngine', () => {
|
|
|
437
439
|
onMetadata = jasmine.createSpy('onMetadata');
|
|
438
440
|
getBandwidthEstimate = jasmine.createSpy('getBandwidthEstimate');
|
|
439
441
|
getBandwidthEstimate.and.returnValue(1e3);
|
|
442
|
+
disableStream = jasmine.createSpy('disableStream');
|
|
443
|
+
disableStream.and.callFake(() => false);
|
|
440
444
|
|
|
441
445
|
beforeAppendSegment.and.callFake((segment) => {
|
|
442
446
|
return Promise.resolve();
|
|
@@ -447,13 +451,13 @@ describe('StreamingEngine', () => {
|
|
|
447
451
|
config.rebufferingGoal = 2;
|
|
448
452
|
config.bufferingGoal = 5;
|
|
449
453
|
config.bufferBehind = Infinity;
|
|
454
|
+
config.maxDisabledTime = 0; // Do not disable stream by default
|
|
450
455
|
}
|
|
451
456
|
|
|
452
457
|
goog.asserts.assert(
|
|
453
458
|
presentationTimeInSeconds != undefined,
|
|
454
459
|
'All tests should have defined an initial presentation time by now!');
|
|
455
460
|
const playerInterface = {
|
|
456
|
-
modifySegmentRequest: (request, segmentInfo) => {},
|
|
457
461
|
getPresentationTime: () => presentationTimeInSeconds,
|
|
458
462
|
getBandwidthEstimate: Util.spyFunc(getBandwidthEstimate),
|
|
459
463
|
mediaSourceEngine: mediaSourceEngine,
|
|
@@ -465,6 +469,7 @@ describe('StreamingEngine', () => {
|
|
|
465
469
|
onInitSegmentAppended: () => {},
|
|
466
470
|
beforeAppendSegment: Util.spyFunc(beforeAppendSegment),
|
|
467
471
|
onMetadata: Util.spyFunc(onMetadata),
|
|
472
|
+
disableStream: Util.spyFunc(disableStream),
|
|
468
473
|
};
|
|
469
474
|
streamingEngine = new shaka.media.StreamingEngine(
|
|
470
475
|
/** @type {shaka.extern.Manifest} */(manifest), playerInterface);
|
|
@@ -521,7 +526,8 @@ describe('StreamingEngine', () => {
|
|
|
521
526
|
expectedMseInit.set(ContentType.TEXT, textStream);
|
|
522
527
|
|
|
523
528
|
expect(mediaSourceEngine.init).toHaveBeenCalledWith(expectedMseInit,
|
|
524
|
-
/**
|
|
529
|
+
/** sequenceMode= */ false, /** manifestType= */ 'UNKNOWN',
|
|
530
|
+
/** ignoreManifestTimestampsInSegmentsMode= */ false);
|
|
525
531
|
expect(mediaSourceEngine.init).toHaveBeenCalledTimes(1);
|
|
526
532
|
|
|
527
533
|
expect(mediaSourceEngine.setDuration).toHaveBeenCalledTimes(1);
|
|
@@ -546,40 +552,47 @@ describe('StreamingEngine', () => {
|
|
|
546
552
|
netEngine.expectRangeRequest(
|
|
547
553
|
'0_audio_init',
|
|
548
554
|
initSegmentRanges[ContentType.AUDIO][0],
|
|
549
|
-
initSegmentRanges[ContentType.AUDIO][1]
|
|
555
|
+
initSegmentRanges[ContentType.AUDIO][1],
|
|
556
|
+
/* isInit= */ true);
|
|
550
557
|
|
|
551
558
|
netEngine.expectRangeRequest(
|
|
552
559
|
'0_video_init',
|
|
553
560
|
initSegmentRanges[ContentType.VIDEO][0],
|
|
554
|
-
initSegmentRanges[ContentType.VIDEO][1]
|
|
561
|
+
initSegmentRanges[ContentType.VIDEO][1],
|
|
562
|
+
/* isInit= */ true);
|
|
555
563
|
|
|
556
564
|
netEngine.expectRangeRequest(
|
|
557
565
|
'1_audio_init',
|
|
558
566
|
initSegmentRanges[ContentType.AUDIO][0],
|
|
559
|
-
initSegmentRanges[ContentType.AUDIO][1]
|
|
567
|
+
initSegmentRanges[ContentType.AUDIO][1],
|
|
568
|
+
/* isInit= */ true);
|
|
560
569
|
|
|
561
570
|
netEngine.expectRangeRequest(
|
|
562
571
|
'1_video_init',
|
|
563
572
|
initSegmentRanges[ContentType.VIDEO][0],
|
|
564
|
-
initSegmentRanges[ContentType.VIDEO][1]
|
|
573
|
+
initSegmentRanges[ContentType.VIDEO][1],
|
|
574
|
+
/* isInit= */ true);
|
|
565
575
|
|
|
566
576
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
577
|
+
const segmentContext = {
|
|
578
|
+
type: shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT,
|
|
579
|
+
};
|
|
567
580
|
|
|
568
|
-
netEngine.expectRequest('0_audio_0', segmentType);
|
|
569
|
-
netEngine.expectRequest('0_video_0', segmentType);
|
|
570
|
-
netEngine.expectRequest('0_text_0', segmentType);
|
|
581
|
+
netEngine.expectRequest('0_audio_0', segmentType, segmentContext);
|
|
582
|
+
netEngine.expectRequest('0_video_0', segmentType, segmentContext);
|
|
583
|
+
netEngine.expectRequest('0_text_0', segmentType, segmentContext);
|
|
571
584
|
|
|
572
|
-
netEngine.expectRequest('0_audio_1', segmentType);
|
|
573
|
-
netEngine.expectRequest('0_video_1', segmentType);
|
|
574
|
-
netEngine.expectRequest('0_text_1', segmentType);
|
|
585
|
+
netEngine.expectRequest('0_audio_1', segmentType, segmentContext);
|
|
586
|
+
netEngine.expectRequest('0_video_1', segmentType, segmentContext);
|
|
587
|
+
netEngine.expectRequest('0_text_1', segmentType, segmentContext);
|
|
575
588
|
|
|
576
|
-
netEngine.expectRequest('1_audio_2', segmentType);
|
|
577
|
-
netEngine.expectRequest('1_video_2', segmentType);
|
|
578
|
-
netEngine.expectRequest('1_text_2', segmentType);
|
|
589
|
+
netEngine.expectRequest('1_audio_2', segmentType, segmentContext);
|
|
590
|
+
netEngine.expectRequest('1_video_2', segmentType, segmentContext);
|
|
591
|
+
netEngine.expectRequest('1_text_2', segmentType, segmentContext);
|
|
579
592
|
|
|
580
|
-
netEngine.expectRequest('1_audio_3', segmentType);
|
|
581
|
-
netEngine.expectRequest('1_video_3', segmentType);
|
|
582
|
-
netEngine.expectRequest('1_text_3', segmentType);
|
|
593
|
+
netEngine.expectRequest('1_audio_3', segmentType, segmentContext);
|
|
594
|
+
netEngine.expectRequest('1_video_3', segmentType, segmentContext);
|
|
595
|
+
netEngine.expectRequest('1_text_3', segmentType, segmentContext);
|
|
583
596
|
});
|
|
584
597
|
|
|
585
598
|
describe('unloadTextStream', () => {
|
|
@@ -597,16 +610,19 @@ describe('StreamingEngine', () => {
|
|
|
597
610
|
// is sent.
|
|
598
611
|
await runTest(() => {
|
|
599
612
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
613
|
+
const segmentContext = {
|
|
614
|
+
type: shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT,
|
|
615
|
+
};
|
|
600
616
|
|
|
601
617
|
if (presentationTimeInSeconds == 1) {
|
|
602
|
-
netEngine.expectRequest('0_text_0', segmentType);
|
|
618
|
+
netEngine.expectRequest('0_text_0', segmentType, segmentContext);
|
|
603
619
|
netEngine.request.calls.reset();
|
|
604
620
|
streamingEngine.unloadTextStream();
|
|
605
621
|
} else if (presentationTimeInSeconds == 35) {
|
|
606
|
-
netEngine.expectNoRequest('0_text_0', segmentType);
|
|
607
|
-
netEngine.expectNoRequest('0_text_1', segmentType);
|
|
608
|
-
netEngine.expectNoRequest('1_text_2', segmentType);
|
|
609
|
-
netEngine.expectNoRequest('1_text_3', segmentType);
|
|
622
|
+
netEngine.expectNoRequest('0_text_0', segmentType, segmentContext);
|
|
623
|
+
netEngine.expectNoRequest('0_text_1', segmentType, segmentContext);
|
|
624
|
+
netEngine.expectNoRequest('1_text_2', segmentType, segmentContext);
|
|
625
|
+
netEngine.expectNoRequest('1_text_3', segmentType, segmentContext);
|
|
610
626
|
}
|
|
611
627
|
});
|
|
612
628
|
});
|
|
@@ -825,8 +841,13 @@ describe('StreamingEngine', () => {
|
|
|
825
841
|
const gt40 = {
|
|
826
842
|
asymmetricMatch: (val) => val > 40 && val <= 40.1,
|
|
827
843
|
};
|
|
844
|
+
const streamsByType = new Map();
|
|
845
|
+
streamsByType.set(ContentType.AUDIO, audioStream);
|
|
846
|
+
streamsByType.set(ContentType.VIDEO, videoStream);
|
|
847
|
+
|
|
828
848
|
expect(mediaSourceEngine.setStreamProperties)
|
|
829
|
-
.toHaveBeenCalledWith('video', 0, lt20, gt40, false
|
|
849
|
+
.toHaveBeenCalledWith('video', 0, lt20, gt40, false,
|
|
850
|
+
videoStream, streamsByType);
|
|
830
851
|
});
|
|
831
852
|
|
|
832
853
|
// Regression test for https://github.com/shaka-project/shaka-player/issues/3717
|
|
@@ -858,22 +879,24 @@ describe('StreamingEngine', () => {
|
|
|
858
879
|
expect(mediaSourceEngine.endOfStream).toHaveBeenCalled();
|
|
859
880
|
|
|
860
881
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
882
|
+
const segmentContext = {
|
|
883
|
+
type: shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT,
|
|
884
|
+
};
|
|
885
|
+
netEngine.expectRequest('0_audio_0', segmentType, segmentContext);
|
|
886
|
+
netEngine.expectRequest('0_video_0', segmentType, segmentContext);
|
|
887
|
+
netEngine.expectRequest('0_text_0', segmentType, segmentContext);
|
|
861
888
|
|
|
862
|
-
netEngine.expectRequest('
|
|
863
|
-
netEngine.expectRequest('
|
|
864
|
-
netEngine.expectRequest('
|
|
865
|
-
|
|
866
|
-
netEngine.expectRequest('0_audio_1', segmentType);
|
|
867
|
-
netEngine.expectRequest('0_video_1', segmentType);
|
|
868
|
-
netEngine.expectRequest('0_text_1', segmentType);
|
|
889
|
+
netEngine.expectRequest('0_audio_1', segmentType, segmentContext);
|
|
890
|
+
netEngine.expectRequest('0_video_1', segmentType, segmentContext);
|
|
891
|
+
netEngine.expectRequest('0_text_1', segmentType, segmentContext);
|
|
869
892
|
|
|
870
|
-
netEngine.expectRequest('1_audio_2', segmentType);
|
|
871
|
-
netEngine.expectRequest('1_video_2', segmentType);
|
|
872
|
-
netEngine.expectRequest('1_text_2', segmentType);
|
|
893
|
+
netEngine.expectRequest('1_audio_2', segmentType, segmentContext);
|
|
894
|
+
netEngine.expectRequest('1_video_2', segmentType, segmentContext);
|
|
895
|
+
netEngine.expectRequest('1_text_2', segmentType, segmentContext);
|
|
873
896
|
|
|
874
|
-
netEngine.expectNoRequest('1_audio_3', segmentType);
|
|
875
|
-
netEngine.expectNoRequest('1_video_3', segmentType);
|
|
876
|
-
netEngine.expectNoRequest('1_text_3', segmentType);
|
|
897
|
+
netEngine.expectNoRequest('1_audio_3', segmentType, segmentContext);
|
|
898
|
+
netEngine.expectNoRequest('1_video_3', segmentType, segmentContext);
|
|
899
|
+
netEngine.expectNoRequest('1_text_3', segmentType, segmentContext);
|
|
877
900
|
});
|
|
878
901
|
|
|
879
902
|
it('does not buffer one media type ahead of another', async () => {
|
|
@@ -1148,10 +1171,15 @@ describe('StreamingEngine', () => {
|
|
|
1148
1171
|
await Util.fakeEventLoop(5);
|
|
1149
1172
|
|
|
1150
1173
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
1174
|
+
const segmentContext = {
|
|
1175
|
+
type: shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT,
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1151
1178
|
// Quickly switching back to text1, and text init segment should be
|
|
1152
1179
|
// fetched again.
|
|
1153
|
-
netEngine.expectRequest('text-20-init', segmentType);
|
|
1154
|
-
netEngine.expectNoRequest('text-21-init', segmentType);
|
|
1180
|
+
netEngine.expectRequest('text-20-init', segmentType, segmentContext);
|
|
1181
|
+
netEngine.expectNoRequest('text-21-init', segmentType, segmentContext);
|
|
1182
|
+
// TODO: huh?
|
|
1155
1183
|
});
|
|
1156
1184
|
});
|
|
1157
1185
|
|
|
@@ -2158,6 +2186,195 @@ describe('StreamingEngine', () => {
|
|
|
2158
2186
|
// baseDelay == 10000, maybe be longer due to delays in the event loop.
|
|
2159
2187
|
expect(callbackTime - startTime).toBeGreaterThanOrEqual(10000);
|
|
2160
2188
|
});
|
|
2189
|
+
|
|
2190
|
+
it('temporarily disables stream if configured to do so', async () => {
|
|
2191
|
+
setupVod();
|
|
2192
|
+
|
|
2193
|
+
const targetUri = '0_video_0';
|
|
2194
|
+
|
|
2195
|
+
failRequestsForTarget(netEngine, targetUri);
|
|
2196
|
+
|
|
2197
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2198
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2199
|
+
config.maxDisabledTime = 2;
|
|
2200
|
+
createStreamingEngine(config);
|
|
2201
|
+
|
|
2202
|
+
spyOn(streamingEngine, 'makeAbortDecision_').and.callFake(() => {
|
|
2203
|
+
return Promise.resolve();
|
|
2204
|
+
});
|
|
2205
|
+
|
|
2206
|
+
onError.and.callFake((error) => {
|
|
2207
|
+
expect(error.severity).toBe(shaka.util.Error.Severity.RECOVERABLE);
|
|
2208
|
+
expect(error.category).toBe(shaka.util.Error.Category.NETWORK);
|
|
2209
|
+
expect(error.code).toBe(shaka.util.Error.Code.BAD_HTTP_STATUS);
|
|
2210
|
+
});
|
|
2211
|
+
|
|
2212
|
+
disableStream.and.callFake((stream, time) => {
|
|
2213
|
+
expect(stream).toBe(variant.video);
|
|
2214
|
+
expect(time).toBeGreaterThan(0);
|
|
2215
|
+
|
|
2216
|
+
createAlternateSegmentIndex(stream, alternateVideoStream);
|
|
2217
|
+
|
|
2218
|
+
streamingEngine.switchVariant(
|
|
2219
|
+
alternateVariant, /* clearBuffer= */ true,
|
|
2220
|
+
/* safeMargin= */ 0, /* force= */ true);
|
|
2221
|
+
return true;
|
|
2222
|
+
});
|
|
2223
|
+
|
|
2224
|
+
// Here we go!
|
|
2225
|
+
streamingEngine.switchVariant(variant);
|
|
2226
|
+
streamingEngine.switchTextStream(textStream);
|
|
2227
|
+
await streamingEngine.start();
|
|
2228
|
+
playing = true;
|
|
2229
|
+
|
|
2230
|
+
await runTest();
|
|
2231
|
+
expect(disableStream).toHaveBeenCalledTimes(1);
|
|
2232
|
+
});
|
|
2233
|
+
|
|
2234
|
+
it('does not temporarily disables stream if not configured to',
|
|
2235
|
+
async () => {
|
|
2236
|
+
setupVod();
|
|
2237
|
+
|
|
2238
|
+
const targetUri = '0_audio_init';
|
|
2239
|
+
failRequestsForTarget(
|
|
2240
|
+
netEngine, targetUri, shaka.util.Error.Code.HTTP_ERROR);
|
|
2241
|
+
|
|
2242
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2243
|
+
const config =
|
|
2244
|
+
shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2245
|
+
config.maxDisabledTime = 0; // Do not disable streams.
|
|
2246
|
+
createStreamingEngine(config);
|
|
2247
|
+
|
|
2248
|
+
onError.and.callFake((error) => {
|
|
2249
|
+
expect(error.code).toBe(shaka.util.Error.Code.HTTP_ERROR);
|
|
2250
|
+
});
|
|
2251
|
+
|
|
2252
|
+
// Here we go!
|
|
2253
|
+
streamingEngine.switchVariant(variant);
|
|
2254
|
+
streamingEngine.switchTextStream(textStream);
|
|
2255
|
+
await streamingEngine.start();
|
|
2256
|
+
playing = true;
|
|
2257
|
+
|
|
2258
|
+
await runTest();
|
|
2259
|
+
expect(disableStream).not.toHaveBeenCalled();
|
|
2260
|
+
});
|
|
2261
|
+
|
|
2262
|
+
it('always tries to recover shaka.util.Error.Code.SEGMENT_MISSING',
|
|
2263
|
+
async () => {
|
|
2264
|
+
setupVod();
|
|
2265
|
+
|
|
2266
|
+
const targetUri = '0_video_0';
|
|
2267
|
+
failRequestsForTarget(
|
|
2268
|
+
netEngine, targetUri, shaka.util.Error.Code.SEGMENT_MISSING);
|
|
2269
|
+
|
|
2270
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2271
|
+
const config =
|
|
2272
|
+
shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2273
|
+
config.maxDisabledTime = 0; // Do not disable streams.
|
|
2274
|
+
createStreamingEngine(config);
|
|
2275
|
+
|
|
2276
|
+
spyOn(streamingEngine, 'makeAbortDecision_').and.callFake(() => {
|
|
2277
|
+
return Promise.resolve();
|
|
2278
|
+
});
|
|
2279
|
+
|
|
2280
|
+
onError.and.callFake((error) => {
|
|
2281
|
+
expect(error.severity).toBe(shaka.util.Error.Severity.RECOVERABLE);
|
|
2282
|
+
expect(error.category).toBe(shaka.util.Error.Category.NETWORK);
|
|
2283
|
+
expect(error.code).toBe(shaka.util.Error.Code.SEGMENT_MISSING);
|
|
2284
|
+
});
|
|
2285
|
+
|
|
2286
|
+
disableStream.and.callFake((stream, time) => {
|
|
2287
|
+
expect(stream).toBe(variant.video);
|
|
2288
|
+
expect(time).toBeGreaterThan(0);
|
|
2289
|
+
|
|
2290
|
+
createAlternateSegmentIndex(stream, alternateVideoStream);
|
|
2291
|
+
|
|
2292
|
+
streamingEngine.switchVariant(
|
|
2293
|
+
alternateVariant, /* clearBuffer= */ true,
|
|
2294
|
+
/* safeMargin= */ 0, /* force= */ true);
|
|
2295
|
+
return true;
|
|
2296
|
+
});
|
|
2297
|
+
|
|
2298
|
+
// Here we go!
|
|
2299
|
+
streamingEngine.switchVariant(variant);
|
|
2300
|
+
streamingEngine.switchTextStream(textStream);
|
|
2301
|
+
await streamingEngine.start();
|
|
2302
|
+
playing = true;
|
|
2303
|
+
|
|
2304
|
+
await runTest();
|
|
2305
|
+
expect(disableStream).toHaveBeenCalledTimes(1);
|
|
2306
|
+
});
|
|
2307
|
+
|
|
2308
|
+
it('throws recoverable error if try to disable stream succeeded',
|
|
2309
|
+
async () => {
|
|
2310
|
+
setupVod();
|
|
2311
|
+
|
|
2312
|
+
const targetUri = '0_video_init';
|
|
2313
|
+
failRequestsForTarget(
|
|
2314
|
+
netEngine, targetUri, shaka.util.Error.Code.BAD_HTTP_STATUS);
|
|
2315
|
+
|
|
2316
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2317
|
+
const config =
|
|
2318
|
+
shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2319
|
+
config.maxDisabledTime = 2;
|
|
2320
|
+
createStreamingEngine(config);
|
|
2321
|
+
|
|
2322
|
+
disableStream.and.callFake(() => true);
|
|
2323
|
+
|
|
2324
|
+
onError.and.callFake((error) => {
|
|
2325
|
+
expect(error).toEqual(jasmine.objectContaining({
|
|
2326
|
+
code: shaka.util.Error.Code.BAD_HTTP_STATUS,
|
|
2327
|
+
category: shaka.util.Error.Category.NETWORK,
|
|
2328
|
+
severity: shaka.util.Error.Severity.RECOVERABLE,
|
|
2329
|
+
handled: true,
|
|
2330
|
+
}));
|
|
2331
|
+
});
|
|
2332
|
+
|
|
2333
|
+
// Here we go!
|
|
2334
|
+
streamingEngine.switchVariant(variant);
|
|
2335
|
+
streamingEngine.switchTextStream(textStream);
|
|
2336
|
+
await streamingEngine.start();
|
|
2337
|
+
playing = true;
|
|
2338
|
+
|
|
2339
|
+
await runTest();
|
|
2340
|
+
expect(disableStream).toHaveBeenCalled();
|
|
2341
|
+
expect(onError).toHaveBeenCalled();
|
|
2342
|
+
});
|
|
2343
|
+
|
|
2344
|
+
it('throws critical error if try to disable stream failed', async () => {
|
|
2345
|
+
setupVod();
|
|
2346
|
+
|
|
2347
|
+
const targetUri = '0_video_init';
|
|
2348
|
+
failRequestsForTarget(
|
|
2349
|
+
netEngine, targetUri, shaka.util.Error.Code.BAD_HTTP_STATUS);
|
|
2350
|
+
|
|
2351
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2352
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2353
|
+
config.maxDisabledTime = 2;
|
|
2354
|
+
createStreamingEngine(config);
|
|
2355
|
+
|
|
2356
|
+
disableStream.and.callFake(() => false);
|
|
2357
|
+
|
|
2358
|
+
onError.and.callFake((error) => {
|
|
2359
|
+
expect(error).toEqual(jasmine.objectContaining({
|
|
2360
|
+
code: shaka.util.Error.Code.BAD_HTTP_STATUS,
|
|
2361
|
+
category: shaka.util.Error.Category.NETWORK,
|
|
2362
|
+
severity: shaka.util.Error.Severity.CRITICAL,
|
|
2363
|
+
handled: false,
|
|
2364
|
+
}));
|
|
2365
|
+
});
|
|
2366
|
+
|
|
2367
|
+
// Here we go!
|
|
2368
|
+
streamingEngine.switchVariant(variant);
|
|
2369
|
+
streamingEngine.switchTextStream(textStream);
|
|
2370
|
+
await streamingEngine.start();
|
|
2371
|
+
playing = true;
|
|
2372
|
+
|
|
2373
|
+
await runTest();
|
|
2374
|
+
|
|
2375
|
+
expect(disableStream).toHaveBeenCalled();
|
|
2376
|
+
expect(onError).toHaveBeenCalled();
|
|
2377
|
+
});
|
|
2161
2378
|
});
|
|
2162
2379
|
|
|
2163
2380
|
describe('retry()', () => {
|
|
@@ -3033,22 +3250,6 @@ describe('StreamingEngine', () => {
|
|
|
3033
3250
|
expectedStartDate.toUTCString());
|
|
3034
3251
|
});
|
|
3035
3252
|
|
|
3036
|
-
it('does not raise event if mediatime exceeds Number.MAX_VALUE',
|
|
3037
|
-
async () => {
|
|
3038
|
-
const prftSegment = Uint8ArrayUtils.fromHex(
|
|
3039
|
-
'00000020707266740100000000000001E683B62E8E63CC58'+
|
|
3040
|
-
'FFFFFFFFFFFFFFFF');
|
|
3041
|
-
segmentData[ContentType.VIDEO].segments[0] = prftSegment;
|
|
3042
|
-
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;
|
|
3043
|
-
|
|
3044
|
-
streamingEngine.switchVariant(variant);
|
|
3045
|
-
streamingEngine.switchTextStream(textStream);
|
|
3046
|
-
await streamingEngine.start();
|
|
3047
|
-
playing = true;
|
|
3048
|
-
await runTest();
|
|
3049
|
-
expect(onEvent).not.toHaveBeenCalled();
|
|
3050
|
-
});
|
|
3051
|
-
|
|
3052
3253
|
it('raises an event once only', async () => {
|
|
3053
3254
|
segmentData[ContentType.VIDEO].segments[0] =
|
|
3054
3255
|
shaka.util.Uint8ArrayUtils.concat(prftSegment, prftSegment);
|
|
@@ -3111,7 +3312,7 @@ describe('StreamingEngine', () => {
|
|
|
3111
3312
|
// For these tests, we don't care about specific data appended.
|
|
3112
3313
|
// Just return any old ArrayBuffer for any requested segment.
|
|
3113
3314
|
netEngine = new shaka.test.FakeNetworkingEngine();
|
|
3114
|
-
netEngine.request.and.callFake((requestType, request) => {
|
|
3315
|
+
netEngine.request.and.callFake((requestType, request, context) => {
|
|
3115
3316
|
const buffer = new ArrayBuffer(0);
|
|
3116
3317
|
const response = {uri: request.uris[0], data: buffer, headers: {}};
|
|
3117
3318
|
const bytes = new shaka.net.NetworkingEngine.NumBytesRemainingClass();
|
|
@@ -3433,7 +3634,7 @@ describe('StreamingEngine', () => {
|
|
|
3433
3634
|
|
|
3434
3635
|
// For these tests, we don't care about specific data appended.
|
|
3435
3636
|
// Just return any old ArrayBuffer for any requested segment.
|
|
3436
|
-
netEngine.request.and.callFake((requestType, request) => {
|
|
3637
|
+
netEngine.request.and.callFake((requestType, request, context) => {
|
|
3437
3638
|
const buffer = new ArrayBuffer(0);
|
|
3438
3639
|
/** @type {shaka.extern.Response} */
|
|
3439
3640
|
const response = {
|
|
@@ -3678,7 +3879,7 @@ describe('StreamingEngine', () => {
|
|
|
3678
3879
|
let isRequested = false;
|
|
3679
3880
|
let isAborted = false;
|
|
3680
3881
|
|
|
3681
|
-
netEngine.request.and.callFake((requestType, request) => {
|
|
3882
|
+
netEngine.request.and.callFake((requestType, request, context) => {
|
|
3682
3883
|
isRequested = true;
|
|
3683
3884
|
|
|
3684
3885
|
const abortOp = () => {
|
|
@@ -3732,6 +3933,149 @@ describe('StreamingEngine', () => {
|
|
|
3732
3933
|
});
|
|
3733
3934
|
});
|
|
3734
3935
|
|
|
3936
|
+
describe('prefetch segments', () => {
|
|
3937
|
+
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
3938
|
+
|
|
3939
|
+
let OriginalSegmentPrefetch;
|
|
3940
|
+
|
|
3941
|
+
beforeEach(() => {
|
|
3942
|
+
OriginalSegmentPrefetch = shaka.media.SegmentPrefetch;
|
|
3943
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
3944
|
+
shaka.media.SegmentPrefetch = function(config, stream) {
|
|
3945
|
+
const fake = new shaka.test.FakeSegmentPrefetch(stream, segmentData);
|
|
3946
|
+
return /** @type {?} */(fake);
|
|
3947
|
+
};
|
|
3948
|
+
|
|
3949
|
+
setupVod();
|
|
3950
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
3951
|
+
createStreamingEngine();
|
|
3952
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
3953
|
+
config.segmentPrefetchLimit = 3;
|
|
3954
|
+
streamingEngine.configure(config);
|
|
3955
|
+
});
|
|
3956
|
+
|
|
3957
|
+
afterEach(() => {
|
|
3958
|
+
shaka.media.SegmentPrefetch = OriginalSegmentPrefetch;
|
|
3959
|
+
});
|
|
3960
|
+
|
|
3961
|
+
it('should use prefetched segment without fetching again', async () => {
|
|
3962
|
+
streamingEngine.switchVariant(variant);
|
|
3963
|
+
await streamingEngine.start();
|
|
3964
|
+
playing = true;
|
|
3965
|
+
expectNoBuffer();
|
|
3966
|
+
|
|
3967
|
+
await runTest();
|
|
3968
|
+
|
|
3969
|
+
expectHasBuffer();
|
|
3970
|
+
expectSegmentRequest(false);
|
|
3971
|
+
});
|
|
3972
|
+
|
|
3973
|
+
it('should re-use prefetch segment when force clear buffer', async () => {
|
|
3974
|
+
streamingEngine.switchVariant(variant);
|
|
3975
|
+
await streamingEngine.start();
|
|
3976
|
+
|
|
3977
|
+
playing = true;
|
|
3978
|
+
expectNoBuffer();
|
|
3979
|
+
await runTest();
|
|
3980
|
+
expectHasBuffer();
|
|
3981
|
+
expectSegmentRequest(false);
|
|
3982
|
+
|
|
3983
|
+
streamingEngine.switchVariant(variant, true, 0, true);
|
|
3984
|
+
presentationTimeInSeconds = 0;
|
|
3985
|
+
await runTest();
|
|
3986
|
+
expectHasBuffer();
|
|
3987
|
+
expectSegmentRequest(false);
|
|
3988
|
+
});
|
|
3989
|
+
|
|
3990
|
+
it('should disable prefetch if reset config in middle', async () => {
|
|
3991
|
+
streamingEngine.switchVariant(variant);
|
|
3992
|
+
await streamingEngine.start();
|
|
3993
|
+
|
|
3994
|
+
playing = true;
|
|
3995
|
+
expectNoBuffer();
|
|
3996
|
+
await runTest();
|
|
3997
|
+
expectHasBuffer();
|
|
3998
|
+
expectSegmentRequest(false);
|
|
3999
|
+
|
|
4000
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
4001
|
+
config.segmentPrefetchLimit = 0;
|
|
4002
|
+
streamingEngine.configure(config);
|
|
4003
|
+
streamingEngine.switchVariant(variant, true, 0, true);
|
|
4004
|
+
presentationTimeInSeconds = 0;
|
|
4005
|
+
await runTest();
|
|
4006
|
+
expectHasBuffer();
|
|
4007
|
+
expectSegmentRequest(true);
|
|
4008
|
+
});
|
|
4009
|
+
|
|
4010
|
+
it('should disable prefetch when reset config at begining', async () => {
|
|
4011
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
4012
|
+
config.segmentPrefetchLimit = 0;
|
|
4013
|
+
streamingEngine.configure(config);
|
|
4014
|
+
streamingEngine.switchVariant(variant);
|
|
4015
|
+
await streamingEngine.start();
|
|
4016
|
+
playing = true;
|
|
4017
|
+
expectNoBuffer();
|
|
4018
|
+
await runTest();
|
|
4019
|
+
expectHasBuffer();
|
|
4020
|
+
expectSegmentRequest(true);
|
|
4021
|
+
});
|
|
4022
|
+
|
|
4023
|
+
/**
|
|
4024
|
+
* Expect no buffer has been added to MSE.
|
|
4025
|
+
*/
|
|
4026
|
+
function expectNoBuffer() {
|
|
4027
|
+
expect(mediaSourceEngine.initSegments).toEqual({
|
|
4028
|
+
audio: [false, false],
|
|
4029
|
+
video: [false, false],
|
|
4030
|
+
text: [],
|
|
4031
|
+
});
|
|
4032
|
+
expect(mediaSourceEngine.segments).toEqual({
|
|
4033
|
+
audio: [false, false, false, false],
|
|
4034
|
+
video: [false, false, false, false],
|
|
4035
|
+
text: [false, false, false, false],
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
/**
|
|
4040
|
+
* Expect buffers have been added to MSE.
|
|
4041
|
+
*/
|
|
4042
|
+
function expectHasBuffer() {
|
|
4043
|
+
expect(mediaSourceEngine.initSegments).toEqual({
|
|
4044
|
+
audio: [false, true],
|
|
4045
|
+
video: [false, true],
|
|
4046
|
+
text: [],
|
|
4047
|
+
});
|
|
4048
|
+
expect(mediaSourceEngine.segments).toEqual({
|
|
4049
|
+
audio: [true, true, true, true],
|
|
4050
|
+
video: [true, true, true, true],
|
|
4051
|
+
text: [false, false, false, false],
|
|
4052
|
+
});
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
/**
|
|
4056
|
+
* @param {?boolean} hasRequest
|
|
4057
|
+
*/
|
|
4058
|
+
function expectSegmentRequest(hasRequest) {
|
|
4059
|
+
const requests = [
|
|
4060
|
+
'0_audio_0', '0_video_0', '0_audio_1',
|
|
4061
|
+
'0_video_1', '1_audio_2', '1_video_2',
|
|
4062
|
+
'1_audio_3', '1_video_3',
|
|
4063
|
+
];
|
|
4064
|
+
|
|
4065
|
+
const context = {
|
|
4066
|
+
type: shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT,
|
|
4067
|
+
};
|
|
4068
|
+
|
|
4069
|
+
for (const request of requests) {
|
|
4070
|
+
if (hasRequest) {
|
|
4071
|
+
netEngine.expectRequest(request, segmentType, context);
|
|
4072
|
+
} else {
|
|
4073
|
+
netEngine.expectNoRequest(request, segmentType, context);
|
|
4074
|
+
}
|
|
4075
|
+
}
|
|
4076
|
+
}
|
|
4077
|
+
});
|
|
4078
|
+
|
|
3735
4079
|
/**
|
|
3736
4080
|
* Slides the segment availability window forward by 1 second.
|
|
3737
4081
|
*/
|
|
@@ -3756,7 +4100,8 @@ describe('StreamingEngine', () => {
|
|
|
3756
4100
|
if (request.uris[0] == targetUri) {
|
|
3757
4101
|
const data = [targetUri];
|
|
3758
4102
|
|
|
3759
|
-
if (errorCode == shaka.util.Error.Code.BAD_HTTP_STATUS
|
|
4103
|
+
if (errorCode == shaka.util.Error.Code.BAD_HTTP_STATUS ||
|
|
4104
|
+
errorCode == shaka.util.Error.Code.SEGMENT_MISSING) {
|
|
3760
4105
|
data.push(404);
|
|
3761
4106
|
data.push('');
|
|
3762
4107
|
}
|
|
@@ -3827,4 +4172,40 @@ describe('StreamingEngine', () => {
|
|
|
3827
4172
|
return segmentReference;
|
|
3828
4173
|
};
|
|
3829
4174
|
}
|
|
4175
|
+
|
|
4176
|
+
/**
|
|
4177
|
+
* Create a valid segment index for |alternateStream| based on |baseStream|
|
|
4178
|
+
* segment index.
|
|
4179
|
+
*
|
|
4180
|
+
* @param {shaka.extern.Stream} baseStream
|
|
4181
|
+
* @param {shaka.extern.Stream} alternateStream
|
|
4182
|
+
*/
|
|
4183
|
+
function createAlternateSegmentIndex(baseStream, alternateStream) {
|
|
4184
|
+
const createSegmentIndexSpy =
|
|
4185
|
+
Util.funcSpy(alternateStream.createSegmentIndex);
|
|
4186
|
+
const altSegmentIndex = new shaka.test.FakeSegmentIndex();
|
|
4187
|
+
|
|
4188
|
+
altSegmentIndex.find.and.callFake(
|
|
4189
|
+
(time) => baseStream.segmentIndex.find(time));
|
|
4190
|
+
|
|
4191
|
+
altSegmentIndex.get.and.callFake((pos) => {
|
|
4192
|
+
const ref = baseStream.segmentIndex.get(pos);
|
|
4193
|
+
|
|
4194
|
+
if (ref) {
|
|
4195
|
+
const altInitUri = ref.initSegmentReference.getUris()[0] + '_alt';
|
|
4196
|
+
const altSegmentUri = ref.getUris()[0] + '_alt';
|
|
4197
|
+
|
|
4198
|
+
ref.initSegmentReference.getUris = () => [altInitUri];
|
|
4199
|
+
ref.getUris = () => [altSegmentUri];
|
|
4200
|
+
return ref;
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4203
|
+
return null;
|
|
4204
|
+
});
|
|
4205
|
+
|
|
4206
|
+
createSegmentIndexSpy.and.callFake(() => {
|
|
4207
|
+
alternateStream.segmentIndex = altSegmentIndex;
|
|
4208
|
+
return Promise.resolve();
|
|
4209
|
+
});
|
|
4210
|
+
}
|
|
3830
4211
|
});
|