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
@@ -8,11 +8,12 @@ goog.provide('shaka.offline.Storage');
8
8
 
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.Player');
11
+ goog.require('shaka.drm.DrmEngine');
11
12
  goog.require('shaka.log');
12
- goog.require('shaka.media.DrmEngine');
13
13
  goog.require('shaka.media.ManifestParser');
14
14
  goog.require('shaka.media.SegmentIndex');
15
15
  goog.require('shaka.media.SegmentReference');
16
+ goog.require('shaka.media.SegmentUtils');
16
17
  goog.require('shaka.net.NetworkingEngine');
17
18
  goog.require('shaka.net.NetworkingUtils');
18
19
  goog.require('shaka.offline.DownloadInfo');
@@ -102,21 +103,21 @@ shaka.offline.Storage = class {
102
103
  * A list of open operations that are being performed by this instance of
103
104
  * |shaka.offline.Storage|.
104
105
  *
105
- * @private {!Array.<!Promise>}
106
+ * @private {!Array<!Promise>}
106
107
  */
107
108
  this.openOperations_ = [];
108
109
 
109
110
  /**
110
111
  * A list of open download managers that are being used to download things.
111
112
  *
112
- * @private {!Array.<!shaka.offline.DownloadManager>}
113
+ * @private {!Array<!shaka.offline.DownloadManager>}
113
114
  */
114
115
  this.openDownloadManagers_ = [];
115
116
 
116
117
  /**
117
118
  * Storage should only destroy the networking engine if it was initialized
118
119
  * without a player instance. Store this as a flag here to avoid including
119
- * the player object in the destoyer's closure.
120
+ * the player object in the destroyer's closure.
120
121
  *
121
122
  * @type {boolean}
122
123
  */
@@ -263,9 +264,9 @@ shaka.offline.Storage = class {
263
264
  * refer to {@link https://bit.ly/StructClone}
264
265
  * @param {?string=} mimeType
265
266
  * The mime type for the content |manifestUri| points to.
266
- * @param {?Array.<string>=} externalThumbnails
267
+ * @param {?Array<string>=} externalThumbnails
267
268
  * The external thumbnails to store along the main content.
268
- * @param {?Array.<shaka.extern.ExtraText>=} externalText
269
+ * @param {?Array<shaka.extern.ExtraText>=} externalText
269
270
  * The external text to store along the main content.
270
271
  * @return {!shaka.extern.IAbortableOperation.<shaka.extern.StoredContent>}
271
272
  * An AbortableOperation that resolves with a structure representing what
@@ -323,12 +324,12 @@ shaka.offline.Storage = class {
323
324
  *
324
325
  * @param {string} uri
325
326
  * @param {!Object} appMetadata
326
- * @param {!Array.<string>} externalThumbnails
327
- * @param {!Array.<shaka.extern.ExtraText>} externalText
328
- * @param {function():!Promise.<shaka.extern.ManifestParser>} getParser
327
+ * @param {!Array<string>} externalThumbnails
328
+ * @param {!Array<shaka.extern.ExtraText>} externalText
329
+ * @param {function(): !Promise<shaka.extern.ManifestParser>} getParser
329
330
  * @param {shaka.extern.PlayerConfiguration} config
330
331
  * @param {!shaka.offline.DownloadManager} downloader
331
- * @return {!Promise.<shaka.extern.StoredContent>}
332
+ * @return {!Promise<shaka.extern.StoredContent>}
332
333
  * @private
333
334
  */
334
335
  async store_(uri, appMetadata, externalThumbnails, externalText,
@@ -342,7 +343,7 @@ shaka.offline.Storage = class {
342
343
 
343
344
  /** @type {?shaka.extern.ManifestParser} */
344
345
  let parser = null;
345
- /** @type {?shaka.media.DrmEngine} */
346
+ /** @type {?shaka.drm.DrmEngine} */
346
347
  let drmEngine = null;
347
348
  /** @type {shaka.offline.StorageMuxer} */
348
349
  const muxer = new shaka.offline.StorageMuxer();
@@ -394,11 +395,38 @@ shaka.offline.Storage = class {
394
395
  this.ensureNotDestroyed_();
395
396
  }
396
397
 
398
+ shaka.drm.DrmEngine.configureClearKey(
399
+ config.drm.clearKeys, manifest.variants);
400
+
401
+ const clearKeyDataLicenseServerUri = manifest.variants.some((v) => {
402
+ if (v.audio) {
403
+ for (const drmInfo of v.audio.drmInfos) {
404
+ if (drmInfo.licenseServerUri.startsWith('data:')) {
405
+ return true;
406
+ }
407
+ }
408
+ }
409
+ if (v.video) {
410
+ for (const drmInfo of v.video.drmInfos) {
411
+ if (drmInfo.licenseServerUri.startsWith('data:')) {
412
+ return true;
413
+ }
414
+ }
415
+ }
416
+ return false;
417
+ });
418
+
419
+ let usePersistentLicense = config.offline.usePersistentLicense;
420
+ if (clearKeyDataLicenseServerUri) {
421
+ usePersistentLicense = false;
422
+ }
423
+
397
424
  // Create the DRM engine, and load the keys in the manifest.
398
425
  drmEngine = await this.createDrmEngine(
399
426
  manifest,
400
427
  (e) => { drmError = drmError || e; },
401
- config);
428
+ config,
429
+ usePersistentLicense);
402
430
 
403
431
  // We could have been asked to destroy ourselves while we were "away"
404
432
  // creating the drm engine.
@@ -407,7 +435,8 @@ shaka.offline.Storage = class {
407
435
  throw drmError;
408
436
  }
409
437
 
410
- await this.filterManifest_(manifest, drmEngine, config);
438
+ await this.filterManifest_(
439
+ manifest, drmEngine, config, usePersistentLicense);
411
440
 
412
441
  await muxer.init();
413
442
  this.ensureNotDestroyed_();
@@ -420,7 +449,8 @@ shaka.offline.Storage = class {
420
449
 
421
450
  goog.asserts.assert(drmEngine, 'drmEngine should be non-null here.');
422
451
  const {manifestDB, toDownload} = this.makeManifestDB_(
423
- drmEngine, manifest, uri, appMetadata, config, downloader);
452
+ drmEngine, manifest, uri, appMetadata, config, downloader,
453
+ usePersistentLicense);
424
454
 
425
455
  // Store the empty manifest, before downloading the segments.
426
456
  const ids = await activeHandle.cell.addManifests([manifestDB]);
@@ -434,10 +464,12 @@ shaka.offline.Storage = class {
434
464
  }
435
465
 
436
466
  await this.downloadSegments_(toDownload, manifestId, manifestDB,
437
- downloader, config, activeHandle.cell, manifest, drmEngine);
467
+ downloader, config, activeHandle.cell, manifest, drmEngine,
468
+ usePersistentLicense);
438
469
  this.ensureNotDestroyed_();
439
470
 
440
- this.setManifestDrmFields_(manifest, manifestDB, drmEngine, config);
471
+ this.setManifestDrmFields_(
472
+ manifest, manifestDB, drmEngine, usePersistentLicense);
441
473
  await activeHandle.cell.updateManifest(manifestId, manifestDB);
442
474
  this.ensureNotDestroyed_();
443
475
 
@@ -471,42 +503,57 @@ shaka.offline.Storage = class {
471
503
  * Download and then store the contents of each segment.
472
504
  * The promise this returns will wait for local downloads.
473
505
  *
474
- * @param {!Array.<!shaka.offline.DownloadInfo>} toDownload
506
+ * @param {!Array<!shaka.offline.DownloadInfo>} toDownload
475
507
  * @param {number} manifestId
476
508
  * @param {shaka.extern.ManifestDB} manifestDB
477
509
  * @param {!shaka.offline.DownloadManager} downloader
478
510
  * @param {shaka.extern.PlayerConfiguration} config
479
511
  * @param {shaka.extern.StorageCell} storage
480
512
  * @param {shaka.extern.Manifest} manifest
481
- * @param {!shaka.media.DrmEngine} drmEngine
513
+ * @param {!shaka.drm.DrmEngine} drmEngine
514
+ * @param {boolean} usePersistentLicense
482
515
  * @return {!Promise}
483
516
  * @private
484
517
  */
485
518
  async downloadSegments_(
486
519
  toDownload, manifestId, manifestDB, downloader, config, storage,
487
- manifest, drmEngine) {
520
+ manifest, drmEngine, usePersistentLicense) {
488
521
  let pendingManifestUpdates = {};
489
522
  let pendingDataSize = 0;
490
523
 
524
+ const ensureNotAbortedOrDestroyed = () => {
525
+ if (this.destroyer_.destroyed() || downloader.isAborted()) {
526
+ throw new shaka.util.Error(
527
+ shaka.util.Error.Severity.CRITICAL,
528
+ shaka.util.Error.Category.STORAGE,
529
+ shaka.util.Error.Code.OPERATION_ABORTED);
530
+ }
531
+ };
532
+
491
533
  /**
492
- * @param {!Array.<!shaka.offline.DownloadInfo>} toDownload
534
+ * @param {!Array<!shaka.offline.DownloadInfo>} toDownload
493
535
  * @param {boolean} updateDRM
494
536
  */
495
537
  const download = async (toDownload, updateDRM) => {
496
538
  for (const download of toDownload) {
539
+ ensureNotAbortedOrDestroyed();
497
540
  const request = download.makeSegmentRequest(config);
498
541
  const estimateId = download.estimateId;
499
542
  const isInitSegment = download.isInitSegment;
500
543
 
501
544
  const onDownloaded = async (data) => {
545
+ const ref = /** @type {!shaka.media.SegmentReference} */ (
546
+ download.ref);
547
+ const id = shaka.offline.DownloadInfo.idForSegmentRef(ref);
548
+ if (ref.aesKey) {
549
+ data = await shaka.media.SegmentUtils.aesDecrypt(
550
+ data, ref.aesKey, download.refPosition);
551
+ }
502
552
  // Store the data.
503
553
  const dataKeys = await storage.addSegments([{data}]);
504
- this.ensureNotDestroyed_();
554
+ ensureNotAbortedOrDestroyed();
505
555
 
506
556
  // Store the necessary update to the manifest, to be processed later.
507
- const ref = /** @type {!shaka.media.SegmentReference} */ (
508
- download.ref);
509
- const id = shaka.offline.DownloadInfo.idForSegmentRef(ref);
510
557
  pendingManifestUpdates[id] = dataKeys[0];
511
558
  pendingDataSize += data.byteLength;
512
559
  };
@@ -523,15 +570,16 @@ shaka.offline.Storage = class {
523
570
  }
524
571
  }
525
572
  await downloader.waitToFinish();
573
+ ensureNotAbortedOrDestroyed();
526
574
 
527
- if (updateDRM) {
575
+ if (updateDRM && !downloader.isAborted()) {
528
576
  // Re-store the manifest, to attach session IDs.
529
577
  // These were (maybe) discovered inside the downloader; we can only add
530
578
  // them now, at the end, since the manifestDB is in flux during the
531
579
  // process of downloading and storing, and assignSegmentsToManifest
532
580
  // does not know about the DRM engine.
533
- this.ensureNotDestroyed_();
534
- this.setManifestDrmFields_(manifest, manifestDB, drmEngine, config);
581
+ this.setManifestDrmFields_(
582
+ manifest, manifestDB, drmEngine, usePersistentLicense);
535
583
  await storage.updateManifest(manifestId, manifestDB);
536
584
  }
537
585
  };
@@ -545,7 +593,7 @@ shaka.offline.Storage = class {
545
593
  // init data from the init segments, download those first before
546
594
  // anything else.
547
595
  await download(toDownload.filter((info) => info.isInitSegment), true);
548
- this.ensureNotDestroyed_();
596
+ ensureNotAbortedOrDestroyed();
549
597
  toDownload = toDownload.filter((info) => !info.isInitSegment);
550
598
 
551
599
  // Copy these and reset them now, before calling await.
@@ -557,12 +605,12 @@ shaka.offline.Storage = class {
557
605
  await shaka.offline.Storage.assignSegmentsToManifest(
558
606
  storage, manifestId, manifestDB, manifestUpdates, dataSize,
559
607
  () => this.ensureNotDestroyed_());
560
- this.ensureNotDestroyed_();
608
+ ensureNotAbortedOrDestroyed();
561
609
  }
562
610
 
563
611
  if (!usingBgFetch) {
564
612
  await download(toDownload, false);
565
- this.ensureNotDestroyed_();
613
+ ensureNotAbortedOrDestroyed();
566
614
 
567
615
  // Copy these and reset them now, before calling await.
568
616
  const manifestUpdates = pendingManifestUpdates;
@@ -572,8 +620,8 @@ shaka.offline.Storage = class {
572
620
 
573
621
  await shaka.offline.Storage.assignSegmentsToManifest(
574
622
  storage, manifestId, manifestDB, manifestUpdates, dataSize,
575
- () => this.ensureNotDestroyed_());
576
- this.ensureNotDestroyed_();
623
+ () => ensureNotAbortedOrDestroyed());
624
+ ensureNotAbortedOrDestroyed();
577
625
 
578
626
  goog.asserts.assert(
579
627
  !manifestDB.isIncomplete, 'The manifest should be complete by now');
@@ -618,7 +666,7 @@ shaka.offline.Storage = class {
618
666
  * @param {shaka.extern.StorageCell} storage
619
667
  * @param {number} manifestId
620
668
  * @param {!shaka.extern.ManifestDB} manifestDB
621
- * @param {!Object.<string, number>} manifestUpdates
669
+ * @param {!Object<string, number>} manifestUpdates
622
670
  * @param {number} dataSizeUpdate
623
671
  * @param {function()} throwIfAbortedFn A function that should throw if the
624
672
  * download has been aborted.
@@ -694,12 +742,13 @@ shaka.offline.Storage = class {
694
742
  * streams that we want to store and can actually play.
695
743
  *
696
744
  * @param {shaka.extern.Manifest} manifest
697
- * @param {!shaka.media.DrmEngine} drmEngine
745
+ * @param {!shaka.drm.DrmEngine} drmEngine
698
746
  * @param {shaka.extern.PlayerConfiguration} config
747
+ * @param {boolean} usePersistentLicense
699
748
  * @return {!Promise}
700
749
  * @private
701
750
  */
702
- async filterManifest_(manifest, drmEngine, config) {
751
+ async filterManifest_(manifest, drmEngine, config, usePersistentLicense) {
703
752
  // Filter the manifest based on the restrictions given in the player
704
753
  // configuration.
705
754
  const maxHwRes = {width: Infinity, height: Infinity};
@@ -709,7 +758,7 @@ shaka.offline.Storage = class {
709
758
  // Filter the manifest based on what we know MediaCapabilities will be able
710
759
  // to play later (no point storing something we can't play).
711
760
  await shaka.util.StreamUtils.filterManifestByMediaCapabilities(
712
- drmEngine, manifest, config.offline.usePersistentLicense,
761
+ drmEngine, manifest, usePersistentLicense,
713
762
  config.drm.preferredKeySystems, config.drm.keySystemsMapping);
714
763
 
715
764
  // Gather all tracks.
@@ -772,11 +821,11 @@ shaka.offline.Storage = class {
772
821
  shaka.util.Error.Code.DOWNLOAD_SIZE_CALLBACK_ERROR);
773
822
  }
774
823
 
775
- /** @type {!Set.<number>} */
824
+ /** @type {!Set<number>} */
776
825
  const variantIds = new Set();
777
- /** @type {!Set.<number>} */
826
+ /** @type {!Set<number>} */
778
827
  const textIds = new Set();
779
- /** @type {!Set.<number>} */
828
+ /** @type {!Set<number>} */
780
829
  const imageIds = new Set();
781
830
 
782
831
  // Collect the IDs of the chosen tracks.
@@ -809,19 +858,21 @@ shaka.offline.Storage = class {
809
858
  * Create a download manager and download the manifest.
810
859
  * This also sets up download infos for each segment to be downloaded.
811
860
  *
812
- * @param {!shaka.media.DrmEngine} drmEngine
861
+ * @param {!shaka.drm.DrmEngine} drmEngine
813
862
  * @param {shaka.extern.Manifest} manifest
814
863
  * @param {string} uri
815
864
  * @param {!Object} metadata
816
865
  * @param {shaka.extern.PlayerConfiguration} config
817
866
  * @param {!shaka.offline.DownloadManager} downloader
867
+ * @param {boolean} usePersistentLicense
818
868
  * @return {{
819
869
  * manifestDB: shaka.extern.ManifestDB,
820
- * toDownload: !Array.<!shaka.offline.DownloadInfo>
870
+ * toDownload: !Array<!shaka.offline.DownloadInfo>
821
871
  * }}
822
872
  * @private
823
873
  */
824
- makeManifestDB_(drmEngine, manifest, uri, metadata, config, downloader) {
874
+ makeManifestDB_(drmEngine, manifest, uri, metadata, config, downloader,
875
+ usePersistentLicense) {
825
876
  const pendingContent = shaka.offline.StoredContentUtils.fromManifest(
826
877
  uri, manifest, /* size= */ 0, metadata);
827
878
  // In https://github.com/shaka-project/shaka-player/issues/2652, we found
@@ -837,7 +888,7 @@ shaka.offline.Storage = class {
837
888
  progressCallback(pendingContent, progress);
838
889
  };
839
890
  const onInitData = (initData, systemId) => {
840
- if (needsInitData && config.offline.usePersistentLicense &&
891
+ if (needsInitData && usePersistentLicense &&
841
892
  currentSystemId == systemId) {
842
893
  drmEngine.newInitData('cenc', initData);
843
894
  }
@@ -869,7 +920,6 @@ shaka.offline.Storage = class {
869
920
  downloader, estimator, drmEngine, manifest, config);
870
921
 
871
922
  const drmInfo = drmEngine.getDrmInfo();
872
- const usePersistentLicense = config.offline.usePersistentLicense;
873
923
  if (drmInfo && usePersistentLicense) {
874
924
  // Don't store init data, since we have stored sessions.
875
925
  drmInfo.initData = [];
@@ -925,19 +975,18 @@ shaka.offline.Storage = class {
925
975
  /**
926
976
  * @param {shaka.extern.Manifest} manifest
927
977
  * @param {shaka.extern.ManifestDB} manifestDB
928
- * @param {!shaka.media.DrmEngine} drmEngine
929
- * @param {shaka.extern.PlayerConfiguration} config
978
+ * @param {!shaka.drm.DrmEngine} drmEngine
979
+ * @param {boolean} usePersistentLicense
930
980
  * @private
931
981
  */
932
- setManifestDrmFields_(manifest, manifestDB, drmEngine, config) {
982
+ setManifestDrmFields_(manifest, manifestDB, drmEngine, usePersistentLicense) {
933
983
  manifestDB.expiration = drmEngine.getExpiration();
934
984
 
935
985
  const sessions = drmEngine.getSessionIds();
936
- manifestDB.sessionIds = config.offline.usePersistentLicense ?
937
- sessions : [];
986
+ manifestDB.sessionIds = usePersistentLicense ? sessions : [];
938
987
 
939
988
  if (this.getManifestIsEncrypted_(manifest) &&
940
- config.offline.usePersistentLicense && !sessions.length) {
989
+ usePersistentLicense && !sessions.length) {
941
990
  throw new shaka.util.Error(
942
991
  shaka.util.Error.Severity.CRITICAL,
943
992
  shaka.util.Error.Category.STORAGE,
@@ -1001,7 +1050,7 @@ shaka.offline.Storage = class {
1001
1050
  /**
1002
1051
  * @param {shaka.extern.ManifestDB} manifestDb
1003
1052
  * @param {boolean} isVideo
1004
- * @return {!Array.<MediaKeySystemMediaCapability>}
1053
+ * @return {!Array<MediaKeySystemMediaCapability>}
1005
1054
  * @private
1006
1055
  */
1007
1056
  static getCapabilities_(manifestDb, isVideo) {
@@ -1045,7 +1094,7 @@ shaka.offline.Storage = class {
1045
1094
  * @private
1046
1095
  */
1047
1096
  removeFromStorage_(storage, uri, manifest) {
1048
- /** @type {!Array.<number>} */
1097
+ /** @type {!Array<number>} */
1049
1098
  const segmentIds = shaka.offline.Storage.getAllSegmentIds_(manifest);
1050
1099
 
1051
1100
  // Count(segments) + Count(manifests)
@@ -1070,7 +1119,7 @@ shaka.offline.Storage = class {
1070
1119
  * Removes any EME sessions that were not successfully removed before. This
1071
1120
  * returns whether all the sessions were successfully removed.
1072
1121
  *
1073
- * @return {!Promise.<boolean>}
1122
+ * @return {!Promise<boolean>}
1074
1123
  * @export
1075
1124
  */
1076
1125
  removeEmeSessions() {
@@ -1078,7 +1127,7 @@ shaka.offline.Storage = class {
1078
1127
  }
1079
1128
 
1080
1129
  /**
1081
- * @return {!Promise.<boolean>}
1130
+ * @return {!Promise<boolean>}
1082
1131
  * @private
1083
1132
  */
1084
1133
  async removeEmeSessions_() {
@@ -1098,7 +1147,7 @@ shaka.offline.Storage = class {
1098
1147
  try {
1099
1148
  await muxer.init();
1100
1149
 
1101
- /** @type {!Array.<shaka.extern.EmeSessionStorageCell>} */
1150
+ /** @type {!Array<shaka.extern.EmeSessionStorageCell>} */
1102
1151
  const cells = [];
1103
1152
  muxer.forEachEmeSessionCell((c) => cells.push(c));
1104
1153
 
@@ -1126,7 +1175,7 @@ shaka.offline.Storage = class {
1126
1175
  /**
1127
1176
  * Lists all the stored content available.
1128
1177
  *
1129
- * @return {!Promise.<!Array.<shaka.extern.StoredContent>>} A Promise to an
1178
+ * @return {!Promise<!Array<shaka.extern.StoredContent>>} A Promise to an
1130
1179
  * array of structures representing all stored content. The "offlineUri"
1131
1180
  * member of the structure is the URI that should be given to Player.load()
1132
1181
  * to play this piece of content offline. The "appMetadata" member is the
@@ -1140,13 +1189,13 @@ shaka.offline.Storage = class {
1140
1189
  /**
1141
1190
  * See |shaka.offline.Storage.list| for details.
1142
1191
  *
1143
- * @return {!Promise.<!Array.<shaka.extern.StoredContent>>}
1192
+ * @return {!Promise<!Array<shaka.extern.StoredContent>>}
1144
1193
  * @private
1145
1194
  */
1146
1195
  async list_() {
1147
1196
  this.requireSupport_();
1148
1197
 
1149
- /** @type {!Array.<shaka.extern.StoredContent>} */
1198
+ /** @type {!Array<shaka.extern.StoredContent>} */
1150
1199
  const result = [];
1151
1200
 
1152
1201
  /** @type {!shaka.offline.StorageMuxer} */
@@ -1189,7 +1238,7 @@ shaka.offline.Storage = class {
1189
1238
  * @param {string} uri
1190
1239
  * @param {shaka.extern.ManifestParser} parser
1191
1240
  * @param {shaka.extern.PlayerConfiguration} config
1192
- * @return {!Promise.<shaka.extern.Manifest>}
1241
+ * @return {!Promise<shaka.extern.Manifest>}
1193
1242
  */
1194
1243
  async parseManifest(uri, parser, config) {
1195
1244
  let error = null;
@@ -1218,8 +1267,6 @@ shaka.offline.Storage = class {
1218
1267
  error = e;
1219
1268
  },
1220
1269
  isLowLatencyMode: () => false,
1221
- isAutoLowLatencyMode: () => false,
1222
- enableLowLatencyMode: () => {},
1223
1270
  updateDuration: () => {},
1224
1271
  newDrmInfo: (stream) => {},
1225
1272
  onManifestUpdated: () => {},
@@ -1265,7 +1312,7 @@ shaka.offline.Storage = class {
1265
1312
  /**
1266
1313
  * @param {string} uri
1267
1314
  * @param {shaka.extern.Manifest} manifest
1268
- * @return {!Promise.<shaka.extern.Stream>}
1315
+ * @return {!Promise<shaka.extern.Stream>}
1269
1316
  * @private
1270
1317
  */
1271
1318
  async createExternalImageStream_(uri, manifest) {
@@ -1448,7 +1495,7 @@ shaka.offline.Storage = class {
1448
1495
 
1449
1496
  /**
1450
1497
  * @param {string} uri
1451
- * @return {!Promise.<string>}
1498
+ * @return {!Promise<string>}
1452
1499
  * @private
1453
1500
  */
1454
1501
  async getTextMimetype_(uri) {
@@ -1456,7 +1503,6 @@ shaka.offline.Storage = class {
1456
1503
  try {
1457
1504
  goog.asserts.assert(
1458
1505
  this.networkingEngine_, 'Need networking engine.');
1459
- // eslint-disable-next-line require-atomic-updates
1460
1506
  mimeType = await shaka.net.NetworkingUtils.getMimeType(uri,
1461
1507
  this.networkingEngine_,
1462
1508
  this.config_.streaming.retryParameters);
@@ -1480,7 +1526,7 @@ shaka.offline.Storage = class {
1480
1526
  * @param {string} uri
1481
1527
  * @param {!shaka.net.NetworkingEngine} netEngine
1482
1528
  * @param {shaka.extern.RetryParameters} retryParams
1483
- * @return {!Promise.<BufferSource>}
1529
+ * @return {!Promise<BufferSource>}
1484
1530
  * @private
1485
1531
  */
1486
1532
  async getTextData_(uri, netEngine, retryParams) {
@@ -1500,15 +1546,16 @@ shaka.offline.Storage = class {
1500
1546
  * @param {shaka.extern.Manifest} manifest
1501
1547
  * @param {function(shaka.util.Error)} onError
1502
1548
  * @param {shaka.extern.PlayerConfiguration} config
1503
- * @return {!Promise.<!shaka.media.DrmEngine>}
1549
+ * @param {boolean} usePersistentLicense
1550
+ * @return {!Promise<!shaka.drm.DrmEngine>}
1504
1551
  */
1505
- async createDrmEngine(manifest, onError, config) {
1552
+ async createDrmEngine(manifest, onError, config, usePersistentLicense) {
1506
1553
  goog.asserts.assert(
1507
1554
  this.networkingEngine_,
1508
1555
  'Cannot call |createDrmEngine| after |destroy|');
1509
1556
 
1510
- /** @type {!shaka.media.DrmEngine} */
1511
- const drmEngine = new shaka.media.DrmEngine({
1557
+ /** @type {!shaka.drm.DrmEngine} */
1558
+ const drmEngine = new shaka.drm.DrmEngine({
1512
1559
  netEngine: this.networkingEngine_,
1513
1560
  onError: onError,
1514
1561
  onKeyStatus: () => {},
@@ -1517,8 +1564,7 @@ shaka.offline.Storage = class {
1517
1564
  });
1518
1565
 
1519
1566
  drmEngine.configure(config.drm);
1520
- await drmEngine.initForStorage(
1521
- manifest.variants, config.offline.usePersistentLicense);
1567
+ await drmEngine.initForStorage(manifest.variants, usePersistentLicense);
1522
1568
  await drmEngine.createOrLoad();
1523
1569
 
1524
1570
  return drmEngine;
@@ -1529,18 +1575,18 @@ shaka.offline.Storage = class {
1529
1575
  *
1530
1576
  * @param {!shaka.offline.DownloadManager} downloader
1531
1577
  * @param {shaka.offline.StreamBandwidthEstimator} estimator
1532
- * @param {!shaka.media.DrmEngine} drmEngine
1578
+ * @param {!shaka.drm.DrmEngine} drmEngine
1533
1579
  * @param {shaka.extern.Manifest} manifest
1534
1580
  * @param {shaka.extern.PlayerConfiguration} config
1535
1581
  * @return {{
1536
- * streams: !Array.<shaka.extern.StreamDB>,
1537
- * toDownload: !Array.<!shaka.offline.DownloadInfo>
1582
+ * streams: !Array<shaka.extern.StreamDB>,
1583
+ * toDownload: !Array<!shaka.offline.DownloadInfo>
1538
1584
  * }}
1539
1585
  * @private
1540
1586
  */
1541
1587
  createStreams_(downloader, estimator, drmEngine, manifest, config) {
1542
- // Download infos are stored based on their refId, to dedup them.
1543
- /** @type {!Map.<string, !shaka.offline.DownloadInfo>} */
1588
+ // Download infos are stored based on their refId, to deduplicate them.
1589
+ /** @type {!Map<string, !shaka.offline.DownloadInfo>} */
1544
1590
  const toDownload = new Map();
1545
1591
 
1546
1592
  // Find the streams we want to download and create a stream db instance
@@ -1580,7 +1626,7 @@ shaka.offline.Storage = class {
1580
1626
  * @param {shaka.extern.Manifest} manifest
1581
1627
  * @param {shaka.extern.Stream} stream
1582
1628
  * @param {shaka.extern.PlayerConfiguration} config
1583
- * @param {!Map.<string, !shaka.offline.DownloadInfo>} toDownload
1629
+ * @param {!Map<string, !shaka.offline.DownloadInfo>} toDownload
1584
1630
  * @return {shaka.extern.StreamDB}
1585
1631
  * @private
1586
1632
  */
@@ -1628,7 +1674,7 @@ shaka.offline.Storage = class {
1628
1674
  const numberOfParallelDownloads = config.offline.numberOfParallelDownloads;
1629
1675
  let groupId = numberOfParallelDownloads === 0 ? stream.id : 0;
1630
1676
 
1631
- shaka.offline.Storage.forEachSegment_(stream, startTime, (segment) => {
1677
+ shaka.offline.Storage.forEachSegment_(stream, startTime, (segment, pos) => {
1632
1678
  const pendingSegmentRefId =
1633
1679
  shaka.offline.DownloadInfo.idForSegmentRef(segment);
1634
1680
  let pendingInitSegmentRefId = undefined;
@@ -1642,7 +1688,8 @@ shaka.offline.Storage = class {
1642
1688
  segment,
1643
1689
  estimateId,
1644
1690
  groupId,
1645
- /* isInitSegment= */ false);
1691
+ /* isInitSegment= */ false,
1692
+ pos);
1646
1693
  toDownload.set(pendingSegmentRefId, segmentDownload);
1647
1694
  }
1648
1695
 
@@ -1657,7 +1704,8 @@ shaka.offline.Storage = class {
1657
1704
  segment.initSegmentReference,
1658
1705
  estimateId,
1659
1706
  groupId,
1660
- /* isInitSegment= */ true);
1707
+ /* isInitSegment= */ true,
1708
+ pos);
1661
1709
  toDownload.set(pendingInitSegmentRefId, initDownload);
1662
1710
  }
1663
1711
  }
@@ -1690,7 +1738,7 @@ shaka.offline.Storage = class {
1690
1738
  /**
1691
1739
  * @param {shaka.extern.Stream} stream
1692
1740
  * @param {number} startTime
1693
- * @param {function(!shaka.media.SegmentReference)} callback
1741
+ * @param {function(!shaka.media.SegmentReference, number)} callback
1694
1742
  * @private
1695
1743
  */
1696
1744
  static forEachSegment_(stream, startTime, callback) {
@@ -1704,7 +1752,7 @@ shaka.offline.Storage = class {
1704
1752
  /** @type {?shaka.media.SegmentReference} */
1705
1753
  let ref = stream.segmentIndex.get(i);
1706
1754
  while (ref) {
1707
- callback(ref);
1755
+ callback(ref, i);
1708
1756
  ref = stream.segmentIndex.get(++i);
1709
1757
  }
1710
1758
  }
@@ -1782,11 +1830,11 @@ shaka.offline.Storage = class {
1782
1830
 
1783
1831
  /**
1784
1832
  * @param {shaka.extern.ManifestDB} manifest
1785
- * @return {!Array.<number>}
1833
+ * @return {!Array<number>}
1786
1834
  * @private
1787
1835
  */
1788
1836
  static getAllSegmentIds_(manifest) {
1789
- /** @type {!Set.<number>} */
1837
+ /** @type {!Set<number>} */
1790
1838
  const ids = new Set();
1791
1839
 
1792
1840
  // Get every segment for every stream in the manifest.
@@ -1839,7 +1887,7 @@ shaka.offline.Storage = class {
1839
1887
 
1840
1888
  const sessionIdCell = muxer.getEmeSessionCell();
1841
1889
 
1842
- /** @type {!Array.<shaka.extern.EmeSessionDB>} */
1890
+ /** @type {!Array<shaka.extern.EmeSessionDB>} */
1843
1891
  const sessions = manifestDb.sessionIds.map((sessionId) => {
1844
1892
  return {
1845
1893
  sessionId: sessionId,
@@ -1869,11 +1917,11 @@ shaka.offline.Storage = class {
1869
1917
  * Get the set of all streams in |manifest|.
1870
1918
  *
1871
1919
  * @param {shaka.extern.Manifest} manifest
1872
- * @return {!Set.<shaka.extern.Stream>}
1920
+ * @return {!Set<shaka.extern.Stream>}
1873
1921
  * @private
1874
1922
  */
1875
1923
  static getAllStreamsFromManifest_(manifest) {
1876
- /** @type {!Set.<shaka.extern.Stream>} */
1924
+ /** @type {!Set<shaka.extern.Stream>} */
1877
1925
  const set = new Set();
1878
1926
 
1879
1927
  for (const variant of manifest.variants) {
@@ -1944,6 +1992,7 @@ shaka.offline.Storage.defaultSystemIds_ = new Map()
1944
1992
  .set('com.microsoft.playready.software',
1945
1993
  '9a04f07998404286ab92e65be0885f95')
1946
1994
  .set('com.microsoft.playready.hardware',
1947
- '9a04f07998404286ab92e65be0885f95');
1995
+ '9a04f07998404286ab92e65be0885f95')
1996
+ .set('com.huawei.wiseplay', '3d5e6d359b9a41e8b843dd3c6e72c42c');
1948
1997
 
1949
1998
  shaka.Player.registerSupportPlugin('offline', shaka.offline.Storage.support);