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.
Files changed (261) hide show
  1. package/AUTHORS +1 -0
  2. package/CONTRIBUTORS +4 -0
  3. package/README.md +22 -21
  4. package/cspell.config.yaml +18 -0
  5. package/dist/controls.css +1 -1
  6. package/dist/controls.css.map +1 -1
  7. package/dist/deps.js +29 -24
  8. package/dist/locales.js +33 -33
  9. package/dist/shaka-player.compiled.d.ts +138 -36
  10. package/dist/shaka-player.compiled.debug.d.ts +138 -36
  11. package/dist/shaka-player.compiled.debug.externs.js +367 -107
  12. package/dist/shaka-player.compiled.debug.js +828 -765
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +367 -107
  15. package/dist/shaka-player.compiled.js +1451 -1416
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +172 -38
  18. package/dist/shaka-player.ui.debug.d.ts +172 -38
  19. package/dist/shaka-player.ui.debug.externs.js +406 -113
  20. package/dist/shaka-player.ui.debug.js +842 -766
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +406 -113
  23. package/dist/shaka-player.ui.js +1670 -1628
  24. package/dist/shaka-player.ui.map +4 -4
  25. package/eslint.config.mjs +343 -0
  26. package/externs/airplay.js +1 -1
  27. package/externs/audiotrack.js +1 -1
  28. package/externs/awesomplete.js +1 -1
  29. package/externs/cast-sdk-v2.js +2 -2
  30. package/externs/cmcd.js +16 -1
  31. package/externs/device_sensor_event.js +1 -1
  32. package/externs/ima.js +8 -8
  33. package/externs/isoboxer.js +31 -31
  34. package/externs/jwk_set.js +1 -1
  35. package/externs/lcevc.js +8 -8
  36. package/externs/mediakeys.js +1 -1
  37. package/externs/mediasession.js +3 -2
  38. package/externs/mediatailor.js +18 -18
  39. package/externs/pictureinpicture.js +41 -1
  40. package/externs/playstation.js +2 -2
  41. package/externs/prefixed_eme.js +1 -1
  42. package/externs/shaka/abortable.js +4 -4
  43. package/externs/shaka/abr_manager.js +1 -1
  44. package/externs/shaka/ads.js +45 -6
  45. package/externs/shaka/cea.js +2 -2
  46. package/externs/shaka/codecs.js +4 -4
  47. package/externs/shaka/drm_info.js +6 -6
  48. package/externs/shaka/error.js +5 -5
  49. package/externs/shaka/manifest.js +51 -56
  50. package/externs/shaka/manifest_parser.js +3 -9
  51. package/externs/shaka/net.js +23 -20
  52. package/externs/shaka/offline.js +37 -37
  53. package/externs/shaka/offline_compat_v1.js +10 -10
  54. package/externs/shaka/offline_compat_v2.js +10 -10
  55. package/externs/shaka/player.js +139 -109
  56. package/externs/shaka/text.js +10 -3
  57. package/externs/shaka/transmuxer.js +1 -1
  58. package/externs/videotrack.js +1 -1
  59. package/lib/abr/ewma.js +1 -1
  60. package/lib/abr/simple_abr_manager.js +70 -22
  61. package/lib/ads/ad_manager.js +43 -18
  62. package/lib/ads/ad_utils.js +160 -58
  63. package/lib/ads/ads_stats.js +1 -1
  64. package/lib/ads/client_side_ad_manager.js +2 -2
  65. package/lib/ads/interstitial_ad.js +16 -11
  66. package/lib/ads/interstitial_ad_manager.js +419 -72
  67. package/lib/ads/interstitial_static_ad.js +299 -0
  68. package/lib/ads/media_tailor_ad.js +1 -0
  69. package/lib/ads/media_tailor_ad_manager.js +37 -36
  70. package/lib/ads/server_side_ad_manager.js +7 -6
  71. package/lib/cast/cast_receiver.js +5 -3
  72. package/lib/cast/cast_sender.js +2 -2
  73. package/lib/cast/cast_utils.js +20 -13
  74. package/lib/cea/cea608_data_channel.js +53 -53
  75. package/lib/cea/cea708_service.js +42 -40
  76. package/lib/cea/cea708_window.js +5 -2
  77. package/lib/cea/cea_decoder.js +5 -7
  78. package/lib/cea/mp4_cea_parser.js +1 -1
  79. package/lib/cea/sei_processor.js +1 -1
  80. package/lib/dash/content_protection.js +62 -192
  81. package/lib/dash/dash_parser.js +119 -119
  82. package/lib/dash/mpd_utils.js +14 -13
  83. package/lib/dash/segment_base.js +5 -5
  84. package/lib/dash/segment_list.js +10 -10
  85. package/lib/dash/segment_template.js +55 -53
  86. package/lib/debug/log.js +2 -2
  87. package/lib/dependencies/all.js +2 -1
  88. package/lib/{media → drm}/drm_engine.js +274 -143
  89. package/lib/{util → drm}/drm_utils.js +20 -11
  90. package/lib/drm/playready.js +233 -0
  91. package/lib/hls/hls_classes.js +14 -14
  92. package/lib/hls/hls_parser.js +257 -196
  93. package/lib/hls/hls_utils.js +14 -14
  94. package/lib/hls/manifest_text_parser.js +10 -10
  95. package/lib/media/adaptation_set.js +6 -5
  96. package/lib/media/adaptation_set_criteria.js +51 -379
  97. package/lib/media/buffering_observer.js +5 -4
  98. package/lib/media/closed_caption_parser.js +2 -2
  99. package/lib/media/content_workarounds.js +2 -2
  100. package/lib/media/example_based_criteria.js +69 -0
  101. package/lib/media/gap_jumping_controller.js +14 -1
  102. package/lib/media/manifest_filterer.js +8 -8
  103. package/lib/media/manifest_parser.js +2 -2
  104. package/lib/media/media_source_capabilities.js +20 -1
  105. package/lib/media/media_source_engine.js +84 -35
  106. package/lib/media/mp4_segment_index_parser.js +5 -5
  107. package/lib/media/playhead.js +2 -8
  108. package/lib/media/playhead_observer.js +1 -1
  109. package/lib/media/preference_based_criteria.js +333 -0
  110. package/lib/media/preload_manager.js +53 -37
  111. package/lib/media/presentation_timeline.js +2 -2
  112. package/lib/media/quality_observer.js +35 -35
  113. package/lib/media/region_observer.js +2 -2
  114. package/lib/media/region_timeline.js +3 -3
  115. package/lib/media/segment_index.js +14 -14
  116. package/lib/media/segment_prefetch.js +17 -13
  117. package/lib/media/segment_reference.js +7 -7
  118. package/lib/media/segment_utils.js +9 -9
  119. package/lib/media/streaming_engine.js +77 -38
  120. package/lib/media/time_ranges_utils.js +1 -1
  121. package/lib/media/video_wrapper.js +1 -1
  122. package/lib/media/webm_segment_index_parser.js +4 -4
  123. package/lib/mss/content_protection.js +17 -222
  124. package/lib/mss/mss_parser.js +23 -24
  125. package/lib/net/data_uri_plugin.js +1 -0
  126. package/lib/net/http_fetch_plugin.js +8 -7
  127. package/lib/net/http_plugin_utils.js +5 -2
  128. package/lib/net/http_xhr_plugin.js +4 -3
  129. package/lib/net/networking_engine.js +72 -17
  130. package/lib/net/networking_utils.js +5 -2
  131. package/lib/offline/download_info.js +5 -1
  132. package/lib/offline/download_manager.js +15 -4
  133. package/lib/offline/download_progress_estimator.js +1 -1
  134. package/lib/offline/indexeddb/base_storage_cell.js +9 -9
  135. package/lib/offline/indexeddb/db_connection.js +1 -1
  136. package/lib/offline/indexeddb/db_operation.js +2 -2
  137. package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
  138. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  139. package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
  140. package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
  141. package/lib/offline/manifest_converter.js +11 -12
  142. package/lib/offline/offline_scheme.js +8 -4
  143. package/lib/offline/session_deleter.js +11 -11
  144. package/lib/offline/storage.js +137 -88
  145. package/lib/offline/storage_muxer.js +8 -8
  146. package/lib/offline/stored_content_utils.js +3 -3
  147. package/lib/offline/stream_bandwidth_estimator.js +1 -1
  148. package/lib/player.js +291 -207
  149. package/lib/polyfill/all.js +1 -1
  150. package/lib/polyfill/media_capabilities.js +5 -5
  151. package/lib/polyfill/patchedmediakeys_apple.js +6 -6
  152. package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
  153. package/lib/polyfill/video_play_promise.js +0 -1
  154. package/lib/text/cue.js +3 -2
  155. package/lib/text/lrc_text_parser.js +1 -1
  156. package/lib/text/mp4_ttml_parser.js +1 -1
  157. package/lib/text/mp4_vtt_parser.js +3 -3
  158. package/lib/text/sbv_text_parser.js +1 -1
  159. package/lib/text/simple_text_displayer.js +37 -10
  160. package/lib/text/ssa_text_parser.js +3 -1
  161. package/lib/text/stub_text_displayer.js +12 -5
  162. package/lib/text/text_engine.js +5 -4
  163. package/lib/text/text_utils.js +4 -4
  164. package/lib/text/ttml_text_parser.js +21 -20
  165. package/lib/text/ui_text_displayer.js +20 -13
  166. package/lib/text/vtt_text_parser.js +10 -10
  167. package/lib/text/web_vtt_generator.js +2 -2
  168. package/lib/transmuxer/aac_transmuxer.js +2 -2
  169. package/lib/transmuxer/ac3_transmuxer.js +2 -2
  170. package/lib/transmuxer/adts.js +2 -0
  171. package/lib/transmuxer/ec3.js +3 -3
  172. package/lib/transmuxer/ec3_transmuxer.js +2 -2
  173. package/lib/transmuxer/h264.js +5 -5
  174. package/lib/transmuxer/h265.js +3 -3
  175. package/lib/transmuxer/mp3_transmuxer.js +2 -2
  176. package/lib/transmuxer/mpeg_audio.js +6 -6
  177. package/lib/transmuxer/mss_transmuxer.js +2 -0
  178. package/lib/transmuxer/transmuxer_engine.js +1 -1
  179. package/lib/transmuxer/ts_transmuxer.js +10 -10
  180. package/lib/util/abortable_operation.js +10 -10
  181. package/lib/util/array_utils.js +6 -6
  182. package/lib/util/cmcd_manager.js +149 -18
  183. package/lib/util/cmsd_manager.js +11 -11
  184. package/lib/util/config_utils.js +3 -3
  185. package/lib/util/content_steering_manager.js +17 -17
  186. package/lib/util/data_view_reader.js +3 -3
  187. package/lib/util/ebml_parser.js +1 -1
  188. package/lib/util/error.js +11 -6
  189. package/lib/util/event_manager.js +1 -1
  190. package/lib/util/exp_golomb.js +1 -1
  191. package/lib/util/fairplay_utils.js +6 -1
  192. package/lib/util/fake_event.js +3 -2
  193. package/lib/util/fake_event_target.js +1 -1
  194. package/lib/util/functional.js +8 -8
  195. package/lib/util/id3_utils.js +1 -1
  196. package/lib/util/iterables.js +6 -6
  197. package/lib/util/language_utils.js +17 -17
  198. package/lib/util/manifest_parser_utils.js +13 -13
  199. package/lib/util/map_utils.js +6 -6
  200. package/lib/util/media_ready_state_utils.js +1 -1
  201. package/lib/util/mime_utils.js +15 -4
  202. package/lib/util/mp4_box_parsers.js +5 -5
  203. package/lib/util/mp4_generator.js +31 -30
  204. package/lib/util/mp4_parser.js +2 -2
  205. package/lib/util/multi_map.js +5 -5
  206. package/lib/util/mutex.js +1 -1
  207. package/lib/util/networking.js +1 -1
  208. package/lib/util/object_utils.js +5 -1
  209. package/lib/util/operation_manager.js +1 -1
  210. package/lib/util/periods.js +24 -24
  211. package/lib/util/platform.js +8 -4
  212. package/lib/util/player_configuration.js +50 -17
  213. package/lib/util/pssh.js +34 -6
  214. package/lib/util/public_promise.js +2 -2
  215. package/lib/util/state_history.js +2 -2
  216. package/lib/util/stream_utils.js +138 -120
  217. package/lib/util/string_utils.js +4 -3
  218. package/lib/util/switch_history.js +2 -2
  219. package/lib/util/tXml.js +22 -17
  220. package/lib/util/text_parser.js +2 -2
  221. package/lib/util/timer.js +1 -1
  222. package/lib/util/ts_parser.js +22 -22
  223. package/lib/util/xml_utils.js +1 -0
  224. package/package.json +7 -4
  225. package/project-words.txt +485 -0
  226. package/shaka-player.uncompiled.js +1 -1
  227. package/third_party/closure-uri/uri.js +2 -2
  228. package/third_party/closure-uri/utils.js +2 -2
  229. package/third_party/language-mapping-list/language-mapping-list.js +1 -1
  230. package/ui/ad_statistics_button.js +9 -5
  231. package/ui/airplay_button.js +1 -0
  232. package/ui/audio_language_selection.js +2 -1
  233. package/ui/context_menu.js +2 -2
  234. package/ui/controls.js +7 -7
  235. package/ui/externs/ui.js +29 -21
  236. package/ui/externs/watermark.js +64 -0
  237. package/ui/fast_forward_button.js +1 -1
  238. package/ui/gl_matrix/matrix_4x4.js +11 -5
  239. package/ui/hidden_fast_forward_button.js +1 -1
  240. package/ui/hidden_seek_button.js +1 -1
  241. package/ui/language_utils.js +27 -26
  242. package/ui/less/buttons.less +2 -2
  243. package/ui/localization.js +21 -21
  244. package/ui/loop_button.js +2 -2
  245. package/ui/overflow_menu.js +2 -2
  246. package/ui/playback_rate_selection.js +1 -1
  247. package/ui/presentation_time.js +4 -1
  248. package/ui/range_element.js +2 -2
  249. package/ui/resolution_selection.js +42 -6
  250. package/ui/rewind_button.js +1 -1
  251. package/ui/seek_bar.js +5 -5
  252. package/ui/statistics_button.js +8 -4
  253. package/ui/text_selection.js +3 -2
  254. package/ui/ui.js +32 -2
  255. package/ui/vr_manager.js +3 -3
  256. package/ui/vr_utils.js +14 -14
  257. package/ui/vr_webgl.js +5 -5
  258. package/ui/watermark.js +313 -0
  259. package/.eslintignore +0 -4
  260. package/.eslintrc.js +0 -310
  261. package/lib/polyfill/patchedmediakeys_nop.js +0 -148
