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
package/lib/media/playhead.js
CHANGED
|
@@ -252,7 +252,7 @@ shaka.media.MediaSourcePlayhead = class {
|
|
|
252
252
|
mediaElement,
|
|
253
253
|
() => this.onSeeking_(),
|
|
254
254
|
(realStartTime) => this.onStarted_(realStartTime),
|
|
255
|
-
this.getStartTime_(startTime));
|
|
255
|
+
() => this.getStartTime_(startTime));
|
|
256
256
|
|
|
257
257
|
/** @type {shaka.util.Timer} */
|
|
258
258
|
this.checkWindowTimer_ = new shaka.util.Timer(() => {
|
|
@@ -219,6 +219,46 @@ shaka.media.PresentationTimeline = class {
|
|
|
219
219
|
return this.presentationDelay_;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Gives PresentationTimeline a Stream's timeline so it can size and position
|
|
224
|
+
* the segment availability window, and account for missing segment
|
|
225
|
+
* information.
|
|
226
|
+
*
|
|
227
|
+
* @param {!Array.<shaka.media.PresentationTimeline.TimeRange>} timeline
|
|
228
|
+
* @param {number} startOffset
|
|
229
|
+
* @export
|
|
230
|
+
*/
|
|
231
|
+
notifyTimeRange(timeline, startOffset) {
|
|
232
|
+
if (timeline.length == 0) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const firstStartTime = timeline[0].start + startOffset;
|
|
237
|
+
const lastEndTime = timeline[timeline.length - 1].end + startOffset;
|
|
238
|
+
|
|
239
|
+
this.notifyMinSegmentStartTime(firstStartTime);
|
|
240
|
+
|
|
241
|
+
this.maxSegmentDuration_ = timeline.reduce(
|
|
242
|
+
(max, r) => { return Math.max(max, r.end - r.start); },
|
|
243
|
+
this.maxSegmentDuration_);
|
|
244
|
+
|
|
245
|
+
this.maxSegmentEndTime_ =
|
|
246
|
+
Math.max(this.maxSegmentEndTime_, lastEndTime);
|
|
247
|
+
|
|
248
|
+
if (this.presentationStartTime_ != null && this.autoCorrectDrift_ &&
|
|
249
|
+
!this.startTimeLocked_) {
|
|
250
|
+
// Since we have explicit segment end times, calculate a presentation
|
|
251
|
+
// start based on them. This start time accounts for drift.
|
|
252
|
+
// Date.now() is in milliseconds, from which we compute "now" in seconds.
|
|
253
|
+
const now = (Date.now() + this.clockOffset_) / 1000.0;
|
|
254
|
+
this.presentationStartTime_ =
|
|
255
|
+
now - this.maxSegmentEndTime_ - this.maxSegmentDuration_;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
shaka.log.v1('notifySegments:',
|
|
259
|
+
'maxSegmentDuration=' + this.maxSegmentDuration_);
|
|
260
|
+
}
|
|
261
|
+
|
|
222
262
|
|
|
223
263
|
/**
|
|
224
264
|
* Gives PresentationTimeline an array of segments so it can size and position
|
|
@@ -573,3 +613,25 @@ shaka.media.PresentationTimeline = class {
|
|
|
573
613
|
}
|
|
574
614
|
}
|
|
575
615
|
};
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* @typedef {{
|
|
620
|
+
* start: number,
|
|
621
|
+
* unscaledStart: number,
|
|
622
|
+
* end: number
|
|
623
|
+
* }}
|
|
624
|
+
*
|
|
625
|
+
* @description
|
|
626
|
+
* Defines a time range of a media segment. Times are in seconds.
|
|
627
|
+
*
|
|
628
|
+
* @property {number} start
|
|
629
|
+
* The start time of the range.
|
|
630
|
+
* @property {number} unscaledStart
|
|
631
|
+
* The start time of the range in representation timescale units.
|
|
632
|
+
* @property {number} end
|
|
633
|
+
* The end time (exclusive) of the range.
|
|
634
|
+
*
|
|
635
|
+
* @export
|
|
636
|
+
*/
|
|
637
|
+
shaka.media.PresentationTimeline.TimeRange;
|
|
@@ -9,6 +9,7 @@ goog.provide('shaka.media.SegmentIndex');
|
|
|
9
9
|
goog.provide('shaka.media.SegmentIterator');
|
|
10
10
|
|
|
11
11
|
goog.require('goog.asserts');
|
|
12
|
+
goog.require('shaka.log');
|
|
12
13
|
goog.require('shaka.media.SegmentReference');
|
|
13
14
|
goog.require('shaka.util.IReleasable');
|
|
14
15
|
goog.require('shaka.util.Timer');
|
|
@@ -44,12 +45,29 @@ shaka.media.SegmentIndex = class {
|
|
|
44
45
|
*
|
|
45
46
|
* @protected {number}
|
|
46
47
|
*/
|
|
47
|
-
this.
|
|
48
|
+
this.numEvicted_ = 0;
|
|
48
49
|
|
|
49
50
|
/** @private {boolean} */
|
|
50
51
|
this.immutable_ = false;
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Get immutability
|
|
56
|
+
*
|
|
57
|
+
* @return {boolean}
|
|
58
|
+
*/
|
|
59
|
+
getIsImmutable() {
|
|
60
|
+
return this.immutable_;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get number of references
|
|
65
|
+
* @protected
|
|
66
|
+
* @return {number}
|
|
67
|
+
*/
|
|
68
|
+
getNumReferences() {
|
|
69
|
+
return this.references.length;
|
|
70
|
+
}
|
|
53
71
|
|
|
54
72
|
/**
|
|
55
73
|
* @override
|
|
@@ -140,11 +158,11 @@ shaka.media.SegmentIndex = class {
|
|
|
140
158
|
this.references[i + 1].startTime : r.endTime;
|
|
141
159
|
// Note that a segment ends immediately before the end time.
|
|
142
160
|
if ((time >= start) && (time < end)) {
|
|
143
|
-
return i + this.
|
|
161
|
+
return i + this.numEvicted_;
|
|
144
162
|
}
|
|
145
163
|
}
|
|
146
164
|
if (this.references.length && time < this.references[0].startTime) {
|
|
147
|
-
return this.
|
|
165
|
+
return this.numEvicted_;
|
|
148
166
|
}
|
|
149
167
|
|
|
150
168
|
return null;
|
|
@@ -164,7 +182,7 @@ shaka.media.SegmentIndex = class {
|
|
|
164
182
|
return null;
|
|
165
183
|
}
|
|
166
184
|
|
|
167
|
-
const index = position - this.
|
|
185
|
+
const index = position - this.numEvicted_;
|
|
168
186
|
if (index < 0 || index >= this.references.length) {
|
|
169
187
|
return null;
|
|
170
188
|
}
|
|
@@ -290,7 +308,7 @@ shaka.media.SegmentIndex = class {
|
|
|
290
308
|
const diff = oldSize - newSize;
|
|
291
309
|
// Tracking the number of evicted refs will keep their "positions" stable
|
|
292
310
|
// for the caller.
|
|
293
|
-
this.
|
|
311
|
+
this.numEvicted_ += diff;
|
|
294
312
|
}
|
|
295
313
|
|
|
296
314
|
|
|
@@ -332,7 +350,7 @@ shaka.media.SegmentIndex = class {
|
|
|
332
350
|
if (firstReference.endTime <= windowStart) {
|
|
333
351
|
this.references.shift();
|
|
334
352
|
if (!isNew) {
|
|
335
|
-
this.
|
|
353
|
+
this.numEvicted_++;
|
|
336
354
|
}
|
|
337
355
|
} else {
|
|
338
356
|
break;
|
|
@@ -407,10 +425,17 @@ shaka.media.SegmentIndex = class {
|
|
|
407
425
|
|
|
408
426
|
/**
|
|
409
427
|
* Returns a new iterator that initially points to the segment that contains
|
|
410
|
-
* the given time
|
|
411
|
-
*
|
|
428
|
+
* the given time, or the nearest independent segment before it.
|
|
429
|
+
*
|
|
430
|
+
* Like the normal iterator, next() must be called first to get to the first
|
|
431
|
+
* element. Returns null if we do not find a segment at the
|
|
412
432
|
* requested time.
|
|
413
433
|
*
|
|
434
|
+
* The first segment returned by the iterator _MUST_ be an independent
|
|
435
|
+
* segment. Assumes that only partial references can be dependent, based on
|
|
436
|
+
* RFC 8216 rev 13, section 8.1: "Each (non-Partial) Media Segment in a Media
|
|
437
|
+
* Playlist will contain at least one independent frame."
|
|
438
|
+
*
|
|
414
439
|
* @param {number} time
|
|
415
440
|
* @return {?shaka.media.SegmentIterator}
|
|
416
441
|
* @export
|
|
@@ -430,9 +455,18 @@ shaka.media.SegmentIndex = class {
|
|
|
430
455
|
if (ref && ref.hasPartialSegments()) {
|
|
431
456
|
// Look for a partial SegmentReference.
|
|
432
457
|
for (let i = ref.partialReferences.length - 1; i >= 0; --i) {
|
|
433
|
-
|
|
458
|
+
let r = ref.partialReferences[i];
|
|
434
459
|
// Note that a segment ends immediately before the end time.
|
|
435
460
|
if ((time >= r.startTime) && (time < r.endTime)) {
|
|
461
|
+
// Find an independent partial segment by moving backwards.
|
|
462
|
+
while (i && !r.isIndependent()) {
|
|
463
|
+
i--;
|
|
464
|
+
r = ref.partialReferences[i];
|
|
465
|
+
}
|
|
466
|
+
if (!r.isIndependent()) {
|
|
467
|
+
shaka.log.alwaysError('No independent partial segment found!');
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
436
470
|
// Call to next() should move the partial segment, not the full
|
|
437
471
|
// segment.
|
|
438
472
|
index++;
|
|
@@ -448,7 +482,7 @@ shaka.media.SegmentIndex = class {
|
|
|
448
482
|
* @return {boolean}
|
|
449
483
|
*/
|
|
450
484
|
isEmpty() {
|
|
451
|
-
return this.
|
|
485
|
+
return this.getNumReferences() == 0;
|
|
452
486
|
}
|
|
453
487
|
|
|
454
488
|
/**
|
|
@@ -629,7 +663,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
629
663
|
*/
|
|
630
664
|
appendSegmentIndex(segmentIndex) {
|
|
631
665
|
goog.asserts.assert(
|
|
632
|
-
this.indexes_.length == 0 || segmentIndex.
|
|
666
|
+
this.indexes_.length == 0 || segmentIndex.numEvicted_ == 0,
|
|
633
667
|
'Should not append a new segment index with already-evicted segments');
|
|
634
668
|
this.indexes_.push(segmentIndex);
|
|
635
669
|
}
|
|
@@ -673,7 +707,8 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
673
707
|
return position + numPassedInEarlierIndexes;
|
|
674
708
|
}
|
|
675
709
|
|
|
676
|
-
numPassedInEarlierIndexes += index.
|
|
710
|
+
numPassedInEarlierIndexes += index.numEvicted_ +
|
|
711
|
+
index.references.length;
|
|
677
712
|
}
|
|
678
713
|
|
|
679
714
|
return null;
|
|
@@ -689,7 +724,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
689
724
|
|
|
690
725
|
for (const index of this.indexes_) {
|
|
691
726
|
goog.asserts.assert(
|
|
692
|
-
!sawSegments || index.
|
|
727
|
+
!sawSegments || index.numEvicted_ == 0,
|
|
693
728
|
'Should not see evicted segments after available segments');
|
|
694
729
|
const reference = index.get(position - numPassedInEarlierIndexes);
|
|
695
730
|
|
|
@@ -697,7 +732,8 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
697
732
|
return reference;
|
|
698
733
|
}
|
|
699
734
|
|
|
700
|
-
numPassedInEarlierIndexes += index.
|
|
735
|
+
numPassedInEarlierIndexes += index.numEvicted_ +
|
|
736
|
+
index.references.length;
|
|
701
737
|
sawSegments = sawSegments || index.references.length != 0;
|
|
702
738
|
}
|
|
703
739
|
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.require('goog.asserts');
|
|
8
|
+
goog.require('shaka.net.NetworkingEngine');
|
|
9
|
+
goog.require('shaka.media.InitSegmentReference');
|
|
10
|
+
goog.require('shaka.media.SegmentReference');
|
|
11
|
+
goog.provide('shaka.media.SegmentPrefetch');
|
|
12
|
+
goog.require('shaka.log');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @summary
|
|
16
|
+
* This class manages segment prefetch operations.
|
|
17
|
+
* Called by StreamingEngine to prefetch next N segments
|
|
18
|
+
* ahead of playhead, to reduce the chances of rebuffering.
|
|
19
|
+
*/
|
|
20
|
+
shaka.media.SegmentPrefetch = class {
|
|
21
|
+
/**
|
|
22
|
+
* @param {number} prefetchLimit
|
|
23
|
+
* @param {shaka.extern.Stream} stream
|
|
24
|
+
* @param {shaka.media.SegmentPrefetch.FetchDispatcher} fetchDispatcher
|
|
25
|
+
*/
|
|
26
|
+
constructor(prefetchLimit, stream, fetchDispatcher) {
|
|
27
|
+
/** @private {number} */
|
|
28
|
+
this.prefetchLimit_ = prefetchLimit;
|
|
29
|
+
|
|
30
|
+
/** @private {shaka.extern.Stream} */
|
|
31
|
+
this.stream_ = stream;
|
|
32
|
+
|
|
33
|
+
/** @private {number} */
|
|
34
|
+
this.prefetchPosTime_ = 0;
|
|
35
|
+
|
|
36
|
+
/** @private {shaka.media.SegmentPrefetch.FetchDispatcher} */
|
|
37
|
+
this.fetchDispatcher_ = fetchDispatcher;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @private {!Map.<shaka.media.SegmentReference,
|
|
41
|
+
* !shaka.media.SegmentPrefetchOperation>}
|
|
42
|
+
*/
|
|
43
|
+
this.segmentPrefetchMap_ = new Map();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Fetch next segments ahead of current segment.
|
|
48
|
+
*
|
|
49
|
+
* @param {(!shaka.media.SegmentReference)} startReference
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
prefetchSegments(startReference) {
|
|
53
|
+
goog.asserts.assert(this.prefetchLimit_ > 0,
|
|
54
|
+
'SegmentPrefetch can not be used when prefetchLimit <= 0.');
|
|
55
|
+
|
|
56
|
+
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
57
|
+
if (!this.stream_.segmentIndex) {
|
|
58
|
+
shaka.log.info(logPrefix, 'missing segmentIndex');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const currTime = startReference.startTime;
|
|
62
|
+
const maxTime = Math.max(currTime, this.prefetchPosTime_);
|
|
63
|
+
const iterator = this.stream_.segmentIndex.getIteratorForTime(maxTime);
|
|
64
|
+
if (!iterator) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let reference = startReference;
|
|
68
|
+
while (this.segmentPrefetchMap_.size < this.prefetchLimit_ &&
|
|
69
|
+
reference != null) {
|
|
70
|
+
// By default doesn't prefech preload partial segments when using
|
|
71
|
+
// byterange
|
|
72
|
+
let prefetchAllowed = true;
|
|
73
|
+
if (reference.isPreload() && reference.endByte != null) {
|
|
74
|
+
prefetchAllowed = false;
|
|
75
|
+
}
|
|
76
|
+
if (reference.getStatus() ==
|
|
77
|
+
shaka.media.SegmentReference.Status.MISSING) {
|
|
78
|
+
prefetchAllowed = false;
|
|
79
|
+
}
|
|
80
|
+
if (prefetchAllowed && !this.segmentPrefetchMap_.has(reference)) {
|
|
81
|
+
const segmentPrefetchOperation =
|
|
82
|
+
new shaka.media.SegmentPrefetchOperation(this.fetchDispatcher_);
|
|
83
|
+
segmentPrefetchOperation.dispatchFetch(reference, this.stream_);
|
|
84
|
+
this.segmentPrefetchMap_.set(reference, segmentPrefetchOperation);
|
|
85
|
+
}
|
|
86
|
+
this.prefetchPosTime_ = reference.startTime;
|
|
87
|
+
reference = iterator.next().value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the result of prefetched segment if already exists.
|
|
93
|
+
* @param {(!shaka.media.SegmentReference)} reference
|
|
94
|
+
* @param {?function(BufferSource):!Promise=} streamDataCallback
|
|
95
|
+
* @return {?shaka.net.NetworkingEngine.PendingRequest} op
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
getPrefetchedSegment(reference, streamDataCallback) {
|
|
99
|
+
goog.asserts.assert(this.prefetchLimit_ > 0,
|
|
100
|
+
'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
|
+
|
|
104
|
+
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
105
|
+
|
|
106
|
+
if (this.segmentPrefetchMap_.has(reference)) {
|
|
107
|
+
const segmentPrefetchOperation = this.segmentPrefetchMap_.get(reference);
|
|
108
|
+
if (streamDataCallback) {
|
|
109
|
+
segmentPrefetchOperation.setStreamDataCallback(streamDataCallback);
|
|
110
|
+
}
|
|
111
|
+
this.segmentPrefetchMap_.delete(reference);
|
|
112
|
+
shaka.log.debug(
|
|
113
|
+
logPrefix,
|
|
114
|
+
'reused prefetched segment at time:', reference.startTime,
|
|
115
|
+
'mapSize', this.segmentPrefetchMap_.size);
|
|
116
|
+
return segmentPrefetchOperation.getOperation();
|
|
117
|
+
} else {
|
|
118
|
+
shaka.log.debug(
|
|
119
|
+
logPrefix,
|
|
120
|
+
'missed segment at time:', reference.startTime,
|
|
121
|
+
'mapSize', this.segmentPrefetchMap_.size);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Clear all segment data.
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
130
|
+
clearAll() {
|
|
131
|
+
if (this.segmentPrefetchMap_.size === 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
135
|
+
for (const reference of this.segmentPrefetchMap_.keys()) {
|
|
136
|
+
if (reference) {
|
|
137
|
+
this.abortPrefetchedSegment_(reference);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
shaka.log.info(logPrefix, 'cleared all');
|
|
141
|
+
this.prefetchPosTime_ = 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Reset the prefetchLimit and clear all internal states.
|
|
146
|
+
* Called by StreamingEngine when configure() was called.
|
|
147
|
+
* @param {number} newPrefetchLimit
|
|
148
|
+
* @public
|
|
149
|
+
*/
|
|
150
|
+
resetLimit(newPrefetchLimit) {
|
|
151
|
+
goog.asserts.assert(newPrefetchLimit >= 0,
|
|
152
|
+
'The new prefetch limit must be >= 0.');
|
|
153
|
+
this.prefetchLimit_ = newPrefetchLimit;
|
|
154
|
+
const keyArr = Array.from(this.segmentPrefetchMap_.keys());
|
|
155
|
+
while (keyArr.length > newPrefetchLimit) {
|
|
156
|
+
const reference = keyArr.pop();
|
|
157
|
+
if (reference) {
|
|
158
|
+
this.abortPrefetchedSegment_(reference);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Called by Streaming Engine when switching variant.
|
|
165
|
+
* @param {shaka.extern.Stream} stream
|
|
166
|
+
* @public
|
|
167
|
+
*/
|
|
168
|
+
switchStream(stream) {
|
|
169
|
+
if (stream && stream !== this.stream_) {
|
|
170
|
+
this.clearAll();
|
|
171
|
+
this.stream_ = stream;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Remove a segment from prefetch map and abort it.
|
|
177
|
+
* @param {(!shaka.media.SegmentReference)} reference
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
180
|
+
abortPrefetchedSegment_(reference) {
|
|
181
|
+
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
182
|
+
const segmentPrefetchOperation = this.segmentPrefetchMap_.get(reference);
|
|
183
|
+
this.segmentPrefetchMap_.delete(reference);
|
|
184
|
+
if (segmentPrefetchOperation) {
|
|
185
|
+
segmentPrefetchOperation.abort();
|
|
186
|
+
shaka.log.info(
|
|
187
|
+
logPrefix,
|
|
188
|
+
'pop and abort prefetched segment at time:', reference.startTime);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The prefix of the logs that are created in this class.
|
|
194
|
+
* @return {string}
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
static logPrefix_(stream) {
|
|
198
|
+
return 'SegmentPrefetch(' + stream.type + ':' + stream.id + ')';
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @summary
|
|
204
|
+
* This class manages a segment prefetch operation.
|
|
205
|
+
*/
|
|
206
|
+
shaka.media.SegmentPrefetchOperation = class {
|
|
207
|
+
/**
|
|
208
|
+
* @param {shaka.media.SegmentPrefetch.FetchDispatcher} fetchDispatcher
|
|
209
|
+
*/
|
|
210
|
+
constructor(fetchDispatcher) {
|
|
211
|
+
/** @private {shaka.media.SegmentPrefetch.FetchDispatcher} */
|
|
212
|
+
this.fetchDispatcher_ = fetchDispatcher;
|
|
213
|
+
|
|
214
|
+
/** @private {?function(BufferSource):!Promise} */
|
|
215
|
+
this.streamDataCallback_ = null;
|
|
216
|
+
|
|
217
|
+
/** @private {?shaka.net.NetworkingEngine.PendingRequest} */
|
|
218
|
+
this.operation_ = null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Fetch a segments
|
|
223
|
+
*
|
|
224
|
+
* @param {!shaka.media.SegmentReference}
|
|
225
|
+
* reference
|
|
226
|
+
* @param {!shaka.extern.Stream} stream
|
|
227
|
+
* @public
|
|
228
|
+
*/
|
|
229
|
+
dispatchFetch(reference, stream) {
|
|
230
|
+
this.operation_ = this.fetchDispatcher_(
|
|
231
|
+
reference, stream, async (data) => {
|
|
232
|
+
if (this.streamDataCallback_) {
|
|
233
|
+
await this.streamDataCallback_(data);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get the operation of prefetched segment if already exists.
|
|
240
|
+
*
|
|
241
|
+
* @return {?shaka.net.NetworkingEngine.PendingRequest} op
|
|
242
|
+
* @public
|
|
243
|
+
*/
|
|
244
|
+
getOperation() {
|
|
245
|
+
return this.operation_;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {?function(BufferSource):!Promise} streamDataCallback
|
|
250
|
+
* @public
|
|
251
|
+
*/
|
|
252
|
+
setStreamDataCallback(streamDataCallback) {
|
|
253
|
+
this.streamDataCallback_ = streamDataCallback;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Abort the current operation if exists.
|
|
258
|
+
*/
|
|
259
|
+
abort() {
|
|
260
|
+
if (this.operation_) {
|
|
261
|
+
this.operation_.abort();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* @typedef {function(
|
|
268
|
+
* !(shaka.media.InitSegmentReference|shaka.media.SegmentReference),
|
|
269
|
+
* shaka.extern.Stream,
|
|
270
|
+
* ?function(BufferSource):!Promise=
|
|
271
|
+
* ):!shaka.net.NetworkingEngine.PendingRequest}
|
|
272
|
+
*
|
|
273
|
+
* @description
|
|
274
|
+
* A callback function that fetches a segment.
|
|
275
|
+
* @export
|
|
276
|
+
*/
|
|
277
|
+
shaka.media.SegmentPrefetch.FetchDispatcher;
|
|
@@ -10,6 +10,7 @@ goog.provide('shaka.media.SegmentReference');
|
|
|
10
10
|
goog.require('goog.asserts');
|
|
11
11
|
goog.require('shaka.log');
|
|
12
12
|
goog.require('shaka.util.ArrayUtils');
|
|
13
|
+
goog.require('shaka.util.BufferUtils');
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -29,9 +30,11 @@ shaka.media.InitSegmentReference = class {
|
|
|
29
30
|
* segment extends to the end of the resource.
|
|
30
31
|
* @param {null|shaka.extern.MediaQualityInfo=} mediaQuality Information about
|
|
31
32
|
* the quality of the media associated with this init segment.
|
|
32
|
-
* @param {number=} timescale
|
|
33
|
+
* @param {(null|number)=} timescale
|
|
34
|
+
* @param {(null|BufferSource)=} segmentData
|
|
33
35
|
*/
|
|
34
|
-
constructor(uris, startByte, endByte, mediaQuality = null, timescale
|
|
36
|
+
constructor(uris, startByte, endByte, mediaQuality = null, timescale = null,
|
|
37
|
+
segmentData = null) {
|
|
35
38
|
/** @type {function():!Array.<string>} */
|
|
36
39
|
this.getUris = uris;
|
|
37
40
|
|
|
@@ -44,8 +47,11 @@ shaka.media.InitSegmentReference = class {
|
|
|
44
47
|
/** @const {shaka.extern.MediaQualityInfo|null} */
|
|
45
48
|
this.mediaQuality = mediaQuality;
|
|
46
49
|
|
|
47
|
-
/** @type {number|
|
|
50
|
+
/** @type {number|null} */
|
|
48
51
|
this.timescale = timescale;
|
|
52
|
+
|
|
53
|
+
/** @type {BufferSource|null} */
|
|
54
|
+
this.segmentData = segmentData;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
/**
|
|
@@ -93,6 +99,16 @@ shaka.media.InitSegmentReference = class {
|
|
|
93
99
|
return this.mediaQuality;
|
|
94
100
|
}
|
|
95
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Return the segment data.
|
|
104
|
+
*
|
|
105
|
+
* @return {?BufferSource}
|
|
106
|
+
*/
|
|
107
|
+
getSegmentData() {
|
|
108
|
+
return this.segmentData;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
96
112
|
/**
|
|
97
113
|
* Check if two initSegmentReference have all the same values.
|
|
98
114
|
* @param {?shaka.media.InitSegmentReference} reference1
|
|
@@ -101,12 +117,15 @@ shaka.media.InitSegmentReference = class {
|
|
|
101
117
|
*/
|
|
102
118
|
static equal(reference1, reference2) {
|
|
103
119
|
const ArrayUtils = shaka.util.ArrayUtils;
|
|
120
|
+
const BufferUtils = shaka.util.BufferUtils;
|
|
104
121
|
if (!reference1 || !reference2) {
|
|
105
122
|
return reference1 == reference2;
|
|
106
123
|
} else {
|
|
107
124
|
return reference1.getStartByte() == reference2.getStartByte() &&
|
|
108
125
|
reference1.getEndByte() == reference2.getEndByte() &&
|
|
109
|
-
ArrayUtils.equal(reference1.getUris(), reference2.getUris())
|
|
126
|
+
ArrayUtils.equal(reference1.getUris(), reference2.getUris()) &&
|
|
127
|
+
BufferUtils.equal(reference1.getSegmentData(),
|
|
128
|
+
reference2.getSegmentData());
|
|
110
129
|
}
|
|
111
130
|
}
|
|
112
131
|
};
|
|
@@ -246,6 +265,12 @@ shaka.media.SegmentReference = class {
|
|
|
246
265
|
/** @type {boolean} */
|
|
247
266
|
this.preload = false;
|
|
248
267
|
|
|
268
|
+
/** @type {boolean} */
|
|
269
|
+
this.independent = true;
|
|
270
|
+
|
|
271
|
+
/** @type {boolean} */
|
|
272
|
+
this.byterangeOptimization = false;
|
|
273
|
+
|
|
249
274
|
/** @type {?shaka.extern.HlsAes128Key} */
|
|
250
275
|
this.hlsAes128Key = hlsAes128Key;
|
|
251
276
|
|
|
@@ -388,6 +413,47 @@ shaka.media.SegmentReference = class {
|
|
|
388
413
|
return this.preload;
|
|
389
414
|
}
|
|
390
415
|
|
|
416
|
+
/**
|
|
417
|
+
* Mark the reference as non-independent.
|
|
418
|
+
*
|
|
419
|
+
* @export
|
|
420
|
+
*/
|
|
421
|
+
markAsNonIndependent() {
|
|
422
|
+
this.independent = false;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Returns true if the segment is independent.
|
|
427
|
+
*
|
|
428
|
+
* @return {boolean}
|
|
429
|
+
* @export
|
|
430
|
+
*/
|
|
431
|
+
isIndependent() {
|
|
432
|
+
return this.independent;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Mark the reference as byterange optimization.
|
|
437
|
+
*
|
|
438
|
+
* The "byterange optimization" means that it is playable using MP4 low
|
|
439
|
+
* latency streaming with chunked data.
|
|
440
|
+
*
|
|
441
|
+
* @export
|
|
442
|
+
*/
|
|
443
|
+
markAsByterangeOptimization() {
|
|
444
|
+
this.byterangeOptimization = true;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Returns true if the segment has a byterange optimization.
|
|
449
|
+
*
|
|
450
|
+
* @return {boolean}
|
|
451
|
+
* @export
|
|
452
|
+
*/
|
|
453
|
+
hasByterangeOptimization() {
|
|
454
|
+
return this.byterangeOptimization;
|
|
455
|
+
}
|
|
456
|
+
|
|
391
457
|
/**
|
|
392
458
|
* Set the segment's thumbnail sprite.
|
|
393
459
|
*
|