shaka-player 4.12.9 → 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 (259) 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 +36 -36
  9. package/dist/shaka-player.compiled.d.ts +131 -36
  10. package/dist/shaka-player.compiled.debug.d.ts +131 -36
  11. package/dist/shaka-player.compiled.debug.externs.js +355 -107
  12. package/dist/shaka-player.compiled.debug.js +799 -742
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +355 -107
  15. package/dist/shaka-player.compiled.js +1456 -1423
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +165 -38
  18. package/dist/shaka-player.ui.debug.d.ts +165 -38
  19. package/dist/shaka-player.ui.debug.externs.js +394 -113
  20. package/dist/shaka-player.ui.debug.js +808 -738
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +394 -113
  23. package/dist/shaka-player.ui.js +1671 -1632
  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 +137 -108
  56. package/externs/shaka/text.js +3 -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 +34 -24
  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 +98 -108
  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 +14 -14
  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/manifest_filterer.js +8 -8
  102. package/lib/media/manifest_parser.js +2 -2
  103. package/lib/media/media_source_capabilities.js +20 -1
  104. package/lib/media/media_source_engine.js +71 -26
  105. package/lib/media/mp4_segment_index_parser.js +5 -5
  106. package/lib/media/playhead.js +2 -8
  107. package/lib/media/playhead_observer.js +1 -1
  108. package/lib/media/preference_based_criteria.js +333 -0
  109. package/lib/media/preload_manager.js +53 -37
  110. package/lib/media/presentation_timeline.js +2 -2
  111. package/lib/media/quality_observer.js +35 -35
  112. package/lib/media/region_observer.js +2 -2
  113. package/lib/media/region_timeline.js +3 -3
  114. package/lib/media/segment_index.js +14 -14
  115. package/lib/media/segment_prefetch.js +17 -13
  116. package/lib/media/segment_reference.js +7 -7
  117. package/lib/media/segment_utils.js +9 -9
  118. package/lib/media/streaming_engine.js +77 -38
  119. package/lib/media/time_ranges_utils.js +1 -1
  120. package/lib/media/video_wrapper.js +1 -1
  121. package/lib/media/webm_segment_index_parser.js +4 -4
  122. package/lib/mss/content_protection.js +17 -222
  123. package/lib/mss/mss_parser.js +23 -24
  124. package/lib/net/data_uri_plugin.js +1 -0
  125. package/lib/net/http_fetch_plugin.js +8 -7
  126. package/lib/net/http_plugin_utils.js +5 -2
  127. package/lib/net/http_xhr_plugin.js +4 -3
  128. package/lib/net/networking_engine.js +72 -17
  129. package/lib/net/networking_utils.js +5 -2
  130. package/lib/offline/download_info.js +5 -1
  131. package/lib/offline/download_manager.js +15 -4
  132. package/lib/offline/download_progress_estimator.js +1 -1
  133. package/lib/offline/indexeddb/base_storage_cell.js +9 -9
  134. package/lib/offline/indexeddb/db_connection.js +1 -1
  135. package/lib/offline/indexeddb/db_operation.js +2 -2
  136. package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
  137. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  138. package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
  139. package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
  140. package/lib/offline/manifest_converter.js +11 -12
  141. package/lib/offline/offline_scheme.js +8 -4
  142. package/lib/offline/session_deleter.js +11 -11
  143. package/lib/offline/storage.js +137 -88
  144. package/lib/offline/storage_muxer.js +8 -8
  145. package/lib/offline/stored_content_utils.js +3 -3
  146. package/lib/offline/stream_bandwidth_estimator.js +1 -1
  147. package/lib/player.js +270 -207
  148. package/lib/polyfill/all.js +1 -1
  149. package/lib/polyfill/media_capabilities.js +5 -5
  150. package/lib/polyfill/patchedmediakeys_apple.js +6 -6
  151. package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
  152. package/lib/polyfill/video_play_promise.js +0 -1
  153. package/lib/text/cue.js +3 -2
  154. package/lib/text/lrc_text_parser.js +1 -1
  155. package/lib/text/mp4_ttml_parser.js +1 -1
  156. package/lib/text/mp4_vtt_parser.js +3 -3
  157. package/lib/text/sbv_text_parser.js +1 -1
  158. package/lib/text/ssa_text_parser.js +3 -1
  159. package/lib/text/stub_text_displayer.js +5 -5
  160. package/lib/text/text_engine.js +5 -4
  161. package/lib/text/text_utils.js +4 -4
  162. package/lib/text/ttml_text_parser.js +21 -20
  163. package/lib/text/ui_text_displayer.js +13 -13
  164. package/lib/text/vtt_text_parser.js +10 -10
  165. package/lib/text/web_vtt_generator.js +2 -2
  166. package/lib/transmuxer/aac_transmuxer.js +2 -2
  167. package/lib/transmuxer/ac3_transmuxer.js +2 -2
  168. package/lib/transmuxer/adts.js +2 -0
  169. package/lib/transmuxer/ec3.js +3 -3
  170. package/lib/transmuxer/ec3_transmuxer.js +2 -2
  171. package/lib/transmuxer/h264.js +5 -5
  172. package/lib/transmuxer/h265.js +3 -3
  173. package/lib/transmuxer/mp3_transmuxer.js +2 -2
  174. package/lib/transmuxer/mpeg_audio.js +6 -6
  175. package/lib/transmuxer/mss_transmuxer.js +2 -0
  176. package/lib/transmuxer/transmuxer_engine.js +1 -1
  177. package/lib/transmuxer/ts_transmuxer.js +10 -10
  178. package/lib/util/abortable_operation.js +10 -10
  179. package/lib/util/array_utils.js +6 -6
  180. package/lib/util/cmcd_manager.js +149 -18
  181. package/lib/util/cmsd_manager.js +11 -11
  182. package/lib/util/config_utils.js +3 -3
  183. package/lib/util/content_steering_manager.js +17 -17
  184. package/lib/util/data_view_reader.js +3 -3
  185. package/lib/util/ebml_parser.js +1 -1
  186. package/lib/util/error.js +11 -6
  187. package/lib/util/event_manager.js +1 -1
  188. package/lib/util/exp_golomb.js +1 -1
  189. package/lib/util/fairplay_utils.js +6 -1
  190. package/lib/util/fake_event.js +3 -2
  191. package/lib/util/fake_event_target.js +1 -1
  192. package/lib/util/functional.js +8 -8
  193. package/lib/util/id3_utils.js +1 -1
  194. package/lib/util/iterables.js +6 -6
  195. package/lib/util/language_utils.js +17 -17
  196. package/lib/util/manifest_parser_utils.js +13 -13
  197. package/lib/util/map_utils.js +6 -6
  198. package/lib/util/media_ready_state_utils.js +1 -1
  199. package/lib/util/mime_utils.js +15 -4
  200. package/lib/util/mp4_box_parsers.js +5 -5
  201. package/lib/util/mp4_generator.js +31 -30
  202. package/lib/util/mp4_parser.js +2 -2
  203. package/lib/util/multi_map.js +5 -5
  204. package/lib/util/mutex.js +1 -1
  205. package/lib/util/networking.js +1 -1
  206. package/lib/util/object_utils.js +5 -1
  207. package/lib/util/operation_manager.js +1 -1
  208. package/lib/util/periods.js +24 -24
  209. package/lib/util/platform.js +8 -4
  210. package/lib/util/player_configuration.js +50 -17
  211. package/lib/util/pssh.js +34 -6
  212. package/lib/util/public_promise.js +2 -2
  213. package/lib/util/state_history.js +2 -2
  214. package/lib/util/stream_utils.js +138 -120
  215. package/lib/util/string_utils.js +4 -3
  216. package/lib/util/switch_history.js +2 -2
  217. package/lib/util/tXml.js +22 -17
  218. package/lib/util/text_parser.js +2 -2
  219. package/lib/util/timer.js +1 -1
  220. package/lib/util/ts_parser.js +22 -22
  221. package/lib/util/xml_utils.js +1 -0
  222. package/package.json +7 -4
  223. package/project-words.txt +485 -0
  224. package/shaka-player.uncompiled.js +1 -1
  225. package/third_party/closure-uri/uri.js +2 -2
  226. package/third_party/closure-uri/utils.js +2 -2
  227. package/third_party/language-mapping-list/language-mapping-list.js +1 -1
  228. package/ui/ad_statistics_button.js +9 -5
  229. package/ui/airplay_button.js +1 -0
  230. package/ui/audio_language_selection.js +2 -1
  231. package/ui/context_menu.js +2 -2
  232. package/ui/controls.js +7 -7
  233. package/ui/externs/ui.js +29 -21
  234. package/ui/externs/watermark.js +64 -0
  235. package/ui/fast_forward_button.js +1 -1
  236. package/ui/gl_matrix/matrix_4x4.js +11 -5
  237. package/ui/hidden_fast_forward_button.js +1 -1
  238. package/ui/hidden_seek_button.js +1 -1
  239. package/ui/language_utils.js +27 -26
  240. package/ui/less/buttons.less +2 -2
  241. package/ui/localization.js +21 -21
  242. package/ui/loop_button.js +2 -2
  243. package/ui/overflow_menu.js +2 -2
  244. package/ui/playback_rate_selection.js +1 -1
  245. package/ui/presentation_time.js +4 -1
  246. package/ui/range_element.js +2 -2
  247. package/ui/resolution_selection.js +42 -6
  248. package/ui/rewind_button.js +1 -1
  249. package/ui/seek_bar.js +5 -5
  250. package/ui/statistics_button.js +8 -4
  251. package/ui/text_selection.js +3 -2
  252. package/ui/ui.js +32 -2
  253. package/ui/vr_manager.js +3 -3
  254. package/ui/vr_utils.js +14 -14
  255. package/ui/vr_webgl.js +5 -5
  256. package/ui/watermark.js +313 -0
  257. package/.eslintignore +0 -4
  258. package/.eslintrc.js +0 -310
  259. package/lib/polyfill/patchedmediakeys_nop.js +0 -148
