shaka-player 4.3.9 → 4.4.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 (321) hide show
  1. package/.github/workflows/build-and-test.yaml +11 -18
  2. package/.github/workflows/compute-incremental-coverage.py +3 -0
  3. package/.github/workflows/release-please.yaml +7 -0
  4. package/.github/workflows/selenium-lab-tests.yaml +45 -10
  5. package/AUTHORS +9 -0
  6. package/CHANGELOG.md +295 -190
  7. package/CONTRIBUTORS +8 -0
  8. package/LICENSE +32 -0
  9. package/README.md +63 -10
  10. package/demo/autoTemplate.txt +40 -5
  11. package/demo/close_button.js +11 -0
  12. package/demo/common/asset.js +13 -1
  13. package/demo/common/assets.js +112 -28
  14. package/demo/common/message_ids.js +25 -1
  15. package/demo/config.js +69 -10
  16. package/demo/customWarning.txt +2 -2
  17. package/demo/index.html +3 -1
  18. package/demo/locales/en.json +26 -2
  19. package/demo/locales/source.json +105 -9
  20. package/demo/main.js +57 -9
  21. package/demo/search.js +3 -1
  22. package/demo/service_worker.js +3 -0
  23. package/dist/controls.css +1 -1
  24. package/dist/controls.css.map +1 -1
  25. package/dist/demo.compiled.debug.js +132 -118
  26. package/dist/demo.compiled.debug.map +3 -3
  27. package/dist/demo.compiled.js +132 -118
  28. package/dist/demo.compiled.map +3 -3
  29. package/dist/deps.js +46 -28
  30. package/dist/locales.js +31 -31
  31. package/dist/receiver.compiled.debug.js +60 -52
  32. package/dist/receiver.compiled.debug.map +3 -3
  33. package/dist/receiver.compiled.js +60 -52
  34. package/dist/receiver.compiled.map +3 -3
  35. package/dist/shaka-player.compiled.d.ts +676 -391
  36. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  37. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  38. package/dist/shaka-player.compiled.debug.js +1046 -700
  39. package/dist/shaka-player.compiled.debug.map +4 -4
  40. package/dist/shaka-player.compiled.externs.js +1188 -616
  41. package/dist/shaka-player.compiled.js +1094 -933
  42. package/dist/shaka-player.compiled.map +4 -4
  43. package/dist/shaka-player.ui.d.ts +677 -392
  44. package/dist/shaka-player.ui.debug.d.ts +677 -392
  45. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  46. package/dist/shaka-player.ui.debug.js +1101 -738
  47. package/dist/shaka-player.ui.debug.map +4 -4
  48. package/dist/shaka-player.ui.externs.js +1023 -451
  49. package/dist/shaka-player.ui.js +1244 -1071
  50. package/dist/shaka-player.ui.map +4 -4
  51. package/docs/tutorials/ad_monetization.md +15 -1
  52. package/docs/tutorials/application-level-redirects.md +1 -1
  53. package/docs/tutorials/config.md +9 -5
  54. package/docs/tutorials/drm-config.md +61 -0
  55. package/docs/tutorials/fairplay.md +19 -4
  56. package/docs/tutorials/license-server-auth.md +4 -4
  57. package/docs/tutorials/license-wrapping.md +2 -2
  58. package/docs/tutorials/ui-customization.md +7 -3
  59. package/docs/tutorials/ui.md +7 -7
  60. package/docs/tutorials/upgrade.md +3 -0
  61. package/externs/ima.js +123 -2
  62. package/externs/isoboxer.js +217 -0
  63. package/externs/mediakeys.js +18 -0
  64. package/externs/mux.js +1 -105
  65. package/externs/pictureinpicture.js +48 -0
  66. package/externs/shaka/ads.js +61 -1
  67. package/externs/shaka/cea.js +110 -0
  68. package/externs/shaka/codecs.js +32 -0
  69. package/externs/shaka/manifest.js +101 -1
  70. package/externs/shaka/manifest_parser.js +0 -10
  71. package/externs/shaka/net.js +36 -7
  72. package/externs/shaka/offline.js +8 -1
  73. package/externs/shaka/player.js +220 -21
  74. package/externs/shaka/text.js +1 -382
  75. package/externs/shaka/transmuxer.js +59 -0
  76. package/karma.conf.js +15 -0
  77. package/lib/abr/simple_abr_manager.js +6 -3
  78. package/lib/ads/ad_manager.js +60 -2
  79. package/lib/ads/client_side_ad.js +86 -0
  80. package/lib/ads/client_side_ad_manager.js +93 -5
  81. package/lib/ads/server_side_ad.js +86 -0
  82. package/lib/ads/server_side_ad_manager.js +13 -0
  83. package/lib/cast/cast_utils.js +1 -0
  84. package/lib/cea/cea608_data_channel.js +24 -14
  85. package/lib/cea/cea608_memory.js +5 -2
  86. package/lib/cea/cea708_service.js +8 -9
  87. package/lib/cea/cea708_window.js +1 -2
  88. package/lib/cea/cea_decoder.js +23 -6
  89. package/lib/cea/cea_utils.js +25 -2
  90. package/lib/cea/dummy_caption_decoder.js +21 -0
  91. package/lib/cea/dummy_cea_parser.js +1 -3
  92. package/lib/cea/mp4_cea_parser.js +15 -10
  93. package/lib/cea/ts_cea_parser.js +69 -0
  94. package/lib/dash/content_protection.js +32 -2
  95. package/lib/dash/dash_parser.js +93 -31
  96. package/lib/dash/mpd_utils.js +6 -25
  97. package/lib/dash/segment_base.js +12 -14
  98. package/lib/dash/segment_list.js +10 -6
  99. package/lib/dash/segment_template.js +349 -32
  100. package/lib/dependencies/all.js +8 -0
  101. package/lib/hls/hls_classes.js +33 -8
  102. package/lib/hls/hls_parser.js +805 -191
  103. package/lib/hls/manifest_text_parser.js +4 -14
  104. package/lib/media/adaptation_set_criteria.js +43 -3
  105. package/lib/media/closed_caption_parser.js +74 -12
  106. package/lib/media/drm_engine.js +189 -49
  107. package/lib/media/gap_jumping_controller.js +1 -1
  108. package/lib/media/manifest_parser.js +34 -0
  109. package/lib/media/media_source_capabilities.js +10 -0
  110. package/lib/media/media_source_engine.js +475 -231
  111. package/lib/media/playhead.js +1 -1
  112. package/lib/media/presentation_timeline.js +62 -0
  113. package/lib/media/segment_index.js +50 -14
  114. package/lib/media/segment_prefetch.js +277 -0
  115. package/lib/media/segment_reference.js +70 -4
  116. package/lib/media/streaming_engine.js +258 -81
  117. package/lib/media/video_wrapper.js +15 -7
  118. package/lib/mss/content_protection.js +353 -0
  119. package/lib/mss/mss_parser.js +1081 -0
  120. package/lib/net/networking_engine.js +60 -10
  121. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  122. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  123. package/lib/offline/manifest_converter.js +6 -0
  124. package/lib/offline/storage.js +2 -4
  125. package/lib/player.js +309 -105
  126. package/lib/polyfill/media_capabilities.js +43 -3
  127. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  128. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  129. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  130. package/lib/text/cue.js +208 -130
  131. package/lib/text/lrc_text_parser.js +2 -2
  132. package/lib/text/mp4_vtt_parser.js +2 -2
  133. package/lib/text/sbv_text_parser.js +1 -1
  134. package/lib/text/simple_text_displayer.js +2 -1
  135. package/lib/text/srt_text_parser.js +9 -1
  136. package/lib/text/ssa_text_parser.js +2 -2
  137. package/lib/text/text_engine.js +3 -21
  138. package/lib/text/text_utils.js +71 -20
  139. package/lib/text/ui_text_displayer.js +14 -14
  140. package/lib/text/vtt_text_parser.js +22 -14
  141. package/lib/transmuxer/aac_transmuxer.js +224 -0
  142. package/lib/transmuxer/ac3.js +142 -0
  143. package/lib/transmuxer/ac3_transmuxer.js +212 -0
  144. package/lib/transmuxer/adts.js +232 -0
  145. package/lib/transmuxer/ec3.js +103 -0
  146. package/lib/transmuxer/ec3_transmuxer.js +212 -0
  147. package/lib/transmuxer/h264.js +324 -0
  148. package/lib/transmuxer/mp3_transmuxer.js +204 -0
  149. package/lib/transmuxer/mpeg_audio.js +196 -0
  150. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  151. package/lib/transmuxer/mss_transmuxer.js +389 -0
  152. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  153. package/lib/transmuxer/transmuxer_engine.js +161 -0
  154. package/lib/transmuxer/ts_transmuxer.js +738 -0
  155. package/lib/util/cmcd_manager.js +131 -71
  156. package/lib/util/error.js +62 -26
  157. package/lib/util/exp_golomb.js +220 -0
  158. package/lib/util/fairplay_utils.js +64 -13
  159. package/lib/util/id3_utils.js +56 -3
  160. package/lib/util/language_utils.js +11 -8
  161. package/lib/util/manifest_parser_utils.js +3 -0
  162. package/lib/util/mime_utils.js +44 -7
  163. package/lib/util/mp4_box_parsers.js +233 -5
  164. package/lib/util/mp4_generator.js +1381 -0
  165. package/lib/util/periods.js +40 -34
  166. package/lib/util/platform.js +25 -3
  167. package/lib/util/player_configuration.js +38 -1
  168. package/lib/util/stream_utils.js +138 -27
  169. package/lib/util/text_parser.js +1 -1
  170. package/lib/util/ts_parser.js +470 -47
  171. package/lib/util/xml_utils.js +16 -3
  172. package/maintained-branches.md +2 -2
  173. package/package.json +4 -2
  174. package/roadmap.md +21 -6
  175. package/shaka-player.uncompiled.js +18 -0
  176. package/test/abr/simple_abr_manager_unit.js +32 -4
  177. package/test/ads/ad_manager_unit.js +18 -2
  178. package/test/cast/cast_utils_unit.js +7 -2
  179. package/test/cea/cea608_memory_unit.js +24 -0
  180. package/test/cea/cea_decoder_unit.js +33 -0
  181. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  182. package/test/dash/dash_parser_live_unit.js +56 -13
  183. package/test/dash/dash_parser_manifest_unit.js +70 -2
  184. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  185. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  186. package/test/demo/demo_unit.js +5 -1
  187. package/test/hls/hls_live_unit.js +188 -28
  188. package/test/hls/hls_parser_unit.js +250 -109
  189. package/test/hls/manifest_text_parser_unit.js +18 -13
  190. package/test/media/adaptation_set_criteria_unit.js +46 -14
  191. package/test/media/adaptation_set_unit.js +2 -0
  192. package/test/media/drm_engine_integration.js +11 -8
  193. package/test/media/drm_engine_unit.js +220 -7
  194. package/test/media/media_source_engine_integration.js +122 -38
  195. package/test/media/media_source_engine_unit.js +133 -153
  196. package/test/media/playhead_unit.js +3 -0
  197. package/test/media/presentation_timeline_unit.js +51 -0
  198. package/test/media/segment_index_unit.js +52 -0
  199. package/test/media/segment_prefetch_unit.js +243 -0
  200. package/test/media/streaming_engine_integration.js +9 -3
  201. package/test/media/streaming_engine_unit.js +440 -59
  202. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  203. package/test/mss/mss_parser_unit.js +472 -0
  204. package/test/mss/mss_player_integration.js +123 -0
  205. package/test/offline/manifest_convert_unit.js +9 -0
  206. package/test/offline/storage_integration.js +6 -1
  207. package/test/player_integration.js +4 -1
  208. package/test/player_unit.js +386 -133
  209. package/test/polyfill/media_capabilities_unit.js +18 -0
  210. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  211. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  212. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  213. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  214. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  215. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  220. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  221. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  222. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  223. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  224. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  229. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  230. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  231. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  232. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  233. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  234. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  235. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  236. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  237. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  238. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  239. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  240. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  241. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  244. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  245. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  246. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  247. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  248. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  251. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  252. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  253. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  254. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  255. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  258. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  259. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  260. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  261. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  262. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  265. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  266. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  267. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  268. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  269. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  270. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  271. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  272. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  273. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  274. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  278. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  279. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  280. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  281. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  282. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  283. package/test/test/boot.js +7 -2
  284. package/test/test/util/fake_ad.js +99 -0
  285. package/test/test/util/fake_ad_manager.js +7 -1
  286. package/test/test/util/fake_networking_engine.js +41 -14
  287. package/test/test/util/fake_segment_prefetch.js +81 -0
  288. package/test/test/util/manifest_generator.js +19 -5
  289. package/test/test/util/mss_parser_util.js +115 -0
  290. package/test/test/util/offline_utils.js +1 -0
  291. package/test/test/util/simple_fakes.js +12 -3
  292. package/test/test/util/streaming_engine_util.js +14 -4
  293. package/test/test/util/ttml_utils.js +2 -2
  294. package/test/test/util/ui_utils.js +5 -1
  295. package/test/text/cue_integration.js +1 -1
  296. package/test/text/srt_text_parser_unit.js +78 -0
  297. package/test/text/text_engine_unit.js +17 -8
  298. package/test/text/ui_text_displayer_unit.js +4 -4
  299. package/test/text/vtt_text_parser_unit.js +59 -40
  300. package/test/text/web_vtt_generator_unit.js +9 -3
  301. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  302. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  303. package/test/transmuxer/transmuxer_integration.js +296 -0
  304. package/test/util/cmcd_manager_unit.js +162 -13
  305. package/test/util/language_utils_unit.js +9 -2
  306. package/test/util/mp4_box_parsers_unit.js +39 -4
  307. package/test/util/periods_unit.js +34 -26
  308. package/test/util/stream_utils_unit.js +60 -107
  309. package/ui/controls.js +19 -1
  310. package/ui/controls.less +1 -0
  311. package/ui/externs/ui.js +13 -3
  312. package/ui/language_utils.js +15 -0
  313. package/ui/less/thumbnails.less +26 -0
  314. package/ui/locales/oc.json +42 -0
  315. package/ui/pip_button.js +83 -2
  316. package/ui/range_element.js +15 -0
  317. package/ui/resolution_selection.js +9 -2
  318. package/ui/seek_bar.js +230 -1
  319. package/ui/ui.js +5 -0
  320. package/lib/cea/i_caption_decoder.js +0 -51
  321. package/lib/cea/i_cea_parser.js +0 -68
