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
@@ -66,8 +66,6 @@ describe('HlsParser live', () => {
66
66
 
67
67
  config = shaka.util.PlayerConfiguration.createDefault().manifest;
68
68
  playerInterface = {
69
- modifyManifestRequest: (request, manifestInfo) => {},
70
- modifySegmentRequest: (request, segmentInfo) => {},
71
69
  filter: () => Promise.resolve(),
72
70
  makeTextStreamsForClosedCaptions: (manifest) => {},
73
71
  networkingEngine: fakeNetEngine,
@@ -90,6 +88,15 @@ describe('HlsParser live', () => {
90
88
  parser.stop();
91
89
  });
92
90
 
91
+ /**
92
+ * Gets a spy on the function that sets the update period.
93
+ * @return {!jasmine.Spy}
94
+ * @suppress {accessControls}
95
+ */
96
+ function updateTickSpy() {
97
+ return spyOn(parser.updatePlaylistTimer_, 'tickAfter');
98
+ }
99
+
93
100
  /**
94
101
  * Trigger a manifest update.
95
102
  * @suppress {accessControls}
@@ -334,6 +341,34 @@ describe('HlsParser live', () => {
334
341
  expect(notifySegmentsSpy).toHaveBeenCalled();
335
342
  });
336
343
 
344
+ it('fatal error on manifest update request failure when ' +
345
+ 'raiseFatalErrorOnManifestUpdateRequestFailure is true', async () => {
346
+ const manifestConfig =
347
+ shaka.util.PlayerConfiguration.createDefault().manifest;
348
+ manifestConfig.raiseFatalErrorOnManifestUpdateRequestFailure = true;
349
+ parser.configure(manifestConfig);
350
+
351
+ const updateTick = updateTickSpy();
352
+
353
+ await testInitialManifest(master, media);
354
+ expect(updateTick).toHaveBeenCalledTimes(1);
355
+
356
+ /** @type {!jasmine.Spy} */
357
+ const onError = jasmine.createSpy('onError');
358
+ playerInterface.onError = shaka.test.Util.spyFunc(onError);
359
+
360
+ const error = new shaka.util.Error(
361
+ shaka.util.Error.Severity.CRITICAL,
362
+ shaka.util.Error.Category.NETWORK,
363
+ shaka.util.Error.Code.BAD_HTTP_STATUS);
364
+ const operation = shaka.util.AbortableOperation.failed(error);
365
+ fakeNetEngine.request.and.returnValue(operation);
366
+
367
+ await delayForUpdatePeriod();
368
+ expect(onError).toHaveBeenCalledWith(error);
369
+ expect(updateTick).toHaveBeenCalledTimes(1);
370
+ });
371
+
337
372
  it('converts to VOD only after all playlists end', async () => {
338
373
  const master = [
339
374
  '#EXTM3U\n',
@@ -373,9 +408,13 @@ describe('HlsParser live', () => {
373
408
  manifest, mediaWithAdditionalSegment + '#EXT-X-ENDLIST\n');
374
409
 
375
410
  // We saw one request for the video playlist, which signalled "ENDLIST".
411
+ const type =
412
+ shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST;
413
+
376
414
  fakeNetEngine.expectRequest(
377
415
  'test:/video',
378
- shaka.net.NetworkingEngine.RequestType.MANIFEST);
416
+ shaka.net.NetworkingEngine.RequestType.MANIFEST,
417
+ {type});
379
418
  expect(manifest.presentationTimeline.isLive()).toBe(false);
380
419
 
381
420
  fakeNetEngine.request.calls.reset();
@@ -505,6 +544,24 @@ describe('HlsParser live', () => {
505
544
  expect(manifest.presentationTimeline.getDelay()).toBe(15);
506
545
  });
507
546
 
547
+ it('sets presentation delay if defined', async () => {
548
+ const media = [
549
+ '#EXTM3U\n',
550
+ '#EXT-X-SERVER-CONTROL:HOLD-BACK=2\n',
551
+ '#EXT-X-TARGETDURATION:5\n',
552
+ '#EXT-X-PART-INF:PART-TARGET=0.5\n',
553
+ '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
554
+ '#EXT-X-MEDIA-SEQUENCE:0\n',
555
+ '#EXTINF:2,\n',
556
+ 'main.mp4\n',
557
+ ].join('');
558
+
559
+ const manifest = await testInitialManifest(master, media);
560
+ // Presentation delay should be the value of 'HOLD-BACK' if not
561
+ // configured.
562
+ expect(manifest.presentationTimeline.getDelay()).toBe(2);
563
+ });
564
+
508
565
  it('sets presentation delay for low latency mode', async () => {
509
566
  const mediaWithLowLatency = [
510
567
  '#EXTM3U\n',
@@ -577,44 +634,44 @@ describe('HlsParser live', () => {
577
634
  '#EXTM3U\n',
578
635
  '#EXT-X-TARGETDURATION:5\n',
579
636
  '#EXT-X-PART-INF:PART-TARGET=1.5\n',
580
- '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
637
+ '#EXT-X-MAP:URI="init.mp4"\n',
581
638
  '#EXT-X-MEDIA-SEQUENCE:0\n',
582
639
  // ref includes partialRef, partialRef2
583
640
  // partialRef
584
- '#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=200@0\n',
641
+ '#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
585
642
  // partialRef2
586
- '#EXT-X-PART:DURATION=2,URI="partial2.mp4",BYTERANGE=230@200\n',
643
+ '#EXT-X-PART:DURATION=2,URI="partial2.mp4",INDEPENDENT=YES\n',
587
644
  '#EXTINF:4,\n',
588
645
  'main.mp4\n',
589
646
  // ref2 includes partialRef3, preloadRef
590
647
  // partialRef3
591
- '#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
648
+ '#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
592
649
  // preloadRef
593
- '#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210,',
594
- 'BYTERANGE-LENGTH=210\n',
650
+ '#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"\n',
595
651
  ].join('');
596
652
 
597
653
  const partialRef = makeReference(
598
654
  'test:/partial.mp4', 0, 2, /* syncTime= */ null,
599
- /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 199);
655
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
600
656
 
601
657
  const partialRef2 = makeReference(
602
658
  'test:/partial2.mp4', 2, 4, /* syncTime= */ null,
603
- /* baseUri= */ '', /* startByte= */ 200, /* endByte= */ 429);
659
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
604
660
 
605
661
  const ref = makeReference(
606
662
  'test:/main.mp4', 0, 4, /* syncTime= */ null,
607
- /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
663
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
608
664
  /* timestampOffset= */ 0, [partialRef, partialRef2]);
609
665
 
610
666
  const partialRef3 = makeReference(
611
667
  'test:/partial.mp4', 4, 6, /* syncTime= */ null,
612
- /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
668
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
613
669
 
614
670
  const preloadRef = makeReference(
615
671
  'test:/partial.mp4', 6, 7.5, /* syncTime= */ null,
616
- /* baseUri= */ '', /* startByte= */ 210, /* endByte= */ null);
672
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
617
673
  preloadRef.markAsPreload();
674
+ preloadRef.markAsNonIndependent();
618
675
 
619
676
  // ref2 is not fully published yet, so it doesn't have a segment uri.
620
677
  const ref2 = makeReference(
@@ -625,6 +682,85 @@ describe('HlsParser live', () => {
625
682
  await testInitialManifest(master, mediaWithPartialSegments, [ref, ref2]);
626
683
  });
627
684
 
685
+ it('parses streams with partial and preload hinted segments and BYTERANGE', async () => { // eslint-disable-line max-len
686
+ playerInterface.isLowLatencyMode = () => true;
687
+ const mediaWithPartialSegments = [
688
+ '#EXTM3U\n',
689
+ '#EXT-X-TARGETDURATION:5\n',
690
+ '#EXT-X-PART-INF:PART-TARGET=1.5\n',
691
+ '#EXT-X-MAP:URI="init.mp4"\n',
692
+ '#EXT-X-MEDIA-SEQUENCE:0\n',
693
+ // ref includes partialRef, partialRef2
694
+ // partialRef
695
+ '#EXT-X-PART:DURATION=2,URI="ref1.mp4",BYTERANGE=200@0,',
696
+ 'INDEPENDENT=YES\n',
697
+ // partialRef2
698
+ '#EXT-X-PART:DURATION=2,URI="ref1.mp4",BYTERANGE=230@200,',
699
+ 'INDEPENDENT=YES\n',
700
+ '#EXTINF:4,\n',
701
+ 'ref1.mp4\n',
702
+ // ref2 includes partialRef3, preloadRef
703
+ // partialRef3
704
+ '#EXT-X-PART:DURATION=2,URI="ref2.mp4",BYTERANGE=210@0,',
705
+ 'INDEPENDENT=YES\n',
706
+ // preloadRef
707
+ '#EXT-X-PRELOAD-HINT:TYPE=PART,URI="ref2.mp4",BYTERANGE-START=210,',
708
+ 'BYTERANGE-LENGTH=210\n',
709
+ ].join('');
710
+
711
+ // If ReadableStream is defined we can apply some optimizations
712
+ if (window.ReadableStream) {
713
+ const ref = makeReference(
714
+ 'test:/ref1.mp4', 0, 4, /* syncTime= */ null,
715
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
716
+ /* timestampOffset= */ 0);
717
+ ref.markAsByterangeOptimization();
718
+
719
+ // ref2 is not fully published yet, so it doesn't have a segment uri.
720
+ const ref2 = makeReference(
721
+ 'test:/ref2.mp4', 4, 7.5, /* syncTime= */ null,
722
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
723
+ /* timestampOffset= */ 0);
724
+ ref2.markAsByterangeOptimization();
725
+ ref2.markAsPreload();
726
+
727
+ await testInitialManifest(master, mediaWithPartialSegments,
728
+ [ref, ref2]);
729
+ } else {
730
+ const partialRef = makeReference(
731
+ 'test:/ref1.mp4', 0, 2, /* syncTime= */ null,
732
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 199);
733
+
734
+ const partialRef2 = makeReference(
735
+ 'test:/ref1.mp4', 2, 4, /* syncTime= */ null,
736
+ /* baseUri= */ '', /* startByte= */ 200, /* endByte= */ 429);
737
+
738
+ const ref = makeReference(
739
+ 'test:/ref1.mp4', 0, 4, /* syncTime= */ null,
740
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
741
+ /* timestampOffset= */ 0, [partialRef, partialRef2]);
742
+
743
+ const partialRef3 = makeReference(
744
+ 'test:/ref2.mp4', 4, 6, /* syncTime= */ null,
745
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
746
+
747
+ const preloadRef = makeReference(
748
+ 'test:/ref2.mp4', 6, 7.5, /* syncTime= */ null,
749
+ /* baseUri= */ '', /* startByte= */ 210, /* endByte= */ 419);
750
+ preloadRef.markAsPreload();
751
+ preloadRef.markAsNonIndependent();
752
+
753
+ // ref2 is not fully published yet, so it doesn't have a segment uri.
754
+ const ref2 = makeReference(
755
+ '', 4, 7.5, /* syncTime= */ null,
756
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 419,
757
+ /* timestampOffset= */ 0, [partialRef3, preloadRef]);
758
+
759
+ await testInitialManifest(master, mediaWithPartialSegments,
760
+ [ref, ref2]);
761
+ }
762
+ });
763
+
628
764
  // Test for https://github.com/shaka-project/shaka-player/issues/4223
629
765
  it('ignores preload hinted segments without target duration', async () => {
630
766
  playerInterface.isLowLatencyMode = () => true;
@@ -640,9 +776,9 @@ describe('HlsParser live', () => {
640
776
  'main.mp4\n',
641
777
  // ref2 includes partialRef, but not preloadRef
642
778
  // partialRef
643
- '#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
779
+ '#EXT-X-PART:DURATION=2,URI="partial.mp4",INDEPENDENT=YES\n',
644
780
  // preloadRef
645
- '#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
781
+ '#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4"\n',
646
782
  ].join('');
647
783
 
648
784
  const ref = makeReference(
@@ -652,12 +788,12 @@ describe('HlsParser live', () => {
652
788
 
653
789
  const partialRef = makeReference(
654
790
  'test:/partial.mp4', 4, 6, /* syncTime= */ null,
655
- /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
791
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null);
656
792
 
657
793
  // ref2 is not fully published yet, so it doesn't have a segment uri.
658
794
  const ref2 = makeReference(
659
795
  '', 4, 6, /* syncTime= */ null,
660
- /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209,
796
+ /* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
661
797
  /* timestampOffset= */ 0, [partialRef]);
662
798
 
663
799
  await testInitialManifest(master, mediaWithPartialSegments, [ref, ref2]);
@@ -843,9 +979,12 @@ describe('HlsParser live', () => {
843
979
  // Only one request was made, and it was for the playlist.
844
980
  // No segment requests were needed to get the start time.
845
981
  expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
982
+ const type =
983
+ shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST;
846
984
  fakeNetEngine.expectRequest(
847
985
  'test:/video',
848
- shaka.net.NetworkingEngine.RequestType.MANIFEST);
986
+ shaka.net.NetworkingEngine.RequestType.MANIFEST,
987
+ {type});
849
988
  });
850
989
 
851
990
  it('request playlist delta updates to skip segments', async () => {
@@ -855,39 +994,60 @@ describe('HlsParser live', () => {
855
994
  '#EXT-X-TARGETDURATION:5\n',
856
995
  '#EXT-X-MEDIA-SEQUENCE:0\n',
857
996
  '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
858
- '#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=60.0\n',
997
+ '#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
859
998
  '#EXTINF:2,\n',
860
- 'main.mp4\n',
999
+ 'main0.mp4\n',
861
1000
  '#EXTINF:2,\n',
862
- 'main2.mp4\n',
1001
+ 'main1.mp4\n',
863
1002
  ].join('');
864
1003
 
865
- const mediaWithSkippedSegments = [
1004
+ const mediaWithSkippedSegments1 = [
866
1005
  '#EXTM3U\n',
867
1006
  '#EXT-X-TARGETDURATION:5\n',
868
1007
  '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
869
- '#EXT-X-MEDIA-SEQUENCE:0\n',
870
- '#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=60.0\n',
1008
+ '#EXT-X-MEDIA-SEQUENCE:1\n',
1009
+ '#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
871
1010
  '#EXT-X-SKIP:SKIPPED-SEGMENTS=1\n',
872
1011
  '#EXTINF:2,\n',
873
1012
  'main2.mp4\n',
1013
+ ].join('');
1014
+
1015
+ const mediaWithSkippedSegments2 = [
1016
+ '#EXTM3U\n',
1017
+ '#EXT-X-TARGETDURATION:5\n',
1018
+ '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
1019
+ '#EXT-X-MEDIA-SEQUENCE:2\n',
1020
+ '#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-UNTIL=60.0,\n',
1021
+ '#EXT-X-SKIP:SKIPPED-SEGMENTS=1\n',
874
1022
  '#EXTINF:2,\n',
875
1023
  'main3.mp4\n',
876
1024
  ].join('');
877
1025
 
878
1026
  fakeNetEngine.setResponseText(
879
- 'test:/video?_HLS_skip=YES', mediaWithSkippedSegments);
1027
+ 'test:/video?_HLS_msn=2&_HLS_skip=YES', mediaWithSkippedSegments1);
1028
+
1029
+ fakeNetEngine.setResponseText(
1030
+ 'test:/video?_HLS_msn=3&_HLS_skip=YES', mediaWithSkippedSegments2);
880
1031
 
881
1032
  playerInterface.isLowLatencyMode = () => true;
882
1033
 
883
1034
  await testInitialManifest(master, mediaWithDeltaUpdates);
884
1035
 
885
1036
  fakeNetEngine.request.calls.reset();
1037
+
886
1038
  await delayForUpdatePeriod();
1039
+ fakeNetEngine.expectRequest(
1040
+ 'test:/video?_HLS_msn=2&_HLS_skip=YES',
1041
+ shaka.net.NetworkingEngine.RequestType.MANIFEST,
1042
+ {type:
1043
+ shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST});
887
1044
 
1045
+ await delayForUpdatePeriod();
888
1046
  fakeNetEngine.expectRequest(
889
- 'test:/video?_HLS_skip=YES',
890
- shaka.net.NetworkingEngine.RequestType.MANIFEST);
1047
+ 'test:/video?_HLS_msn=3&_HLS_skip=YES',
1048
+ shaka.net.NetworkingEngine.RequestType.MANIFEST,
1049
+ {type:
1050
+ shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_PLAYLIST});
891
1051
  });
892
1052
 
893
1053
  it('skips older segments', async () => {