shaka-player 4.3.11 → 4.4.1

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 (315) hide show
  1. package/AUTHORS +9 -0
  2. package/CHANGELOG.md +303 -202
  3. package/CONTRIBUTORS +8 -0
  4. package/LICENSE +32 -0
  5. package/README.md +63 -10
  6. package/demo/autoTemplate.txt +40 -5
  7. package/demo/close_button.js +11 -0
  8. package/demo/common/asset.js +13 -1
  9. package/demo/common/assets.js +53 -3
  10. package/demo/common/message_ids.js +25 -1
  11. package/demo/config.js +69 -10
  12. package/demo/customWarning.txt +2 -2
  13. package/demo/index.html +3 -1
  14. package/demo/locales/en.json +26 -2
  15. package/demo/locales/source.json +105 -9
  16. package/demo/main.js +52 -9
  17. package/demo/search.js +3 -1
  18. package/demo/service_worker.js +3 -0
  19. package/dist/controls.css +1 -1
  20. package/dist/controls.css.map +1 -1
  21. package/dist/demo.compiled.debug.js +124 -112
  22. package/dist/demo.compiled.debug.map +3 -3
  23. package/dist/demo.compiled.js +124 -112
  24. package/dist/demo.compiled.map +3 -3
  25. package/dist/deps.js +46 -28
  26. package/dist/locales.js +33 -33
  27. package/dist/receiver.compiled.debug.js +52 -46
  28. package/dist/receiver.compiled.debug.map +3 -3
  29. package/dist/receiver.compiled.js +52 -46
  30. package/dist/receiver.compiled.map +3 -3
  31. package/dist/shaka-player.compiled.d.ts +676 -391
  32. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  33. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  34. package/dist/shaka-player.compiled.debug.js +1043 -699
  35. package/dist/shaka-player.compiled.debug.map +4 -4
  36. package/dist/shaka-player.compiled.externs.js +1188 -616
  37. package/dist/shaka-player.compiled.js +1091 -929
  38. package/dist/shaka-player.compiled.map +4 -4
  39. package/dist/shaka-player.ui.d.ts +677 -392
  40. package/dist/shaka-player.ui.debug.d.ts +677 -392
  41. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  42. package/dist/shaka-player.ui.debug.js +1098 -737
  43. package/dist/shaka-player.ui.debug.map +4 -4
  44. package/dist/shaka-player.ui.externs.js +1023 -451
  45. package/dist/shaka-player.ui.js +1246 -1071
  46. package/dist/shaka-player.ui.map +4 -4
  47. package/docs/tutorials/ad_monetization.md +15 -1
  48. package/docs/tutorials/application-level-redirects.md +1 -1
  49. package/docs/tutorials/config.md +9 -5
  50. package/docs/tutorials/drm-config.md +61 -0
  51. package/docs/tutorials/fairplay.md +19 -4
  52. package/docs/tutorials/license-server-auth.md +4 -4
  53. package/docs/tutorials/license-wrapping.md +2 -2
  54. package/docs/tutorials/ui-customization.md +7 -3
  55. package/docs/tutorials/ui.md +7 -7
  56. package/docs/tutorials/upgrade.md +3 -0
  57. package/externs/ima.js +123 -2
  58. package/externs/isoboxer.js +217 -0
  59. package/externs/mediakeys.js +18 -0
  60. package/externs/mux.js +1 -105
  61. package/externs/pictureinpicture.js +48 -0
  62. package/externs/shaka/ads.js +61 -1
  63. package/externs/shaka/cea.js +110 -0
  64. package/externs/shaka/codecs.js +32 -0
  65. package/externs/shaka/manifest.js +101 -1
  66. package/externs/shaka/manifest_parser.js +0 -10
  67. package/externs/shaka/net.js +36 -7
  68. package/externs/shaka/offline.js +8 -1
  69. package/externs/shaka/player.js +220 -21
  70. package/externs/shaka/text.js +1 -382
  71. package/externs/shaka/transmuxer.js +60 -0
  72. package/karma.conf.js +13 -0
  73. package/lib/abr/simple_abr_manager.js +6 -3
  74. package/lib/ads/ad_manager.js +60 -2
  75. package/lib/ads/client_side_ad.js +86 -0
  76. package/lib/ads/client_side_ad_manager.js +79 -3
  77. package/lib/ads/server_side_ad.js +86 -0
  78. package/lib/ads/server_side_ad_manager.js +13 -0
  79. package/lib/cast/cast_utils.js +1 -0
  80. package/lib/cea/cea608_data_channel.js +24 -14
  81. package/lib/cea/cea608_memory.js +5 -2
  82. package/lib/cea/cea708_service.js +8 -9
  83. package/lib/cea/cea708_window.js +1 -2
  84. package/lib/cea/cea_decoder.js +23 -6
  85. package/lib/cea/cea_utils.js +25 -2
  86. package/lib/cea/dummy_caption_decoder.js +21 -0
  87. package/lib/cea/dummy_cea_parser.js +1 -3
  88. package/lib/cea/mp4_cea_parser.js +15 -10
  89. package/lib/cea/ts_cea_parser.js +69 -0
  90. package/lib/dash/content_protection.js +32 -2
  91. package/lib/dash/dash_parser.js +93 -31
  92. package/lib/dash/mpd_utils.js +6 -25
  93. package/lib/dash/segment_base.js +12 -14
  94. package/lib/dash/segment_list.js +10 -6
  95. package/lib/dash/segment_template.js +349 -32
  96. package/lib/dependencies/all.js +8 -0
  97. package/lib/hls/hls_classes.js +33 -8
  98. package/lib/hls/hls_parser.js +805 -191
  99. package/lib/hls/manifest_text_parser.js +4 -14
  100. package/lib/media/adaptation_set_criteria.js +43 -3
  101. package/lib/media/closed_caption_parser.js +74 -12
  102. package/lib/media/drm_engine.js +189 -49
  103. package/lib/media/gap_jumping_controller.js +1 -1
  104. package/lib/media/manifest_parser.js +34 -0
  105. package/lib/media/media_source_capabilities.js +10 -0
  106. package/lib/media/media_source_engine.js +495 -231
  107. package/lib/media/playhead.js +1 -1
  108. package/lib/media/presentation_timeline.js +62 -0
  109. package/lib/media/segment_index.js +50 -14
  110. package/lib/media/segment_prefetch.js +277 -0
  111. package/lib/media/segment_reference.js +70 -4
  112. package/lib/media/streaming_engine.js +258 -81
  113. package/lib/media/video_wrapper.js +15 -7
  114. package/lib/mss/content_protection.js +353 -0
  115. package/lib/mss/mss_parser.js +1082 -0
  116. package/lib/net/networking_engine.js +60 -10
  117. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  118. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  119. package/lib/offline/manifest_converter.js +6 -0
  120. package/lib/offline/storage.js +2 -4
  121. package/lib/player.js +309 -105
  122. package/lib/polyfill/media_capabilities.js +43 -3
  123. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  124. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  125. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  126. package/lib/text/cue.js +208 -130
  127. package/lib/text/lrc_text_parser.js +2 -2
  128. package/lib/text/mp4_vtt_parser.js +2 -2
  129. package/lib/text/sbv_text_parser.js +1 -1
  130. package/lib/text/simple_text_displayer.js +1 -1
  131. package/lib/text/srt_text_parser.js +9 -1
  132. package/lib/text/ssa_text_parser.js +2 -2
  133. package/lib/text/text_engine.js +3 -21
  134. package/lib/text/text_utils.js +71 -20
  135. package/lib/text/ui_text_displayer.js +14 -14
  136. package/lib/text/vtt_text_parser.js +22 -14
  137. package/lib/transmuxer/aac_transmuxer.js +224 -0
  138. package/lib/transmuxer/ac3.js +142 -0
  139. package/lib/transmuxer/ac3_transmuxer.js +213 -0
  140. package/lib/transmuxer/adts.js +232 -0
  141. package/lib/transmuxer/ec3.js +103 -0
  142. package/lib/transmuxer/ec3_transmuxer.js +213 -0
  143. package/lib/transmuxer/h264.js +324 -0
  144. package/lib/transmuxer/mp3_transmuxer.js +205 -0
  145. package/lib/transmuxer/mpeg_audio.js +196 -0
  146. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  147. package/lib/transmuxer/mss_transmuxer.js +389 -0
  148. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  149. package/lib/transmuxer/transmuxer_engine.js +161 -0
  150. package/lib/transmuxer/ts_transmuxer.js +721 -0
  151. package/lib/util/cmcd_manager.js +131 -71
  152. package/lib/util/error.js +62 -26
  153. package/lib/util/exp_golomb.js +220 -0
  154. package/lib/util/fairplay_utils.js +64 -13
  155. package/lib/util/id3_utils.js +56 -3
  156. package/lib/util/language_utils.js +11 -8
  157. package/lib/util/manifest_parser_utils.js +3 -0
  158. package/lib/util/mime_utils.js +44 -7
  159. package/lib/util/mp4_box_parsers.js +233 -5
  160. package/lib/util/mp4_generator.js +1388 -0
  161. package/lib/util/periods.js +40 -34
  162. package/lib/util/platform.js +17 -3
  163. package/lib/util/player_configuration.js +38 -1
  164. package/lib/util/stream_utils.js +138 -27
  165. package/lib/util/text_parser.js +1 -1
  166. package/lib/util/ts_parser.js +460 -74
  167. package/lib/util/xml_utils.js +16 -3
  168. package/maintained-branches.md +2 -2
  169. package/package.json +3 -1
  170. package/roadmap.md +21 -6
  171. package/shaka-player.uncompiled.js +18 -0
  172. package/test/abr/simple_abr_manager_unit.js +32 -4
  173. package/test/ads/ad_manager_unit.js +18 -2
  174. package/test/cast/cast_utils_unit.js +7 -2
  175. package/test/cea/cea608_memory_unit.js +24 -0
  176. package/test/cea/cea_decoder_unit.js +33 -0
  177. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  178. package/test/dash/dash_parser_live_unit.js +56 -13
  179. package/test/dash/dash_parser_manifest_unit.js +70 -2
  180. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  181. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  182. package/test/demo/demo_unit.js +5 -1
  183. package/test/hls/hls_live_unit.js +188 -28
  184. package/test/hls/hls_parser_unit.js +250 -109
  185. package/test/hls/manifest_text_parser_unit.js +18 -13
  186. package/test/media/adaptation_set_criteria_unit.js +46 -14
  187. package/test/media/adaptation_set_unit.js +2 -0
  188. package/test/media/drm_engine_integration.js +11 -8
  189. package/test/media/drm_engine_unit.js +220 -7
  190. package/test/media/media_source_engine_integration.js +124 -40
  191. package/test/media/media_source_engine_unit.js +133 -153
  192. package/test/media/playhead_unit.js +3 -0
  193. package/test/media/presentation_timeline_unit.js +51 -0
  194. package/test/media/segment_index_unit.js +52 -0
  195. package/test/media/segment_prefetch_unit.js +243 -0
  196. package/test/media/streaming_engine_integration.js +9 -3
  197. package/test/media/streaming_engine_unit.js +440 -59
  198. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  199. package/test/mss/mss_parser_unit.js +472 -0
  200. package/test/mss/mss_player_integration.js +123 -0
  201. package/test/offline/manifest_convert_unit.js +9 -0
  202. package/test/offline/storage_integration.js +6 -1
  203. package/test/player_unit.js +386 -133
  204. package/test/polyfill/media_capabilities_unit.js +18 -0
  205. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  206. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  207. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  208. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  209. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  210. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  211. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  212. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  213. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  214. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  215. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  220. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  221. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  222. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  223. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  224. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  229. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  230. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  231. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  232. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  233. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  234. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  235. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  236. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  237. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  238. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  239. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  240. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  241. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  244. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  245. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  246. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  247. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  248. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  251. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  252. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  253. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  254. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  255. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  258. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  259. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  260. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  261. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  262. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  265. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  266. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  267. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  268. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  269. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  270. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  271. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  272. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  273. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  274. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  278. package/test/test/boot.js +7 -2
  279. package/test/test/util/fake_ad.js +99 -0
  280. package/test/test/util/fake_ad_manager.js +7 -1
  281. package/test/test/util/fake_networking_engine.js +41 -14
  282. package/test/test/util/fake_segment_prefetch.js +81 -0
  283. package/test/test/util/manifest_generator.js +19 -5
  284. package/test/test/util/mss_parser_util.js +115 -0
  285. package/test/test/util/offline_utils.js +1 -0
  286. package/test/test/util/simple_fakes.js +12 -3
  287. package/test/test/util/streaming_engine_util.js +14 -4
  288. package/test/test/util/ttml_utils.js +2 -2
  289. package/test/text/cue_integration.js +1 -1
  290. package/test/text/srt_text_parser_unit.js +78 -0
  291. package/test/text/text_engine_unit.js +17 -8
  292. package/test/text/ui_text_displayer_unit.js +4 -4
  293. package/test/text/vtt_text_parser_unit.js +59 -40
  294. package/test/text/web_vtt_generator_unit.js +9 -3
  295. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  296. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  297. package/test/transmuxer/transmuxer_integration.js +296 -0
  298. package/test/util/cmcd_manager_unit.js +162 -13
  299. package/test/util/language_utils_unit.js +9 -2
  300. package/test/util/mp4_box_parsers_unit.js +39 -4
  301. package/test/util/periods_unit.js +34 -26
  302. package/test/util/stream_utils_unit.js +60 -107
  303. package/ui/controls.js +19 -1
  304. package/ui/controls.less +1 -0
  305. package/ui/externs/ui.js +11 -1
  306. package/ui/language_utils.js +15 -0
  307. package/ui/less/thumbnails.less +26 -0
  308. package/ui/locales/oc.json +42 -0
  309. package/ui/pip_button.js +83 -2
  310. package/ui/range_element.js +15 -0
  311. package/ui/resolution_selection.js +9 -2
  312. package/ui/seek_bar.js +223 -0
  313. package/ui/ui.js +5 -0
  314. package/lib/cea/i_caption_decoder.js +0 -51
  315. package/lib/cea/i_cea_parser.js +0 -68