@@ -307,7 +307,7 @@ describe('ManifestTextParser', () => {
307
307
  new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'),
308
308
  ],
309
309
  segments: [
310
- new shaka.hls.Segment('https://test/test.mp4',
310
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4',
311
311
  [
312
312
  new shaka.hls.Tag(/* id= */ 2, 'EXTINF', [], '5.99467'),
313
313
  ]),
@@ -332,7 +332,7 @@ describe('ManifestTextParser', () => {
332
332
  new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'),
333
333
  ],
334
334
  segments: [
335
- new shaka.hls.Segment('https://test/test.mp4', [
335
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4', [
336
336
  new shaka.hls.Tag(
337
337
  /* id= */ 2,
338
338
  'EXTINF',
@@ -360,7 +360,7 @@ describe('ManifestTextParser', () => {
360
360
  new shaka.hls.Tag(/* id= */ 2, 'EXT-X-TARGETDURATION', [], '6'),
361
361
  ],
362
362
  segments: [
363
- new shaka.hls.Segment('https://test/test.mp4',
363
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4',
364
364
  [
365
365
  new shaka.hls.Tag(/* id= */ 1, 'EXT-X-KEY',
366
366
  [
@@ -393,7 +393,7 @@ describe('ManifestTextParser', () => {
393
393
  new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'),
394
394
  ],
395
395
  segments: [
396
- new shaka.hls.Segment('https://test/test.mp4',
396
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'test.mp4',
397
397
  [
398
398
  new shaka.hls.Tag(/* id= */ 2, 'EXTINF', [], '5.99467'),
399
399
  ]),
@@ -427,9 +427,9 @@ describe('ManifestTextParser', () => {
427
427
  new shaka.hls.Tag(/* id= */ 0, 'EXT-X-TARGETDURATION', [], '6'),
428
428
  ],
429
429
  segments: [
430
- new shaka.hls.Segment('https://test/uri',
430
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'uri',
431
431
  [new shaka.hls.Tag(2, 'EXTINF', [], '5')]),
432
- new shaka.hls.Segment('https://test/uri2',
432
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'uri2',
433
433
  [new shaka.hls.Tag(3, 'EXTINF', [], '4')]),
434
434
  ],
435
435
  },
@@ -449,9 +449,9 @@ describe('ManifestTextParser', () => {
449
449
  new shaka.hls.Tag(/* id= */ 4, 'EXT-X-ENDLIST', []),
450
450
  ],
451
451
  segments: [
452
- new shaka.hls.Segment('https://test/uri',
452
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'uri',
453
453
  [new shaka.hls.Tag(2, 'EXTINF', [], '5')]),
454
- new shaka.hls.Segment('https://test/uri2',
454
+ new shaka.hls.Segment('https://test/manifest.m3u8', 'uri2',
455
455
  [new shaka.hls.Tag(3, 'EXTINF', [], '4')]),
456
456
  ],
457
457
  },
@@ -508,20 +508,23 @@ describe('ManifestTextParser', () => {
508
508
  ],
509
509
  segments: [
510
510
  new shaka.hls.Segment(
511
- /* absoluteUri= */ 'https://test/uri',
511
+ /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8',
512
+ /* verbatimSegmentUri= */ 'uri',
512
513
  /* tags= */ [
513
514
  new shaka.hls.Tag(3, 'EXTINF', [], '5'),
514
515
  mapTag,
515
516
  ]),
516
517
  new shaka.hls.Segment(
517
- /* absoluteUri= */ 'https://test/uri2',
518
+ /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8',
519
+ /* verbatimSegmentUri= */ 'uri2',
518
520
  /* tags= */ [
519
521
  new shaka.hls.Tag(6, 'EXTINF', [], '2'),
520
522
  mapTag,
521
523
  ],
522
524
  /* partialSegments= */ partialSegments1),
523
525
  new shaka.hls.Segment(
524
- /* absoluteUri= */ '',
526
+ /* absoluteMediaPlaylistUri= */ '',
527
+ /* verbatimSegmentUri= */ '',
525
528
  /* tags= */ [mapTag],
526
529
  /* partialSegments= */ partialSegments2),
527
530
  ],
@@ -574,13 +577,15 @@ describe('ManifestTextParser', () => {
574
577
  ],
575
578
  segments: [
576
579
  new shaka.hls.Segment(
577
- /* absoluteUri= */ 'https://test/uri',
580
+ /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8',
581
+ /* verbatimSegmentUri= */ 'uri',
578
582
  /* tags= */ [
579
583
  new shaka.hls.Tag(3, 'EXTINF', [], '5'),
580
584
  mapTag,
581
585
  ]),
582
586
  new shaka.hls.Segment(
583
- /* absoluteUri= */ '',
587
+ /* absoluteMediaPlaylistUri= */ '',
588
+ /* verbatimSegmentUri= */ '',
584
589
  /* tags= */ [preloadMapTag],
585
590
  /* partialSegments= */ preloadSegment),
586
591
  ],
@@ -19,7 +19,7 @@ describe('AdaptationSetCriteria', () => {
19
19
  });
20
20
  });
21
21
 
22
- const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0);
22
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '');
23
23
  const set = builder.create(manifest.variants);
24
24
 
25
25
  checkSet(set, [
@@ -40,7 +40,7 @@ describe('AdaptationSetCriteria', () => {
40
40
  });
41
41
  });
42
42
 
43
- const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0);
43
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '');
44
44
  const set = builder.create(manifest.variants);
45
45
 
46
46
  checkSet(set, [
@@ -71,7 +71,8 @@ describe('AdaptationSetCriteria', () => {
71
71
  });
72
72
  });
73
73
 
74
- const builder = new shaka.media.PreferenceBasedCriteria('en', 'main', 0);
74
+ const builder = new shaka.media.PreferenceBasedCriteria(
75
+ 'en', 'main', 0, '');
75
76
  const set = builder.create(manifest.variants);
76
77
 
77
78
  checkSet(set, [
@@ -120,7 +121,7 @@ describe('AdaptationSetCriteria', () => {
120
121
  });
121
122
  });
122
123
 
123
- const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0);
124
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '');
124
125
  const set = builder.create(manifest.variants);
125
126
 
126
127
  // Which role is chosen is an implementation detail.
@@ -178,7 +179,7 @@ describe('AdaptationSetCriteria', () => {
178
179
  });
179
180
  });
180
181
 
181
- const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0);
182
+ const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0, '');
182
183
  const set = builder.create(manifest.variants);
183
184
 
184
185
  // Which role is chosen is an implementation detail.
@@ -214,7 +215,7 @@ describe('AdaptationSetCriteria', () => {
214
215
  });
215
216
  });
216
217
 
217
- const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0);
218
+ const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0, '');
218
219
  const set = builder.create(manifest.variants);
219
220
 
220
221
  // Which language is chosen is an implementation detail.
@@ -270,7 +271,8 @@ describe('AdaptationSetCriteria', () => {
270
271
  });
271
272
  });