@@ -10,6 +10,9 @@ goog.provide('shaka.hls.HlsParser');
10
10
  goog.require('goog.Uri');
11
11
  goog.require('goog.asserts');
12
12
  goog.require('shaka.abr.Ewma');
13
+ goog.require('shaka.drm.DrmUtils');
14
+ goog.require('shaka.drm.PlayReady');
15
+ goog.require('shaka.hls.Attribute');
13
16
  goog.require('shaka.hls.ManifestTextParser');
14
17
  goog.require('shaka.hls.Playlist');
15
18
  goog.require('shaka.hls.PlaylistType');
@@ -22,12 +25,12 @@ goog.require('shaka.media.PresentationTimeline');
22
25
  goog.require('shaka.media.QualityObserver');
23
26
  goog.require('shaka.media.SegmentIndex');
24
27
  goog.require('shaka.media.SegmentReference');
28
+ goog.require('shaka.media.SegmentUtils');
25
29
  goog.require('shaka.net.DataUriPlugin');
26
30
  goog.require('shaka.net.NetworkingEngine');
27
31
  goog.require('shaka.net.NetworkingEngine.PendingRequest');
28
32
  goog.require('shaka.util.ArrayUtils');
29
33
  goog.require('shaka.util.BufferUtils');
30
- goog.require('shaka.util.DrmUtils');
31
34
  goog.require('shaka.util.ContentSteeringManager');
32
35
  goog.require('shaka.util.Error');
33
36
  goog.require('shaka.util.EventManager');
@@ -38,7 +41,6 @@ goog.require('shaka.util.MimeUtils');
38
41
  goog.require('shaka.util.Networking');
39
42
  goog.require('shaka.util.OperationManager');
40
43
  goog.require('shaka.util.Pssh');
41
- goog.require('shaka.media.SegmentUtils');
42
44
  goog.require('shaka.util.Timer');
43
45
  goog.require('shaka.util.TsParser');
44
46
  goog.require('shaka.util.TXml');