@@ -133,14 +133,14 @@ shaka.util.FairPlayUtils = class {
133
133
  }
134
134
 
135
135
  /**
136
- * Verimatrix initDataTransform configuration.
136
+ * Basic initDataTransform configuration.
137
137
  *
138
138
  * @param {!Uint8Array} initData
139
139
  * @param {string} initDataType
140
140
  * @param {?shaka.extern.DrmInfo} drmInfo
141
- * @export
141
+ * @private
142
142
  */
143
- static verimatrixInitDataTransform(initData, initDataType, drmInfo) {
143
+ static basicInitDataTransform_(initData, initDataType, drmInfo) {
144
144
  if (initDataType !== 'skd') {
145
145
  return initData;
146
146
  }
@@ -152,6 +152,19 @@ shaka.util.FairPlayUtils = class {
152
152
  return FairPlayUtils.initDataTransform(initData, contentId, cert);
153
153
  }
154
154
 
155
+ /**
156
+ * Verimatrix initDataTransform configuration.
157
+ *
158
+ * @param {!Uint8Array} initData
159
+ * @param {string} initDataType
160
+ * @param {?shaka.extern.DrmInfo} drmInfo
161
+ * @export
162
+ */
163
+ static verimatrixInitDataTransform(initData, initDataType, drmInfo) {
164
+ return shaka.util.FairPlayUtils.basicInitDataTransform_(
165
+ initData, initDataType, drmInfo);
166
+ }
167
+
155
168
  /**
156
169
  * EZDRM initDataTransform configuration.
157
170
  *
@@ -202,14 +215,28 @@ shaka.util.FairPlayUtils = class {
202
215
  return FairPlayUtils.initDataTransform(initData, contentId, cert);
203
216
  }
204
217
 
218
+ /**
219
+ * ExpressPlay initDataTransform configuration.
220
+ *
221
+ * @param {!Uint8Array} initData
222
+ * @param {string} initDataType
223
+ * @param {?shaka.extern.DrmInfo} drmInfo
224
+ * @export
225
+ */
226
+ static expressplayInitDataTransform(initData, initDataType, drmInfo) {
227
+ return shaka.util.FairPlayUtils.basicInitDataTransform_(
228
+ initData, initDataType, drmInfo);
229
+ }
230
+
205
231
  /**
206
232
  * Verimatrix FairPlay request.
207
233
  *
208
234
  * @param {shaka.net.NetworkingEngine.RequestType} type
209
235
  * @param {shaka.extern.Request} request
236
+ * @param {shaka.extern.RequestContext=} context
210
237
  * @export
211
238
  */
212
- static verimatrixFairPlayRequest(type, request) {
239
+ static verimatrixFairPlayRequest(type, request, context) {
213
240
  if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
214
241
  return;
215
242
  }
@@ -221,31 +248,54 @@ shaka.util.FairPlayUtils = class {
221
248
  }
222
249
 
223
250
  /**
224
- * EZDRM FairPlay request.
251
+ * Set content-type to application/octet-stream in a FairPlay request.
225
252
  *
226
253
  * @param {shaka.net.NetworkingEngine.RequestType} type
227
254
  * @param {shaka.extern.Request} request
228
- * @export
255
+ * @param {shaka.extern.RequestContext=} context
256
+ * @private
229
257
  */
230
- static ezdrmFairPlayRequest(type, request) {
258
+ static octetStreamFairPlayRequest_(type, request, context) {
231
259
  if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
232
260
  return;
233
261
  }
234
262
  request.headers['Content-Type'] = 'application/octet-stream';
235
263
  }
236
264
 
265
+ /**
266
+ * EZDRM FairPlay request.
267
+ *
268
+ * @param {shaka.net.NetworkingEngine.RequestType} type
269
+ * @param {shaka.extern.Request} request
270
+ * @param {shaka.extern.RequestContext=} context
271
+ * @export
272
+ */
273
+ static ezdrmFairPlayRequest(type, request, context) {
274
+ shaka.util.FairPlayUtils.octetStreamFairPlayRequest_(type, request);
275
+ }
276
+
237
277
  /**
238
278
  * Conax FairPlay request.
239
279
  *
240
280
  * @param {shaka.net.NetworkingEngine.RequestType} type
241
281
  * @param {shaka.extern.Request} request
282
+ * @param {shaka.extern.RequestContext=} context
242
283
  * @export
243
284
  */
244
- static conaxFairPlayRequest(type, request) {
245
- if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
246
- return;
247
- }
248
- request.headers['Content-Type'] = 'application/octet-stream';
285
+ static conaxFairPlayRequest(type, request, context) {
286
+ shaka.util.FairPlayUtils.octetStreamFairPlayRequest_(type, request);
287
+ }
288
+
289
+ /**
290
+ * ExpressPlay FairPlay request.
291
+ *
292
+ * @param {shaka.net.NetworkingEngine.RequestType} type
293
+ * @param {shaka.extern.Request} request
294
+ * @param {shaka.extern.RequestContext=} context
295
+ * @export
296
+ */
297
+ static expressplayFairPlayRequest(type, request, context) {
298
+ shaka.util.FairPlayUtils.octetStreamFairPlayRequest_(type, request);
249
299
  }
250
300
 
251
301
  /**
@@ -253,9 +303,10 @@ shaka.util.FairPlayUtils = class {
253
303
  *
254
304
  * @param {shaka.net.NetworkingEngine.RequestType} type
255
305
  * @param {shaka.extern.Response} response
306
+ * @param {shaka.extern.RequestContext=} context
256
307
  * @export
257
308
  */
258
- static commonFairPlayResponse(type, response) {
309
+ static commonFairPlayResponse(type, response, context) {
259
310
  if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
260
311
  return;
261
312
  }
@@ -211,10 +211,26 @@ shaka.util.Id3Utils = class {
211
211
  }
212
212
  const text = StringUtils.fromUTF8(
213
213
  BufferUtils.toUint8(frame.data, 0, textEndIndex));
214
- const data = BufferUtils.toArrayBuffer(
215
- frame.data.subarray(text.length + 1));
216
214
  metadataFrame.description = text;
217
- metadataFrame.data = data;
215
+ if (text == 'com.apple.streaming.transportStreamTimestamp') {
216
+ const data = frame.data.subarray(text.length + 1);
217
+ // timestamp is 33 bit expressed as a big-endian eight-octet number,
218
+ // with the upper 31 bits set to zero.
219
+ const pts33Bit = data[3] & 0x1;
220
+ let timestamp =
221
+ (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];
222
+ timestamp /= 45;
223
+
224
+ if (pts33Bit) {
225
+ timestamp += 47721858.84;
226
+ } // 2^32 / 90
227
+
228
+ metadataFrame.data = timestamp;
229
+ } else {
230
+ const data = BufferUtils.toArrayBuffer(
231
+ frame.data.subarray(text.length + 1));
232
+ metadataFrame.data = data;
233
+ }
218
234
  return metadataFrame;
219
235
  } else if (frame.type[0] === 'T') {
220
236
  /*
@@ -291,6 +307,43 @@ shaka.util.Id3Utils = class {
291
307
  }
292
308
  return frames;
293
309
  }
310
+
311
+ /**
312
+ * Returns any adjacent ID3 tags found in data starting at offset, as one
313
+ * block of data
314
+ * @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags
315
+ * @param {number=} offset - The offset at which to start searching
316
+ * @return {!Uint8Array}
317
+ * @export
318
+ */
319
+ static getID3Data(id3Data, offset = 0) {
320
+ const Id3Utils = shaka.util.Id3Utils;
321
+ const front = offset;
322
+ let length = 0;
323
+
324
+ while (Id3Utils.isHeader_(id3Data, offset)) {
325
+ if ((id3Data[offset + 5] >> 6) & 1) {
326
+ // skip extended header
327
+ length += 10;
328
+ }
329
+ // skip past ID3 header
330
+ length += 10;
331
+
332
+ const size = Id3Utils.readSize_(id3Data, offset + 6);
333
+ length += size;
334
+
335
+ if (Id3Utils.isFooter_(id3Data, offset + 10)) {
336
+ // ID3 footer is 10 bytes
337
+ length += 10;
338
+ }
339
+ offset += length;
340
+ }
341
+
342
+ if (length > 0) {
343
+ return id3Data.subarray(front, front + length);
344
+ }
345
+ return new Uint8Array([]);
346
+ }
294
347
  };
295
348
 
296
349
  /**
@@ -191,12 +191,16 @@ shaka.util.LanguageUtils = class {
191
191
  static normalize(locale) {
192
192
  const LanguageUtils = shaka.util.LanguageUtils;
193
193
 
194
- const components = locale.split('-');
194
+ const privateusePrefix = 'x-';
195
+ const components = locale.split(`-${privateusePrefix}`);
196
+ const languageAndRegion = components[0].split('-');
195
197
 
196
- // We are only going to use the language and the region. If there was
197
- // a dialect or anything else, we are throwing it a way.
198
- let language = components[0] || '';
199
- let region = components[1] || '';
198
+ // We are only going to use the language, the region and the "privateuse" part (as per https://datatracker.ietf.org/doc/html/rfc5646).
199
+ // Anything else is thrown away.
200
+ let language = languageAndRegion[0] || '';
201
+ let region = languageAndRegion[1] || '';
202
+ const privateuse = components[1] ?
203
+ `${privateusePrefix}${components[1]}` : '';
200
204
 
201
205
  // Convert the language to lower case. It is standard for the language code
202
206
  // to be in lower case, but it will also make the map look-up easier.
@@ -208,9 +212,8 @@ shaka.util.LanguageUtils = class {
208
212
  // and this will be a no-op.
209
213
  region = region.toUpperCase();
210
214
 
211
- return region ?
212
- language + '-' + region :
213
- language;
215
+ return `${region ? `${language}-${region}` : language}${
216
+ privateuse ? `-${privateuse}` : ''}`;
214
217
  }
215
218
 
216
219
  /**
@@ -19,6 +19,9 @@ shaka.util.ManifestParserUtils = class {
19
19
  * Resolves an array of relative URIs to the given base URIs. This will result
20
20
  * in M*N number of URIs.
21
21
  *
22
+ * Note: This method is slow in SmartTVs and Consoles. It should only be
23
+ * called when necessary.
24
+ *
22
25
  * @param {!Array.<string>} baseUris
23
26
  * @param {!Array.<string>} relativeUris
24
27
  * @return {!Array.<string>}
@@ -6,7 +6,7 @@
6
6
 
7
7
  goog.provide('shaka.util.MimeUtils');
8
8
 
9
- goog.require('shaka.media.Transmuxer');
9
+ goog.require('shaka.transmuxer.TransmuxerEngine');
10
10
  goog.require('shaka.util.ManifestParserUtils');
11
11
 
12
12
  /**
@@ -16,7 +16,7 @@ goog.require('shaka.util.ManifestParserUtils');
16
16
  shaka.util.MimeUtils = class {
17
17
  /**
18
18
  * Takes a MIME type and optional codecs string and produces the full MIME
19
- * type.
19
+ * type. Also remove the codecs for raw formats.
20
20
  *
21
21
  * @param {string} mimeType
22
22
  * @param {string=} codecs
@@ -24,6 +24,23 @@ shaka.util.MimeUtils = class {
24
24
  * @export
25
25
  */
26
26
  static getFullType(mimeType, codecs) {
27
+ let fullMimeType = mimeType;
28
+ if (codecs && !shaka.util.MimeUtils.RAW_FORMATS.includes(mimeType)) {
29
+ fullMimeType += '; codecs="' + codecs + '"';
30
+ }
31
+ return fullMimeType;
32
+ }
33
+
34
+ /**
35
+ * Takes a MIME type and optional codecs string and produces the full MIME
36
+ * type.
37
+ *
38
+ * @param {string} mimeType
39
+ * @param {string=} codecs
40
+ * @return {string}
41
+ * @export
42
+ */
43
+ static getFullTypeWithAllCodecs(mimeType, codecs) {
27
44
  let fullMimeType = mimeType;
28
45
  if (codecs) {
29
46
  fullMimeType += '; codecs="' + codecs + '"';
@@ -43,12 +60,16 @@ shaka.util.MimeUtils = class {
43
60
  * @return {string}
44
61
  */
45
62
  static getFullOrConvertedType(mimeType, codecs, contentType) {
46
- const fullMimeType = shaka.util.MimeUtils.getFullType(mimeType, codecs);
63
+ const MimeUtils = shaka.util.MimeUtils;
64
+ const fullMimeType = MimeUtils.getFullType(mimeType, codecs);
65
+ const fullMimeTypeWithAllCodecs = MimeUtils.getFullTypeWithAllCodecs(
66
+ mimeType, codecs);
47
67
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
48
- const Transmuxer = shaka.media.Transmuxer;
68
+ const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
49
69
 
50
- if (Transmuxer.isSupported(fullMimeType, contentType)) {
51
- return shaka.media.Transmuxer.convertCodecs(contentType, fullMimeType);
70
+ if (TransmuxerEngine.isSupported(fullMimeTypeWithAllCodecs, contentType)) {
71
+ return TransmuxerEngine.convertCodecs(
72
+ contentType, fullMimeTypeWithAllCodecs);
52
73
  } else if (mimeType != 'video/mp2t' && contentType == ContentType.AUDIO) {
53
74
  // video/mp2t is the correct mime type for TS audio, so only replace the
54
75
  // word "video" with "audio" for non-TS audio content.
@@ -71,7 +92,10 @@ shaka.util.MimeUtils = class {
71
92
  const extendedMimeParams = shaka.util.MimeUtils.EXTENDED_MIME_PARAMETERS_;
72
93
  extendedMimeParams.forEach((mimeKey, streamKey) => {
73
94
  const value = stream[streamKey];
74
- if (value) {
95
+ if (streamKey == 'codecs' &&
96
+ shaka.util.MimeUtils.RAW_FORMATS.includes(stream.mimeType)) {
97
+ // Skip codecs for raw formats
98
+ } else if (value) {
75
99
  components.push(mimeKey + '="' + value + '"');
76
100
  }
77
101
  });
@@ -117,6 +141,7 @@ shaka.util.MimeUtils = class {
117
141
  switch (true) {
118
142
  case base === 'mp4a' && profile === '69':
119
143
  case base === 'mp4a' && profile === '6b':
144
+ case base === 'mp4a' && profile === '40.34':
120
145
  return 'mp3';
121
146
  case base === 'mp4a' && profile === '66':
122
147
  case base === 'mp4a' && profile === '67':
@@ -254,3 +279,15 @@ shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE = 'application/cea-608';
254
279
  * @const {string}
255
280
  */
256
281
  shaka.util.MimeUtils.CEA708_CLOSED_CAPTION_MIMETYPE = 'application/cea-708';
282
+
283
+ /**
284
+ * MIME types of raw formats.
285
+ *
286
+ * @const {!Array.<string>}
287
+ */
288
+ shaka.util.MimeUtils.RAW_FORMATS = [
289
+ 'audio/aac',
290
+ 'audio/ac3',
291
+ 'audio/ec3',
292
+ 'audio/mpeg',
293
+ ];
@@ -66,6 +66,59 @@ shaka.util.Mp4BoxParsers = class {
66
66
  };
67
67
  }
68
68
 
69
+ /**
70
+ * Parses a TFDT Box, with a loss of precision beyond 53 bits.
71
+ * Use only when exact integers are not required, e.g. when
72
+ * dividing by the timescale.
73
+ *
74
+ * @param {!shaka.util.DataViewReader} reader
75
+ * @param {number} version
76
+ * @return {!shaka.util.ParsedTFDTBox}
77
+ */
78
+ static parseTFDTInaccurate(reader, version) {
79
+ if (version == 1) {
80
+ const high = reader.readUint32();
81
+ const low = reader.readUint32();
82
+ return {
83
+ baseMediaDecodeTime: (high * Math.pow(2, 32)) + low,
84
+ };
85
+ } else {
86
+ return {
87
+ baseMediaDecodeTime: reader.readUint32(),
88
+ };
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Parses a PRFT Box, with a loss of precision beyond 53 bits.
94
+ * Use only when exact integers are not required, e.g. when
95
+ * dividing by the timescale.
96
+ *
97
+ * @param {!shaka.util.DataViewReader} reader
98
+ * @param {number} version
99
+ * @return {!shaka.util.ParsedPRFTBox}
100
+ */
101
+ static parsePRFTInaccurate(reader, version) {
102
+ reader.readUint32(); // Ignore referenceTrackId
103
+ const ntpTimestampSec = reader.readUint32();
104
+ const ntpTimestampFrac = reader.readUint32();
105
+ const ntpTimestamp = ntpTimestampSec * 1000 +
106
+ ntpTimestampFrac / 2**32 * 1000;
107
+
108
+ let mediaTime;
109
+ if (version === 0) {
110
+ mediaTime = reader.readUint32();
111
+ } else {
112
+ const high = reader.readUint32();
113
+ const low = reader.readUint32();
114
+ mediaTime = (high * Math.pow(2, 32)) + low;
115
+ }
116
+ return {
117
+ mediaTime,
118
+ ntpTimestamp,
119
+ };
120
+ }
121
+
69
122
  /**
70
123
  * Parses a MDHD Box.
71
124
  * @param {!shaka.util.DataViewReader} reader
@@ -83,8 +136,21 @@ shaka.util.Mp4BoxParsers = class {
83
136
 
84
137
  const timescale = reader.readUint32();
85
138
 
139
+ reader.skip(4); // Skip "duration"
140
+
141
+ const language = reader.readUint16();
142
+
143
+ // language is stored as an ISO-639-2/T code in an array of three
144
+ // 5-bit fields each field is the packed difference between its ASCII
145
+ // value and 0x60
146
+ const languageString =
147
+ String.fromCharCode((language >> 10) + 0x60) +
148
+ String.fromCharCode(((language & 0x03c0) >> 5) + 0x60) +
149
+ String.fromCharCode((language & 0x1f) + 0x60);
150
+
86
151
  return {
87
152
  timescale,
153
+ language: languageString,
88
154
  };
89
155
  }
90
156
 
@@ -174,22 +240,88 @@ shaka.util.Mp4BoxParsers = class {
174
240
  * @return {!shaka.util.ParsedTKHDBox}
175
241
  */
176
242
  static parseTKHD(reader, version) {
177
- let trackId = 0;
178
243
  if (version == 1) {
179
244
  reader.skip(8); // Skip "creation_time"
180
245
  reader.skip(8); // Skip "modification_time"
181
- trackId = reader.readUint32();
182
246
  } else {
183
247
  reader.skip(4); // Skip "creation_time"
184
248
  reader.skip(4); // Skip "modification_time"
185
- trackId = reader.readUint32();
186
249
  }
187
250
 
251
+ const trackId = reader.readUint32();
252
+
253
+ if (version == 1) {
254
+ reader.skip(8); // Skip "reserved"
255
+ } else {
256
+ reader.skip(4); // Skip "reserved"
257
+ }
258
+ reader.skip(4); // Skip "duration"
259
+ reader.skip(8); // Skip "reserved"
260
+ reader.skip(2); // Skip "layer"
261
+ reader.skip(2); // Skip "alternate_group"
262
+ reader.skip(2); // Skip "volume"
263
+ reader.skip(2); // Skip "reserved"
264
+ reader.skip(36); // Skip "matrix_structure"
265
+
266
+ const width = reader.readUint16() + (reader.readUint16() / 16);
267
+ const height = reader.readUint16() + (reader.readUint16() / 16);
268
+
188
269
  return {
189
270
  trackId,
271
+ width,
272
+ height,
190
273
  };
191
274
  }
192
275
 
276
+ /**
277
+ * Parses a MP4A box.
278
+ * @param {!shaka.util.DataViewReader} reader
279
+ * @return {!shaka.util.ParsedMP4ABox}
280
+ */
281
+ static parseMP4A(reader) {
282
+ reader.skip(6); // Skip "reserved"
283
+ reader.skip(2); // Skip "data_reference_index"
284
+ reader.skip(8); // Skip "reserved"
285
+ const channelCount = reader.readUint16();
286
+ reader.skip(2); // Skip "samplesize"
287
+ reader.skip(2); // Skip "pre_defined"
288
+ reader.skip(2); // Skip "reserved"
289
+ const sampleRate = reader.readUint16() + (reader.readUint16() / 65536);
290
+
291
+ return {
292
+ channelCount,
293
+ sampleRate,
294
+ };
295
+ }
296
+
297
+ /**
298
+ * Parses a ESDS box.
299
+ * @param {!shaka.util.DataViewReader} reader
300
+ * @return {!shaka.util.ParsedESDSBox}
301
+ */
302
+ static parseESDS(reader) {
303
+ let codec = 'mp4a';
304
+ reader.skip(11);
305
+ codec += '.' + this.toHex_(reader.readUint8());
306
+ // this value is only a single digit
307
+ codec += '.' +
308
+ this.toHex_((reader.readUint8() >>> 2) & 0x3f).replace(/^0/, '');
309
+ return {codec};
310
+ }
311
+
312
+ /**
313
+ * Parses a AVC box.
314
+ * @param {!shaka.util.DataViewReader} reader
315
+ * @param {string} boxName
316
+ * @return {!shaka.util.ParsedAVCBox}
317
+ */
318
+ static parseAVC(reader, boxName) {
319
+ reader.skip(87);
320
+ const codec = boxName + '.' + this.toHex_(reader.readUint8()) +
321
+ this.toHex_(reader.readUint8()) + this.toHex_(reader.readUint8());
322
+ return {codec};
323
+ }
324
+
193
325
  /**
194
326
  * Parses a FRMA box.
195
327
  * @param {!shaka.util.DataViewReader} reader
@@ -200,6 +332,34 @@ shaka.util.Mp4BoxParsers = class {
200
332
  const codec = shaka.util.Mp4Parser.typeToString(fourcc);
201
333
  return {codec};
202
334
  }
335
+
336
+ /**
337
+ * Parses a HDLR box.
338
+ * @param {!shaka.util.DataViewReader} reader
339
+ * @return {!shaka.util.ParsedHDLRBox}
340
+ */
341
+ static parseHDLR(reader) {
342
+ reader.skip(8); // Skip "pre_defined"
343
+
344
+ const data = reader.readBytes(4);
345
+ let handlerType = '';
346
+ handlerType += String.fromCharCode(data[0]);
347
+ handlerType += String.fromCharCode(data[1]);
348
+ handlerType += String.fromCharCode(data[2]);
349
+ handlerType += String.fromCharCode(data[3]);
350
+
351
+ return {handlerType};
352
+ }
353
+
354
+ /**
355
+ * Convert a number to hex
356
+ * @param {number} x
357
+ * @return {string}
358
+ * @private
359
+ */
360
+ static toHex_(x) {
361
+ return ('0' + x.toString(16).toUpperCase()).slice(-2);
362
+ }
203
363
  };
204
364
 
205
365
 
@@ -242,12 +402,25 @@ shaka.util.ParsedTFDTBox;
242
402
 
243
403
  /**
244
404
  * @typedef {{
245
- * timescale: number
405
+ * mediaTime: number,
406
+ * ntpTimestamp: number
407
+ * }}
408
+ *
409
+ * @exportDoc
410
+ */
411
+ shaka.util.ParsedPRFTBox;
412
+
413
+ /**
414
+ * @typedef {{
415
+ * timescale: number,
416
+ * language: string
246
417
  * }}
247
418
  *
248
419
  * @property {number} timescale
249
420
  * As per the spec: an integer that specifies the time‐scale for this media;
250
421
  * this is the number of time units that pass in one second
422
+ * @property {string} language
423
+ * Language code for this media
251
424
  *
252
425
  * @exportDoc
253
426
  */
@@ -309,11 +482,17 @@ shaka.util.ParsedTRUNSample;
309
482
 
310
483
  /**
311
484
  * @typedef {{
312
- * trackId: number
485
+ * trackId: number,
486
+ * width: number,
487
+ * height: number
313
488
  * }}
314
489
  *
315
490
  * @property {number} trackId
316
491
  * Unique ID indicative of this track
492
+ * @property {number} width
493
+ * Width of this track in pixels
494
+ * @property {number} height
495
+ * Height of this track in pixels.
317
496
  *
318
497
  * @exportDoc
319
498
  */
@@ -330,3 +509,52 @@ shaka.util.ParsedTKHDBox;
330
509
  * @exportDoc
331
510
  */
332
511
  shaka.util.ParsedFRMABox;
512
+
513
+ /**
514
+ * @typedef {{
515
+ * channelCount: number,
516
+ * sampleRate: number
517
+ * }}
518
+ *
519
+ * @property {number} channelCount
520
+ * @property {number} sampleRate
521
+ *
522
+ * @exportDoc
523
+ */
524
+ shaka.util.ParsedMP4ABox;
525
+
526
+ /**
527
+ * @typedef {{
528
+ * codec: string
529
+ * }}
530
+ *
531
+ * @property {string} codec
532
+ *
533
+ * @exportDoc
534
+ */
535
+ shaka.util.ParsedESDSBox;
536
+
537
+ /**
538
+ * @typedef {{
539
+ * codec: string
540
+ * }}
541
+ *
542
+ * @property {string} codec
543
+ *
544
+ * @exportDoc
545
+ */
546
+ shaka.util.ParsedAVCBox;
547
+
548
+ /**
549
+ * @typedef {{
550
+ * handlerType: string
551
+ * }}
552
+ *
553
+ * @property {string} handlerType
554
+ * A four-character code that identifies the type of the media handler or
555
+ * data handler. For media handlers, this field defines the type of
556
+ * data—for example, 'vide' for video data, 'soun' for sound data.
557
+ *
558
+ * @exportDoc
559
+ */
560
+ shaka.util.ParsedHDLRBox;