@@ -15,9 +15,9 @@ goog.requireType('shaka.hls.Tag');
15
15
  shaka.hls.Utils = class {
16
16
  /**
17
17
  *
18
- * @param {!Array.<!shaka.hls.Tag>} tags
18
+ * @param {!Array<!shaka.hls.Tag>} tags
19
19
  * @param {string} name
20
- * @return {!Array.<!shaka.hls.Tag>}
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.<!shaka.hls.Tag>} tags
31
+ * @param {!Array<!shaka.hls.Tag>} tags
32
32
  * @param {string} type
33
- * @return {!Array.<!shaka.hls.Tag>}
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.<!shaka.hls.Tag>} tags
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.<!shaka.hls.Tag>} tags
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.<string>} baseUris
74
+ * @param {!Array<string>} baseUris
75
75
  * @param {?string} relativeUri
76
- * @param {?Map.<string, string>=} variables
77
- * @return {!Array.<string>}
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.<string>} baseUris
89
- * @param {!Array.<string>} relativeUris
90
- * @param {?Map.<string, string>=} variables
91
- * @return {!Array.<string>}
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.<string, string>=} variables
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.<shaka.hls.Tag>} */
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.<string>} lines
125
- * @param {!Array.<!shaka.hls.Tag>} playlistTags
126
- * @return {!Array.<shaka.hls.Segment>}
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.<shaka.hls.Segment>} */
130
+ /** @type {!Array<shaka.hls.Segment>} */
131
131
  const segments = [];
