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
package/lib/hls/hls_utils.js
CHANGED
|
@@ -15,9 +15,9 @@ goog.requireType('shaka.hls.Tag');
|
|
|
15
15
|
shaka.hls.Utils = class {
|
|
16
16
|
/**
|
|
17
17
|
*
|
|
18
|
-
* @param {!Array
|
|
18
|
+
* @param {!Array<!shaka.hls.Tag>} tags
|
|
19
19
|
* @param {string} name
|
|
20
|
-
* @return {!Array
|
|
20
|
+
* @return {!Array<!shaka.hls.Tag>}
|
|
21
21
|
*/
|
|
22
22
|
static filterTagsByName(tags, name) {
|
|
23
23
|
return tags.filter((tag) => {
|
|
@@ -28,9 +28,9 @@ shaka.hls.Utils = class {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
*
|
|
31
|
-
* @param {!Array
|
|
31
|
+
* @param {!Array<!shaka.hls.Tag>} tags
|
|
32
32
|
* @param {string} type
|
|
33
|
-
* @return {!Array
|
|
33
|
+
* @return {!Array<!shaka.hls.Tag>}
|
|
34
34
|
*/
|
|
35
35
|
static filterTagsByType(tags, type) {
|
|
36
36
|
return tags.filter((tag) => {
|
|
@@ -42,7 +42,7 @@ shaka.hls.Utils = class {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
*
|
|
45
|
-
* @param {!Array
|
|
45
|
+
* @param {!Array<!shaka.hls.Tag>} tags
|
|
46
46
|
* @param {string} name
|
|
47
47
|
* @return {?shaka.hls.Tag}
|
|
48
48
|
*/
|
|
@@ -59,7 +59,7 @@ shaka.hls.Utils = class {
|
|
|
59
59
|
* Get the numerical value of the first tag with given name if available.
|
|
60
60
|
* Return the default value if the tag is not present.
|
|
61
61
|
*
|
|
62
|
-
* @param {!Array
|
|
62
|
+
* @param {!Array<!shaka.hls.Tag>} tags
|
|
63
63
|
* @param {string} name
|
|
64
64
|
* @param {number=} defaultValue
|
|
65
65
|
* @return {number}
|
|
@@ -71,10 +71,10 @@ shaka.hls.Utils = class {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* @param {!Array
|
|
74
|
+
* @param {!Array<string>} baseUris
|
|
75
75
|
* @param {?string} relativeUri
|
|
76
|
-
* @param {?Map
|
|
77
|
-
* @return {!Array
|
|
76
|
+
* @param {?Map<string, string>=} variables
|
|
77
|
+
* @return {!Array<string>}
|
|
78
78
|
*/
|
|
79
79
|
static constructSegmentUris(baseUris, relativeUri, variables) {
|
|
80
80
|
if (!relativeUri) {
|
|
@@ -85,10 +85,10 @@ shaka.hls.Utils = class {
|
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* @param {!Array
|
|
89
|
-
* @param {!Array
|
|
90
|
-
* @param {?Map
|
|
91
|
-
* @return {!Array
|
|
88
|
+
* @param {!Array<string>} baseUris
|
|
89
|
+
* @param {!Array<string>} relativeUris
|
|
90
|
+
* @param {?Map<string, string>=} variables
|
|
91
|
+
* @return {!Array<string>}
|
|
92
92
|
*/
|
|
93
93
|
static constructUris(baseUris, relativeUris, variables) {
|
|
94
94
|
if (!relativeUris.length) {
|
|
@@ -109,7 +109,7 @@ shaka.hls.Utils = class {
|
|
|
109
109
|
* Replaces the variables of a given URI.
|
|
110
110
|
*
|
|
111
111
|
* @param {string} uri
|
|
112
|
-
* @param {?Map
|
|
112
|
+
* @param {?Map<string, string>=} variables
|
|
113
113
|
* @return {string}
|
|
114
114
|
*/
|
|
115
115
|
static variableSubstitution(uri, variables) {
|
|
@@ -76,7 +76,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
/** {Array
|
|
79
|
+
/** {Array<shaka.hls.Tag>} */
|
|
80
80
|
const tags = [];
|
|
81
81
|
// Initialize to "true" to skip the first element.
|
|
82
82
|
skip = true;
|
|
@@ -121,18 +121,18 @@ shaka.hls.ManifestTextParser = class {
|
|
|
121
121
|
/**
|
|
122
122
|
* Parses an array of strings into an array of HLS Segment objects.
|
|
123
123
|
*
|
|
124
|
-
* @param {!Array
|
|
125
|
-
* @param {!Array
|
|
126
|
-
* @return {!Array
|
|
124
|
+
* @param {!Array<string>} lines
|
|
125
|
+
* @param {!Array<!shaka.hls.Tag>} playlistTags
|
|
126
|
+
* @return {!Array<shaka.hls.Segment>}
|
|
127
127
|
* @private
|
|
128
128
|
*/
|
|
129
129
|
parseSegments_(lines, playlistTags) {
|
|
130
|
-
/** @type {!Array
|
|
130
|
+
/** @type {!Array<shaka.hls.Segment>} */
|
|
131
131
|
const segments = [];
|
|
132
|
-
/** @type {!Array
|
|
132
|
+
/** @type {!Array<shaka.hls.Tag>} */
|
|
133
133
|
let segmentTags = [];
|
|
134
134
|
|
|
135
|
-
/** @type {!Array
|
|
135
|
+
/** @type {!Array<shaka.hls.Tag>} */
|
|
136
136
|
let partialSegmentTags = [];
|
|
137
137
|
|
|
138
138
|
// The last parsed EXT-X-MAP tag.
|
|
@@ -221,7 +221,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
221
221
|
An attribute's format is 'AttributeName=AttributeValue'.
|
|
222
222
|
The parsing logic goes like this:
|
|
223
223
|
1. Everything before ':' is a name (we ignore '#').
|
|
224
|
-
2. Everything after ':' is a list of comma-
|
|
224
|
+
2. Everything after ':' is a list of comma-separated items,
|
|
225
225
|
2a. The first item might be a value, if it does not contain '='.
|
|
226
226
|
2b. Otherwise, items are attributes.
|
|
227
227
|
3. If there is no ":", it's a simple tag with no attributes and no value.
|
|
@@ -283,7 +283,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
283
283
|
* HLS tags that only appear on Media Playlists.
|
|
284
284
|
* Used to determine a playlist type.
|
|
285
285
|
*
|
|
286
|
-
* @const {!Array
|
|
286
|
+
* @const {!Array<string>}
|
|
287
287
|
*/
|
|
288
288
|
shaka.hls.ManifestTextParser.MEDIA_PLAYLIST_TAGS = [
|
|
289
289
|
'EXT-X-TARGETDURATION',
|
|
@@ -303,7 +303,7 @@ shaka.hls.ManifestTextParser.MEDIA_PLAYLIST_TAGS = [
|
|
|
303
303
|
* HLS tags that only appear on Segments in a Media Playlists.
|
|
304
304
|
* Used to determine the start of the segments info.
|
|
305
305
|
*
|
|
306
|
-
* @const {!Array
|
|
306
|
+
* @const {!Array<string>}
|
|
307
307
|
*/
|
|
308
308
|
shaka.hls.ManifestTextParser.SEGMENT_TAGS = [
|
|
309
309
|
'EXTINF',
|
|
@@ -15,6 +15,7 @@ goog.require('shaka.util.MimeUtils');
|
|
|
15
15
|
* A set of variants that we want to adapt between.
|
|
16
16
|
*
|
|
17
17
|
* @final
|
|
18
|
+
* @export
|
|
18
19
|
*/
|
|
19
20
|
shaka.media.AdaptationSet = class {
|
|
20
21
|
/**
|
|
@@ -22,7 +23,7 @@ shaka.media.AdaptationSet = class {
|
|
|
22
23
|
* The variant that all other variants will be tested against when being
|
|
23
24
|
* added to the adaptation set. If a variant is not compatible with the
|
|
24
25
|
* root, it will not be added.
|
|
25
|
-
* @param {!Iterable
|
|
26
|
+
* @param {!Iterable<shaka.extern.Variant>=} candidates
|
|
26
27
|
* Variants that may be compatible with the root and should be added if
|
|
27
28
|
* compatible. If a candidate is not compatible, it will not end up in the
|
|
28
29
|
* adaptation set.
|
|
@@ -31,7 +32,7 @@ shaka.media.AdaptationSet = class {
|
|
|
31
32
|
constructor(root, candidates, compareCodecs = true) {
|
|
32
33
|
/** @private {shaka.extern.Variant} */
|
|
33
34
|
this.root_ = root;
|
|
34
|
-
/** @private {!Set
|
|
35
|
+
/** @private {!Set<shaka.extern.Variant>} */
|
|
35
36
|
this.variants_ = new Set([root]);
|
|
36
37
|
|
|
37
38
|
// Try to add all the candidates. If they cannot be added (because they
|
|
@@ -116,7 +117,7 @@ shaka.media.AdaptationSet = class {
|
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
/**
|
|
119
|
-
* @return {!Iterable
|
|
120
|
+
* @return {!Iterable<shaka.extern.Variant>}
|
|
120
121
|
*/
|
|
121
122
|
values() {
|
|
122
123
|
return this.variants_.values();
|
|
@@ -245,8 +246,8 @@ shaka.media.AdaptationSet = class {
|
|
|
245
246
|
* Check if two role lists are the equal. This will take into account all
|
|
246
247
|
* unique behaviours when comparing roles.
|
|
247
248
|
*
|
|
248
|
-
* @param {!Iterable
|
|
249
|
-
* @param {!Iterable
|
|
249
|
+
* @param {!Iterable<string>} a
|
|
250
|
+
* @param {!Iterable<string>} b
|
|
250
251
|
* @return {boolean}
|
|
251
252
|
* @private
|
|
252
253
|
*/
|
|
@@ -5,14 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.media.AdaptationSetCriteria');
|
|
8
|
-
goog.provide('shaka.media.ExampleBasedCriteria');
|
|
9
|
-
goog.provide('shaka.media.PreferenceBasedCriteria');
|
|
10
8
|
|
|
11
|
-
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
12
|
-
goog.require('shaka.log');
|
|
13
9
|
goog.require('shaka.media.AdaptationSet');
|
|
14
|
-
goog.require('shaka.
|
|
15
|
-
goog.require('shaka.util.LanguageUtils');
|
|
10
|
+
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
16
11
|
|
|
17
12
|
|
|
18
13
|
/**
|
|
@@ -21,393 +16,70 @@ goog.require('shaka.util.LanguageUtils');
|
|
|
21
16
|
* adapted between.
|
|
22
17
|
*
|
|
23
18
|
* @interface
|
|
19
|
+
* @export
|
|
24
20
|
*/
|
|
25
21
|
shaka.media.AdaptationSetCriteria = class {
|
|
26
22
|
/**
|
|
27
23
|
* Take a set of variants, and return a subset of variants that can be
|
|
28
24
|
* adapted between.
|
|
29
25
|
*
|
|
30
|
-
* @param {!Array
|
|
26
|
+
* @param {!Array<shaka.extern.Variant>} variants
|
|
31
27
|
* @return {!shaka.media.AdaptationSet}
|
|
28
|
+
* @exportInterface
|
|
32
29
|
*/
|
|
33
30
|
create(variants) {}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
31
|
|
|
37
|
-
/**
|
|
38
|
-
* @implements {shaka.media.AdaptationSetCriteria}
|
|
39
|
-
* @final
|
|
40
|
-
*/
|
|
41
|
-
shaka.media.ExampleBasedCriteria = class {
|
|
42
32
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
33
|
+
* Sets the AdaptationSetCriteria configuration.
|
|
34
|
+
*
|
|
35
|
+
* @param {shaka.media.AdaptationSetCriteria.Configuration} config
|
|
36
|
+
* @exportInterface
|
|
45
37
|
*/
|
|
46
|
-
|
|
47
|
-
// We can't know if role and label are really important, so we don't use
|
|
48
|
-
// role and label for this.
|
|
49
|
-
const role = '';
|
|
50
|
-
const audioLabel = '';
|
|
51
|
-
const videoLabel = '';
|
|
52
|
-
const hdrLevel = example.video && example.video.hdr ?
|
|
53
|
-
example.video.hdr : '';
|
|
54
|
-
const spatialAudio = example.audio && example.audio.spatialAudio ?
|
|
55
|
-
example.audio.spatialAudio : false;
|
|
56
|
-
const videoLayout = example.video && example.video.videoLayout ?
|
|
57
|
-
example.video.videoLayout : '';
|
|
58
|
-
const channelCount = example.audio && example.audio.channelsCount ?
|
|
59
|
-
example.audio.channelsCount : 0;
|
|
60
|
-
const audioCodec = example.audio && example.audio.codecs ?
|
|
61
|
-
example.audio.codecs : '';
|
|
62
|
-
|
|
63
|
-
/** @private {!shaka.media.AdaptationSetCriteria} */
|
|
64
|
-
this.preferenceBasedCriteria_ = new shaka.media.PreferenceBasedCriteria(
|
|
65
|
-
example.language, role, channelCount, hdrLevel, spatialAudio,
|
|
66
|
-
videoLayout, audioLabel, videoLabel,
|
|
67
|
-
codecSwitchingStrategy, audioCodec);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** @override */
|
|
71
|
-
create(variants) {
|
|
72
|
-
return this.preferenceBasedCriteria_.create(variants);
|
|
73
|
-
}
|
|
38
|
+
configure(config) {}
|
|
74
39
|
};
|
|
75
40
|
|
|
76
|
-
|
|
77
41
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
42
|
+
* A factory for creating the AdaptationSetCriteria.
|
|
43
|
+
*
|
|
44
|
+
* @typedef {function():!shaka.media.AdaptationSetCriteria}
|
|
45
|
+
* @export
|
|
80
46
|
*/
|
|
81
|
-
shaka.media.
|
|
82
|
-
/**
|
|
83
|
-
* @param {string} language
|
|
84
|
-
* @param {string} role
|
|
85
|
-
* @param {number} channelCount
|
|
86
|
-
* @param {string} hdrLevel
|
|
87
|
-
* @param {boolean} spatialAudio
|
|
88
|
-
* @param {string} videoLayout
|
|
89
|
-
* @param {string} audioLabel
|
|
90
|
-
* @param {string} videoLabel
|
|
91
|
-
* @param {shaka.config.CodecSwitchingStrategy} codecSwitchingStrategy
|
|
92
|
-
* @param {string} audioCodec
|
|
93
|
-
*/
|
|
94
|
-
constructor(language, role, channelCount, hdrLevel, spatialAudio,
|
|
95
|
-
videoLayout, audioLabel, videoLabel, codecSwitchingStrategy, audioCodec) {
|
|
96
|
-
/** @private {string} */
|
|
97
|
-
this.language_ = language;
|
|
98
|
-
/** @private {string} */
|
|
99
|
-
this.role_ = role;
|
|
100
|
-
/** @private {number} */
|
|
101
|
-
this.channelCount_ = channelCount;
|
|
102
|
-
/** @private {string} */
|
|
103
|
-
this.hdrLevel_ = hdrLevel;
|
|
104
|
-
/** @private {boolean} */
|
|
105
|
-
this.spatialAudio_ = spatialAudio;
|
|
106
|
-
/** @private {string} */
|
|
107
|
-
this.videoLayout_ = videoLayout;
|
|
108
|
-
/** @private {string} */
|
|
109
|
-
this.audioLabel_ = audioLabel;
|
|
110
|
-
/** @private {string} */
|
|
111
|
-
this.videoLabel_ = videoLabel;
|
|
112
|
-
/** @private {shaka.config.CodecSwitchingStrategy} */
|
|
113
|
-
this.codecSwitchingStrategy_ = codecSwitchingStrategy;
|
|
114
|
-
/** @private {string} */
|
|
115
|
-
this.audioCodec_ = audioCodec;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** @override */
|
|
119
|
-
create(variants) {
|
|
120
|
-
const Class = shaka.media.PreferenceBasedCriteria;
|
|
121
|
-
|
|
122
|
-
let current = [];
|
|
123
|
-
|
|
124
|
-
const byLanguage = Class.filterByLanguage_(variants, this.language_);
|
|
125
|
-
const byPrimary = variants.filter((variant) => variant.primary);
|
|
126
|
-
|
|
127
|
-
if (byLanguage.length) {
|
|
128
|
-
current = byLanguage;
|
|
129
|
-
} else if (byPrimary.length) {
|
|
130
|
-
current = byPrimary;
|
|
131
|
-
} else {
|
|
132
|
-
current = variants;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Now refine the choice based on role preference. Even the empty string
|
|
136
|
-
// works here, and will match variants without any roles.
|
|
137
|
-
const byRole = Class.filterVariantsByRole_(current, this.role_);
|
|
138
|
-
if (byRole.length) {
|
|
139
|
-
current = byRole;
|
|
140
|
-
} else {
|
|
141
|
-
shaka.log.warning('No exact match for variant role could be found.');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (this.videoLayout_) {
|
|
145
|
-
const byVideoLayout = Class.filterVariantsByVideoLayout_(
|
|
146
|
-
current, this.videoLayout_);
|
|
147
|
-
if (byVideoLayout.length) {
|
|
148
|
-
current = byVideoLayout;
|
|
149
|
-
} else {
|
|
150
|
-
shaka.log.warning(
|
|
151
|
-
'No exact match for the video layout could be found.');
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (this.hdrLevel_) {
|
|
156
|
-
const byHdrLevel = Class.filterVariantsByHDRLevel_(
|
|
157
|
-
current, this.hdrLevel_);
|
|
158
|
-
if (byHdrLevel.length) {
|
|
159
|
-
current = byHdrLevel;
|
|
160
|
-
} else {
|
|
161
|
-
shaka.log.warning(
|
|
162
|
-
'No exact match for the hdr level could be found.');
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (this.channelCount_) {
|
|
167
|
-
const byChannel = Class.filterVariantsByAudioChannelCount_(
|
|
168
|
-
current, this.channelCount_);
|
|
169
|
-
if (byChannel.length) {
|
|
170
|
-
current = byChannel;
|
|
171
|
-
} else {
|
|
172
|
-
shaka.log.warning(
|
|
173
|
-
'No exact match for the channel count could be found.');
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (this.audioLabel_) {
|
|
178
|
-
const byLabel = Class.filterVariantsByAudioLabel_(
|
|
179
|
-
current, this.audioLabel_);
|
|
180
|
-
if (byLabel.length) {
|
|
181
|
-
current = byLabel;
|
|
182
|
-
} else {
|
|
183
|
-
shaka.log.warning('No exact match for audio label could be found.');
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (this.videoLabel_) {
|
|
188
|
-
const byLabel = Class.filterVariantsByVideoLabel_(
|
|
189
|
-
current, this.videoLabel_);
|
|
190
|
-
if (byLabel.length) {
|
|
191
|
-
current = byLabel;
|
|
192
|
-
} else {
|
|
193
|
-
shaka.log.warning('No exact match for video label could be found.');
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const bySpatialAudio = Class.filterVariantsBySpatialAudio_(
|
|
198
|
-
current, this.spatialAudio_);
|
|
199
|
-
if (bySpatialAudio.length) {
|
|
200
|
-
current = bySpatialAudio;
|
|
201
|
-
} else {
|
|
202
|
-
shaka.log.warning('No exact match for spatial audio could be found.');
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (this.audioCodec_) {
|
|
206
|
-
const byAudioCodec = Class.filterVariantsByAudioCodec_(
|
|
207
|
-
current, this.audioCodec_);
|
|
208
|
-
if (byAudioCodec.length) {
|
|
209
|
-
current = byAudioCodec;
|
|
210
|
-
} else {
|
|
211
|
-
shaka.log.warning('No exact match for audio codec could be found.');
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const supportsSmoothCodecTransitions = this.codecSwitchingStrategy_ ==
|
|
216
|
-
shaka.config.CodecSwitchingStrategy.SMOOTH &&
|
|
217
|
-
shaka.media.Capabilities.isChangeTypeSupported();
|
|
218
|
-
|
|
219
|
-
return new shaka.media.AdaptationSet(current[0], current,
|
|
220
|
-
!supportsSmoothCodecTransitions);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
225
|
-
* @param {string} preferredLanguage
|
|
226
|
-
* @return {!Array.<shaka.extern.Variant>}
|
|
227
|
-
* @private
|
|
228
|
-
*/
|
|
229
|
-
static filterByLanguage_(variants, preferredLanguage) {
|
|
230
|
-
const LanguageUtils = shaka.util.LanguageUtils;
|
|
231
|
-
|
|
232
|
-
/** @type {string} */
|
|
233
|
-
const preferredLocale = LanguageUtils.normalize(preferredLanguage);
|
|
234
|
-
|
|
235
|
-
/** @type {?string} */
|
|
236
|
-
const closestLocale = LanguageUtils.findClosestLocale(
|
|
237
|
-
preferredLocale,
|
|
238
|
-
variants.map((variant) => LanguageUtils.getLocaleForVariant(variant)));
|
|
239
|
-
|
|
240
|
-
// There were no locales close to what we preferred.
|
|
241
|
-
if (!closestLocale) {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Find the variants that use the closest variant.
|
|
246
|
-
return variants.filter((variant) => {
|
|
247
|
-
return closestLocale == LanguageUtils.getLocaleForVariant(variant);
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Filter Variants by role.
|
|
253
|
-
*
|
|
254
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
255
|
-
* @param {string} preferredRole
|
|
256
|
-
* @return {!Array.<shaka.extern.Variant>}
|
|
257
|
-
* @private
|
|
258
|
-
*/
|
|
259
|
-
static filterVariantsByRole_(variants, preferredRole) {
|
|
260
|
-
return variants.filter((variant) => {
|
|
261
|
-
if (!variant.audio) {
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
47
|
+
shaka.media.AdaptationSetCriteria.Factory;
|
|
264
48
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return variants.filter((variant) => {
|
|
303
|
-
if (!variant.video || !variant.video.label) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const label1 = variant.video.label.toLowerCase();
|
|
308
|
-
const label2 = preferredLabel.toLowerCase();
|
|
309
|
-
return label1 == label2;
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Filter Variants by channelCount.
|
|
315
|
-
*
|
|
316
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
317
|
-
* @param {number} channelCount
|
|
318
|
-
* @return {!Array.<shaka.extern.Variant>}
|
|
319
|
-
* @private
|
|
320
|
-
*/
|
|
321
|
-
static filterVariantsByAudioChannelCount_(variants, channelCount) {
|
|
322
|
-
return variants.filter((variant) => {
|
|
323
|
-
if (variant.audio && variant.audio.channelsCount &&
|
|
324
|
-
variant.audio.channelsCount != channelCount) {
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
return true;
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Filters variants according to the given hdr level config.
|
|
333
|
-
*
|
|
334
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
335
|
-
* @param {string} hdrLevel
|
|
336
|
-
* @private
|
|
337
|
-
*/
|
|
338
|
-
static filterVariantsByHDRLevel_(variants, hdrLevel) {
|
|
339
|
-
if (hdrLevel == 'AUTO') {
|
|
340
|
-
// Auto detect the ideal HDR level.
|
|
341
|
-
if (window.matchMedia('(color-gamut: p3)').matches) {
|
|
342
|
-
const someHLG = variants.some((variant) => {
|
|
343
|
-
if (variant.video && variant.video.hdr &&
|
|
344
|
-
variant.video.hdr == 'HLG') {
|
|
345
|
-
return true;
|
|
346
|
-
}
|
|
347
|
-
return false;
|
|
348
|
-
});
|
|
349
|
-
hdrLevel = someHLG ? 'HLG' : 'PQ';
|
|
350
|
-
} else {
|
|
351
|
-
hdrLevel = 'SDR';
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return variants.filter((variant) => {
|
|
355
|
-
if (variant.video && variant.video.hdr && variant.video.hdr != hdrLevel) {
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
return true;
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Filters variants according to the given video layout config.
|
|
365
|
-
*
|
|
366
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
367
|
-
* @param {string} videoLayout
|
|
368
|
-
* @private
|
|
369
|
-
*/
|
|
370
|
-
static filterVariantsByVideoLayout_(variants, videoLayout) {
|
|
371
|
-
return variants.filter((variant) => {
|
|
372
|
-
if (variant.video && variant.video.videoLayout &&
|
|
373
|
-
variant.video.videoLayout != videoLayout) {
|
|
374
|
-
return false;
|
|
375
|
-
}
|
|
376
|
-
return true;
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Filters variants according to the given spatial audio config.
|
|
383
|
-
*
|
|
384
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
385
|
-
* @param {boolean} spatialAudio
|
|
386
|
-
* @private
|
|
387
|
-
*/
|
|
388
|
-
static filterVariantsBySpatialAudio_(variants, spatialAudio) {
|
|
389
|
-
return variants.filter((variant) => {
|
|
390
|
-
if (variant.audio && variant.audio.spatialAudio != spatialAudio) {
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
return true;
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Filters variants according to the given audio codec.
|
|
400
|
-
*
|
|
401
|
-
* @param {!Array<shaka.extern.Variant>} variants
|
|
402
|
-
* @param {string} audioCodec
|
|
403
|
-
* @private
|
|
404
|
-
*/
|
|
405
|
-
static filterVariantsByAudioCodec_(variants, audioCodec) {
|
|
406
|
-
return variants.filter((variant) => {
|
|
407
|
-
if (variant.audio && variant.audio.codecs != audioCodec) {
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
return true;
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
};
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {{
|
|
51
|
+
* language: string,
|
|
52
|
+
* role: string,
|
|
53
|
+
* channelCount: number,
|
|
54
|
+
* hdrLevel: string,
|
|
55
|
+
* spatialAudio: boolean,
|
|
56
|
+
* videoLayout: string,
|
|
57
|
+
* audioLabel: string,
|
|
58
|
+
* videoLabel: string,
|
|
59
|
+
* codecSwitchingStrategy: shaka.config.CodecSwitchingStrategy,
|
|
60
|
+
* audioCodec: string
|
|
61
|
+
* }}
|
|
62
|
+
*
|
|
63
|
+
* @property {string} language
|
|
64
|
+
* The language used to filter variants.
|
|
65
|
+
* @property {string} role
|
|
66
|
+
* The adaptation role used to filter variants.
|
|
67
|
+
* @property {string} channelCount
|
|
68
|
+
* The audio channel count used to filter variants.
|
|
69
|
+
* @property {string} hdrLevel
|
|
70
|
+
* The HDR level used to filter variants.
|
|
71
|
+
* @property {boolean} spatialAudio
|
|
72
|
+
* Whether should prefer audio tracks with spatial audio.
|
|
73
|
+
* @property {string} videoLayout
|
|
74
|
+
* The video layout used to filter variants.
|
|
75
|
+
* @property {string} audioLabel
|
|
76
|
+
* The audio label used to filter variants.
|
|
77
|
+
* @property {string} videoLabel
|
|
78
|
+
* The video label used to filter variants.
|
|
79
|
+
* @property {shaka.config.CodecSwitchingStrategy} codecSwitchingStrategy
|
|
80
|
+
* The codec switching strategy used to filter variants.
|
|
81
|
+
* @property {string} audioCodec
|
|
82
|
+
* The audio codec used to filter variants.
|
|
83
|
+
* @export
|
|
84
|
+
*/
|
|
85
|
+
shaka.media.AdaptationSetCriteria.Configuration;
|
|
@@ -24,7 +24,7 @@ shaka.media.BufferingObserver = class {
|
|
|
24
24
|
/** @private {shaka.media.BufferingObserver.State} */
|
|
25
25
|
this.previousState_ = State.SATISFIED;
|
|
26
26
|
|
|
27
|
-
/** @private {!Map
|
|
27
|
+
/** @private {!Map<shaka.media.BufferingObserver.State, number>} */
|
|
28
28
|
this.thresholds_ = new Map()
|
|
29
29
|
.set(State.SATISFIED, thresholdWhenSatisfied)
|
|
30
30
|
.set(State.STARVING, thresholdWhenStarving);
|
|
@@ -67,9 +67,10 @@ shaka.media.BufferingObserver = class {
|
|
|
67
67
|
const threshold = this.thresholds_.get(this.previousState_);
|
|
68
68
|
|
|
69
69
|
const oldState = this.previousState_;
|
|
70
|
-
const newState =
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const newState =
|
|
71
|
+
(bufferedToEnd || (bufferLead >= threshold && bufferLead > 0)) ?
|
|
72
|
+
(State.SATISFIED) :
|
|
73
|
+
(State.STARVING);
|
|
73
74
|
|
|
74
75
|
// Save the new state now so that calls to |getState| from any callbacks
|
|
75
76
|
// will be accurate.
|
|
@@ -17,7 +17,7 @@ goog.require('shaka.util.BufferUtils');
|
|
|
17
17
|
* The IClosedCaptionParser defines the interface to provide all operations for
|
|
18
18
|
* parsing the closed captions embedded in Dash videos streams.
|
|
19
19
|
* TODO: Remove this interface and move method definitions
|
|
20
|
-
* directly to
|
|
20
|
+
* directly to ClosedCaptionParser.
|
|
21
21
|
* @interface
|
|
22
22
|
* @export
|
|
23
23
|
*/
|
|
@@ -49,7 +49,7 @@ shaka.media.IClosedCaptionParser = class {
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Returns the streams that the CEA decoder found.
|
|
52
|
-
* @return {!Array
|
|
52
|
+
* @return {!Array<string>}
|
|
53
53
|
*/
|
|
54
54
|
getStreams() {}
|
|
55
55
|
};
|