shaka-player 4.4.3 → 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/.github/workflows/release-please.yaml +2 -27
- package/AUTHORS +2 -0
- package/CHANGELOG.md +156 -39
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +54 -42
- package/demo/asset_card.js +18 -21
- package/demo/cast_receiver/index.html +0 -1
- package/demo/close_button.js +0 -3
- package/demo/common/asset.js +33 -22
- package/demo/common/assets.js +249 -60
- package/demo/config.js +219 -253
- package/demo/custom.js +88 -133
- package/demo/front.js +7 -10
- package/demo/index.html +19 -22
- package/demo/input.js +6 -11
- package/demo/input_container.js +8 -9
- package/demo/main.js +62 -126
- package/demo/search.js +29 -34
- package/demo/service_worker.js +0 -3
- package/demo/tooltip.js +3 -5
- package/demo/visualizer.js +3 -5
- package/demo/visualizer_button.js +1 -20
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +211 -228
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +211 -228
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +42 -37
- package/dist/locales.js +34 -30
- package/dist/receiver.compiled.debug.js +64 -77
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +64 -77
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.externs.js +356 -117
- package/dist/shaka-player.compiled.debug.js +952 -811
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +356 -117
- package/dist/shaka-player.compiled.js +1165 -1078
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +359 -153
- package/dist/shaka-player.ui.debug.d.ts +359 -153
- package/dist/shaka-player.ui.debug.externs.js +382 -117
- package/dist/shaka-player.ui.debug.js +1084 -918
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +382 -117
- package/dist/shaka-player.ui.js +1377 -1274
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- 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/faq.md +27 -55
- package/docs/tutorials/index.json +2 -1
- package/docs/tutorials/lcevc.md +118 -0
- package/docs/tutorials/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +17 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/managedmediasource.js +24 -0
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +31 -10
- package/externs/shaka/manifest_parser.js +24 -1
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +13 -2
- package/externs/shaka/player.js +65 -8
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +66 -9
- package/lib/ads/ad_manager.js +104 -50
- package/lib/ads/media_tailor_ad.js +297 -0
- package/lib/ads/media_tailor_ad_manager.js +839 -0
- 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/cea/ts_cea_parser.js +15 -2
- package/lib/config/codec_switching_strategy.js +24 -0
- package/lib/dash/content_protection.js +120 -2
- package/lib/dash/dash_parser.js +322 -93
- package/lib/dash/mpd_utils.js +62 -37
- package/lib/dash/segment_base.js +17 -10
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +122 -107
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +798 -658
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +32 -14
- package/lib/media/adaptation_set_criteria.js +86 -16
- 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 +286 -44
- 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 +6 -6
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +73 -7
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +73 -38
- package/lib/mss/mss_parser.js +19 -2
- package/lib/net/networking_engine.js +67 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
- package/lib/offline/manifest_converter.js +3 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +14 -7
- package/lib/player.js +1098 -1537
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/cue.js +15 -0
- 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 +45 -5
- package/lib/text/ui_text_displayer.js +8 -0
- package/lib/text/vtt_text_parser.js +40 -22
- 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 +863 -0
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +187 -22
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +30 -15
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +8 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +6 -8
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +156 -179
- package/lib/util/platform.js +44 -3
- package/lib/util/player_configuration.js +43 -6
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +206 -283
- package/lib/util/ts_parser.js +335 -98
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +25 -5
- package/shaka-player.uncompiled.js +2 -2
- package/support.html +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 +50 -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 +182 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +74 -0
- package/test/dash/dash_parser_live_unit.js +2 -19
- package/test/dash/dash_parser_manifest_unit.js +536 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -0
- package/test/dash/dash_parser_segment_template_unit.js +2 -0
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +14 -3
- package/test/hls/hls_parser_unit.js +385 -33
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +284 -15
- package/test/media/adaptation_set_unit.js +2 -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 +166 -2
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +5 -4
- package/test/media/segment_prefetch_unit.js +1 -1
- package/test/media/streaming_engine_unit.js +17 -17
- package/test/mss/mss_parser_unit.js +2 -0
- 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 +14 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +22 -13
- 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 +182 -158
- package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/dash.mpd +18 -0
- package/test/test/assets/dash-aes-128/license +1 -0
- package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
- package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
- package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
- package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
- package/test/test/assets/hls-ts-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
- package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +13 -2
- 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 +11 -3
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +2 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +10 -4
- 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 +85 -2
- package/test/text/vtt_text_parser_unit.js +103 -31
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +150 -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 +28 -29
- 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 +207 -169
- 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/controls.js +125 -0
- package/ui/externs/ui.js +24 -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/pip_button.js +22 -120
- package/ui/remote_button.js +203 -0
- 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 +11 -4
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -288
- package/demo/locales/source.json +0 -1146
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -43
- package/lib/routing/walker.js +0 -587
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/routing/walker_unit.js +0 -504
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.media.PlayRateController');
|
|
8
8
|
|
|
9
|
-
goog.require('goog.asserts');
|
|
10
9
|
goog.require('shaka.log');
|
|
11
10
|
goog.require('shaka.util.IReleasable');
|
|
12
11
|
goog.require('shaka.util.Timer');
|
|
@@ -17,8 +16,6 @@ goog.require('shaka.util.Timer');
|
|
|
17
16
|
* the playback rate on the media element can change outside of the controller,
|
|
18
17
|
* the playback controller will need to be updated to stay in-sync.
|
|
19
18
|
*
|
|
20
|
-
* TODO: Try not to manage buffering above the browser with playbackRate=0.
|
|
21
|
-
*
|
|
22
19
|
* @implements {shaka.util.IReleasable}
|
|
23
20
|
* @final
|
|
24
21
|
*/
|
|
@@ -30,9 +27,6 @@ shaka.media.PlayRateController = class {
|
|
|
30
27
|
/** @private {?shaka.media.PlayRateController.Harness} */
|
|
31
28
|
this.harness_ = harness;
|
|
32
29
|
|
|
33
|
-
/** @private {boolean} */
|
|
34
|
-
this.isBuffering_ = false;
|
|
35
|
-
|
|
36
30
|
/** @private {number} */
|
|
37
31
|
this.rate_ = this.harness_.getRate();
|
|
38
32
|
|
|
@@ -56,25 +50,15 @@ shaka.media.PlayRateController = class {
|
|
|
56
50
|
}
|
|
57
51
|
|
|
58
52
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* @param {boolean} isBuffering If true, forces playback rate to 0 internally.
|
|
62
|
-
*/
|
|
63
|
-
setBuffering(isBuffering) {
|
|
64
|
-
this.isBuffering_ = isBuffering;
|
|
65
|
-
this.apply_();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Set the playback rate. This rate will only be used as provided when the
|
|
70
|
-
* player is not buffering. You should never set the rate to 0.
|
|
53
|
+
* Set the playback rate.
|
|
71
54
|
*
|
|
72
55
|
* @param {number} rate
|
|
73
56
|
*/
|
|
74
57
|
set(rate) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
58
|
+
if (this.rate_ != rate) {
|
|
59
|
+
this.rate_ = rate;
|
|
60
|
+
this.apply_();
|
|
61
|
+
}
|
|
78
62
|
}
|
|
79
63
|
|
|
80
64
|
/**
|
|
@@ -108,14 +92,11 @@ shaka.media.PlayRateController = class {
|
|
|
108
92
|
// Always stop the timer. We may not start it again.
|
|
109
93
|
this.timer_.stop();
|
|
110
94
|
|
|
111
|
-
|
|
112
|
-
const rate = this.calculateCurrentRate_();
|
|
95
|
+
shaka.log.v1('Changing effective playback rate to', this.rate_);
|
|
113
96
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (rate >= 0) {
|
|
97
|
+
if (this.rate_ >= 0) {
|
|
117
98
|
try {
|
|
118
|
-
this.applyRate_(
|
|
99
|
+
this.applyRate_(this.rate_);
|
|
119
100
|
return;
|
|
120
101
|
} catch (e) {
|
|
121
102
|
// Fall through to the next clause.
|
|
@@ -135,17 +116,6 @@ shaka.media.PlayRateController = class {
|
|
|
135
116
|
this.applyRate_(0);
|
|
136
117
|
}
|
|
137
118
|
|
|
138
|
-
/**
|
|
139
|
-
* Calculate the rate that the controller wants the media element to have
|
|
140
|
-
* based on the current state of the controller.
|
|
141
|
-
*
|
|
142
|
-
* @return {number}
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
|
-
calculateCurrentRate_() {
|
|
146
|
-
return this.isBuffering_ ? 0 : this.rate_;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
119
|
/**
|
|
150
120
|
* If the new rate is different than the media element's playback rate, this
|
|
151
121
|
* will change the playback rate. If the rate does not need to change, it will
|
|
@@ -619,7 +619,9 @@ shaka.media.PresentationTimeline = class {
|
|
|
619
619
|
* @typedef {{
|
|
620
620
|
* start: number,
|
|
621
621
|
* unscaledStart: number,
|
|
622
|
-
* end: number
|
|
622
|
+
* end: number,
|
|
623
|
+
* partialSegments: number,
|
|
624
|
+
* segmentPosition: number
|
|
623
625
|
* }}
|
|
624
626
|
*
|
|
625
627
|
* @description
|
|
@@ -631,6 +633,10 @@ shaka.media.PresentationTimeline = class {
|
|
|
631
633
|
* The start time of the range in representation timescale units.
|
|
632
634
|
* @property {number} end
|
|
633
635
|
* The end time (exclusive) of the range.
|
|
636
|
+
* @property {number} partialSegments
|
|
637
|
+
* The number of partial segments
|
|
638
|
+
* @property {number} segmentPosition
|
|
639
|
+
* The segment position of the timeline entry as it appears in the manifest
|
|
634
640
|
*
|
|
635
641
|
* @export
|
|
636
642
|
*/
|
|
@@ -261,7 +261,7 @@ shaka.media.QualityObserver.QualityChangePosition;
|
|
|
261
261
|
*
|
|
262
262
|
* @description
|
|
263
263
|
* Contains media quality information for a specific content type
|
|
264
|
-
* e.g video or audio.
|
|
264
|
+
* e.g. video or audio.
|
|
265
265
|
*
|
|
266
266
|
* @property {!Array.<shaka.media.QualityObserver.QualityChangePosition>}
|
|
267
267
|
* qualityChangePositions
|
|
@@ -379,7 +379,7 @@ shaka.media.SegmentIndex = class {
|
|
|
379
379
|
lastReference.tileDuration,
|
|
380
380
|
lastReference.syncTime,
|
|
381
381
|
lastReference.status,
|
|
382
|
-
lastReference.
|
|
382
|
+
lastReference.aes128Key,
|
|
383
383
|
);
|
|
384
384
|
this.references[this.references.length - 1].discontinuitySequence =
|
|
385
385
|
lastReference.discontinuitySequence;
|
|
@@ -582,7 +582,7 @@ shaka.media.SegmentIterator = class {
|
|
|
582
582
|
// new references in merge(), the pointers may not make sense any more.
|
|
583
583
|
// This adjusts the invalid pointer values to point to the next newly added
|
|
584
584
|
// segment or partial segment.
|
|
585
|
-
if (ref && ref.hasPartialSegments() && ref.
|
|
585
|
+
if (ref && ref.hasPartialSegments() && ref.hasAllPartialSegments() &&
|
|
586
586
|
this.currentPartialPosition_ >= ref.partialReferences.length) {
|
|
587
587
|
this.currentPosition_++;
|
|
588
588
|
this.currentPartialPosition_ = 0;
|
|
@@ -609,12 +609,12 @@ shaka.media.SegmentIterator = class {
|
|
|
609
609
|
// If the regular segment contains partial segments, move to the next
|
|
610
610
|
// partial SegmentReference.
|
|
611
611
|
this.currentPartialPosition_++;
|
|
612
|
-
// If the current regular segment has been published completely
|
|
613
|
-
//
|
|
614
|
-
//
|
|
612
|
+
// If the current regular segment has been published completely, and
|
|
613
|
+
// we've reached the end of its partial segments list, move to the next
|
|
614
|
+
// regular segment.
|
|
615
615
|
// If the Partial Segments list is still on the fly, do not move to
|
|
616
616
|
// the next regular segment.
|
|
617
|
-
if (ref.
|
|
617
|
+
if (ref.hasAllPartialSegments() &&
|
|
618
618
|
this.currentPartialPosition_ == ref.partialReferences.length) {
|
|
619
619
|
this.currentPosition_++;
|
|
620
620
|
this.currentPartialPosition_ = 0;
|
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
goog.provide('shaka.media.SegmentPrefetch');
|
|
8
|
+
|
|
7
9
|
goog.require('goog.asserts');
|
|
8
|
-
goog.require('shaka.
|
|
10
|
+
goog.require('shaka.log');
|
|
9
11
|
goog.require('shaka.media.InitSegmentReference');
|
|
10
12
|
goog.require('shaka.media.SegmentReference');
|
|
11
|
-
goog.
|
|
12
|
-
goog.require('shaka.
|
|
13
|
+
goog.require('shaka.net.NetworkingEngine');
|
|
14
|
+
goog.require('shaka.util.Uint8ArrayUtils');
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* @summary
|
|
@@ -37,8 +40,9 @@ shaka.media.SegmentPrefetch = class {
|
|
|
37
40
|
this.fetchDispatcher_ = fetchDispatcher;
|
|
38
41
|
|
|
39
42
|
/**
|
|
40
|
-
* @private {!Map.<
|
|
41
|
-
*
|
|
43
|
+
* @private {!Map.<
|
|
44
|
+
* !(shaka.media.SegmentReference|shaka.media.InitSegmentReference),
|
|
45
|
+
* !shaka.media.SegmentPrefetchOperation>}
|
|
42
46
|
*/
|
|
43
47
|
this.segmentPrefetchMap_ = new Map();
|
|
44
48
|
}
|
|
@@ -47,9 +51,10 @@ shaka.media.SegmentPrefetch = class {
|
|
|
47
51
|
* Fetch next segments ahead of current segment.
|
|
48
52
|
*
|
|
49
53
|
* @param {(!shaka.media.SegmentReference)} startReference
|
|
54
|
+
* @param {boolean=} skipFirst
|
|
50
55
|
* @public
|
|
51
56
|
*/
|
|
52
|
-
prefetchSegments(startReference) {
|
|
57
|
+
prefetchSegments(startReference, skipFirst = false) {
|
|
53
58
|
goog.asserts.assert(this.prefetchLimit_ > 0,
|
|
54
59
|
'SegmentPrefetch can not be used when prefetchLimit <= 0.');
|
|
55
60
|
|
|
@@ -65,6 +70,14 @@ shaka.media.SegmentPrefetch = class {
|
|
|
65
70
|
return;
|
|
66
71
|
}
|
|
67
72
|
let reference = startReference;
|
|
73
|
+
if (skipFirst) {
|
|
74
|
+
reference = iterator.next().value;
|
|
75
|
+
if (reference &&
|
|
76
|
+
reference.startTime == startReference.startTime &&
|
|
77
|
+
reference.endTime == startReference.endTime) {
|
|
78
|
+
reference = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
68
81
|
while (this.segmentPrefetchMap_.size < this.prefetchLimit_ &&
|
|
69
82
|
reference != null) {
|
|
70
83
|
// By default doesn't prefech preload partial segments when using
|
|
@@ -88,9 +101,38 @@ shaka.media.SegmentPrefetch = class {
|
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Fetch init segment.
|
|
106
|
+
*
|
|
107
|
+
* @param {!shaka.media.InitSegmentReference} initSegmentReference
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
prefetchInitSegment(initSegmentReference) {
|
|
111
|
+
goog.asserts.assert(this.prefetchLimit_ > 0,
|
|
112
|
+
'SegmentPrefetch can not be used when prefetchLimit <= 0.');
|
|
113
|
+
|
|
114
|
+
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
115
|
+
if (!this.stream_.segmentIndex) {
|
|
116
|
+
shaka.log.info(logPrefix, 'missing segmentIndex');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (this.segmentPrefetchMap_.size < this.prefetchLimit_) {
|
|
121
|
+
if (!this.segmentPrefetchMap_.has(initSegmentReference)) {
|
|
122
|
+
const segmentPrefetchOperation =
|
|
123
|
+
new shaka.media.SegmentPrefetchOperation(this.fetchDispatcher_);
|
|
124
|
+
segmentPrefetchOperation.dispatchFetch(
|
|
125
|
+
initSegmentReference, this.stream_);
|
|
126
|
+
this.segmentPrefetchMap_.set(
|
|
127
|
+
initSegmentReference, segmentPrefetchOperation);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
91
132
|
/**
|
|
92
133
|
* Get the result of prefetched segment if already exists.
|
|
93
|
-
* @param {(
|
|
134
|
+
* @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)}
|
|
135
|
+
* reference
|
|
94
136
|
* @param {?function(BufferSource):!Promise=} streamDataCallback
|
|
95
137
|
* @return {?shaka.net.NetworkingEngine.PendingRequest} op
|
|
96
138
|
* @public
|
|
@@ -98,8 +140,6 @@ shaka.media.SegmentPrefetch = class {
|
|
|
98
140
|
getPrefetchedSegment(reference, streamDataCallback) {
|
|
99
141
|
goog.asserts.assert(this.prefetchLimit_ > 0,
|
|
100
142
|
'SegmentPrefetch can not be used when prefetchLimit <= 0.');
|
|
101
|
-
goog.asserts.assert(reference instanceof shaka.media.SegmentReference,
|
|
102
|
-
'getPrefetchedSegment is only used for shaka.media.SegmentReference.');
|
|
103
143
|
|
|
104
144
|
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
105
145
|
|
|
@@ -109,16 +149,30 @@ shaka.media.SegmentPrefetch = class {
|
|
|
109
149
|
segmentPrefetchOperation.setStreamDataCallback(streamDataCallback);
|
|
110
150
|
}
|
|
111
151
|
this.segmentPrefetchMap_.delete(reference);
|
|
112
|
-
shaka.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
152
|
+
if (reference instanceof shaka.media.SegmentReference) {
|
|
153
|
+
shaka.log.debug(
|
|
154
|
+
logPrefix,
|
|
155
|
+
'reused prefetched segment at time:', reference.startTime,
|
|
156
|
+
'mapSize', this.segmentPrefetchMap_.size);
|
|
157
|
+
} else {
|
|
158
|
+
shaka.log.debug(
|
|
159
|
+
logPrefix,
|
|
160
|
+
'reused prefetched init segment at time, mapSize',
|
|
161
|
+
this.segmentPrefetchMap_.size);
|
|
162
|
+
}
|
|
116
163
|
return segmentPrefetchOperation.getOperation();
|
|
117
164
|
} else {
|
|
118
|
-
shaka.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
165
|
+
if (reference instanceof shaka.media.SegmentReference) {
|
|
166
|
+
shaka.log.debug(
|
|
167
|
+
logPrefix,
|
|
168
|
+
'reused prefetched segment at time:', reference.startTime,
|
|
169
|
+
'mapSize', this.segmentPrefetchMap_.size);
|
|
170
|
+
} else {
|
|
171
|
+
shaka.log.debug(
|
|
172
|
+
logPrefix,
|
|
173
|
+
'reused prefetched init segment at time, mapSize',
|
|
174
|
+
this.segmentPrefetchMap_.size);
|
|
175
|
+
}
|
|
122
176
|
return null;
|
|
123
177
|
}
|
|
124
178
|
}
|
|
@@ -174,7 +228,8 @@ shaka.media.SegmentPrefetch = class {
|
|
|
174
228
|
|
|
175
229
|
/**
|
|
176
230
|
* Remove a segment from prefetch map and abort it.
|
|
177
|
-
* @param {(
|
|
231
|
+
* @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)}
|
|
232
|
+
* reference
|
|
178
233
|
* @private
|
|
179
234
|
*/
|
|
180
235
|
abortPrefetchedSegment_(reference) {
|
|
@@ -183,9 +238,13 @@ shaka.media.SegmentPrefetch = class {
|
|
|
183
238
|
this.segmentPrefetchMap_.delete(reference);
|
|
184
239
|
if (segmentPrefetchOperation) {
|
|
185
240
|
segmentPrefetchOperation.abort();
|
|
186
|
-
shaka.
|
|
187
|
-
|
|
188
|
-
|
|
241
|
+
if (reference instanceof shaka.media.SegmentReference) {
|
|
242
|
+
shaka.log.info(
|
|
243
|
+
logPrefix,
|
|
244
|
+
'pop and abort prefetched segment at time:', reference.startTime);
|
|
245
|
+
} else {
|
|
246
|
+
shaka.log.info(logPrefix, 'pop and abort prefetched init segment');
|
|
247
|
+
}
|
|
189
248
|
}
|
|
190
249
|
}
|
|
191
250
|
|
|
@@ -221,16 +280,25 @@ shaka.media.SegmentPrefetchOperation = class {
|
|
|
221
280
|
/**
|
|
222
281
|
* Fetch a segments
|
|
223
282
|
*
|
|
224
|
-
* @param {!shaka.media.SegmentReference}
|
|
225
|
-
*
|
|
283
|
+
* @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)}
|
|
284
|
+
* reference
|
|
226
285
|
* @param {!shaka.extern.Stream} stream
|
|
227
286
|
* @public
|
|
228
287
|
*/
|
|
229
288
|
dispatchFetch(reference, stream) {
|
|
289
|
+
// We need to store the data, because streamDataCallback_ might not be
|
|
290
|
+
// available when you start getting the first data.
|
|
291
|
+
let buffered = new Uint8Array(0);
|
|
230
292
|
this.operation_ = this.fetchDispatcher_(
|
|
231
293
|
reference, stream, async (data) => {
|
|
294
|
+
if (buffered.byteLength > 0) {
|
|
295
|
+
buffered = shaka.util.Uint8ArrayUtils.concat(buffered, data);
|
|
296
|
+
} else {
|
|
297
|
+
buffered = data;
|
|
298
|
+
}
|
|
232
299
|
if (this.streamDataCallback_) {
|
|
233
|
-
await this.streamDataCallback_(
|
|
300
|
+
await this.streamDataCallback_(buffered);
|
|
301
|
+
buffered = new Uint8Array(0);
|
|
234
302
|
}
|
|
235
303
|
});
|
|
236
304
|
}
|
|
@@ -32,7 +32,7 @@ shaka.media.InitSegmentReference = class {
|
|
|
32
32
|
* the quality of the media associated with this init segment.
|
|
33
33
|
* @param {(null|number)=} timescale
|
|
34
34
|
* @param {(null|BufferSource)=} segmentData
|
|
35
|
-
* @param {?shaka.extern.
|
|
35
|
+
* @param {?shaka.extern.aes128Key=} aes128Key
|
|
36
36
|
* The segment's AES-128-CBC full segment encryption key and iv.
|
|
37
37
|
*/
|
|
38
38
|
constructor(uris, startByte, endByte, mediaQuality = null, timescale = null,
|
|
@@ -55,8 +55,8 @@ shaka.media.InitSegmentReference = class {
|
|
|
55
55
|
/** @type {BufferSource|null} */
|
|
56
56
|
this.segmentData = segmentData;
|
|
57
57
|
|
|
58
|
-
/** @type {?shaka.extern.
|
|
59
|
-
this.
|
|
58
|
+
/** @type {?shaka.extern.aes128Key} */
|
|
59
|
+
this.aes128Key = aes128Key;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -196,15 +196,17 @@ shaka.media.SegmentReference = class {
|
|
|
196
196
|
* @param {shaka.media.SegmentReference.Status=} status
|
|
197
197
|
* The segment status is used to indicate that a segment does not exist or is
|
|
198
198
|
* not available.
|
|
199
|
-
* @param {?shaka.extern.
|
|
199
|
+
* @param {?shaka.extern.aes128Key=} aes128Key
|
|
200
200
|
* The segment's AES-128-CBC full segment encryption key and iv.
|
|
201
|
+
* @param {boolean=} allPartialSegments
|
|
202
|
+
* Indicate if the segment has all partial segments
|
|
201
203
|
*/
|
|
202
204
|
constructor(
|
|
203
205
|
startTime, endTime, uris, startByte, endByte, initSegmentReference,
|
|
204
206
|
timestampOffset, appendWindowStart, appendWindowEnd,
|
|
205
207
|
partialReferences = [], tilesLayout = '', tileDuration = null,
|
|
206
208
|
syncTime = null, status = shaka.media.SegmentReference.Status.AVAILABLE,
|
|
207
|
-
|
|
209
|
+
aes128Key = null, allPartialSegments = false) {
|
|
208
210
|
// A preload hinted Partial Segment has the same startTime and endTime.
|
|
209
211
|
goog.asserts.assert(startTime <= endTime,
|
|
210
212
|
'startTime must be less than or equal to endTime');
|
|
@@ -276,14 +278,32 @@ shaka.media.SegmentReference = class {
|
|
|
276
278
|
/** @type {boolean} */
|
|
277
279
|
this.byterangeOptimization = false;
|
|
278
280
|
|
|
279
|
-
/** @type {?shaka.extern.
|
|
280
|
-
this.
|
|
281
|
+
/** @type {?shaka.extern.aes128Key} */
|
|
282
|
+
this.aes128Key = aes128Key;
|
|
281
283
|
|
|
282
284
|
/** @type {?shaka.media.SegmentReference.ThumbnailSprite} */
|
|
283
285
|
this.thumbnailSprite = null;
|
|
284
286
|
|
|
285
287
|
/** @type {number} */
|
|
286
288
|
this.discontinuitySequence = 0;
|
|
289
|
+
|
|
290
|
+
/** @type {boolean} */
|
|
291
|
+
this.allPartialSegments = allPartialSegments;
|
|
292
|
+
|
|
293
|
+
/** @type {boolean} */
|
|
294
|
+
this.partial = false;
|
|
295
|
+
|
|
296
|
+
/** @type {boolean} */
|
|
297
|
+
this.lastPartial = false;
|
|
298
|
+
|
|
299
|
+
for (const partial of this.partialReferences) {
|
|
300
|
+
partial.markAsPartial();
|
|
301
|
+
}
|
|
302
|
+
if (this.allPartialSegments && this.partialReferences.length) {
|
|
303
|
+
const lastPartial =
|
|
304
|
+
this.partialReferences[this.partialReferences.length - 1];
|
|
305
|
+
lastPartial.markAsLastPartial();
|
|
306
|
+
}
|
|
287
307
|
}
|
|
288
308
|
|
|
289
309
|
/**
|
|
@@ -359,6 +379,14 @@ shaka.media.SegmentReference = class {
|
|
|
359
379
|
return this.partialReferences.length > 0;
|
|
360
380
|
}
|
|
361
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Returns true if it contains all partial SegmentReferences.
|
|
384
|
+
* @return {boolean}
|
|
385
|
+
*/
|
|
386
|
+
hasAllPartialSegments() {
|
|
387
|
+
return this.allPartialSegments;
|
|
388
|
+
}
|
|
389
|
+
|
|
362
390
|
/**
|
|
363
391
|
* Returns the segment's tiles layout. Only defined in image segments.
|
|
364
392
|
*
|
|
@@ -437,6 +465,44 @@ shaka.media.SegmentReference = class {
|
|
|
437
465
|
return this.independent;
|
|
438
466
|
}
|
|
439
467
|
|
|
468
|
+
/**
|
|
469
|
+
* Mark the reference as partial.
|
|
470
|
+
*
|
|
471
|
+
* @export
|
|
472
|
+
*/
|
|
473
|
+
markAsPartial() {
|
|
474
|
+
this.partial = true;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Returns true if the segment is partial.
|
|
479
|
+
*
|
|
480
|
+
* @return {boolean}
|
|
481
|
+
* @export
|
|
482
|
+
*/
|
|
483
|
+
isPartial() {
|
|
484
|
+
return this.partial;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Mark the reference as being the last part of the full segment
|
|
489
|
+
*
|
|
490
|
+
* @export
|
|
491
|
+
*/
|
|
492
|
+
markAsLastPartial() {
|
|
493
|
+
this.lastPartial = true;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Returns true if reference as being the last part of the full segment.
|
|
498
|
+
*
|
|
499
|
+
* @return {boolean}
|
|
500
|
+
* @export
|
|
501
|
+
*/
|
|
502
|
+
isLastPartial() {
|
|
503
|
+
return this.lastPartial;
|
|
504
|
+
}
|
|
505
|
+
|
|
440
506
|
/**
|
|
441
507
|
* Mark the reference as byterange optimization.
|
|
442
508
|
*
|