132
- /** @type {!Array.<shaka.hls.Tag>} */
132
+ /** @type {!Array<shaka.hls.Tag>} */
133
133
  let segmentTags = [];
134
134
 
135
- /** @type {!Array.<shaka.hls.Tag>} */
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-seprated items,
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.<string>}
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.<string>}
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.<shaka.extern.Variant>=} candidates
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.<shaka.extern.Variant>} */
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.<shaka.extern.Variant>}
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.<string>} a
249
- * @param {!Iterable.<string>} b
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.media.Capabilities');
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.<shaka.extern.Variant>} variants
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
- * @param {shaka.extern.Variant} example
44
- * @param {shaka.config.CodecSwitchingStrategy} codecSwitchingStrategy
33
+ * Sets the AdaptationSetCriteria configuration.
34
+ *
35
+ * @param {shaka.media.AdaptationSetCriteria.Configuration} config
36
+ * @exportInterface
45
37
  */
46
- constructor(example, codecSwitchingStrategy) {
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
- * @implements {shaka.media.AdaptationSetCriteria}
79
- * @final
42
+ * A factory for creating the AdaptationSetCriteria.
43
+ *
44
+ * @typedef {function():!shaka.media.AdaptationSetCriteria}
45
+ * @export
80
46
  */
81
- shaka.media.PreferenceBasedCriteria = class {
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
- if (preferredRole) {
266
- return variant.audio.roles.includes(preferredRole);
267
- } else {
268
- return variant.audio.roles.length == 0;
269
- }
270
- });
271
- }
272
-
273
- /**
274
- * Filter Variants by audio label.
275
- *
276
- * @param {!Array.<shaka.extern.Variant>} variants
277
- * @param {string} preferredLabel
278
- * @return {!Array.<shaka.extern.Variant>}
279
- * @private
280
- */
281
- static filterVariantsByAudioLabel_(variants, preferredLabel) {
282
- return variants.filter((variant) => {
283
- if (!variant.audio || !variant.audio.label) {
284
- return false;
285
- }
286
-
287
- const label1 = variant.audio.label.toLowerCase();
288
- const label2 = preferredLabel.toLowerCase();
289
- return label1 == label2;
290
- });
291
- }
292
-
293
- /**
294
- * Filter Variants by video label.
295
- *
296
- * @param {!Array.<shaka.extern.Variant>} variants
297
- * @param {string} preferredLabel
298
- * @return {!Array.<shaka.extern.Variant>}
299
- * @private
300
- */
301
- static filterVariantsByVideoLabel_(variants, preferredLabel) {
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.<shaka.media.BufferingObserver.State, number>} */
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 = (bufferedToEnd || bufferLead >= threshold) ?
71
- (State.SATISFIED) :
72
- (State.STARVING);
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 ClosedCaptonParser.
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.<string>}
52
+ * @return {!Array<string>}
53
53
  */
54
54
  getStreams() {}
55
55
  };