shaka-player 4.12.8 → 4.13.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/AUTHORS +1 -0
- package/CONTRIBUTORS +4 -0
- package/README.md +22 -21
- package/cspell.config.yaml +18 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +29 -24
- package/dist/locales.js +33 -33
- package/dist/shaka-player.compiled.d.ts +138 -36
- package/dist/shaka-player.compiled.debug.d.ts +138 -36
- package/dist/shaka-player.compiled.debug.externs.js +367 -107
- package/dist/shaka-player.compiled.debug.js +828 -765
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +367 -107
- package/dist/shaka-player.compiled.js +1451 -1416
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +172 -38
- package/dist/shaka-player.ui.debug.d.ts +172 -38
- package/dist/shaka-player.ui.debug.externs.js +406 -113
- package/dist/shaka-player.ui.debug.js +842 -766
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +406 -113
- package/dist/shaka-player.ui.js +1670 -1628
- package/dist/shaka-player.ui.map +4 -4
- package/eslint.config.mjs +343 -0
- package/externs/airplay.js +1 -1
- package/externs/audiotrack.js +1 -1
- package/externs/awesomplete.js +1 -1
- package/externs/cast-sdk-v2.js +2 -2
- package/externs/cmcd.js +16 -1
- package/externs/device_sensor_event.js +1 -1
- package/externs/ima.js +8 -8
- package/externs/isoboxer.js +31 -31
- package/externs/jwk_set.js +1 -1
- package/externs/lcevc.js +8 -8
- package/externs/mediakeys.js +1 -1
- package/externs/mediasession.js +3 -2
- package/externs/mediatailor.js +18 -18
- package/externs/pictureinpicture.js +41 -1
- package/externs/playstation.js +2 -2
- package/externs/prefixed_eme.js +1 -1
- package/externs/shaka/abortable.js +4 -4
- package/externs/shaka/abr_manager.js +1 -1
- package/externs/shaka/ads.js +45 -6
- package/externs/shaka/cea.js +2 -2
- package/externs/shaka/codecs.js +4 -4
- package/externs/shaka/drm_info.js +6 -6
- package/externs/shaka/error.js +5 -5
- package/externs/shaka/manifest.js +51 -56
- package/externs/shaka/manifest_parser.js +3 -9
- package/externs/shaka/net.js +23 -20
- package/externs/shaka/offline.js +37 -37
- package/externs/shaka/offline_compat_v1.js +10 -10
- package/externs/shaka/offline_compat_v2.js +10 -10
- package/externs/shaka/player.js +139 -109
- package/externs/shaka/text.js +10 -3
- package/externs/shaka/transmuxer.js +1 -1
- package/externs/videotrack.js +1 -1
- package/lib/abr/ewma.js +1 -1
- package/lib/abr/simple_abr_manager.js +70 -22
- package/lib/ads/ad_manager.js +43 -18
- package/lib/ads/ad_utils.js +160 -58
- package/lib/ads/ads_stats.js +1 -1
- package/lib/ads/client_side_ad_manager.js +2 -2
- package/lib/ads/interstitial_ad.js +16 -11
- package/lib/ads/interstitial_ad_manager.js +419 -72
- package/lib/ads/interstitial_static_ad.js +299 -0
- package/lib/ads/media_tailor_ad.js +1 -0
- package/lib/ads/media_tailor_ad_manager.js +37 -36
- package/lib/ads/server_side_ad_manager.js +7 -6
- package/lib/cast/cast_receiver.js +5 -3
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cast/cast_utils.js +20 -13
- package/lib/cea/cea608_data_channel.js +53 -53
- package/lib/cea/cea708_service.js +42 -40
- package/lib/cea/cea708_window.js +5 -2
- package/lib/cea/cea_decoder.js +5 -7
- package/lib/cea/mp4_cea_parser.js +1 -1
- package/lib/cea/sei_processor.js +1 -1
- package/lib/dash/content_protection.js +62 -192
- package/lib/dash/dash_parser.js +119 -119
- package/lib/dash/mpd_utils.js +14 -13
- package/lib/dash/segment_base.js +5 -5
- package/lib/dash/segment_list.js +10 -10
- package/lib/dash/segment_template.js +55 -53
- package/lib/debug/log.js +2 -2
- package/lib/dependencies/all.js +2 -1
- package/lib/{media → drm}/drm_engine.js +274 -143
- package/lib/{util → drm}/drm_utils.js +20 -11
- package/lib/drm/playready.js +233 -0
- package/lib/hls/hls_classes.js +14 -14
- package/lib/hls/hls_parser.js +257 -196
- package/lib/hls/hls_utils.js +14 -14
- package/lib/hls/manifest_text_parser.js +10 -10
- package/lib/media/adaptation_set.js +6 -5
- package/lib/media/adaptation_set_criteria.js +51 -379
- package/lib/media/buffering_observer.js +5 -4
- package/lib/media/closed_caption_parser.js +2 -2
- package/lib/media/content_workarounds.js +2 -2
- package/lib/media/example_based_criteria.js +69 -0
- package/lib/media/gap_jumping_controller.js +14 -1
- package/lib/media/manifest_filterer.js +8 -8
- package/lib/media/manifest_parser.js +2 -2
- package/lib/media/media_source_capabilities.js +20 -1
- package/lib/media/media_source_engine.js +84 -35
- package/lib/media/mp4_segment_index_parser.js +5 -5
- package/lib/media/playhead.js +2 -8
- package/lib/media/playhead_observer.js +1 -1
- package/lib/media/preference_based_criteria.js +333 -0
- package/lib/media/preload_manager.js +53 -37
- package/lib/media/presentation_timeline.js +2 -2
- package/lib/media/quality_observer.js +35 -35
- package/lib/media/region_observer.js +2 -2
- package/lib/media/region_timeline.js +3 -3
- package/lib/media/segment_index.js +14 -14
- package/lib/media/segment_prefetch.js +17 -13
- package/lib/media/segment_reference.js +7 -7
- package/lib/media/segment_utils.js +9 -9
- package/lib/media/streaming_engine.js +77 -38
- package/lib/media/time_ranges_utils.js +1 -1
- package/lib/media/video_wrapper.js +1 -1
- package/lib/media/webm_segment_index_parser.js +4 -4
- package/lib/mss/content_protection.js +17 -222
- package/lib/mss/mss_parser.js +23 -24
- package/lib/net/data_uri_plugin.js +1 -0
- package/lib/net/http_fetch_plugin.js +8 -7
- package/lib/net/http_plugin_utils.js +5 -2
- package/lib/net/http_xhr_plugin.js +4 -3
- package/lib/net/networking_engine.js +72 -17
- package/lib/net/networking_utils.js +5 -2
- package/lib/offline/download_info.js +5 -1
- package/lib/offline/download_manager.js +15 -4
- package/lib/offline/download_progress_estimator.js +1 -1
- package/lib/offline/indexeddb/base_storage_cell.js +9 -9
- package/lib/offline/indexeddb/db_connection.js +1 -1
- package/lib/offline/indexeddb/db_operation.js +2 -2
- package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
- package/lib/offline/manifest_converter.js +11 -12
- package/lib/offline/offline_scheme.js +8 -4
- package/lib/offline/session_deleter.js +11 -11
- package/lib/offline/storage.js +137 -88
- package/lib/offline/storage_muxer.js +8 -8
- package/lib/offline/stored_content_utils.js +3 -3
- package/lib/offline/stream_bandwidth_estimator.js +1 -1
- package/lib/player.js +291 -207
- package/lib/polyfill/all.js +1 -1
- package/lib/polyfill/media_capabilities.js +5 -5
- package/lib/polyfill/patchedmediakeys_apple.js +6 -6
- package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
- package/lib/polyfill/video_play_promise.js +0 -1
- package/lib/text/cue.js +3 -2
- package/lib/text/lrc_text_parser.js +1 -1
- package/lib/text/mp4_ttml_parser.js +1 -1
- package/lib/text/mp4_vtt_parser.js +3 -3
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +37 -10
- package/lib/text/ssa_text_parser.js +3 -1
- package/lib/text/stub_text_displayer.js +12 -5
- package/lib/text/text_engine.js +5 -4
- package/lib/text/text_utils.js +4 -4
- package/lib/text/ttml_text_parser.js +21 -20
- package/lib/text/ui_text_displayer.js +20 -13
- package/lib/text/vtt_text_parser.js +10 -10
- package/lib/text/web_vtt_generator.js +2 -2
- package/lib/transmuxer/aac_transmuxer.js +2 -2
- package/lib/transmuxer/ac3_transmuxer.js +2 -2
- package/lib/transmuxer/adts.js +2 -0
- package/lib/transmuxer/ec3.js +3 -3
- package/lib/transmuxer/ec3_transmuxer.js +2 -2
- package/lib/transmuxer/h264.js +5 -5
- package/lib/transmuxer/h265.js +3 -3
- package/lib/transmuxer/mp3_transmuxer.js +2 -2
- package/lib/transmuxer/mpeg_audio.js +6 -6
- package/lib/transmuxer/mss_transmuxer.js +2 -0
- package/lib/transmuxer/transmuxer_engine.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +10 -10
- package/lib/util/abortable_operation.js +10 -10
- package/lib/util/array_utils.js +6 -6
- package/lib/util/cmcd_manager.js +149 -18
- package/lib/util/cmsd_manager.js +11 -11
- package/lib/util/config_utils.js +3 -3
- package/lib/util/content_steering_manager.js +17 -17
- package/lib/util/data_view_reader.js +3 -3
- package/lib/util/ebml_parser.js +1 -1
- package/lib/util/error.js +11 -6
- package/lib/util/event_manager.js +1 -1
- package/lib/util/exp_golomb.js +1 -1
- package/lib/util/fairplay_utils.js +6 -1
- package/lib/util/fake_event.js +3 -2
- package/lib/util/fake_event_target.js +1 -1
- package/lib/util/functional.js +8 -8
- package/lib/util/id3_utils.js +1 -1
- package/lib/util/iterables.js +6 -6
- package/lib/util/language_utils.js +17 -17
- package/lib/util/manifest_parser_utils.js +13 -13
- package/lib/util/map_utils.js +6 -6
- package/lib/util/media_ready_state_utils.js +1 -1
- package/lib/util/mime_utils.js +15 -4
- package/lib/util/mp4_box_parsers.js +5 -5
- package/lib/util/mp4_generator.js +31 -30
- package/lib/util/mp4_parser.js +2 -2
- package/lib/util/multi_map.js +5 -5
- package/lib/util/mutex.js +1 -1
- package/lib/util/networking.js +1 -1
- package/lib/util/object_utils.js +5 -1
- package/lib/util/operation_manager.js +1 -1
- package/lib/util/periods.js +24 -24
- package/lib/util/platform.js +8 -4
- package/lib/util/player_configuration.js +50 -17
- package/lib/util/pssh.js +34 -6
- package/lib/util/public_promise.js +2 -2
- package/lib/util/state_history.js +2 -2
- package/lib/util/stream_utils.js +138 -120
- package/lib/util/string_utils.js +4 -3
- package/lib/util/switch_history.js +2 -2
- package/lib/util/tXml.js +22 -17
- package/lib/util/text_parser.js +2 -2
- package/lib/util/timer.js +1 -1
- package/lib/util/ts_parser.js +22 -22
- package/lib/util/xml_utils.js +1 -0
- package/package.json +7 -4
- package/project-words.txt +485 -0
- package/shaka-player.uncompiled.js +1 -1
- package/third_party/closure-uri/uri.js +2 -2
- package/third_party/closure-uri/utils.js +2 -2
- package/third_party/language-mapping-list/language-mapping-list.js +1 -1
- package/ui/ad_statistics_button.js +9 -5
- package/ui/airplay_button.js +1 -0
- package/ui/audio_language_selection.js +2 -1
- package/ui/context_menu.js +2 -2
- package/ui/controls.js +7 -7
- package/ui/externs/ui.js +29 -21
- package/ui/externs/watermark.js +64 -0
- package/ui/fast_forward_button.js +1 -1
- package/ui/gl_matrix/matrix_4x4.js +11 -5
- package/ui/hidden_fast_forward_button.js +1 -1
- package/ui/hidden_seek_button.js +1 -1
- package/ui/language_utils.js +27 -26
- package/ui/less/buttons.less +2 -2
- package/ui/localization.js +21 -21
- package/ui/loop_button.js +2 -2
- package/ui/overflow_menu.js +2 -2
- package/ui/playback_rate_selection.js +1 -1
- package/ui/presentation_time.js +4 -1
- package/ui/range_element.js +2 -2
- package/ui/resolution_selection.js +42 -6
- package/ui/rewind_button.js +1 -1
- package/ui/seek_bar.js +5 -5
- package/ui/statistics_button.js +8 -4
- package/ui/text_selection.js +3 -2
- package/ui/ui.js +32 -2
- package/ui/vr_manager.js +3 -3
- package/ui/vr_utils.js +14 -14
- package/ui/vr_webgl.js +5 -5
- package/ui/watermark.js +313 -0
- package/.eslintignore +0 -4
- package/.eslintrc.js +0 -310
- package/lib/polyfill/patchedmediakeys_nop.js +0 -148
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.media.PreferenceBasedCriteria');
|
|
8
|
+
|
|
9
|
+
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
10
|
+
goog.require('shaka.log');
|
|
11
|
+
goog.require('shaka.media.AdaptationSet');
|
|
12
|
+
goog.require('shaka.media.AdaptationSetCriteria');
|
|
13
|
+
goog.require('shaka.media.Capabilities');
|
|
14
|
+
goog.require('shaka.util.LanguageUtils');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @implements {shaka.media.AdaptationSetCriteria}
|
|
19
|
+
* @final
|
|
20
|
+
*/
|
|
21
|
+
shaka.media.PreferenceBasedCriteria = class {
|
|
22
|
+
/** */
|
|
23
|
+
constructor() {
|
|
24
|
+
/** @private {?shaka.media.AdaptationSetCriteria.Configuration} */
|
|
25
|
+
this.config_ = null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @override
|
|
30
|
+
*/
|
|
31
|
+
configure(config) {
|
|
32
|
+
this.config_ = config;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
create(variants) {
|
|
39
|
+
const Class = shaka.media.PreferenceBasedCriteria;
|
|
40
|
+
|
|
41
|
+
let current = [];
|
|
42
|
+
|
|
43
|
+
const byLanguage = Class.filterByLanguage_(variants, this.config_.language);
|
|
44
|
+
const byPrimary = variants.filter((variant) => variant.primary);
|
|
45
|
+
|
|
46
|
+
if (byLanguage.length) {
|
|
47
|
+
current = byLanguage;
|
|
48
|
+
} else if (byPrimary.length) {
|
|
49
|
+
current = byPrimary;
|
|
50
|
+
} else {
|
|
51
|
+
current = variants;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Now refine the choice based on role preference. Even the empty string
|
|
55
|
+
// works here, and will match variants without any roles.
|
|
56
|
+
const byRole = Class.filterVariantsByRole_(current, this.config_.role);
|
|
57
|
+
if (byRole.length) {
|
|
58
|
+
current = byRole;
|
|
59
|
+
} else {
|
|
60
|
+
shaka.log.warning('No exact match for variant role could be found.');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this.config_.videoLayout) {
|
|
64
|
+
const byVideoLayout = Class.filterVariantsByVideoLayout_(
|
|
65
|
+
current, this.config_.videoLayout);
|
|
66
|
+
if (byVideoLayout.length) {
|
|
67
|
+
current = byVideoLayout;
|
|
68
|
+
} else {
|
|
69
|
+
shaka.log.warning(
|
|
70
|
+
'No exact match for the video layout could be found.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (this.config_.hdrLevel) {
|
|
75
|
+
const byHdrLevel = Class.filterVariantsByHDRLevel_(
|
|
76
|
+
current, this.config_.hdrLevel);
|
|
77
|
+
if (byHdrLevel.length) {
|
|
78
|
+
current = byHdrLevel;
|
|
79
|
+
} else {
|
|
80
|
+
shaka.log.warning(
|
|
81
|
+
'No exact match for the hdr level could be found.');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (this.config_.channelCount) {
|
|
86
|
+
const byChannel = Class.filterVariantsByAudioChannelCount_(
|
|
87
|
+
current, this.config_.channelCount);
|
|
88
|
+
if (byChannel.length) {
|
|
89
|
+
current = byChannel;
|
|
90
|
+
} else {
|
|
91
|
+
shaka.log.warning(
|
|
92
|
+
'No exact match for the channel count could be found.');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (this.config_.audioLabel) {
|
|
97
|
+
const byLabel = Class.filterVariantsByAudioLabel_(
|
|
98
|
+
current, this.config_.audioLabel);
|
|
99
|
+
if (byLabel.length) {
|
|
100
|
+
current = byLabel;
|
|
101
|
+
} else {
|
|
102
|
+
shaka.log.warning('No exact match for audio label could be found.');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (this.config_.videoLabel) {
|
|
107
|
+
const byLabel = Class.filterVariantsByVideoLabel_(
|
|
108
|
+
current, this.config_.videoLabel);
|
|
109
|
+
if (byLabel.length) {
|
|
110
|
+
current = byLabel;
|
|
111
|
+
} else {
|
|
112
|
+
shaka.log.warning('No exact match for video label could be found.');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const bySpatialAudio = Class.filterVariantsBySpatialAudio_(
|
|
117
|
+
current, this.config_.spatialAudio);
|
|
118
|
+
if (bySpatialAudio.length) {
|
|
119
|
+
current = bySpatialAudio;
|
|
120
|
+
} else {
|
|
121
|
+
shaka.log.warning('No exact match for spatial audio could be found.');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (this.config_.audioCodec) {
|
|
125
|
+
const byAudioCodec = Class.filterVariantsByAudioCodec_(
|
|
126
|
+
current, this.config_.audioCodec);
|
|
127
|
+
if (byAudioCodec.length) {
|
|
128
|
+
current = byAudioCodec;
|
|
129
|
+
} else {
|
|
130
|
+
shaka.log.warning('No exact match for audio codec could be found.');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const supportsSmoothCodecTransitions =
|
|
135
|
+
this.config_.codecSwitchingStrategy ==
|
|
136
|
+
shaka.config.CodecSwitchingStrategy.SMOOTH &&
|
|
137
|
+
shaka.media.Capabilities.isChangeTypeSupported();
|
|
138
|
+
|
|
139
|
+
return new shaka.media.AdaptationSet(current[0], current,
|
|
140
|
+
!supportsSmoothCodecTransitions);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
145
|
+
* @param {string} preferredLanguage
|
|
146
|
+
* @return {!Array<shaka.extern.Variant>}
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
static filterByLanguage_(variants, preferredLanguage) {
|
|
150
|
+
const LanguageUtils = shaka.util.LanguageUtils;
|
|
151
|
+
|
|
152
|
+
/** @type {string} */
|
|
153
|
+
const preferredLocale = LanguageUtils.normalize(preferredLanguage);
|
|
154
|
+
|
|
155
|
+
/** @type {?string} */
|
|
156
|
+
const closestLocale = LanguageUtils.findClosestLocale(
|
|
157
|
+
preferredLocale,
|
|
158
|
+
variants.map((variant) => LanguageUtils.getLocaleForVariant(variant)));
|
|
159
|
+
|
|
160
|
+
// There were no locales close to what we preferred.
|
|
161
|
+
if (!closestLocale) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Find the variants that use the closest variant.
|
|
166
|
+
return variants.filter((variant) => {
|
|
167
|
+
return closestLocale == LanguageUtils.getLocaleForVariant(variant);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Filter Variants by role.
|
|
173
|
+
*
|
|
174
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
175
|
+
* @param {string} preferredRole
|
|
176
|
+
* @return {!Array<shaka.extern.Variant>}
|
|
177
|
+
* @private
|
|
178
|
+
*/
|
|
179
|
+
static filterVariantsByRole_(variants, preferredRole) {
|
|
180
|
+
return variants.filter((variant) => {
|
|
181
|
+
if (!variant.audio) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (preferredRole) {
|
|
186
|
+
return variant.audio.roles.includes(preferredRole);
|
|
187
|
+
} else {
|
|
188
|
+
return variant.audio.roles.length == 0;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Filter Variants by audio label.
|
|
195
|
+
*
|
|
196
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
197
|
+
* @param {string} preferredLabel
|
|
198
|
+
* @return {!Array<shaka.extern.Variant>}
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
static filterVariantsByAudioLabel_(variants, preferredLabel) {
|
|
202
|
+
return variants.filter((variant) => {
|
|
203
|
+
if (!variant.audio || !variant.audio.label) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const label1 = variant.audio.label.toLowerCase();
|
|
208
|
+
const label2 = preferredLabel.toLowerCase();
|
|
209
|
+
return label1 == label2;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Filter Variants by video label.
|
|
215
|
+
*
|
|
216
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
217
|
+
* @param {string} preferredLabel
|
|
218
|
+
* @return {!Array<shaka.extern.Variant>}
|
|
219
|
+
* @private
|
|
220
|
+
*/
|
|
221
|
+
static filterVariantsByVideoLabel_(variants, preferredLabel) {
|
|
222
|
+
return variants.filter((variant) => {
|
|
223
|
+
if (!variant.video || !variant.video.label) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const label1 = variant.video.label.toLowerCase();
|
|
228
|
+
const label2 = preferredLabel.toLowerCase();
|
|
229
|
+
return label1 == label2;
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Filter Variants by channelCount.
|
|
235
|
+
*
|
|
236
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
237
|
+
* @param {number} channelCount
|
|
238
|
+
* @return {!Array<shaka.extern.Variant>}
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
static filterVariantsByAudioChannelCount_(variants, channelCount) {
|
|
242
|
+
return variants.filter((variant) => {
|
|
243
|
+
if (variant.audio && variant.audio.channelsCount &&
|
|
244
|
+
variant.audio.channelsCount != channelCount) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Filters variants according to the given hdr level config.
|
|
253
|
+
*
|
|
254
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
255
|
+
* @param {string} hdrLevel
|
|
256
|
+
* @private
|
|
257
|
+
*/
|
|
258
|
+
static filterVariantsByHDRLevel_(variants, hdrLevel) {
|
|
259
|
+
if (hdrLevel == 'AUTO') {
|
|
260
|
+
// Auto detect the ideal HDR level.
|
|
261
|
+
if (window.matchMedia('(color-gamut: p3)').matches) {
|
|
262
|
+
const someHLG = variants.some((variant) => {
|
|
263
|
+
if (variant.video && variant.video.hdr &&
|
|
264
|
+
variant.video.hdr == 'HLG') {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
return false;
|
|
268
|
+
});
|
|
269
|
+
hdrLevel = someHLG ? 'HLG' : 'PQ';
|
|
270
|
+
} else {
|
|
271
|
+
hdrLevel = 'SDR';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return variants.filter((variant) => {
|
|
275
|
+
if (variant.video && variant.video.hdr && variant.video.hdr != hdrLevel) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Filters variants according to the given video layout config.
|
|
285
|
+
*
|
|
286
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
287
|
+
* @param {string} videoLayout
|
|
288
|
+
* @private
|
|
289
|
+
*/
|
|
290
|
+
static filterVariantsByVideoLayout_(variants, videoLayout) {
|
|
291
|
+
return variants.filter((variant) => {
|
|
292
|
+
if (variant.video && variant.video.videoLayout &&
|
|
293
|
+
variant.video.videoLayout != videoLayout) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Filters variants according to the given spatial audio config.
|
|
303
|
+
*
|
|
304
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
305
|
+
* @param {boolean} spatialAudio
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
308
|
+
static filterVariantsBySpatialAudio_(variants, spatialAudio) {
|
|
309
|
+
return variants.filter((variant) => {
|
|
310
|
+
if (variant.audio && variant.audio.spatialAudio != spatialAudio) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
return true;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Filters variants according to the given audio codec.
|
|
320
|
+
*
|
|
321
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
322
|
+
* @param {string} audioCodec
|
|
323
|
+
* @private
|
|
324
|
+
*/
|
|
325
|
+
static filterVariantsByAudioCodec_(variants, audioCodec) {
|
|
326
|
+
return variants.filter((variant) => {
|
|
327
|
+
if (variant.audio && variant.audio.codecs != audioCodec) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
return true;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
};
|
|
@@ -7,28 +7,26 @@
|
|
|
7
7
|
goog.provide('shaka.media.PreloadManager');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
+
goog.require('shaka.drm.DrmEngine');
|
|
10
11
|
goog.require('shaka.log');
|
|
11
|
-
goog.require('shaka.
|
|
12
|
+
goog.require('shaka.media.AdaptationSetCriteria');
|
|
12
13
|
goog.require('shaka.media.ManifestFilterer');
|
|
13
14
|
goog.require('shaka.media.ManifestParser');
|
|
14
|
-
goog.require('shaka.util.PublicPromise');
|
|
15
|
-
goog.require('shaka.media.PreferenceBasedCriteria');
|
|
16
|
-
goog.require('shaka.util.Stats');
|
|
17
|
-
goog.require('shaka.media.SegmentPrefetch');
|
|
18
|
-
goog.require('shaka.util.IDestroyable');
|
|
19
|
-
goog.require('shaka.net.NetworkingEngine');
|
|
20
|
-
goog.require('shaka.media.AdaptationSetCriteria');
|
|
21
|
-
goog.require('shaka.media.DrmEngine');
|
|
22
|
-
goog.require('shaka.media.RegionTimeline');
|
|
23
15
|
goog.require('shaka.media.QualityObserver');
|
|
24
|
-
goog.require('shaka.
|
|
25
|
-
goog.require('shaka.media.StreamingEngine');
|
|
16
|
+
goog.require('shaka.media.RegionTimeline');
|
|
26
17
|
goog.require('shaka.media.SegmentPrefetch');
|
|
18
|
+
goog.require('shaka.media.StreamingEngine');
|
|
19
|
+
goog.require('shaka.net.NetworkingEngine');
|
|
27
20
|
goog.require('shaka.util.ConfigUtils');
|
|
21
|
+
goog.require('shaka.util.Error');
|
|
28
22
|
goog.require('shaka.util.FakeEvent');
|
|
29
23
|
goog.require('shaka.util.FakeEventTarget');
|
|
24
|
+
goog.require('shaka.util.IDestroyable');
|
|
30
25
|
goog.require('shaka.util.ObjectUtils');
|
|
31
26
|
goog.require('shaka.util.PlayerConfiguration');
|
|
27
|
+
goog.require('shaka.util.PublicPromise');
|
|
28
|
+
goog.require('shaka.util.Stats');
|
|
29
|
+
goog.require('shaka.util.StreamUtils');
|
|
32
30
|
|
|
33
31
|
/**
|
|
34
32
|
* @implements {shaka.util.IDestroyable}
|
|
@@ -69,7 +67,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
69
67
|
/** @private {number} */
|
|
70
68
|
this.startTimeOfDrm_ = 0;
|
|
71
69
|
|
|
72
|
-
/** @private {function():!shaka.
|
|
70
|
+
/** @private {function():!shaka.drm.DrmEngine} */
|
|
73
71
|
this.createDrmEngine_ = typedPlayerInterface.createDrmEngine;
|
|
74
72
|
|
|
75
73
|
/** @private {!shaka.media.ManifestFilterer} */
|
|
@@ -100,7 +98,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
100
98
|
/** @private {boolean} */
|
|
101
99
|
this.regionTimelineEntrusted_ = false;
|
|
102
100
|
|
|
103
|
-
/** @private {?shaka.
|
|
101
|
+
/** @private {?shaka.drm.DrmEngine} */
|
|
104
102
|
this.drmEngine_ = null;
|
|
105
103
|
|
|
106
104
|
/** @private {boolean} */
|
|
@@ -115,7 +113,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
115
113
|
/** @private {boolean} */
|
|
116
114
|
this.abrManagerEntrusted_ = false;
|
|
117
115
|
|
|
118
|
-
/** @private {!Map
|
|
116
|
+
/** @private {!Map<number, shaka.media.SegmentPrefetch>} */
|
|
119
117
|
this.segmentPrefetchById_ = new Map();
|
|
120
118
|
|
|
121
119
|
/** @private {boolean} */
|
|
@@ -151,10 +149,10 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
151
149
|
/** @private {boolean} */
|
|
152
150
|
this.hasBeenAttached_ = false;
|
|
153
151
|
|
|
154
|
-
/** @private {?Array
|
|
152
|
+
/** @private {?Array<function()>} */
|
|
155
153
|
this.queuedOperations_ = [];
|
|
156
154
|
|
|
157
|
-
/** @private {?Array
|
|
155
|
+
/** @private {?Array<function()>} */
|
|
158
156
|
this.latePhaseQueuedOperations_ = [];
|
|
159
157
|
|
|
160
158
|
/** @private {boolean} */
|
|
@@ -322,7 +320,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
322
320
|
/**
|
|
323
321
|
* Gets the drm engine, if it exists. Also marks that the drm engine should
|
|
324
322
|
* not be destroyed if this manager is destroyed.
|
|
325
|
-
* @return {?shaka.
|
|
323
|
+
* @return {?shaka.drm.DrmEngine}
|
|
326
324
|
*/
|
|
327
325
|
receiveDrmEngine() {
|
|
328
326
|
this.drmEngineEntrusted_ = true;
|
|
@@ -330,7 +328,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
330
328
|
}
|
|
331
329
|
|
|
332
330
|
/**
|
|
333
|
-
* @return {?shaka.
|
|
331
|
+
* @return {?shaka.drm.DrmEngine}
|
|
334
332
|
*/
|
|
335
333
|
getDrmEngine() {
|
|
336
334
|
return this.drmEngine_;
|
|
@@ -346,7 +344,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
346
344
|
/**
|
|
347
345
|
* Gets the SegmentPrefetch objects for the initial stream ids. Also marks
|
|
348
346
|
* that those objects should not be aborted if this manager is destroyed.
|
|
349
|
-
* @return {!Map
|
|
347
|
+
* @return {!Map<number, shaka.media.SegmentPrefetch>}
|
|
350
348
|
*/
|
|
351
349
|
receiveSegmentPrefetchesById() {
|
|
352
350
|
this.segmentPrefetchEntrusted_ = true;
|
|
@@ -478,7 +476,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
478
476
|
|
|
479
477
|
/**
|
|
480
478
|
* @param {!shaka.util.FakeEvent.EventName} name
|
|
481
|
-
* @param {Map
|
|
479
|
+
* @param {Map<string, Object>=} data
|
|
482
480
|
* @return {!shaka.util.FakeEvent}
|
|
483
481
|
* @private
|
|
484
482
|
*/
|
|
@@ -513,6 +511,19 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
513
511
|
if (!this.manifest_) {
|
|
514
512
|
this.manifest_ = await this.parser_.start(
|
|
515
513
|
this.assetUri_, this.manifestPlayerInterface_);
|
|
514
|
+
|
|
515
|
+
if (this.manifest_.variants.length == 1) {
|
|
516
|
+
const createSegmentIndexPromises = [];
|
|
517
|
+
const variant = this.manifest_.variants[0];
|
|
518
|
+
for (const stream of [variant.video, variant.audio]) {
|
|
519
|
+
if (stream && !stream.segmentIndex) {
|
|
520
|
+
createSegmentIndexPromises.push(stream.createSegmentIndex());
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (createSegmentIndexPromises.length > 0) {
|
|
524
|
+
await Promise.all(createSegmentIndexPromises);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
516
527
|
}
|
|
517
528
|
|
|
518
529
|
this.manifestPromise_.resolve();
|
|
@@ -632,17 +643,20 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
632
643
|
// Copy preferred languages from the config again, in case the config was
|
|
633
644
|
// changed between construction and playback.
|
|
634
645
|
this.currentAdaptationSetCriteria_ =
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
+
this.config_.adaptationSetCriteriaFactory();
|
|
647
|
+
this.currentAdaptationSetCriteria_.configure({
|
|
648
|
+
language: this.config_.preferredAudioLanguage,
|
|
649
|
+
role: this.config_.preferredVariantRole,
|
|
650
|
+
channelCount: this.config_.preferredAudioChannelCount,
|
|
651
|
+
hdrLevel: this.config_.preferredVideoHdrLevel,
|
|
652
|
+
spatialAudio: this.config_.preferSpatialAudio,
|
|
653
|
+
videoLayout: this.config_.preferredVideoLayout,
|
|
654
|
+
audioLabel: this.config_.preferredAudioLabel,
|
|
655
|
+
videoLabel: this.config_.preferredVideoLabel,
|
|
656
|
+
codecSwitchingStrategy:
|
|
657
|
+
this.config_.mediaSource.codecSwitchingStrategy,
|
|
658
|
+
audioCodec: '',
|
|
659
|
+
});
|
|
646
660
|
}
|
|
647
661
|
|
|
648
662
|
// Make the ABR manager.
|
|
@@ -699,7 +713,9 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
699
713
|
this.segmentPrefetchById_.set(stream.id, prefetch);
|
|
700
714
|
|
|
701
715
|
// Start prefetching a bit.
|
|
702
|
-
|
|
716
|
+
if (!stream.segmentIndex) {
|
|
717
|
+
await stream.createSegmentIndex();
|
|
718
|
+
}
|
|
703
719
|
const startTime = this.startTime_ || 0;
|
|
704
720
|
const prefetchSegmentIterator =
|
|
705
721
|
stream.segmentIndex.getIteratorForTime(startTime);
|
|
@@ -823,7 +839,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
823
839
|
* manifestPlayerInterface: !shaka.extern.ManifestParser.PlayerInterface,
|
|
824
840
|
* regionTimeline: !shaka.media.RegionTimeline,
|
|
825
841
|
* qualityObserver: ?shaka.media.QualityObserver,
|
|
826
|
-
* createDrmEngine: function():!shaka.
|
|
842
|
+
* createDrmEngine: function():!shaka.drm.DrmEngine,
|
|
827
843
|
* networkingEngine: !shaka.net.NetworkingEngine,
|
|
828
844
|
* manifestFilterer: !shaka.media.ManifestFilterer,
|
|
829
845
|
* allowPrefetch: boolean,
|
|
@@ -831,11 +847,11 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
831
847
|
* }}
|
|
832
848
|
*
|
|
833
849
|
* @property {!shaka.extern.PlayerConfiguration} config
|
|
834
|
-
* @property {!shaka.extern.ManifestParser.PlayerInterface
|
|
835
|
-
*
|
|
850
|
+
* @property {!shaka.extern.ManifestParser.PlayerInterface
|
|
851
|
+
* } manifestPlayerInterface
|
|
836
852
|
* @property {!shaka.media.RegionTimeline} regionTimeline
|
|
837
853
|
* @property {?shaka.media.QualityObserver} qualityObserver
|
|
838
|
-
* @property {function():!shaka.
|
|
854
|
+
* @property {function():!shaka.drm.DrmEngine} createDrmEngine
|
|
839
855
|
* @property {!shaka.net.NetworkingEngine} networkingEngine
|
|
840
856
|
* @property {!shaka.media.ManifestFilterer} manifestFilterer
|
|
841
857
|
* @property {boolean} allowPrefetch
|
|
@@ -244,7 +244,7 @@ shaka.media.PresentationTimeline = class {
|
|
|
244
244
|
* the segment availability window, and account for missing segment
|
|
245
245
|
* information.
|
|
246
246
|
*
|
|
247
|
-
* @param {!Array
|
|
247
|
+
* @param {!Array<shaka.media.PresentationTimeline.TimeRange>} timeline
|
|
248
248
|
* @param {number} startOffset
|
|
249
249
|
* @export
|
|
250
250
|
*/
|
|
@@ -294,7 +294,7 @@ shaka.media.PresentationTimeline = class {
|
|
|
294
294
|
* information. These segments do not necessarily need to all be from the
|
|
295
295
|
* same stream.
|
|
296
296
|
*
|
|
297
|
-
* @param {!Array
|
|
297
|
+
* @param {!Array<!shaka.media.SegmentReference>} references
|
|
298
298
|
* @export
|
|
299
299
|
*/
|
|
300
300
|
notifySegments(references) {
|
|
@@ -32,7 +32,7 @@ shaka.media.QualityObserver = class extends shaka.util.FakeEventTarget {
|
|
|
32
32
|
super();
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* @private {!Map
|
|
35
|
+
* @private {!Map<string, !shaka.media.QualityObserver.ContentTypeState>}
|
|
36
36
|
*/
|
|
37
37
|
this.contentTypeStates_ = new Map();
|
|
38
38
|
|
|
@@ -47,7 +47,7 @@ shaka.media.QualityObserver = class extends shaka.util.FakeEventTarget {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Get the
|
|
50
|
+
* Get the ContentTypeState for a contentType, creating a new
|
|
51
51
|
* one if necessary.
|
|
52
52
|
*
|
|
53
53
|
* @param {!string} contentType
|
|
@@ -301,40 +301,40 @@ shaka.media.QualityObserver = class extends shaka.util.FakeEventTarget {
|
|
|
301
301
|
};
|
|
302
302
|
|
|
303
303
|
/**
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
304
|
+
* @typedef {{
|
|
305
|
+
* mediaQuality: !shaka.extern.MediaQualityInfo,
|
|
306
|
+
* position: !number
|
|
307
|
+
* }}
|
|
308
|
+
*
|
|
309
|
+
* @description
|
|
310
|
+
* Identifies the position of a media quality change in the
|
|
311
|
+
* source buffer.
|
|
312
|
+
*
|
|
313
|
+
* @property {!shaka.extern.MediaQualityInfo} mediaQuality
|
|
314
|
+
* The new media quality for content after position in the source buffer.
|
|
315
|
+
* @property {!number} position
|
|
316
|
+
* A position in seconds in the source buffer
|
|
317
|
+
*/
|
|
318
318
|
shaka.media.QualityObserver.QualityChangePosition;
|
|
319
319
|
|
|
320
320
|
/**
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
321
|
+
* @typedef {{
|
|
322
|
+
* qualityChangePositions:
|
|
323
|
+
* !Array<shaka.media.QualityObserver.QualityChangePosition>,
|
|
324
|
+
* currentQuality: ?shaka.extern.MediaQualityInfo,
|
|
325
|
+
* contentType: !string
|
|
326
|
+
* }}
|
|
327
|
+
*
|
|
328
|
+
* @description
|
|
329
|
+
* Contains media quality information for a specific content type
|
|
330
|
+
* e.g. video or audio.
|
|
331
|
+
*
|
|
332
|
+
* @property {!Array<shaka.media.QualityObserver.QualityChangePosition>
|
|
333
|
+
* } qualityChangePositions
|
|
334
|
+
* Quality changes ordered by position ascending.
|
|
335
|
+
* @property {?shaka.media.MediaQualityInfo} currentMediaQuality
|
|
336
|
+
* The media quality at the playhead position.
|
|
337
|
+
* @property {string} contentType
|
|
338
|
+
* The contentType e.g. 'video' or 'audio'
|
|
339
|
+
*/
|
|
340
340
|
shaka.media.QualityObserver.ContentTypeState;
|
|
@@ -50,7 +50,7 @@ shaka.media.RegionObserver = class extends shaka.util.FakeEventTarget {
|
|
|
50
50
|
* When the value here differs from what we calculate, it means we moved and
|
|
51
51
|
* should fire an event.
|
|
52
52
|
*
|
|
53
|
-
* @private {!Map
|
|
53
|
+
* @private {!Map<shaka.extern.TimelineRegionInfo,
|
|
54
54
|
* shaka.media.RegionObserver.RelativePosition_>}
|
|
55
55
|
*/
|
|
56
56
|
this.oldPosition_ = new Map();
|
|
@@ -65,7 +65,7 @@ shaka.media.RegionObserver = class extends shaka.util.FakeEventTarget {
|
|
|
65
65
|
* A read-only collection of rules for what to do when we change position
|
|
66
66
|
* relative to a region.
|
|
67
67
|
*
|
|
68
|
-
* @private {!Iterable
|
|
68
|
+
* @private {!Iterable<shaka.media.RegionObserver.Rule_>}
|
|
69
69
|
*/
|
|
70
70
|
this.rules_ = [
|
|
71
71
|
{
|
|
@@ -27,7 +27,7 @@ shaka.media.RegionTimeline = class extends shaka.util.FakeEventTarget {
|
|
|
27
27
|
constructor(getSeekRange) {
|
|
28
28
|
super();
|
|
29
29
|
|
|
30
|
-
/** @private {!Set
|
|
30
|
+
/** @private {!Set<shaka.extern.TimelineRegionInfo>} */
|
|
31
31
|
this.regions_ = new Set();
|
|
32
32
|
|
|
33
33
|
/** @private {!function():{start: number, end: number}} */
|
|
@@ -80,7 +80,7 @@ shaka.media.RegionTimeline = class extends shaka.util.FakeEventTarget {
|
|
|
80
80
|
// Future regions might become relevant eventually,
|
|
81
81
|
// but regions that are in the past and can't ever be
|
|
82
82
|
// seeked to will never come up again, and there's no
|
|
83
|
-
//
|
|
83
|
+
// reason to store or process them.
|
|
84
84
|
if (region.endTime < seekRange.start) {
|
|
85
85
|
this.regions_.delete(region);
|
|
86
86
|
const event = new shaka.util.FakeEvent('regionremove', new Map([
|
|
@@ -123,7 +123,7 @@ shaka.media.RegionTimeline = class extends shaka.util.FakeEventTarget {
|
|
|
123
123
|
* others to see what regions are in the timeline while not being able to
|
|
124
124
|
* change the collection.
|
|
125
125
|
*
|
|
126
|
-
* @return {!Iterable
|
|
126
|
+
* @return {!Iterable<shaka.extern.TimelineRegionInfo>}
|
|
127
127
|
*/
|
|
128
128
|
regions() {
|
|
129
129
|
return this.regions_;
|