shaka-player 4.3.10 → 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 (316) hide show
  1. package/.github/workflows/release-please.yaml +7 -0
  2. package/AUTHORS +9 -0
  3. package/CHANGELOG.md +295 -200
  4. package/CONTRIBUTORS +8 -0
  5. package/LICENSE +32 -0
  6. package/README.md +63 -10
  7. package/demo/autoTemplate.txt +40 -5
  8. package/demo/close_button.js +11 -0
  9. package/demo/common/asset.js +13 -1
  10. package/demo/common/assets.js +53 -3
  11. package/demo/common/message_ids.js +25 -1
  12. package/demo/config.js +69 -10
  13. package/demo/customWarning.txt +2 -2
  14. package/demo/index.html +3 -1
  15. package/demo/locales/en.json +26 -2
  16. package/demo/locales/source.json +105 -9
  17. package/demo/main.js +52 -9
  18. package/demo/search.js +3 -1
  19. package/demo/service_worker.js +3 -0
  20. package/dist/controls.css +1 -1
  21. package/dist/controls.css.map +1 -1
  22. package/dist/demo.compiled.debug.js +124 -112
  23. package/dist/demo.compiled.debug.map +3 -3
  24. package/dist/demo.compiled.js +124 -112
  25. package/dist/demo.compiled.map +3 -3
  26. package/dist/deps.js +46 -28
  27. package/dist/locales.js +28 -28
  28. package/dist/receiver.compiled.debug.js +52 -46
  29. package/dist/receiver.compiled.debug.map +3 -3
  30. package/dist/receiver.compiled.js +52 -46
  31. package/dist/receiver.compiled.map +3 -3
  32. package/dist/shaka-player.compiled.d.ts +676 -391
  33. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  34. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  35. package/dist/shaka-player.compiled.debug.js +1045 -700
  36. package/dist/shaka-player.compiled.debug.map +4 -4
  37. package/dist/shaka-player.compiled.externs.js +1188 -616
  38. package/dist/shaka-player.compiled.js +1094 -933
  39. package/dist/shaka-player.compiled.map +4 -4
  40. package/dist/shaka-player.ui.d.ts +677 -392
  41. package/dist/shaka-player.ui.debug.d.ts +677 -392
  42. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  43. package/dist/shaka-player.ui.debug.js +1100 -739
  44. package/dist/shaka-player.ui.debug.map +4 -4
  45. package/dist/shaka-player.ui.externs.js +1023 -451
  46. package/dist/shaka-player.ui.js +1244 -1071
  47. package/dist/shaka-player.ui.map +4 -4
  48. package/docs/tutorials/ad_monetization.md +15 -1
  49. package/docs/tutorials/application-level-redirects.md +1 -1
  50. package/docs/tutorials/config.md +9 -5
  51. package/docs/tutorials/drm-config.md +61 -0
  52. package/docs/tutorials/fairplay.md +19 -4
  53. package/docs/tutorials/license-server-auth.md +4 -4
  54. package/docs/tutorials/license-wrapping.md +2 -2
  55. package/docs/tutorials/ui-customization.md +7 -3
  56. package/docs/tutorials/ui.md +7 -7
  57. package/docs/tutorials/upgrade.md +3 -0
  58. package/externs/ima.js +123 -2
  59. package/externs/isoboxer.js +217 -0
  60. package/externs/mediakeys.js +18 -0
  61. package/externs/mux.js +1 -105
  62. package/externs/pictureinpicture.js +48 -0
  63. package/externs/shaka/ads.js +61 -1
  64. package/externs/shaka/cea.js +110 -0
  65. package/externs/shaka/codecs.js +32 -0
  66. package/externs/shaka/manifest.js +101 -1
  67. package/externs/shaka/manifest_parser.js +0 -10
  68. package/externs/shaka/net.js +36 -7
  69. package/externs/shaka/offline.js +8 -1
  70. package/externs/shaka/player.js +220 -21
  71. package/externs/shaka/text.js +1 -382
  72. package/externs/shaka/transmuxer.js +59 -0
  73. package/karma.conf.js +13 -0
  74. package/lib/abr/simple_abr_manager.js +6 -3
  75. package/lib/ads/ad_manager.js +60 -2
  76. package/lib/ads/client_side_ad.js +86 -0
  77. package/lib/ads/client_side_ad_manager.js +79 -3
  78. package/lib/ads/server_side_ad.js +86 -0
  79. package/lib/ads/server_side_ad_manager.js +13 -0
  80. package/lib/cast/cast_utils.js +1 -0
  81. package/lib/cea/cea608_data_channel.js +24 -14
  82. package/lib/cea/cea608_memory.js +5 -2
  83. package/lib/cea/cea708_service.js +8 -9
  84. package/lib/cea/cea708_window.js +1 -2
  85. package/lib/cea/cea_decoder.js +23 -6
  86. package/lib/cea/cea_utils.js +25 -2
  87. package/lib/cea/dummy_caption_decoder.js +21 -0
  88. package/lib/cea/dummy_cea_parser.js +1 -3
  89. package/lib/cea/mp4_cea_parser.js +15 -10
  90. package/lib/cea/ts_cea_parser.js +69 -0
  91. package/lib/dash/content_protection.js +32 -2
  92. package/lib/dash/dash_parser.js +93 -31
  93. package/lib/dash/mpd_utils.js +6 -25
  94. package/lib/dash/segment_base.js +12 -14
  95. package/lib/dash/segment_list.js +10 -6
  96. package/lib/dash/segment_template.js +349 -32
  97. package/lib/dependencies/all.js +8 -0
  98. package/lib/hls/hls_classes.js +33 -8
  99. package/lib/hls/hls_parser.js +805 -191
  100. package/lib/hls/manifest_text_parser.js +4 -14
  101. package/lib/media/adaptation_set_criteria.js +43 -3
  102. package/lib/media/closed_caption_parser.js +74 -12
  103. package/lib/media/drm_engine.js +189 -49
  104. package/lib/media/gap_jumping_controller.js +1 -1
  105. package/lib/media/manifest_parser.js +34 -0
  106. package/lib/media/media_source_capabilities.js +10 -0
  107. package/lib/media/media_source_engine.js +475 -231
  108. package/lib/media/playhead.js +1 -1
  109. package/lib/media/presentation_timeline.js +62 -0
  110. package/lib/media/segment_index.js +50 -14
  111. package/lib/media/segment_prefetch.js +277 -0
  112. package/lib/media/segment_reference.js +70 -4
  113. package/lib/media/streaming_engine.js +258 -81
  114. package/lib/media/video_wrapper.js +15 -7
  115. package/lib/mss/content_protection.js +353 -0
  116. package/lib/mss/mss_parser.js +1081 -0
  117. package/lib/net/networking_engine.js +60 -10
  118. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  119. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  120. package/lib/offline/manifest_converter.js +6 -0
  121. package/lib/offline/storage.js +2 -4
  122. package/lib/player.js +309 -105
  123. package/lib/polyfill/media_capabilities.js +43 -3
  124. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  125. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  126. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  127. package/lib/text/cue.js +208 -130
  128. package/lib/text/lrc_text_parser.js +2 -2
  129. package/lib/text/mp4_vtt_parser.js +2 -2
  130. package/lib/text/sbv_text_parser.js +1 -1
  131. package/lib/text/simple_text_displayer.js +2 -1
  132. package/lib/text/srt_text_parser.js +9 -1
  133. package/lib/text/ssa_text_parser.js +2 -2
  134. package/lib/text/text_engine.js +3 -21
  135. package/lib/text/text_utils.js +71 -20
  136. package/lib/text/ui_text_displayer.js +14 -14
  137. package/lib/text/vtt_text_parser.js +22 -14
  138. package/lib/transmuxer/aac_transmuxer.js +224 -0
  139. package/lib/transmuxer/ac3.js +142 -0
  140. package/lib/transmuxer/ac3_transmuxer.js +212 -0
  141. package/lib/transmuxer/adts.js +232 -0
  142. package/lib/transmuxer/ec3.js +103 -0
  143. package/lib/transmuxer/ec3_transmuxer.js +212 -0
  144. package/lib/transmuxer/h264.js +324 -0
  145. package/lib/transmuxer/mp3_transmuxer.js +204 -0
  146. package/lib/transmuxer/mpeg_audio.js +196 -0
  147. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  148. package/lib/transmuxer/mss_transmuxer.js +389 -0
  149. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  150. package/lib/transmuxer/transmuxer_engine.js +161 -0
  151. package/lib/transmuxer/ts_transmuxer.js +738 -0
  152. package/lib/util/cmcd_manager.js +131 -71
  153. package/lib/util/error.js +62 -26
  154. package/lib/util/exp_golomb.js +220 -0
  155. package/lib/util/fairplay_utils.js +64 -13
  156. package/lib/util/id3_utils.js +56 -3
  157. package/lib/util/language_utils.js +11 -8
  158. package/lib/util/manifest_parser_utils.js +3 -0
  159. package/lib/util/mime_utils.js +44 -7
  160. package/lib/util/mp4_box_parsers.js +233 -5
  161. package/lib/util/mp4_generator.js +1381 -0
  162. package/lib/util/periods.js +40 -34
  163. package/lib/util/platform.js +17 -3
  164. package/lib/util/player_configuration.js +38 -1
  165. package/lib/util/stream_utils.js +138 -27
  166. package/lib/util/text_parser.js +1 -1
  167. package/lib/util/ts_parser.js +470 -47
  168. package/lib/util/xml_utils.js +16 -3
  169. package/maintained-branches.md +2 -2
  170. package/package.json +3 -1
  171. package/roadmap.md +21 -6
  172. package/shaka-player.uncompiled.js +18 -0
  173. package/test/abr/simple_abr_manager_unit.js +32 -4
  174. package/test/ads/ad_manager_unit.js +18 -2
  175. package/test/cast/cast_utils_unit.js +7 -2
  176. package/test/cea/cea608_memory_unit.js +24 -0
  177. package/test/cea/cea_decoder_unit.js +33 -0
  178. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  179. package/test/dash/dash_parser_live_unit.js +56 -13
  180. package/test/dash/dash_parser_manifest_unit.js +70 -2
  181. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  182. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  183. package/test/demo/demo_unit.js +5 -1
  184. package/test/hls/hls_live_unit.js +188 -28
  185. package/test/hls/hls_parser_unit.js +250 -109
  186. package/test/hls/manifest_text_parser_unit.js +18 -13
  187. package/test/media/adaptation_set_criteria_unit.js +46 -14
  188. package/test/media/adaptation_set_unit.js +2 -0
  189. package/test/media/drm_engine_integration.js +11 -8
  190. package/test/media/drm_engine_unit.js +220 -7
  191. package/test/media/media_source_engine_integration.js +122 -38
  192. package/test/media/media_source_engine_unit.js +133 -153
  193. package/test/media/playhead_unit.js +3 -0
  194. package/test/media/presentation_timeline_unit.js +51 -0
  195. package/test/media/segment_index_unit.js +52 -0
  196. package/test/media/segment_prefetch_unit.js +243 -0
  197. package/test/media/streaming_engine_integration.js +9 -3
  198. package/test/media/streaming_engine_unit.js +440 -59
  199. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  200. package/test/mss/mss_parser_unit.js +472 -0
  201. package/test/mss/mss_player_integration.js +123 -0
  202. package/test/offline/manifest_convert_unit.js +9 -0
  203. package/test/offline/storage_integration.js +6 -1
  204. package/test/player_unit.js +386 -133
  205. package/test/polyfill/media_capabilities_unit.js +18 -0
  206. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  207. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  208. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  209. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  210. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  211. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  212. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  213. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  214. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  215. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  220. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  221. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  222. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  223. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  224. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  229. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  230. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  231. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  232. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  233. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  234. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  235. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  236. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  237. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  238. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  239. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  240. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  241. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  244. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  245. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  246. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  247. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  248. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  251. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  252. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  253. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  254. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  255. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  258. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  259. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  260. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  261. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  262. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  265. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  266. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  267. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  268. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  269. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  270. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  271. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  272. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  273. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  274. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  278. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  279. package/test/test/boot.js +7 -2
  280. package/test/test/util/fake_ad.js +99 -0
  281. package/test/test/util/fake_ad_manager.js +7 -1
  282. package/test/test/util/fake_networking_engine.js +41 -14
  283. package/test/test/util/fake_segment_prefetch.js +81 -0
  284. package/test/test/util/manifest_generator.js +19 -5
  285. package/test/test/util/mss_parser_util.js +115 -0
  286. package/test/test/util/offline_utils.js +1 -0
  287. package/test/test/util/simple_fakes.js +12 -3
  288. package/test/test/util/streaming_engine_util.js +14 -4
  289. package/test/test/util/ttml_utils.js +2 -2
  290. package/test/text/cue_integration.js +1 -1
  291. package/test/text/srt_text_parser_unit.js +78 -0
  292. package/test/text/text_engine_unit.js +17 -8
  293. package/test/text/ui_text_displayer_unit.js +4 -4
  294. package/test/text/vtt_text_parser_unit.js +59 -40
  295. package/test/text/web_vtt_generator_unit.js +9 -3
  296. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  297. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  298. package/test/transmuxer/transmuxer_integration.js +296 -0
  299. package/test/util/cmcd_manager_unit.js +162 -13
  300. package/test/util/language_utils_unit.js +9 -2
  301. package/test/util/mp4_box_parsers_unit.js +39 -4
  302. package/test/util/periods_unit.js +34 -26
  303. package/test/util/stream_utils_unit.js +60 -107
  304. package/ui/controls.js +19 -1
  305. package/ui/controls.less +1 -0
  306. package/ui/externs/ui.js +11 -1
  307. package/ui/language_utils.js +15 -0
  308. package/ui/less/thumbnails.less +26 -0
  309. package/ui/locales/oc.json +42 -0
  310. package/ui/pip_button.js +83 -2
  311. package/ui/range_element.js +15 -0
  312. package/ui/resolution_selection.js +9 -2
  313. package/ui/seek_bar.js +223 -0
  314. package/ui/ui.js +5 -0
  315. package/lib/cea/i_caption_decoder.js +0 -51
  316. package/lib/cea/i_cea_parser.js +0 -68