@@ -68,12 +70,12 @@ shaka.hls.HlsParser = class {
68
70
  /** @private {number} */
69
71
  this.globalId_ = 1;
70
72
 
71
- /** @private {!Map.<string, string>} */
73
+ /** @private {!Map<string, string>} */
72
74
  this.globalVariables_ = new Map();
73
75
 
74
76
  /**
75
77
  * A map from group id to stream infos created from the media tags.
76
- * @private {!Map.<string, !Array.<?shaka.hls.HlsParser.StreamInfo>>}
78
+ * @private {!Map<string, !Array<?shaka.hls.HlsParser.StreamInfo>>}
77
79
  */
78
80
  this.groupIdToStreamInfosMap_ = new Map();
79
81
 
@@ -84,7 +86,7 @@ shaka.hls.HlsParser = class {
84
86
  * This map stores those relationships.
85
87
  * Only used during livestreams; we do not assume that VOD content is
86
88
  * aligned in that way.
87
- * @private {!Map.<string, !Map.<number, number>>}
89
+ * @private {!Map<string, !Map<number, number>>}
88
90
  */
89
91
  this.mediaSequenceToStartTimeByType_ = new Map();
90
92
 
@@ -102,7 +104,7 @@ shaka.hls.HlsParser = class {
102
104
  *
103
105
  * Used to avoid duplicates that vary only in their text stream.
104
106
  *
105
- * @private {!Set.<string>}
107
+ * @private {!Set<string>}
106
108
  */
107
109
  this.variantUriSet_ = new Set();
108
110
 
@@ -119,7 +121,7 @@ shaka.hls.HlsParser = class {
119
121
  * createStreamInfoFromMediaTags_, createStreamInfoFromImageTag_ and
120
122
  * createStreamInfoFromVariantTags_.
121
123
  *
122
- * @private {!Map.<string, shaka.hls.HlsParser.StreamInfo>}
124
+ * @private {!Map<string, shaka.hls.HlsParser.StreamInfo>}
123
125
  */
124
126
  this.uriToStreamInfosMap_ = new Map();
125
127
 
@@ -208,7 +210,8 @@ shaka.hls.HlsParser = class {
208
210
  /** @private {number} */
209
211
  this.lastTargetDuration_ = Infinity;
210
212
 
211
- /** Partial segments target duration.
213
+ /**
214
+ * Partial segments target duration.
212
215
  * @private {number}
213
216
  */
214
217
  this.partialTargetDuration_ = 0;
@@ -222,32 +225,35 @@ shaka.hls.HlsParser = class {
222
225
  /** @private {shaka.util.OperationManager} */
223
226
  this.operationManager_ = new shaka.util.OperationManager();
224
227
 
225
- /** A map from closed captions' group id, to a map of closed captions info.
228
+ /**
229
+ * A map from closed captions' group id, to a map of closed captions info.
226
230
  * {group id -> {closed captions channel id -> language}}
227
- * @private {Map.<string, Map.<string, string>>}
231
+ * @private {Map<string, Map<string, string>>}
228
232
  */
229
233
  this.groupIdToClosedCaptionsMap_ = new Map();
230
234
 
231
- /** @private {Map.<string, string>} */
235
+ /** @private {Map<string, string>} */
232
236
  this.groupIdToCodecsMap_ = new Map();
233
237
 
234
- /** A cache mapping EXT-X-MAP tag info to the InitSegmentReference created
238
+ /**
239
+ * A cache mapping EXT-X-MAP tag info to the InitSegmentReference created
235
240
  * from the tag.
236
241
  * The key is a string combining the EXT-X-MAP tag's absolute uri, and
237
242
  * its BYTERANGE if available.
238
- * {!Map.<string, !shaka.media.InitSegmentReference>} */
243
+ * @private {!Map<string, !shaka.media.InitSegmentReference>}
244
+ */
239
245
  this.mapTagToInitSegmentRefMap_ = new Map();
240
246
 
241
- /** @private {Map.<string, !shaka.extern.aesKey>} */
247
+ /** @private {Map<string, !shaka.extern.aesKey>} */
242
248
  this.aesKeyInfoMap_ = new Map();
243
249
 
244
- /** @private {Map.<string, !Promise.<shaka.extern.Response>>} */
250
+ /** @private {Map<string, !Promise<shaka.extern.Response>>} */
245
251
  this.aesKeyMap_ = new Map();
246
252
 
247
- /** @private {Map.<string, !Promise.<shaka.extern.Response>>} */
253
+ /** @private {Map<string, !Promise<shaka.extern.Response>>} */
248
254
  this.identityKeyMap_ = new Map();
249
255
 
250
- /** @private {Map.<!shaka.media.InitSegmentReference, ?string>} */
256
+ /** @private {Map<!shaka.media.InitSegmentReference, ?string>} */
251
257
  this.identityKidMap_ = new Map();
252
258
 
253
259
  /** @private {boolean} */
@@ -269,7 +275,7 @@ shaka.hls.HlsParser = class {
269
275
  /** @private {boolean} */
270
276
  this.needsClosedCaptionsDetection_ = true;
271
277
 
272
- /** @private {Set.<string>} */
278
+ /** @private {Set<string>} */
273
279
  this.dateRangeIdsEmitted_ = new Set();
274
280
 
275
281
  /** @private {shaka.util.EventManager} */
@@ -344,7 +350,7 @@ shaka.hls.HlsParser = class {
344
350
  this.updatePlaylistTimer_ = null;
345
351
  }
346
352
 
347
- /** @type {!Array.<!Promise>} */
353
+ /** @type {!Array<!Promise>} */
348
354
  const pending = [];
349
355
 
350
356
  if (this.operationManager_) {
@@ -388,7 +394,7 @@ shaka.hls.HlsParser = class {
388
394
  return;
389
395
  }
390
396
 
391
- /** @type {!Array.<!Promise>} */
397
+ /** @type {!Array<!Promise>} */
392
398
  const updates = [];
393
399
  const streamInfos = Array.from(this.uriToStreamInfosMap_.values());
394
400
 
@@ -438,7 +444,7 @@ shaka.hls.HlsParser = class {
438
444
 
439
445
  /**
440
446
  * @param {!shaka.hls.HlsParser.StreamInfo} streamInfo
441
- * @return {!Map.<number, number>}
447
+ * @return {!Map<number, number>}
442
448
  * @private
443
449
  */
444
450
  getMediaSequenceToStartTimeFor_(streamInfo) {
@@ -519,7 +525,7 @@ shaka.hls.HlsParser = class {
519
525
  streamInfo.redirectUris.push(responseUri);
520
526
  }
521
527
 
522
- /** @type {!Array.<!shaka.hls.Tag>} */
528
+ /** @type {!Array<!shaka.hls.Tag>} */
523
529
  const variablesTags = shaka.hls.Utils.filterTagsByName(playlist.tags,
524
530
  'EXT-X-DEFINE');
525
531
 
@@ -640,7 +646,7 @@ shaka.hls.HlsParser = class {
640
646
  /**
641
647
  * Align the streams by sequence number by dropping early segments. Then
642
648
  * offset the streams to begin at presentation time 0.
643
- * @param {!Array.<!shaka.hls.HlsParser.StreamInfo>} streamInfos
649
+ * @param {!Array<!shaka.hls.HlsParser.StreamInfo>} streamInfos
644
650
  * @param {boolean=} force
645
651
  * @private
646
652
  */
@@ -728,7 +734,7 @@ shaka.hls.HlsParser = class {
728
734
  * Synchronize streams by the EXT-X-PROGRAM-DATE-TIME tags attached to their
729
735
  * segments. Also normalizes segment times so that the earliest segment in
730
736
  * any stream is at time 0.
731
- * @param {!Array.<!shaka.hls.HlsParser.StreamInfo>} streamInfos
737
+ * @param {!Array<!shaka.hls.HlsParser.StreamInfo>} streamInfos
732
738
  * @private
733
739
  */
734
740
  syncStreamsWithProgramDateTime_(streamInfos) {
@@ -836,14 +842,14 @@ shaka.hls.HlsParser = class {
836
842
 
837
843
  const playlist = this.manifestTextParser_.parsePlaylist(data);
838
844
 
839
- /** @type {!Array.<!shaka.hls.Tag>} */
845
+ /** @type {!Array<!shaka.hls.Tag>} */
840
846
  const variablesTags = Utils.filterTagsByName(playlist.tags, 'EXT-X-DEFINE');
841
847
 
842
- /** @type {!Array.<!shaka.extern.Variant>} */
848
+ /** @type {!Array<!shaka.extern.Variant>} */
843
849
  let variants = [];
844
- /** @type {!Array.<!shaka.extern.Stream>} */
850
+ /** @type {!Array<!shaka.extern.Stream>} */
845
851
  let textStreams = [];
846
- /** @type {!Array.<!shaka.extern.Stream>} */
852
+ /** @type {!Array<!shaka.extern.Stream>} */
847
853
  let imageStreams = [];
848
854
 
849
855
  // This assert is our own sanity check.
@@ -865,14 +871,14 @@ shaka.hls.HlsParser = class {
865
871
  /** @type {?string} */
866
872
  let mediaPlaylistType = null;
867
873
 
868
- /** @type {!Map.<string, string>} */
874
+ /** @type {!Map<string, string>} */
869
875
  let mediaVariables = new Map();
870
876
 
871
877
  // Parsing a media playlist results in a single-variant stream.
872
878
  if (playlist.type == shaka.hls.PlaylistType.MEDIA) {
873
879
  this.needsClosedCaptionsDetection_ = false;
874
880
 
875
- /** @type {!Array.<!shaka.hls.Tag>} */
881
+ /** @type {!Array<!shaka.hls.Tag>} */
876
882
  const variablesTags = shaka.hls.Utils.filterTagsByName(playlist.tags,
877
883
  'EXT-X-DEFINE');
878
884
 
@@ -932,31 +938,58 @@ shaka.hls.HlsParser = class {
932
938
  } else {
933
939
  this.parseMasterVariables_(variablesTags);
934
940
 
935
- /** @type {!Array.<!shaka.hls.Tag>} */
941
+ /** @type {!Array<!shaka.hls.Tag>} */
936
942
  const mediaTags = Utils.filterTagsByName(
937
943
  playlist.tags, 'EXT-X-MEDIA');
938
- /** @type {!Array.<!shaka.hls.Tag>} */
944
+ /** @type {!Array<!shaka.hls.Tag>} */
939
945
  const variantTags = Utils.filterTagsByName(
940
946
  playlist.tags, 'EXT-X-STREAM-INF');
941
- /** @type {!Array.<!shaka.hls.Tag>} */
947
+ /** @type {!Array<!shaka.hls.Tag>} */
942
948
  const imageTags = Utils.filterTagsByName(
943
949
  playlist.tags, 'EXT-X-IMAGE-STREAM-INF');
944
- /** @type {!Array.<!shaka.hls.Tag>} */
950
+ /** @type {!Array<!shaka.hls.Tag>} */
945
951
  const iFrameTags = Utils.filterTagsByName(
946
952
  playlist.tags, 'EXT-X-I-FRAME-STREAM-INF');
947
- /** @type {!Array.<!shaka.hls.Tag>} */
953
+ /** @type {!Array<!shaka.hls.Tag>} */
948
954
  const sessionKeyTags = Utils.filterTagsByName(
949
955
  playlist.tags, 'EXT-X-SESSION-KEY');
950
- /** @type {!Array.<!shaka.hls.Tag>} */
956
+ /** @type {!Array<!shaka.hls.Tag>} */
951
957
  const sessionDataTags = Utils.filterTagsByName(
952
958
  playlist.tags, 'EXT-X-SESSION-DATA');
953
- /** @type {!Array.<!shaka.hls.Tag>} */
959
+ /** @type {!Array<!shaka.hls.Tag>} */
954
960
  const contentSteeringTags = Utils.filterTagsByName(
955
961
  playlist.tags, 'EXT-X-CONTENT-STEERING');
956
962
 
957
963
  this.processSessionData_(sessionDataTags);
958
964
  await this.processContentSteering_(contentSteeringTags);
959
965
 
966
+ if (!this.config_.hls.ignoreSupplementalCodecs) {
967
+ // Duplicate variant tags with supplementalCodecs
968
+ const newVariantTags = [];
969
+ for (const tag of variantTags) {
970
+ const supplementalCodecsString =
971
+ tag.getAttributeValue('SUPPLEMENTAL-CODECS');
972
+ if (!supplementalCodecsString) {
973
+ continue;
974
+ }
975
+ const supplementalCodecs = supplementalCodecsString.split(/\s*,\s*/)
976
+ .map((codec) => {
977
+ return codec.split('/')[0];
978
+ });
979
+ const newAttributes = tag.attributes.map((attr) => {
980
+ const name = attr.name;
981
+ let value = attr.value;
982
+ if (name == 'CODECS') {
983
+ value = supplementalCodecs.join(',');
984
+ }
985
+ return new shaka.hls.Attribute(name, value);
986
+ });
987
+ newVariantTags.push(
988
+ new shaka.hls.Tag(tag.id, tag.name, newAttributes, null));
989
+ }
990
+ variantTags.push(...newVariantTags);
991
+ }
992
+
960
993
  this.parseCodecs_(variantTags);
961
994
 
962
995
  this.parseClosedCaptions_(mediaTags);
@@ -1002,7 +1035,6 @@ shaka.hls.HlsParser = class {
1002
1035
  textStreams,
1003
1036
  imageStreams,
1004
1037
  offlineSessionIds: [],
1005
- minBufferTime: 0,
1006
1038
  sequenceMode: this.config_.hls.sequenceMode,
1007
1039
  ignoreManifestTimestampsInSegmentsMode:
1008
1040
  this.config_.hls.ignoreManifestTimestampsInSegmentsMode,
@@ -1033,24 +1065,11 @@ shaka.hls.HlsParser = class {
1033
1065
  }
1034
1066
 
1035
1067
  this.playerInterface_.makeTextStreamsForClosedCaptions(this.manifest_);
1036
-
1037
- if (variants.length == 1) {
1038
- const createSegmentIndexPromises = [];
1039
- const variant = variants[0];
1040
- for (const stream of [variant.video, variant.audio]) {
1041
- if (stream && !stream.segmentIndex) {
1042
- createSegmentIndexPromises.push(stream.createSegmentIndex());
1043
- }
1044
- }
1045
- if (createSegmentIndexPromises.length > 0) {
1046
- await Promise.all(createSegmentIndexPromises);
1047
- }
1048
- }
1049
1068
  }
1050
1069
 
1051
1070
  /**
1052
- * @param {!Array.<!shaka.media.SegmentReference>} segments
1053
- * @return {!Promise.<shaka.media.SegmentUtils.BasicInfo>}
1071
+ * @param {!Array<!shaka.media.SegmentReference>} segments
1072
+ * @return {!Promise<shaka.media.SegmentUtils.BasicInfo>}
1054
1073
  * @private
1055
1074
  */
1056
1075
  async getBasicInfoFromSegments_(segments) {
@@ -1222,7 +1241,7 @@ shaka.hls.HlsParser = class {
1222
1241
 
1223
1242
  /**
1224
1243
  * Get the variables of each variant tag, and store in a map.
1225
- * @param {!Array.<!shaka.hls.Tag>} tags Variant tags from the playlist.
1244
+ * @param {!Array<!shaka.hls.Tag>} tags Variant tags from the playlist.
1226
1245
  * @private
1227
1246
  */
1228
1247
  parseMasterVariables_(tags) {
@@ -1247,9 +1266,9 @@ shaka.hls.HlsParser = class {
1247
1266
 
1248
1267
  /**
1249
1268
  * Get the variables of each variant tag, and store in a map.
1250
- * @param {!Array.<!shaka.hls.Tag>} tags Variant tags from the playlist.
1269
+ * @param {!Array<!shaka.hls.Tag>} tags Variant tags from the playlist.
1251
1270
  * @param {string} uri Media playlist URI.
1252
- * @return {!Map.<string, string>}
1271
+ * @return {!Map<string, string>}
1253
1272
  * @private
1254
1273
  */
1255
1274
  parseMediaVariables_(tags, uri) {
@@ -1283,8 +1302,8 @@ shaka.hls.HlsParser = class {
1283
1302
 
1284
1303
  /**
1285
1304
  * Get the codecs of each variant tag, and store in a map from
1286
- * audio/video/subtitle group id to the codecs arraylist.
1287
- * @param {!Array.<!shaka.hls.Tag>} tags Variant tags from the playlist.
1305
+ * audio/video/subtitle group id to the codecs array list.
1306
+ * @param {!Array<!shaka.hls.Tag>} tags Variant tags from the playlist.
1288
1307
  * @private
1289
1308
  */
1290
1309
  parseCodecs_(tags) {
@@ -1325,7 +1344,7 @@ shaka.hls.HlsParser = class {
1325
1344
  /**
1326
1345
  * Process EXT-X-SESSION-DATA tags.
1327
1346
  *
1328
- * @param {!Array.<!shaka.hls.Tag>} tags
1347
+ * @param {!Array<!shaka.hls.Tag>} tags
1329
1348
  * @private
1330
1349
  */
1331
1350
  processSessionData_(tags) {
@@ -1355,7 +1374,7 @@ shaka.hls.HlsParser = class {
1355
1374
  /**
1356
1375
  * Process EXT-X-CONTENT-STEERING tags.
1357
1376
  *
1358
- * @param {!Array.<!shaka.hls.Tag>} tags
1377
+ * @param {!Array<!shaka.hls.Tag>} tags
1359
1378
  * @return {!Promise}
1360
1379
  * @private
1361
1380
  */
@@ -1388,8 +1407,8 @@ shaka.hls.HlsParser = class {
1388
1407
  * Parse Subtitles and Closed Captions from 'EXT-X-MEDIA' tags.
1389
1408
  * Create text streams for Subtitles, but not Closed Captions.
1390
1409
  *
1391
- * @param {!Array.<!shaka.hls.Tag>} mediaTags Media tags from the playlist.
1392
- * @return {!Array.<!shaka.extern.Stream>}
1410
+ * @param {!Array<!shaka.hls.Tag>} mediaTags Media tags from the playlist.
1411
+ * @return {!Array<!shaka.extern.Stream>}
1393
1412
  * @private
1394
1413
  */
1395
1414
  parseTexts_(mediaTags) {
@@ -1454,9 +1473,9 @@ shaka.hls.HlsParser = class {
1454
1473
  }
1455
1474
 
1456
1475
  /**
1457
- * @param {!Array.<!shaka.hls.Tag>} imageTags from the playlist.
1458
- * @param {!Array.<!shaka.hls.Tag>} iFrameTags from the playlist.
1459
- * @return {!Promise.<!Array.<!shaka.extern.Stream>>}
1476
+ * @param {!Array<!shaka.hls.Tag>} imageTags from the playlist.
1477
+ * @param {!Array<!shaka.hls.Tag>} iFrameTags from the playlist.
1478
+ * @return {!Promise<!Array<!shaka.extern.Stream>>}
1460
1479
  * @private
1461
1480
  */
1462
1481
  async parseImages_(imageTags, iFrameTags) {
@@ -1499,8 +1518,8 @@ shaka.hls.HlsParser = class {
1499
1518
  }
1500
1519
 
1501
1520
  /**
1502
- * @param {!Array.<!shaka.hls.Tag>} mediaTags Media tags from the playlist.
1503
- * @param {!Map.<string, string>} groupIdPathwayIdMapping
1521
+ * @param {!Array<!shaka.hls.Tag>} mediaTags Media tags from the playlist.
1522
+ * @param {!Map<string, string>} groupIdPathwayIdMapping
1504
1523
  * @private
1505
1524
  */
1506
1525
  createStreamInfosFromMediaTags_(mediaTags, groupIdPathwayIdMapping) {
@@ -1529,8 +1548,8 @@ shaka.hls.HlsParser = class {
1529
1548
  }
1530
1549
 
1531
1550
  /**
1532
- * @param {!Array.<!shaka.hls.Tag>} iFrameTags from the playlist.
1533
- * @return {!Array.<!shaka.extern.Stream>}
1551
+ * @param {!Array<!shaka.hls.Tag>} iFrameTags from the playlist.
1552
+ * @return {!Array<!shaka.extern.Stream>}
1534
1553
  * @private
1535
1554
  */
1536
1555
  parseIFrames_(iFrameTags) {
@@ -1549,15 +1568,15 @@ shaka.hls.HlsParser = class {
1549
1568
  }
1550
1569
 
1551
1570
  /**
1552
- * @param {!Array.<!shaka.hls.Tag>} tags Variant tags from the playlist.
1553
- * @param {!Array.<!shaka.hls.Tag>} sessionKeyTags EXT-X-SESSION-KEY tags
1571
+ * @param {!Array<!shaka.hls.Tag>} tags Variant tags from the playlist.
1572
+ * @param {!Array<!shaka.hls.Tag>} sessionKeyTags EXT-X-SESSION-KEY tags
1554
1573
  * from the playlist.
1555
- * @param {!Array.<!shaka.hls.Tag>} mediaTags EXT-X-MEDIA tags from the
1574
+ * @param {!Array<!shaka.hls.Tag>} mediaTags EXT-X-MEDIA tags from the
1556
1575
  * playlist.
1557
- * @param {function():!Array.<string>} getUris
1558
- * @param {?Map.<string, string>} variables
1559
- * @param {!Array.<!shaka.extern.Stream>} iFrameStreams
1560
- * @return {!Promise.<!Array.<!shaka.extern.Variant>>}
1576
+ * @param {function(): !Array<string>} getUris
1577
+ * @param {?Map<string, string>} variables
1578
+ * @param {!Array<!shaka.extern.Stream>} iFrameStreams
1579
+ * @return {!Promise<!Array<!shaka.extern.Variant>>}
1561
1580
  * @private
1562
1581
  */
1563
1582
  async createVariantsForTags_(tags, sessionKeyTags, mediaTags, getUris,
@@ -1681,8 +1700,8 @@ shaka.hls.HlsParser = class {
1681
1700
  * Create audio and video streamInfos from an 'EXT-X-STREAM-INF' tag and its
1682
1701
  * related media tags.
1683
1702
  *
1684
- * @param {!Array.<!shaka.hls.Tag>} tags
1685
- * @param {!Array.<!shaka.hls.Tag>} mediaTags
1703
+ * @param {!Array<!shaka.hls.Tag>} tags
1704
+ * @param {!Array<!shaka.hls.Tag>} mediaTags
1686
1705
  * @param {?string} resolution
1687
1706
  * @param {?string} frameRate
1688
1707
  * @return {!shaka.hls.HlsParser.StreamInfos}
@@ -1757,7 +1776,7 @@ shaka.hls.HlsParser = class {
1757
1776
  });
1758
1777
  });
1759
1778
 
1760
- /** @type {!Array.<string>} */
1779
+ /** @type {!Array<string>} */
1761
1780
  let allCodecs = this.getCodecsForVariantTag_(tags[0]);
1762
1781
  const videoCodecs = shaka.util.ManifestParserUtils.guessCodecsSafe(
1763
1782
  ContentType.VIDEO, allCodecs);
@@ -1809,15 +1828,12 @@ shaka.hls.HlsParser = class {
1809
1828
  * Get the codecs from the 'EXT-X-STREAM-INF' tag.
1810
1829
  *
1811
1830
  * @param {!shaka.hls.Tag} tag
1812
- * @return {!Array.<string>} codecs
1831
+ * @return {!Array<string>} codecs
1813
1832
  * @private
1814
1833
  */
1815
1834
  getCodecsForVariantTag_(tag) {
1816
1835
  let codecsString = tag.getAttributeValue('CODECS') || '';
1817
1836
 
1818
- const supplementalCodecsString =
1819
- tag.getAttributeValue('SUPPLEMENTAL-CODECS');
1820
-
1821
1837
  this.codecInfoInManifest_ = codecsString.length > 0;
1822
1838
 
1823
1839
  if (!this.codecInfoInManifest_ && !this.config_.hls.disableCodecGuessing) {
@@ -1835,17 +1851,9 @@ shaka.hls.HlsParser = class {
1835
1851
  }
1836
1852
 
1837
1853
  // Strip out internal whitespace while splitting on commas:
1838
- /** @type {!Array.<string>} */
1854
+ /** @type {!Array<string>} */
1839
1855
  const codecs = codecsString.split(/\s*,\s*/);
1840
1856
 
1841
- if (supplementalCodecsString) {
1842
- const supplementalCodecs = supplementalCodecsString.split(/\s*,\s*/)
1843
- .map((codec) => {
1844
- return codec.split('/')[0];
1845
- });
1846
- codecs.push(...supplementalCodecs);
1847
- }
1848
-
1849
1857
  return shaka.media.SegmentUtils.codecsFiltering(codecs);
1850
1858
  }
1851
1859
 
@@ -1865,8 +1873,8 @@ shaka.hls.HlsParser = class {
1865
1873
  if (!channels) {
1866
1874
  return null;
1867
1875
  }
1868
- const channelcountstring = channels.split('/')[0];
1869
- const count = parseInt(channelcountstring, 10);
1876
+ const channelCountString = channels.split('/')[0];
1877
+ const count = parseInt(channelCountString, 10);
1870
1878
  return count;
1871
1879
  }
1872
1880
 
@@ -1911,7 +1919,7 @@ shaka.hls.HlsParser = class {
1911
1919
  * create the stream info.
1912
1920
  * @param {!shaka.hls.Tag} tag
1913
1921
  * @param {string} type
1914
- * @return {Map.<string, string>} closedCaptions
1922
+ * @return {Map<string, string>} closedCaptions
1915
1923
  * @private
1916
1924
  */
1917
1925
  getClosedCaptions_(tag, type) {
@@ -1973,25 +1981,25 @@ shaka.hls.HlsParser = class {
1973
1981
  }
1974
1982
 
1975
1983
  /**
1976
- * @param {!Array.<shaka.hls.HlsParser.StreamInfo>} audioInfos
1977
- * @param {!Array.<shaka.hls.HlsParser.StreamInfo>} videoInfos
1984
+ * @param {!Array<shaka.hls.HlsParser.StreamInfo>} audioInfos
1985
+ * @param {!Array<shaka.hls.HlsParser.StreamInfo>} videoInfos
1978
1986
  * @param {number} bandwidth
1979
1987
  * @param {?string} width
1980
1988
  * @param {?string} height
1981
1989
  * @param {?string} frameRate
1982
1990
  * @param {?string} videoRange
1983
1991
  * @param {?string} videoLayout
1984
- * @param {!Array.<shaka.extern.DrmInfo>} drmInfos
1985
- * @param {!Set.<string>} keyIds
1986
- * @param {!Array.<!shaka.extern.Stream>} iFrameStreams
1987
- * @return {!Array.<!shaka.extern.Variant>}
1992
+ * @param {!Array<shaka.extern.DrmInfo>} drmInfos
1993
+ * @param {!Set<string>} keyIds
1994
+ * @param {!Array<!shaka.extern.Stream>} iFrameStreams
1995
+ * @return {!Array<!shaka.extern.Variant>}
1988
1996
  * @private
1989
1997
  */
1990
1998
  createVariants_(
1991
1999
  audioInfos, videoInfos, bandwidth, width, height, frameRate, videoRange,
1992
2000
  videoLayout, drmInfos, keyIds, iFrameStreams) {
1993
2001
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
1994
- const DrmUtils = shaka.util.DrmUtils;
2002
+ const DrmUtils = shaka.drm.DrmUtils;
1995
2003
 
1996
2004
  for (const info of videoInfos) {
1997
2005
  this.addVideoAttributes_(
@@ -2041,7 +2049,18 @@ shaka.hls.HlsParser = class {
2041
2049
  videoInfo ? videoInfo.getUris().sort().join(',') : '';
2042
2050
  const audioStreamUri =
2043
2051
  audioInfo ? audioInfo.getUris().sort().join(',') : '';
2044
- const variantUriKey = videoStreamUri + ' - ' + audioStreamUri;
2052
+ const codecs = [];
2053
+ if (audioStream && audioStream.codecs) {
2054
+ codecs.push(audioStream.codecs);
2055
+ }
2056
+ if (videoStream && videoStream.codecs) {
2057
+ codecs.push(videoStream.codecs);
2058
+ }
2059
+ const variantUriKey = [
2060
+ videoStreamUri,
2061
+ audioStreamUri,
2062
+ codecs.sort(),
2063
+ ].join('-');
2045
2064
 
2046
2065
  if (audioStream && videoStream) {
2047
2066
  if (!DrmUtils.areDrmCompatible(audioDrmInfos, videoDrmInfos)) {
@@ -2090,7 +2109,7 @@ shaka.hls.HlsParser = class {
2090
2109
  * Parses an array of EXT-X-MEDIA tags, then stores the values of all tags
2091
2110
  * with TYPE="CLOSED-CAPTIONS" into a map of group id to closed captions.
2092
2111
  *
2093
- * @param {!Array.<!shaka.hls.Tag>} mediaTags
2112
+ * @param {!Array<!shaka.hls.Tag>} mediaTags
2094
2113
  * @private
2095
2114
  */
2096
2115
  parseClosedCaptions_(mediaTags) {
@@ -2129,8 +2148,8 @@ shaka.hls.HlsParser = class {
2129
2148
  /**
2130
2149
  * Parse EXT-X-MEDIA media tag into a Stream object.
2131
2150
  *
2132
- * @param {!Array.<!shaka.hls.Tag>} tags
2133
- * @param {!Map.<string, string>} groupIdPathwayIdMapping
2151
+ * @param {!Array<!shaka.hls.Tag>} tags
2152
+ * @param {!Map<string, string>} groupIdPathwayIdMapping
2134
2153
  * @param {boolean=} requireUri
2135
2154
  * @return {!shaka.hls.HlsParser.StreamInfo}
2136
2155
  * @private
@@ -2139,7 +2158,7 @@ shaka.hls.HlsParser = class {
2139
2158
  requireUri = true) {
2140
2159
  const verbatimMediaPlaylistUris = [];
2141
2160
  const globalGroupIds = [];
2142
- const groupIdUriMappping = new Map();
2161
+ const groupIdUriMapping = new Map();
2143
2162
  for (const tag of tags) {
2144
2163
  goog.asserts.assert(tag.name == 'EXT-X-MEDIA',
2145
2164
  'Should only be called on media tags!');
@@ -2148,7 +2167,7 @@ shaka.hls.HlsParser = class {
2148
2167
  const groupId = tag.getRequiredAttrValue('GROUP-ID');
2149
2168
  verbatimMediaPlaylistUris.push(uri);
2150
2169
  globalGroupIds.push(groupId);
2151
- groupIdUriMappping.set(groupId, uri);
2170
+ groupIdUriMapping.set(groupId, uri);
2152
2171
  }
2153
2172
 
2154
2173
  const globalGroupId = globalGroupIds.sort().join(',');
@@ -2175,7 +2194,7 @@ shaka.hls.HlsParser = class {
2175
2194
  }
2176
2195
  const streamId = this.globalId_++;
2177
2196
  if (this.contentSteeringManager_) {
2178
- for (const [groupId, uri] of groupIdUriMappping) {
2197
+ for (const [groupId, uri] of groupIdUriMapping) {
2179
2198
  const pathwayId = groupIdPathwayIdMapping.get(groupId);
2180
2199
  if (pathwayId) {
2181
2200
  this.contentSteeringManager_.addLocation(streamId, pathwayId, uri);
@@ -2227,7 +2246,7 @@ shaka.hls.HlsParser = class {
2227
2246
  * Parse EXT-X-IMAGE-STREAM-INF media tag into a Stream object.
2228
2247
  *
2229
2248
  * @param {shaka.hls.Tag} tag
2230
- * @return {!Promise.<!shaka.hls.HlsParser.StreamInfo>}
2249
+ * @return {!Promise<!shaka.hls.HlsParser.StreamInfo>}
2231
2250
  * @private
2232
2251
  */
2233
2252
  async createStreamInfoFromImageTag_(tag) {
@@ -2341,8 +2360,8 @@ shaka.hls.HlsParser = class {
2341
2360
  /**
2342
2361
  * Parse an EXT-X-STREAM-INF media tag into a Stream object.
2343
2362
  *
2344
- * @param {!Array.<!shaka.hls.Tag>} tags
2345
- * @param {!Array.<string>} allCodecs
2363
+ * @param {!Array<!shaka.hls.Tag>} tags
2364
+ * @param {!Array<string>} allCodecs
2346
2365
  * @param {string} type
2347
2366
  * @return {!shaka.hls.HlsParser.StreamInfo}
2348
2367
  * @private
@@ -2361,7 +2380,8 @@ shaka.hls.HlsParser = class {
2361
2380
  verbatimMediaPlaylistUris.push(uri);
2362
2381
  }
2363
2382
 
2364
- const key = verbatimMediaPlaylistUris.sort().join(',');
2383
+ const key = verbatimMediaPlaylistUris.sort().join(',') +
2384
+ allCodecs.sort().join(',');
2365
2385
  if (this.uriToStreamInfosMap_.has(key)) {
2366
2386
  return this.uriToStreamInfosMap_.get(key);
2367
2387
  }
@@ -2371,7 +2391,7 @@ shaka.hls.HlsParser = class {
2371
2391
  const streamInfo = this.createStreamInfo_(
2372
2392
  streamId, verbatimMediaPlaylistUris,
2373
2393
  codecs, type, /* language= */ null, /* primary= */ false,
2374
- /* name= */ null, /* channelcount= */ null, closedCaptions,
2394
+ /* name= */ null, /* channelCount= */ null, closedCaptions,
2375
2395
  /* characteristics= */ null, /* forced= */ false,
2376
2396
  /* sampleRate= */ null, /* spatialAudio= */ false);
2377
2397
 
@@ -2382,14 +2402,14 @@ shaka.hls.HlsParser = class {
2382
2402
 
2383
2403
  /**
2384
2404
  * @param {number} streamId
2385
- * @param {!Array.<string>} verbatimMediaPlaylistUris
2405
+ * @param {!Array<string>} verbatimMediaPlaylistUris
2386
2406
  * @param {string} codecs
2387
2407
  * @param {string} type
2388
2408
  * @param {?string} languageValue
2389
2409
  * @param {boolean} primary
2390
2410
  * @param {?string} name
2391
2411
  * @param {?number} channelsCount
2392
- * @param {Map.<string, string>} closedCaptions
2412
+ * @param {Map<string, string>} closedCaptions
2393
2413
  * @param {?string} characteristics
2394
2414
  * @param {boolean} forced
2395
2415
  * @param {?number} sampleRate
@@ -2477,7 +2497,7 @@ shaka.hls.HlsParser = class {
2477
2497
  shaka.util.Error.Code.HLS_INVALID_PLAYLIST_HIERARCHY);
2478
2498
  }
2479
2499
 
2480
- /** @type {!Array.<!shaka.hls.Tag>} */
2500
+ /** @type {!Array<!shaka.hls.Tag>} */
2481
2501
  const variablesTags = shaka.hls.Utils.filterTagsByName(playlist.tags,
2482
2502
  'EXT-X-DEFINE');
2483
2503
 
@@ -2735,7 +2755,7 @@ shaka.hls.HlsParser = class {
2735
2755
  }
2736
2756
 
2737
2757
  /**
2738
- * @param {!Array.<!shaka.extern.Stream>} streams
2758
+ * @param {!Array<!shaka.extern.Stream>} streams
2739
2759
  * @private
2740
2760
  */
2741
2761
  notifySegmentsForStreams_(streams) {
@@ -2753,7 +2773,7 @@ shaka.hls.HlsParser = class {
2753
2773
  }
2754
2774
 
2755
2775
  /**
2756
- * @param {!Array.<!shaka.hls.HlsParser.StreamInfo>} streamInfos
2776
+ * @param {!Array<!shaka.hls.HlsParser.StreamInfo>} streamInfos
2757
2777
  * @private
2758
2778
  */
2759
2779
  finalizeStreams_(streamInfos) {
@@ -2836,8 +2856,9 @@ shaka.hls.HlsParser = class {
2836
2856
 
2837
2857
  /**
2838
2858
  * @param {number} streamId
2859
+ * @param {!Map<string, string>} variables
2839
2860
  * @param {!shaka.hls.Playlist} playlist
2840
- * @param {function():!Array.<string>} getUris
2861
+ * @param {function(): !Array<string>} getUris
2841
2862
  * @param {string} responseUri
2842
2863
  * @param {string} codecs
2843
2864
  * @param {string} type
@@ -2845,7 +2866,7 @@ shaka.hls.HlsParser = class {
2845
2866
  * @param {boolean} primary
2846
2867
  * @param {?string} name
2847
2868
  * @param {?number} channelsCount
2848
- * @param {Map.<string, string>} closedCaptions
2869
+ * @param {Map<string, string>} closedCaptions
2849
2870
  * @param {?string} characteristics
2850
2871
  * @param {boolean} forced
2851
2872
  * @param {?number} sampleRate
@@ -2853,7 +2874,7 @@ shaka.hls.HlsParser = class {
2853
2874
  * @param {(string|undefined)} mimeType
2854
2875
  * @param {boolean=} requestBasicInfo
2855
2876
  * @param {boolean=} allowOverrideMimeType
2856
- * @return {!Promise.<!shaka.hls.HlsParser.StreamInfo>}
2877
+ * @return {!Promise<!shaka.hls.HlsParser.StreamInfo>}
2857
2878
  * @private
2858
2879
  */
2859
2880
  async convertParsedPlaylistIntoStreamInfo_(streamId, variables, playlist,
@@ -2943,7 +2964,7 @@ shaka.hls.HlsParser = class {
2943
2964
  const stream = this.makeStreamObject_(streamId, codecs, type,
2944
2965
  languageValue, primary, name, channelsCount, closedCaptions,
2945
2966
  characteristics, forced, sampleRate, spatialAudio);
2946
- stream.encrypted = encrypted;
2967
+ stream.encrypted = encrypted && !aesEncrypted;
2947
2968
  stream.drmInfos = drmInfos;
2948
2969
  stream.keyIds = keyIds;
2949
2970
  stream.mimeType = mimeType;
@@ -3005,7 +3026,7 @@ shaka.hls.HlsParser = class {
3005
3026
  * Get the next msn and part
3006
3027
  *
3007
3028
  * @param {number} mediaSequenceNumber
3008
- * @param {!Array.<!shaka.media.SegmentReference>} segments
3029
+ * @param {!Array<!shaka.media.SegmentReference>} segments
3009
3030
  * @return {{nextMediaSequence: number, nextPart:number}}}
3010
3031
  * @private
3011
3032
  */
@@ -3058,7 +3079,7 @@ shaka.hls.HlsParser = class {
3058
3079
  * @param {boolean} primary
3059
3080
  * @param {?string} name
3060
3081
  * @param {?number} channelsCount
3061
- * @param {Map.<string, string>} closedCaptions
3082
+ * @param {Map<string, string>} closedCaptions
3062
3083
  * @param {?string} characteristics
3063
3084
  * @param {boolean} forced
3064
3085
  * @param {?number} sampleRate
@@ -3152,11 +3173,11 @@ shaka.hls.HlsParser = class {
3152
3173
  /**
3153
3174
  * @param {!shaka.hls.Playlist} playlist
3154
3175
  * @param {string} mimeType
3155
- * @param {function():!Array.<string>} getUris
3156
- * @param {?Map.<string, string>=} variables
3157
- * @return {Promise.<{
3158
- * drmInfos: !Array.<shaka.extern.DrmInfo>,
3159
- * keyIds: !Set.<string>,
3176
+ * @param {function(): !Array<string>} getUris
3177
+ * @param {?Map<string, string>=} variables
3178
+ * @return {Promise<{
3179
+ * drmInfos: !Array<shaka.extern.DrmInfo>,
3180
+ * keyIds: !Set<string>,
3160
3181
  * encrypted: boolean,
3161
3182
  * aesEncrypted: boolean
3162
3183
  * }>}
@@ -3183,7 +3204,7 @@ shaka.hls.HlsParser = class {
3183
3204
  let encrypted = false;
3184
3205
  let aesEncrypted = false;
3185
3206
 
3186
- /** @type {!Array.<shaka.extern.DrmInfo>}*/
3207
+ /** @type {!Array<shaka.extern.DrmInfo>}*/
3187
3208
  const drmInfos = [];
3188
3209
  const keyIds = new Set();
3189
3210
 
@@ -3234,8 +3255,8 @@ shaka.hls.HlsParser = class {
3234
3255
  /**
3235
3256
  * @param {!shaka.hls.Tag} drmTag
3236
3257
  * @param {!shaka.hls.Playlist} playlist
3237
- * @param {function():!Array.<string>} getUris
3238
- * @param {?Map.<string, string>=} variables
3258
+ * @param {function(): !Array<string>} getUris
3259
+ * @param {?Map<string, string>=} variables
3239
3260
  * @return {!shaka.extern.aesKey}
3240
3261
  * @private
3241
3262
  */
@@ -3274,7 +3295,11 @@ shaka.hls.HlsParser = class {
3274
3295
  }
3275
3296
  }
3276
3297
 
3277
- const aesKeyInfoKey = `${drmTag.toString()}-${firstMediaSequenceNumber}`;
3298
+ const keyUris = shaka.hls.Utils.constructSegmentUris(
3299
+ getUris(), drmTag.getRequiredAttrValue('URI'), variables);
3300
+ const keyMapKey = keyUris.sort().join('');
3301
+ const aesKeyInfoKey =
3302
+ `${drmTag.toString()}-${firstMediaSequenceNumber}-${keyMapKey}`;
3278
3303
  if (!this.aesKeyInfoMap_.has(aesKeyInfoKey)) {
3279
3304
  // Default AES-128
3280
3305
  const keyInfo = {
@@ -3298,10 +3323,6 @@ shaka.hls.HlsParser = class {
3298
3323
  // Don't download the key object until the segment is parsed, to avoid a
3299
3324
  // startup delay for long manifests with lots of keys.
3300
3325
  keyInfo.fetchKey = async () => {
3301
- const keyUris = shaka.hls.Utils.constructSegmentUris(
3302
- getUris(), drmTag.getRequiredAttrValue('URI'), variables);
3303
-
3304
- const keyMapKey = keyUris.sort().join('');
3305
3326
  if (!this.aesKeyMap_.has(keyMapKey)) {
3306
3327
  const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
3307
3328
  const request = shaka.net.NetworkingEngine.makeRequest(
@@ -3521,9 +3542,9 @@ shaka.hls.HlsParser = class {
3521
3542
  /**
3522
3543
  * Get the InitSegmentReference for a segment if it has a EXT-X-MAP tag.
3523
3544
  * @param {!shaka.hls.Playlist} playlist
3524
- * @param {!Array.<!shaka.hls.Tag>} tags Segment tags
3525
- * @param {function():!Array.<string>} getUris
3526
- * @param {?Map.<string, string>=} variables
3545
+ * @param {!Array<!shaka.hls.Tag>} tags Segment tags
3546
+ * @param {function(): !Array<string>} getUris
3547
+ * @param {?Map<string, string>=} variables
3527
3548
  * @return {shaka.media.InitSegmentReference}
3528
3549
  * @private
3529
3550
  */
@@ -3568,7 +3589,7 @@ shaka.hls.HlsParser = class {
3568
3589
  /**
3569
3590
  * Create an InitSegmentReference object for the EXT-X-MAP tag in the media
3570
3591
  * playlist.
3571
- * @param {!Array.<string>} absoluteInitSegmentUris
3592
+ * @param {!Array<string>} absoluteInitSegmentUris
3572
3593
  * @param {!shaka.hls.Tag} mapTag EXT-X-MAP
3573
3594
  * @param {shaka.hls.Tag=} byteRangeTag EXT-X-BYTERANGE
3574
3595
  * @param {shaka.extern.aesKey=} aesKey
@@ -3620,10 +3641,10 @@ shaka.hls.HlsParser = class {
3620
3641
  * @param {shaka.media.SegmentReference} previousReference
3621
3642
  * @param {!shaka.hls.Segment} hlsSegment
3622
3643
  * @param {number} startTime
3623
- * @param {!Map.<string, string>} variables
3644
+ * @param {!Map<string, string>} variables
3624
3645
  * @param {!shaka.hls.Playlist} playlist
3625
3646
  * @param {string} type
3626
- * @param {function():!Array.<string>} getUris
3647
+ * @param {function(): !Array<string>} getUris
3627
3648
  * @param {shaka.extern.aesKey=} aesKey
3628
3649
  * @return {shaka.media.SegmentReference}
3629
3650
  * @private
@@ -3837,7 +3858,7 @@ shaka.hls.HlsParser = class {
3837
3858
  } else if (partialSegmentRefs.length) {
3838
3859
  endTime = partialSegmentRefs[partialSegmentRefs.length - 1].endTime;
3839
3860
  } else {
3840
- // Skip segments without duration and without partialsegments
3861
+ // Skip segments without duration and without partial segments
3841
3862
  return null;
3842
3863
  }
3843
3864
 
@@ -3941,7 +3962,7 @@ shaka.hls.HlsParser = class {
3941
3962
  * Parse the startByte and endByte.
3942
3963
  * @param {shaka.media.SegmentReference} previousReference
3943
3964
  * @param {?string} byterange
3944
- * @return {!Array.<number>} An array with the start byte and end byte.
3965
+ * @return {!Array<number>} An array with the start byte and end byte.
3945
3966
  * @private
3946
3967
  */
3947
3968
  parseByteRange_(previousReference, byterange) {
@@ -3965,10 +3986,10 @@ shaka.hls.HlsParser = class {
3965
3986
  }
3966
3987
 
3967
3988
  /**
3968
- * @param {!Array.<!shaka.hls.Tag>} tags
3989
+ * @param {!Array<!shaka.hls.Tag>} tags
3969
3990
  * @param {string} contentType
3970
- * @param {!Map.<string, string>} variables
3971
- * @param {function():!Array.<string>} getUris
3991
+ * @param {!Map<string, string>} variables
3992
+ * @param {function(): !Array<string>} getUris
3972
3993
  * @private
3973
3994
  */
3974
3995
  processDateRangeTags_(tags, contentType, variables, getUris) {
@@ -4090,7 +4111,7 @@ shaka.hls.HlsParser = class {
4090
4111
  'END-ON-NEXT',
4091
4112
  ];
4092
4113
 
4093
- /* @type {!Array.<shaka.extern.MetadataFrame>} */
4114
+ /* @type {!Array<shaka.extern.MetadataFrame>} */
4094
4115
  const values = [];
4095
4116
  for (const attribute of tag.attributes) {
4096
4117
  if (excludedAttributes.includes(attribute.name)) {
@@ -4119,7 +4140,7 @@ shaka.hls.HlsParser = class {
4119
4140
 
4120
4141
  this.dateRangeIdsEmitted_.add(id);
4121
4142
  } catch (e) {
4122
- shaka.log.warning('Ignorando DATERANGE con errores', tag.toString());
4143
+ shaka.log.warning('Ignoring DATERANGE with errors', tag.toString());
4123
4144
  }
4124
4145
  }
4125
4146
  }
@@ -4130,17 +4151,17 @@ shaka.hls.HlsParser = class {
4130
4151
  * playlist.
4131
4152
  *
4132
4153
  * @param {!shaka.hls.Playlist} playlist
4133
- * @param {!Map.<number, number>} mediaSequenceToStartTime
4134
- * @param {!Map.<string, string>} variables
4135
- * @param {function():!Array.<string>} getUris
4154
+ * @param {!Map<number, number>} mediaSequenceToStartTime
4155
+ * @param {!Map<string, string>} variables
4156
+ * @param {function(): !Array<string>} getUris
4136
4157
  * @param {string} type
4137
- * @return {{segments: !Array.<!shaka.media.SegmentReference>,
4158
+ * @return {{segments: !Array<!shaka.media.SegmentReference>,
4138
4159
  * bandwidth: (number|undefined)}}
4139
4160
  * @private
4140
4161
  */
4141
4162
  createSegments_(playlist, mediaSequenceToStartTime, variables,
4142
4163
  getUris, type) {
4143
- /** @type {Array.<!shaka.hls.Segment>} */
4164
+ /** @type {Array<!shaka.hls.Segment>} */
4144
4165
  const hlsSegments = playlist.segments;
4145
4166
  goog.asserts.assert(hlsSegments.length, 'Playlist should have segments!');
4146
4167
 
@@ -4175,12 +4196,12 @@ shaka.hls.HlsParser = class {
4175
4196
  firstStartTime = this.presentationTimeline_.getSegmentAvailabilityStart();
4176
4197
  }
4177
4198
 
4178
- /** @type {!Array.<!shaka.media.SegmentReference>} */
4199
+ /** @type {!Array<!shaka.media.SegmentReference>} */
4179
4200
  const references = [];
4180
4201
 
4181
4202
  let previousReference = null;
4182
4203
 
4183
- /** @type {!Array.<{bitrate: number, duration: number}>} */
4204
+ /** @type {!Array<{bitrate: number, duration: number}>} */
4184
4205
  const bitrates = [];
4185
4206
 
4186
4207
  for (let i = 0; i < hlsSegments.length; i++) {
@@ -4212,18 +4233,6 @@ shaka.hls.HlsParser = class {
4212
4233
  initSegmentRef = this.getInitSegmentReference_(playlist,
4213
4234
  item.tags, getUris, variables);
4214
4235
 
4215
- // If the stream is low latency and the user has not configured the
4216
- // lowLatencyMode, but if it has been configured to activate the
4217
- // lowLatencyMode if a stream of this type is detected, we automatically
4218
- // activate the lowLatencyMode.
4219
- if (!this.lowLatencyMode_) {
4220
- const autoLowLatencyMode = this.playerInterface_.isAutoLowLatencyMode();
4221
- if (autoLowLatencyMode) {
4222
- this.playerInterface_.enableLowLatencyMode();
4223
- this.lowLatencyMode_ = this.playerInterface_.isLowLatencyMode();
4224
- }
4225
- }
4226
-
4227
4236
  const reference = this.createSegmentReference_(
4228
4237
  initSegmentRef,
4229
4238
  previousReference,
@@ -4430,7 +4439,7 @@ shaka.hls.HlsParser = class {
4430
4439
  }
4431
4440
 
4432
4441
  /**
4433
- * @param {!Array.<!shaka.media.SegmentReference>} segments
4442
+ * @param {!Array<!shaka.media.SegmentReference>} segments
4434
4443
  * @return {{segment: !shaka.media.SegmentReference, segmentIndex: number}}
4435
4444
  * @private
4436
4445
  */
@@ -4456,8 +4465,8 @@ shaka.hls.HlsParser = class {
4456
4465
  *
4457
4466
  * @param {string} contentType
4458
4467
  * @param {string} codecs
4459
- * @param {!Array.<!shaka.media.SegmentReference>} segments
4460
- * @return {!Promise.<string>}
4468
+ * @param {!Array<!shaka.media.SegmentReference>} segments
4469
+ * @return {!Promise<string>}
4461
4470
  * @private
4462
4471
  */
4463
4472
  async guessMimeType_(contentType, codecs, segments) {
@@ -4528,7 +4537,7 @@ shaka.hls.HlsParser = class {
4528
4537
  * Returns a tag with a given name.
4529
4538
  * Throws an error if tag was not found.
4530
4539
  *
4531
- * @param {!Array.<shaka.hls.Tag>} tags
4540
+ * @param {!Array<shaka.hls.Tag>} tags
4532
4541
  * @param {string} tagName
4533
4542
  * @return {!shaka.hls.Tag}
4534
4543
  * @private
@@ -4571,7 +4580,7 @@ shaka.hls.HlsParser = class {
4571
4580
  * Makes a network request for the manifest and returns a Promise
4572
4581
  * with the resulting data.
4573
4582
  *
4574
- * @param {!Array.<string>} uris
4583
+ * @param {!Array<string>} uris
4575
4584
  * @param {boolean=} isPlaylist
4576
4585
  * @return {!shaka.net.NetworkingEngine.PendingRequest}
4577
4586
  * @private
@@ -4871,6 +4880,56 @@ shaka.hls.HlsParser = class {
4871
4880
  {initDataType: 'cenc', initData: pssh},
4872
4881
  ]);
4873
4882
 
4883
+ const input = shaka.util.TXml.parseXmlString([
4884
+ '<PLAYREADY>',
4885
+ shaka.util.Uint8ArrayUtils.toBase64(data),
4886
+ '</PLAYREADY>',
4887
+ ].join('\n'));
4888
+ if (input) {
4889
+ drmInfo.licenseServerUri = shaka.drm.PlayReady.getLicenseUrl(input);
4890
+ }
4891
+
4892
+ return drmInfo;
4893
+ }
4894
+
4895
+ /**
4896
+ * @param {!shaka.hls.Tag} drmTag
4897
+ * @return {?shaka.extern.DrmInfo}
4898
+ * @private
4899
+ */
4900
+ static wiseplayDrmParser_(drmTag) {
4901
+ const method = drmTag.getRequiredAttrValue('METHOD');
4902
+ const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR'];
4903
+ if (!VALID_METHODS.includes(method)) {
4904
+ shaka.log.error('WisePlay in HLS is only supported with [',
4905
+ VALID_METHODS.join(', '), '], not', method);
4906
+ return null;
4907
+ }
4908
+
4909
+ let encryptionScheme = 'cenc';
4910
+ if (method == 'SAMPLE-AES') {
4911
+ encryptionScheme = 'cbcs';
4912
+ }
4913
+
4914
+ const uri = drmTag.getRequiredAttrValue('URI');
4915
+ const parsedData = shaka.net.DataUriPlugin.parseRaw(uri.split('?')[0]);
4916
+
4917
+ // The data encoded in the URI is a PSSH box to be used as init data.
4918
+ const pssh = shaka.util.BufferUtils.toUint8(parsedData.data);
4919
+ const drmInfo = shaka.util.ManifestParserUtils.createDrmInfo(
4920
+ 'com.huawei.wiseplay', encryptionScheme, [
4921
+ {initDataType: 'cenc', initData: pssh},
4922
+ ]);
4923
+
4924
+ const keyId = drmTag.getAttributeValue('KEYID');
4925
+ if (keyId) {
4926
+ const keyIdLowerCase = keyId.toLowerCase();
4927
+ // This value should begin with '0x':
4928
+ goog.asserts.assert(
4929
+ keyIdLowerCase.startsWith('0x'), 'Incorrect KEYID format!');
4930
+ // But the output should not contain the '0x':
4931
+ drmInfo.keyIds = new Set([keyIdLowerCase.substr(2)]);
4932
+ }
4874
4933
  return drmInfo;
4875
4934
  }
4876
4935
 
@@ -4879,10 +4938,10 @@ shaka.hls.HlsParser = class {
4879
4938
  *
4880
4939
  * @param {!shaka.hls.Tag} drmTag
4881
4940
  * @param {string} mimeType
4882
- * @param {function():!Array.<string>} getUris
4941
+ * @param {function(): !Array<string>} getUris
4883
4942
  * @param {?shaka.media.InitSegmentReference} initSegmentRef
4884
- * @param {?Map.<string, string>=} variables
4885
- * @return {!Promise.<?shaka.extern.DrmInfo>}
4943
+ * @param {?Map<string, string>=} variables
4944
+ * @return {!Promise<?shaka.extern.DrmInfo>}
4886
4945
  * @private
4887
4946
  */
4888
4947
  async identityDrmParser_(drmTag, mimeType, getUris, initSegmentRef,
@@ -4986,11 +5045,11 @@ shaka.hls.HlsParser = class {
4986
5045
  * @typedef {{
4987
5046
  * stream: !shaka.extern.Stream,
4988
5047
  * type: string,
4989
- * redirectUris: !Array.<string>,
4990
- * getUris: function():!Array.<string>,
5048
+ * redirectUris: !Array<string>,
5049
+ * getUris: function():!Array<string>,
4991
5050
  * minTimestamp: number,
4992
5051
  * maxTimestamp: number,
4993
- * mediaSequenceToStartTime: !Map.<number, number>,
5052
+ * mediaSequenceToStartTime: !Map<number, number>,
4994
5053
  * canSkipSegments: boolean,
4995
5054
  * canBlockReload: boolean,
4996
5055
  * hasEndList: boolean,
@@ -5007,15 +5066,15 @@ shaka.hls.HlsParser = class {
5007
5066
  * The Stream itself.
5008
5067
  * @property {string} type
5009
5068
  * The type value. Could be 'video', 'audio', 'text', or 'image'.
5010
- * @property {!Array.<string>} redirectUris
5069
+ * @property {!Array<string>} redirectUris
5011
5070
  * The redirect URIs.
5012
- * @property {function():!Array.<string>} getUris
5071
+ * @property {function():!Array<string>} getUris
5013
5072
  * The verbatim media playlist URIs, as it appeared in the master playlist.
5014
5073
  * @property {number} minTimestamp
5015
5074
  * The minimum timestamp found in the stream.
5016
5075
  * @property {number} maxTimestamp
5017
5076
  * The maximum timestamp found in the stream.
5018
- * @property {!Map.<number, number>} mediaSequenceToStartTime
5077
+ * @property {!Map<number, number>} mediaSequenceToStartTime
5019
5078
  * A map of media sequence numbers to media start times.
5020
5079
  * Only used for VOD content.
5021
5080
  * @property {boolean} canSkipSegments
@@ -5041,19 +5100,19 @@ shaka.hls.HlsParser.StreamInfo;
5041
5100
 
5042
5101
  /**
5043
5102
  * @typedef {{
5044
- * audio: !Array.<shaka.hls.HlsParser.StreamInfo>,
5045
- * video: !Array.<shaka.hls.HlsParser.StreamInfo>
5103
+ * audio: !Array<shaka.hls.HlsParser.StreamInfo>,
5104
+ * video: !Array<shaka.hls.HlsParser.StreamInfo>
5046
5105
  * }}
5047
5106
  *
5048
5107
  * @description Audio and video stream infos.
5049
- * @property {!Array.<shaka.hls.HlsParser.StreamInfo>} audio
5050
- * @property {!Array.<shaka.hls.HlsParser.StreamInfo>} video
5108
+ * @property {!Array<shaka.hls.HlsParser.StreamInfo>} audio
5109
+ * @property {!Array<shaka.hls.HlsParser.StreamInfo>} video
5051
5110
  */
5052
5111
  shaka.hls.HlsParser.StreamInfos;
5053
5112
 
5054
5113
 
5055
5114
  /**
5056
- * @const {!Object.<string, string>}
5115
+ * @const {!Object<string, string>}
5057
5116
  * @private
5058
5117
  */
5059
5118
  shaka.hls.HlsParser.RAW_FORMATS_TO_MIME_TYPES_ = {
@@ -5065,7 +5124,7 @@ shaka.hls.HlsParser.RAW_FORMATS_TO_MIME_TYPES_ = {
5065
5124
 
5066
5125
 
5067
5126
  /**
5068
- * @const {!Object.<string, string>}
5127
+ * @const {!Object<string, string>}
5069
5128
  * @private
5070
5129
  */
5071
5130
  shaka.hls.HlsParser.AUDIO_EXTENSIONS_TO_MIME_TYPES_ = {
@@ -5083,7 +5142,7 @@ shaka.hls.HlsParser.AUDIO_EXTENSIONS_TO_MIME_TYPES_ = {
5083
5142
 
5084
5143
 
5085
5144
  /**
5086
- * @const {!Object.<string, string>}
5145
+ * @const {!Object<string, string>}
5087
5146
  * @private
5088
5147
  */
5089
5148
  shaka.hls.HlsParser.VIDEO_EXTENSIONS_TO_MIME_TYPES_ = {
@@ -5100,7 +5159,7 @@ shaka.hls.HlsParser.VIDEO_EXTENSIONS_TO_MIME_TYPES_ = {
5100
5159
 
5101
5160
 
5102
5161
  /**
5103
- * @const {!Object.<string, string>}
5162
+ * @const {!Object<string, string>}
5104
5163
  * @private
5105
5164
  */
5106
5165
  shaka.hls.HlsParser.TEXT_EXTENSIONS_TO_MIME_TYPES_ = {
@@ -5116,7 +5175,7 @@ shaka.hls.HlsParser.TEXT_EXTENSIONS_TO_MIME_TYPES_ = {
5116
5175
 
5117
5176
 
5118
5177
  /**
5119
- * @const {!Object.<string, string>}
5178
+ * @const {!Object<string, string>}
5120
5179
  * @private
5121
5180
  */
5122
5181
  shaka.hls.HlsParser.IMAGE_EXTENSIONS_TO_MIME_TYPES_ = {
@@ -5129,7 +5188,7 @@ shaka.hls.HlsParser.IMAGE_EXTENSIONS_TO_MIME_TYPES_ = {
5129
5188
 
5130
5189
 
5131
5190
  /**
5132
- * @const {!Object.<string, !Object.<string, string>>}
5191
+ * @const {!Object<string, !Object<string, string>>}
5133
5192
  * @private
5134
5193
  */
5135
5194
  shaka.hls.HlsParser.EXTENSION_MAP_BY_CONTENT_TYPE_ = {
@@ -5143,7 +5202,7 @@ shaka.hls.HlsParser.EXTENSION_MAP_BY_CONTENT_TYPE_ = {
5143
5202
  /**
5144
5203
  * MIME types without init segment.
5145
5204
  *
5146
- * @const {!Set.<string>}
5205
+ * @const {!Set<string>}
5147
5206
  * @private
5148
5207
  */
5149
5208
  shaka.hls.HlsParser.MIME_TYPES_WITHOUT_INIT_SEGMENT_ = new Set([
@@ -5161,7 +5220,7 @@ shaka.hls.HlsParser.DrmParser_;
5161
5220
 
5162
5221
 
5163
5222
  /**
5164
- * @const {!Object.<string, shaka.hls.HlsParser.DrmParser_>}
5223
+ * @const {!Object<string, shaka.hls.HlsParser.DrmParser_>}
5165
5224
  * @private
5166
5225
  */
5167
5226
  shaka.hls.HlsParser.KEYFORMATS_TO_DRM_PARSERS_ = {
@@ -5171,6 +5230,8 @@ shaka.hls.HlsParser.KEYFORMATS_TO_DRM_PARSERS_ = {
5171
5230
  shaka.hls.HlsParser.widevineDrmParser_,
5172
5231
  'com.microsoft.playready':
5173
5232
  shaka.hls.HlsParser.playreadyDrmParser_,
5233
+ 'urn:uuid:3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c':
5234
+ shaka.hls.HlsParser.wiseplayDrmParser_,
5174
5235
  };
5175
5236
 
5176
5237