272
273
 
273
- const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0);
274
+ const builder = new shaka.media.PreferenceBasedCriteria(
275
+ 'zh', '', 0, '');
274
276
  const set = builder.create(manifest.variants);
275
277
 
276
278
  // Which role is chosen is an implementation detail. Each role is
@@ -327,7 +329,8 @@ describe('AdaptationSetCriteria', () => {
327
329
  });
328
330
  });
329
331
 
330
- const builder = new shaka.media.PreferenceBasedCriteria('zh', '', 0);
332
+ const builder = new shaka.media.PreferenceBasedCriteria(
333
+ 'zh', '', 0, '');
331
334
  const set = builder.create(manifest.variants);
332
335
 
333
336
  checkSet(set, [
@@ -336,6 +339,34 @@ describe('AdaptationSetCriteria', () => {
336
339
  ]);
337
340
  });
338
341
 
342
+ it('chooses variants with preferred hdr level', () => {
343
+ const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
344
+ manifest.addVariant(1, (variant) => {
345
+ variant.addVideo(10, (stream) => {
346
+ stream.hdr = 'PQ';
347
+ });
348
+ });
349
+ manifest.addVariant(2, (variant) => {
350
+ variant.addVideo(20, (stream) => {
351
+ stream.hdr = 'SDR';
352
+ });
353
+ });
354
+ manifest.addVariant(3, (variant) => {
355
+ variant.addVideo(30, (stream) => {
356
+ stream.hdr = 'PQ';
357
+ });
358
+ });
359
+ });
360
+
361
+ const builder = new shaka.media.PreferenceBasedCriteria('', '', 0, 'PQ');
362
+ const set = builder.create(manifest.variants);
363
+
364
+ checkSet(set, [
365
+ manifest.variants[0],
366
+ manifest.variants[2],
367
+ ]);
368
+ });
369
+
339
370
  it('chooses variants with preferred audio channels count', () => {
340
371
  const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
341
372
  manifest.addVariant(1, (variant) => {
@@ -355,7 +386,7 @@ describe('AdaptationSetCriteria', () => {
355
386
  });
356
387
  });
357
388
 
358
- const builder = new shaka.media.PreferenceBasedCriteria('', '', 2);
389
+ const builder = new shaka.media.PreferenceBasedCriteria('', '', 2, '');
359
390
  const set = builder.create(manifest.variants);
360
391
 
361
392
  checkSet(set, [
@@ -384,7 +415,8 @@ describe('AdaptationSetCriteria', () => {
384
415
  });
385
416
  });
386
417
 
387
- const builder = new shaka.media.PreferenceBasedCriteria('', '', 6);
418
+ const builder =
419
+ new shaka.media.PreferenceBasedCriteria('', '', 6, '');
388
420
  const set = builder.create(manifest.variants);
389
421
 
390
422
  checkSet(set, [
@@ -413,7 +445,7 @@ describe('AdaptationSetCriteria', () => {
413
445
  });
414
446
  });
415
447
 
416
- const builder = new shaka.media.PreferenceBasedCriteria('', '', 2);
448
+ const builder = new shaka.media.PreferenceBasedCriteria('', '', 2, '');
417
449
  const set = builder.create(manifest.variants);
418
450
 
419
451
  checkSet(set, [
@@ -441,8 +473,8 @@ describe('AdaptationSetCriteria', () => {
441
473
  });
442
474
  });
443
475
 
444
- const builder =
445
- new shaka.media.PreferenceBasedCriteria('', '', 0, 'preferredLabel');
476
+ const builder = new shaka.media.PreferenceBasedCriteria(
477
+ '', '', 0, '', 'preferredLabel');
446
478
  const set = builder.create(manifest.variants);
447
479
 
448
480
  checkSet(set, [
@@ -484,7 +516,7 @@ describe('AdaptationSetCriteria', () => {
484
516
  });
485
517
 
486
518
  const builder = new shaka.media.PreferenceBasedCriteria(
487
- 'zh', '', 0, 'preferredLabel');
519
+ 'zh', '', 0, '', 'preferredLabel');
488
520
  const set = builder.create(manifest.variants);
489
521
 
490
522
  checkSet(set, [
@@ -211,6 +211,7 @@ describe('AdaptationSet', () => {
211
211
  keyIds: new Set(),
212
212
  label: null,
213
213
  language: '',
214
+ originalLanguage: null,
214
215
  mimeType: mimeType,
215
216
  originalId: String(id),
216
217
  primary: false,
@@ -218,6 +219,7 @@ describe('AdaptationSet', () => {
218
219
  forced: false,
219
220
  trickModeVideo: null,
220
221
  type: '',
222
+ accessibilityPurpose: null,
221
223
  external: false,
222
224
  };
223
225
  }
@@ -49,6 +49,9 @@ describe('DrmEngine', () => {
49
49
  /** @type {!ArrayBuffer} */
50
50
  let audioSegment;
51
51
 
52
+ /** @type {shaka.extern.Stream} */
53
+ const fakeStream = shaka.test.StreamingEngineUtil.createMockVideoStream(1);
54
+
52
55
  beforeAll(async () => {
53
56
  video = shaka.test.UiUtils.createVideoElement();
54
57
  document.body.appendChild(video);
@@ -198,10 +201,10 @@ describe('DrmEngine', () => {
198
201
  await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
199
202
  await drmEngine.attach(video);
200
203
  await mediaSourceEngine.appendBuffer(
201
- ContentType.VIDEO, videoInitSegment, null,
204
+ ContentType.VIDEO, videoInitSegment, null, fakeStream,
202
205
  /* hasClosedCaptions= */ false);
203
206
  await mediaSourceEngine.appendBuffer(
204
- ContentType.AUDIO, audioInitSegment, null,
207
+ ContentType.AUDIO, audioInitSegment, null, fakeStream,
205
208
  /* hasClosedCaptions= */ false);
206
209
  await encryptedEventSeen;
207
210
  // With PlayReady, a persistent license policy can cause a different
@@ -237,10 +240,10 @@ describe('DrmEngine', () => {
237
240
  const reference = dummyReference(0, 10);
238
241
 
239
242
  await mediaSourceEngine.appendBuffer(
240
- ContentType.VIDEO, videoSegment, reference,
243
+ ContentType.VIDEO, videoSegment, reference, fakeStream,
241
244
  /* hasClosedCaptions= */ false);
242
245
  await mediaSourceEngine.appendBuffer(
243
- ContentType.AUDIO, audioSegment, reference,
246
+ ContentType.AUDIO, audioSegment, reference, fakeStream,
244
247
  /* hasClosedCaptions= */ false);
245
248
 
246
249
  expect(video.buffered.end(0)).toBeGreaterThan(0);
@@ -296,10 +299,10 @@ describe('DrmEngine', () => {
296
299
  await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
297
300
  await drmEngine.attach(video);
298
301
  await mediaSourceEngine.appendBuffer(
299
- ContentType.VIDEO, videoInitSegment, null,
302
+ ContentType.VIDEO, videoInitSegment, null, fakeStream,
300
303
  /* hasClosedCaptions= */ false);
301
304
  await mediaSourceEngine.appendBuffer(
302
- ContentType.AUDIO, audioInitSegment, null,
305
+ ContentType.AUDIO, audioInitSegment, null, fakeStream,
303
306
  /* hasClosedCaptions= */ false);
304
307
  await encryptedEventSeen;
305
308
 
@@ -320,10 +323,10 @@ describe('DrmEngine', () => {
320
323
  const reference = dummyReference(0, 10);
321
324
 
322
325
  await mediaSourceEngine.appendBuffer(
323
- ContentType.VIDEO, videoSegment, reference,
326
+ ContentType.VIDEO, videoSegment, reference, fakeStream,
324
327
  /* hasClosedCaptions= */ false);
325
328
  await mediaSourceEngine.appendBuffer(
326
- ContentType.AUDIO, audioSegment, reference,
329
+ ContentType.AUDIO, audioSegment, reference, fakeStream,
327
330
  /* hasClosedCaptions= */ false);
328
331
 
329
332
  expect(video.buffered.end(0)).toBeGreaterThan(0);
@@ -214,7 +214,9 @@ describe('DrmEngine', () => {
214
214
  const variants = manifest.variants;
215
215
  await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
216
216
 
217
- expect(variants[0].decodingInfos.length).toBe(2);
217
+ // should be only one variant, as preferredKeySystems is propagated
218
+ // to getDecodingInfos
219
+ expect(variants[0].decodingInfos.length).toBe(1);
218
220
  expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
219
221
  .toBe('drm.def');
220
222
  });
@@ -713,15 +715,27 @@ describe('DrmEngine', () => {
713
715
  });
714
716
 
715
717
  it('maps TS MIME types through the transmuxer', async () => {
716
- const originalIsSupported = shaka.media.Transmuxer.isSupported;
718
+ const originalIsSupported =
719
+ shaka.transmuxer.TransmuxerEngine.isSupported;
720
+ const originalConvertCodecs =
721
+ shaka.transmuxer.TransmuxerEngine.convertCodecs;
717
722
 
718
723
  try {
719
724
  // Mock out isSupported on Transmuxer so that we don't have to care
720
725
  // about what MediaSource supports under that. All we really care about
721
726
  // is the translation of MIME types.
722
- shaka.media.Transmuxer.isSupported = (mimeType, contentType) => {
723
- return mimeType.startsWith('video/mp2t');
724
- };
727
+ shaka.transmuxer.TransmuxerEngine.isSupported =
728
+ (mimeType, contentType) => {
729
+ return mimeType.startsWith('video/mp2t');
730
+ };
731
+ shaka.transmuxer.TransmuxerEngine.convertCodecs =
732
+ (contentType, mimeType) => {
733
+ let newMimeType = mimeType.replace('mp2t', 'mp4');
734
+ if (contentType == 'audio') {
735
+ newMimeType = newMimeType.replace('video', 'audio');
736
+ }
737
+ return newMimeType;
738
+ };
725
739
 
726
740
  // The default mock for this is so unrealistic, some of our test
727
741
  // conditions would always fail. Make it realistic enough for this
@@ -758,7 +772,9 @@ describe('DrmEngine', () => {
758
772
  expect(drmEngine.supportsVariant(variants[0])).toBeTruthy();
759
773
  } finally {
760
774
  // Restore the mock.
761
- shaka.media.Transmuxer.isSupported = originalIsSupported;
775
+ shaka.transmuxer.TransmuxerEngine.isSupported = originalIsSupported;
776
+ shaka.transmuxer.TransmuxerEngine.convertCodecs =
777
+ originalConvertCodecs;
762
778
  }
763
779
  });
764
780
  }); // describe('init')
@@ -1093,6 +1109,178 @@ describe('DrmEngine', () => {
1093
1109
  shaka.util.Error.Code.FAILED_TO_GENERATE_LICENSE_REQUEST,
1094
1110
  message, nativeError, undefined));
1095
1111
  });
1112
+
1113
+ it('should throw a OFFLINE_SESSION_REMOVED error', async () => {
1114
+ // Given persistent session is not available
1115
+ session1.load.and.returnValue(false);
1116
+
1117
+ onErrorSpy.and.stub();
1118
+
1119
+ await drmEngine.initForPlayback(
1120
+ manifest.variants, ['persistent-session-id']);
1121
+ await drmEngine.attach(mockVideo);
1122
+
1123
+ expect(drmEngine.initialized()).toBe(true);
1124
+
1125
+ await Util.shortDelay();
1126
+
1127
+ expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(1);
1128
+ expect(mockMediaKeys.createSession)
1129
+ .toHaveBeenCalledWith('persistent-license');
1130
+ expect(session1.load).toHaveBeenCalledWith('persistent-session-id');
1131
+
1132
+ expect(onErrorSpy).toHaveBeenCalled();
1133
+ const error = onErrorSpy.calls.argsFor(0)[0];
1134
+ shaka.test.Util.expectToEqualError(error, new shaka.util.Error(
1135
+ shaka.util.Error.Severity.CRITICAL,
1136
+ shaka.util.Error.Category.DRM,
1137
+ shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
1138
+ });
1139
+
1140
+ it('uses persistent session ids when available', async () => {
1141
+ const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
1142
+
1143
+ const keyId1 = makeKeyId(1);
1144
+ const keyId2 = makeKeyId(2);
1145
+
1146
+ /** @type {!Uint8Array} */
1147
+ const initData1 = new Uint8Array(5);
1148
+
1149
+ // Key IDs in manifest
1150
+ tweakDrmInfos((drmInfos) => {
1151
+ drmInfos[0].keyIds = new Set([
1152
+ Uint8ArrayUtils.toHex(keyId1), Uint8ArrayUtils.toHex(keyId2),
1153
+ ]);
1154
+ drmInfos[0].initData = [
1155
+ {initData: initData1, initDataType: 'cenc', keyId: null},
1156
+ ];
1157
+ });
1158
+
1159
+ // Given persistent session is available
1160
+ session1.load.and.returnValue(true);
1161
+
1162
+ config.persistentSessionOnlinePlayback = true;
1163
+ config.persistentSessionsMetadata = [{
1164
+ sessionId: 'persistent-session-id',
1165
+ initData: initData1,
1166
+ initDataType: 'cenc'}];
1167
+
1168
+ drmEngine.configure(config);
1169
+
1170
+ await initAndAttach();
1171
+
1172
+ await Util.shortDelay();
1173
+
1174
+ session1.keyStatuses.forEach.and.callFake((callback) => {
1175
+ callback(keyId1, 'usable');
1176
+ callback(keyId2, 'usable');
1177
+ });
1178
+
1179
+ session1.on['keystatuseschange']({target: session1});
1180
+
1181
+ expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(1);
1182
+ expect(mockMediaKeys.createSession)
1183
+ .toHaveBeenCalledWith('persistent-license');
1184
+ expect(session1.load).toHaveBeenCalledWith('persistent-session-id');
1185
+
1186
+ expect(session2.generateRequest).not.toHaveBeenCalled();
1187
+ });
1188
+
1189
+ it(
1190
+ 'tries persistent session ids before requesting a license',
1191
+ async () => {
1192
+ const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
1193
+
1194
+ const keyId1 = makeKeyId(1);
1195
+
1196
+ /** @type {!Uint8Array} */
1197
+ const initData1 = new Uint8Array(5);
1198
+
1199
+ // Key IDs in manifest
1200
+ tweakDrmInfos((drmInfos) => {
1201
+ drmInfos[0].keyIds = new Set([
1202
+ Uint8ArrayUtils.toHex(keyId1),
1203
+ ]);
1204
+ drmInfos[0].sessionType = 'temporary';
1205
+ drmInfos[0].initData = [
1206
+ {initData: initData1, initDataType: 'cenc', keyId: null},
1207
+ ];
1208
+ });
1209
+
1210
+ // Given persistent sessions aren't available
1211
+ session1.load.and.returnValue(Promise.resolve(false));
1212
+ session2.load.and.returnValue(
1213
+ Promise.reject(new Error('This should be a recoverable error')));
1214
+
1215
+ manifest.offlineSessionIds = ['persistent-session-id-1'];
1216
+
1217
+ config.persistentSessionsMetadata = [{
1218
+ sessionId: 'persistent-session-id-2',
1219
+ initData: initData1,
1220
+ initDataType: 'cenc'}];
1221
+ config.persistentSessionOnlinePlayback = true;
1222
+
1223
+ drmEngine.configure(config);
1224
+
1225
+ onErrorSpy.and.stub();
1226
+
1227
+ await initAndAttach();
1228
+
1229
+ await Util.shortDelay();
1230
+
1231
+ shaka.test.Util.expectToEqualError(
1232
+ onErrorSpy.calls.argsFor(0)[0],
1233
+ new shaka.util.Error(
1234
+ shaka.util.Error.Severity.RECOVERABLE,
1235
+ shaka.util.Error.Category.DRM,
1236
+ shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
1237
+
1238
+ shaka.test.Util.expectToEqualError(
1239
+ onErrorSpy.calls.argsFor(1)[0],
1240
+ new shaka.util.Error(
1241
+ shaka.util.Error.Severity.RECOVERABLE,
1242
+ shaka.util.Error.Category.DRM,
1243
+ shaka.util.Error.Code.FAILED_TO_CREATE_SESSION,
1244
+ 'This should be a recoverable error'));
1245
+
1246
+ // We need to go through the whole license request / update,
1247
+ // otherwise the DrmEngine will be destroyed while waiting for
1248
+ // sessions to be marked as loaded, throwing an unhandled exception
1249
+ const operation = shaka.util.AbortableOperation.completed(
1250
+ new Uint8Array(0));
1251
+ fakeNetEngine.request.and.returnValue(operation);
1252
+
1253
+ await Util.shortDelay();
1254
+
1255
+ session3.on['message']({
1256
+ target: session3,
1257
+ message: new Uint8Array(0),
1258
+ messageType: 'license-request'});
1259
+
1260
+ session3.keyStatuses.forEach.and.callFake((callback) => {
1261
+ callback(keyId1, 'usable');
1262
+ });
1263
+
1264
+ session3.on['keystatuseschange']({target: session3});
1265
+
1266
+ await Util.shortDelay();
1267
+
1268
+ expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(3);
1269
+ expect(mockMediaKeys.createSession)
1270
+ .toHaveBeenCalledWith('persistent-license');
1271
+ expect(session1.load)
1272
+ .toHaveBeenCalledWith('persistent-session-id-1');
1273
+
1274
+ expect(mockMediaKeys.createSession)
1275
+ .toHaveBeenCalledWith('persistent-license');
1276
+ expect(session2.load)
1277
+ .toHaveBeenCalledWith('persistent-session-id-2');
1278
+
1279
+ expect(mockMediaKeys.createSession)
1280
+ .toHaveBeenCalledWith('temporary');
1281
+ expect(session3.generateRequest)
1282
+ .toHaveBeenCalledWith('cenc', initData1);
1283
+ });
1096
1284
  }); // describe('attach')
1097
1285
 
1098
1286
  describe('events', () => {
@@ -1512,7 +1700,7 @@ describe('DrmEngine', () => {
1512
1700
 
1513
1701
  // Not mocked. Run data through real data URI parser to ensure that it is
1514
1702
  // correctly formatted.
1515
- fakeNetEngine.request.and.callFake((type, request) => {
1703
+ fakeNetEngine.request.and.callFake((type, request, context) => {
1516
1704
  const requestType = shaka.net.NetworkingEngine.RequestType.LICENSE;
1517
1705
 
1518
1706
  // A dummy progress callback.
@@ -1630,6 +1818,31 @@ describe('DrmEngine', () => {
1630
1818
  expect(session2.remove).toHaveBeenCalled();
1631
1819
  });
1632
1820
 
1821
+ it(
1822
+ // eslint-disable-next-line max-len
1823
+ 'tears down & does not remove active persistent sessions based on configuration flag',
1824
+ async () => {
1825
+ config.advanced['drm.abc'] = createAdvancedConfig(null);
1826
+ config.advanced['drm.abc'].sessionType = 'persistent-license';
1827
+ config.persistentSessionOnlinePlayback = true;
1828
+
1829
+ drmEngine.configure(config);
1830
+
1831
+ await initAndAttach();
1832
+ await sendEncryptedEvent('cenc', new Uint8Array(2));
1833
+
1834
+ const message = new Uint8Array(0);
1835
+ session1.on['message']({target: session1, message: message});
1836
+ session1.update.and.returnValue(Promise.resolve());
1837
+
1838
+ await shaka.test.Util.shortDelay();
1839
+ mockVideo.setMediaKeys.calls.reset();
1840
+ await drmEngine.destroy();
1841
+
1842
+ expect(session1.close).toHaveBeenCalled();
1843
+ expect(session1.remove).not.toHaveBeenCalled();
1844
+ });
1845
+
1633
1846
  it('swallows errors when closing sessions', async () => {
1634
1847
  await initAndAttach();
1635
1848
  await sendEncryptedEvent('webm');