@@ -0,0 +1,353 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.mss.ContentProtection');
8
+
9
+ goog.require('shaka.log');
10
+ goog.require('shaka.util.BufferUtils');
11
+ goog.require('shaka.util.ManifestParserUtils');
12
+ goog.require('shaka.util.Pssh');
13
+ goog.require('shaka.util.StringUtils');
14
+ goog.require('shaka.util.Uint8ArrayUtils');
15
+ goog.require('shaka.util.XmlUtils');
16
+
17
+
18
+ /**
19
+ * @summary A set of functions for parsing and interpreting Protection
20
+ * elements.
21
+ */
22
+ shaka.mss.ContentProtection = class {
23
+ /**
24
+ * Parses info from the Protection elements.
25
+ *
26
+ * @param {!Array.<!Element>} elems
27
+ * @param {!Object.<string, string>} keySystemsBySystemId
28
+ * @return {!Array.<shaka.extern.DrmInfo>}
29
+ */
30
+ static parseFromProtection(elems, keySystemsBySystemId) {
31
+ const ContentProtection = shaka.mss.ContentProtection;
32
+ const XmlUtils = shaka.util.XmlUtils;
33
+
34
+ /** @type {!Array.<!Element>} */
35
+ let protectionHeader = [];
36
+ for (const elem of elems) {
37
+ protectionHeader = protectionHeader.concat(
38
+ XmlUtils.findChildren(elem, 'ProtectionHeader'));
39
+ }
40
+ if (!protectionHeader.length) {
41
+ return [];
42
+ }
43
+ return ContentProtection.convertElements_(
44
+ protectionHeader, keySystemsBySystemId);
45
+ }
46
+
47
+ /**
48
+ * Parses an Array buffer starting at byteOffset for PlayReady Object Records.
49
+ * Each PRO Record is preceded by its PlayReady Record type and length in
50
+ * bytes.
51
+ *
52
+ * PlayReady Object Record format: https://goo.gl/FTcu46
53
+ *
54
+ * @param {!DataView} view
55
+ * @param {number} byteOffset
56
+ * @return {!Array.<shaka.mss.ContentProtection.PlayReadyRecord>}
57
+ * @private
58
+ */
59
+ static parseMsProRecords_(view, byteOffset) {
60
+ const records = [];
61
+
62
+ while (byteOffset < view.byteLength - 1) {
63
+ const type = view.getUint16(byteOffset, true);
64
+ byteOffset += 2;
65
+
66
+ const byteLength = view.getUint16(byteOffset, true);
67
+ byteOffset += 2;
68
+
69
+ if ((byteLength & 1) != 0 || byteLength + byteOffset > view.byteLength) {
70
+ shaka.log.warning('Malformed MS PRO object');
71
+ return [];
72
+ }
73
+
74
+ const recordValue = shaka.util.BufferUtils.toUint8(
75
+ view, byteOffset, byteLength);
76
+ records.push({
77
+ type: type,
78
+ value: recordValue,
79
+ });
80
+
81
+ byteOffset += byteLength;
82
+ }
83
+
84
+ return records;
85
+ }
86
+
87
+ /**
88
+ * Parses a buffer for PlayReady Objects. The data
89
+ * should contain a 32-bit integer indicating the length of
90
+ * the PRO in bytes. Following that, a 16-bit integer for
91
+ * the number of PlayReady Object Records in the PRO. Lastly,
92
+ * a byte array of the PRO Records themselves.
93
+ *
94
+ * PlayReady Object format: https://goo.gl/W8yAN4
95
+ *
96
+ * @param {BufferSource} data
97
+ * @return {!Array.<shaka.mss.ContentProtection.PlayReadyRecord>}
98
+ * @private
99
+ */
100
+ static parseMsPro_(data) {
101
+ let byteOffset = 0;
102
+ const view = shaka.util.BufferUtils.toDataView(data);
103
+
104
+ // First 4 bytes is the PRO length (DWORD)
105
+ const byteLength = view.getUint32(byteOffset, /* littleEndian= */ true);
106
+ byteOffset += 4;
107
+
108
+ if (byteLength != data.byteLength) {
109
+ // Malformed PRO
110
+ shaka.log.warning('PlayReady Object with invalid length encountered.');
111
+ return [];
112
+ }
113
+
114
+ // Skip PRO Record count (WORD)
115
+ byteOffset += 2;
116
+
117
+ // Rest of the data contains the PRO Records
118
+ const ContentProtection = shaka.mss.ContentProtection;
119
+ return ContentProtection.parseMsProRecords_(view, byteOffset);
120
+ }
121
+
122
+ /**
123
+ * Parse a PlayReady Header format: https://goo.gl/dBzxNA
124
+ * a try to find the LA_URL value.
125
+ *
126
+ * @param {!Element} xml
127
+ * @return {string}
128
+ * @private
129
+ */
130
+ static getLaurl_(xml) {
131
+ // LA_URL element is optional and no more than one is
132
+ // allowed inside the DATA element. Only absolute URLs are allowed.
133
+ // If the LA_URL element exists, it must not be empty.
134
+ for (const elem of xml.getElementsByTagName('DATA')) {
135
+ const laUrl = shaka.util.XmlUtils.findChild(elem, 'LA_URL');
136
+ if (laUrl) {
137
+ return laUrl.textContent;
138
+ }
139
+ }
140
+
141
+ // Not found
142
+ // We return a empty string instead null because is the default value for
143
+ // a License in our model.
144
+ return '';
145
+ }
146
+
147
+ /**
148
+ * Gets a PlayReady license URL from a protection element
149
+ * containing a PlayReady Header Object
150
+ *
151
+ * @param {!Element} element
152
+ * @return {string}
153
+ */
154
+ static getPlayReadyLicenseUrl(element) {
155
+ const ContentProtection = shaka.mss.ContentProtection;
156
+ const rootElement = ContentProtection.getPlayReadyHeaderObject_(element);
157
+ if (!rootElement) {
158
+ return '';
159
+ }
160
+
161
+ return ContentProtection.getLaurl_(rootElement);
162
+ }
163
+
164
+ /**
165
+ * Parse a PlayReady Header format: https://goo.gl/dBzxNA
166
+ * a try to find the KID value.
167
+ *
168
+ * @param {!Element} xml
169
+ * @return {?string}
170
+ * @private
171
+ */
172
+ static getKID_(xml) {
173
+ // KID element is optional and no more than one is
174
+ // allowed inside the DATA element.
175
+ for (const elem of xml.getElementsByTagName('DATA')) {
176
+ const kid = shaka.util.XmlUtils.findChild(elem, 'KID');
177
+ if (kid) {
178
+ // GUID: [DWORD, WORD, WORD, 8-BYTE]
179
+ const guidBytes =
180
+ shaka.util.Uint8ArrayUtils.fromBase64(kid.textContent);
181
+ // Reverse byte order from little-endian to big-endian
182
+ const kidBytes = new Uint8Array([
183
+ guidBytes[3], guidBytes[2], guidBytes[1], guidBytes[0],
184
+ guidBytes[5], guidBytes[4],
185
+ guidBytes[7], guidBytes[6],
186
+ ...guidBytes.slice(8),
187
+ ]);
188
+ return shaka.util.Uint8ArrayUtils.toHex(kidBytes);
189
+ }
190
+ }
191
+
192
+ // Not found
193
+ return null;
194
+ }
195
+
196
+ /**
197
+ * Gets a PlayReady KID from a protection element
198
+ * containing a PlayReady Header Object
199
+ *
200
+ * @param {!Element} element
201
+ * @return {?string}
202
+ * @private
203
+ */
204
+ static getPlayReadyKID_(element) {
205
+ const ContentProtection = shaka.mss.ContentProtection;
206
+ const rootElement = ContentProtection.getPlayReadyHeaderObject_(element);
207
+ if (!rootElement) {
208
+ return null;
209
+ }
210
+
211
+ return ContentProtection.getKID_(rootElement);
212
+ }
213
+
214
+ /**
215
+ * Gets a PlayReady Header Object from a protection element
216
+ *
217
+ * @param {!Element} element
218
+ * @return {?Element}
219
+ * @private
220
+ */
221
+ static getPlayReadyHeaderObject_(element) {
222
+ const ContentProtection = shaka.mss.ContentProtection;
223
+ const PLAYREADY_RECORD_TYPES = ContentProtection.PLAYREADY_RECORD_TYPES;
224
+
225
+ const bytes = shaka.util.Uint8ArrayUtils.fromBase64(element.textContent);
226
+ const records = ContentProtection.parseMsPro_(bytes);
227
+ const record = records.filter((record) => {
228
+ return record.type === PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT;
229
+ })[0];
230
+
231
+ if (!record) {
232
+ return null;
233
+ }
234
+
235
+ const xml = shaka.util.StringUtils.fromUTF16(record.value, true);
236
+ const rootElement = shaka.util.XmlUtils.parseXmlString(xml, 'WRMHEADER');
237
+ if (!rootElement) {
238
+ return null;
239
+ }
240
+ return rootElement;
241
+ }
242
+
243
+ /**
244
+ * Gets a initData from a protection element.
245
+ *
246
+ * @param {!Element} element
247
+ * @param {string} systemID
248
+ * @param {?string} keyId
249
+ * @return {?Array.<shaka.extern.InitDataOverride>}
250
+ * @private
251
+ */
252
+ static getInitDataFromPro_(element, systemID, keyId) {
253
+ const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
254
+ const data = Uint8ArrayUtils.fromBase64(element.textContent);
255
+ const systemId = Uint8ArrayUtils.fromHex(systemID.replace(/-/g, ''));
256
+ const keyIds = new Set();
257
+ const psshVersion = 0;
258
+ const pssh =
259
+ shaka.util.Pssh.createPssh(data, systemId, keyIds, psshVersion);
260
+ return [
261
+ {
262
+ initData: pssh,
263
+ initDataType: 'cenc',
264
+ keyId: keyId,
265
+ },
266
+ ];
267
+ }
268
+
269
+ /**
270
+ * Creates DrmInfo objects from an array of elements.
271
+ *
272
+ * @param {!Array.<!Element>} elements
273
+ * @param {!Object.<string, string>} keySystemsBySystemId
274
+ * @return {!Array.<shaka.extern.DrmInfo>}
275
+ * @private
276
+ */
277
+ static convertElements_(elements, keySystemsBySystemId) {
278
+ const ContentProtection = shaka.mss.ContentProtection;
279
+ const ManifestParserUtils = shaka.util.ManifestParserUtils;
280
+ const licenseUrlParsers = ContentProtection.licenseUrlParsers_;
281
+
282
+ /** @type {!Array.<shaka.extern.DrmInfo>} */
283
+ const out = [];
284
+
285
+ for (let i = 0; i < elements.length; i++) {
286
+ const element = elements[i];
287
+ const systemID = element.getAttribute('SystemID').toLowerCase();
288
+ const keySystem = keySystemsBySystemId[systemID];
289
+ if (keySystem) {
290
+ const KID = ContentProtection.getPlayReadyKID_(element);
291
+ const initData = ContentProtection.getInitDataFromPro_(
292
+ element, systemID, KID);
293
+
294
+ const info = ManifestParserUtils.createDrmInfo(keySystem, initData);
295
+ if (KID) {
296
+ info.keyIds.add(KID);
297
+ }
298
+
299
+ const licenseParser = licenseUrlParsers.get(keySystem);
300
+ if (licenseParser) {
301
+ info.licenseServerUri = licenseParser(element);
302
+ }
303
+
304
+ out.push(info);
305
+ }
306
+ }
307
+
308
+ return out;
309
+ }
310
+ };
311
+
312
+ /**
313
+ * @typedef {{
314
+ * type: number,
315
+ * value: !Uint8Array
316
+ * }}
317
+ *
318
+ * @description
319
+ * The parsed result of a PlayReady object record.
320
+ *
321
+ * @property {number} type
322
+ * Type of data stored in the record.
323
+ * @property {!Uint8Array} value
324
+ * Record content.
325
+ */
326
+ shaka.mss.ContentProtection.PlayReadyRecord;
327
+
328
+ /**
329
+ * Enum for PlayReady record types.
330
+ * @enum {number}
331
+ */
332
+ shaka.mss.ContentProtection.PLAYREADY_RECORD_TYPES = {
333
+ RIGHTS_MANAGEMENT: 0x001,
334
+ RESERVED: 0x002,
335
+ EMBEDDED_LICENSE: 0x003,
336
+ };
337
+
338
+ /**
339
+ * A map of key system name to license server url parser.
340
+ *
341
+ * @const {!Map.<string, function(!Element)>}
342
+ * @private
343
+ */
344
+ shaka.mss.ContentProtection.licenseUrlParsers_ = new Map()
345
+ .set('com.microsoft.playready',
346
+ shaka.mss.ContentProtection.getPlayReadyLicenseUrl)
347
+ .set('com.microsoft.playready.recommendation',
348
+ shaka.mss.ContentProtection.getPlayReadyLicenseUrl)
349
+ .set('com.microsoft.playready.software',
350
+ shaka.mss.ContentProtection.getPlayReadyLicenseUrl)
351
+ .set('com.microsoft.playready.hardware',
352
+ shaka.mss.ContentProtection.getPlayReadyLicenseUrl);
353
+