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
@@ -740,6 +740,58 @@ describe('SegmentIndex', /** @suppress {accessControls} */ () => {
740
740
  expect(iterator.current()).toBe(null);
741
741
  });
742
742
 
743
+ describe('getIteratorForTime', () => {
744
+ it('begins with an independent partial segment', () => {
745
+ // This test contains its own segment refs, which are manipulated to
746
+ // look a little different from the more general ones used elsewhere.
747
+ // In particular, we mark some partial refs as dependent, and we make
748
+ // the second partial list much longer.
749
+ const partialRefs1 = [
750
+ makeReference(uri(10.15), 10, 15),
751
+ makeReference(uri(15.20), 15, 20),
752
+ ];
753
+ partialRefs1[1].markAsNonIndependent();
754
+
755
+ const partialRefs2 = [
756
+ makeReference(uri(20.25), 20, 25),
757
+ makeReference(uri(25.30), 25, 30),
758
+ makeReference(uri(30.35), 30, 35),
759
+ makeReference(uri(35.40), 35, 40),
760
+ makeReference(uri(40.45), 40, 45),
761
+ makeReference(uri(45.50), 45, 50),
762
+ makeReference(uri(50.55), 50, 55),
763
+ makeReference(uri(55.60), 55, 60),
764
+ makeReference(uri(60.65), 60, 65),
765
+ makeReference(uri(65.70), 65, 70),
766
+ ];
767
+ // All but the first:
768
+ for (const r of partialRefs2.slice(1)) {
769
+ r.markAsNonIndependent();
770
+ }
771
+
772
+ const localInputRefs = [
773
+ makeReference(uri(0.10), 0, 10),
774
+ makeReference(uri(10.20), 10, 20, partialRefs1),
775
+ makeReference(uri(20.70), 20, 70, partialRefs2),
776
+ ];
777
+ const index = new shaka.media.SegmentIndex(localInputRefs);
778
+
779
+ // This time points to partialRefs1[0], which is independent.
780
+ const iterator1 = index.getIteratorForTime(11);
781
+ expect(iterator1.next().value).toBe(partialRefs1[0]);
782
+
783
+ // Even though the time would point to partialRefs1[1], that is not
784
+ // independent. So it walks back to partialRefs1[0].
785
+ const iterator2 = index.getIteratorForTime(16);
786
+ expect(iterator2.next().value).toBe(partialRefs1[0]);
787
+
788
+ // Even though the time would point to partialRefs2[9], that is not
789
+ // independent. So it walks all the way back to partialRefs2[0].
790
+ const iterator3 = index.getIteratorForTime(69);
791
+ expect(iterator3.next().value).toBe(partialRefs2[0]);
792
+ });
793
+ });
794
+
743
795
  describe('next', () => {
744
796
  it('starts with the first segment', () => {
745
797
  const index = new shaka.media.SegmentIndex(inputRefs);
@@ -0,0 +1,243 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+
8
+ describe('SegmentPrefetch', () => {
9
+ const Util = shaka.test.Util;
10
+ /** @type {shaka.media.SegmentPrefetch} */
11
+ let segmentPrefetch;
12
+
13
+ /** @type {!jasmine.Spy} */
14
+ let fetchDispatcher;
15
+
16
+ /** @type {jasmine.Spy} */
17
+ let pendingRequestAbort;
18
+
19
+ /** @type {shaka.extern.Stream} */
20
+ let stream;
21
+
22
+ const references = [
23
+ makeReference(uri('0.10'), 0, 10),
24
+ makeReference(uri('10.20'), 10, 20),
25
+ makeReference(uri('20.30'), 20, 30),
26
+ makeReference(uri('30.40'), 30, 40),
27
+ ];
28
+
29
+ beforeEach(() => {
30
+ pendingRequestAbort =
31
+ jasmine.createSpy('abort').and.returnValue(Promise.resolve());
32
+ const pendingRequestAbortFunc = Util.spyFunc(pendingRequestAbort);
33
+ const bytes = new shaka.net.NetworkingEngine.NumBytesRemainingClass();
34
+ bytes.setBytes(200);
35
+ stream = createStream();
36
+ stream.segmentIndex = new shaka.media.SegmentIndex(references);
37
+ fetchDispatcher = jasmine.createSpy('appendBuffer')
38
+ .and.callFake((ref, stream) =>
39
+ new shaka.net.NetworkingEngine.PendingRequest(
40
+ Promise.resolve({
41
+ uri: ref.getUris()[0],
42
+ data: new ArrayBuffer(0),
43
+ headers: {},
44
+ }),
45
+ pendingRequestAbortFunc,
46
+ bytes,
47
+ ),
48
+ );
49
+ segmentPrefetch = new shaka.media.SegmentPrefetch(
50
+ 3, stream, Util.spyFunc(fetchDispatcher),
51
+ );
52
+ });
53
+
54
+ describe('prefetchSegments', () => {
55
+ it('should prefetch next 3 segments', async () => {
56
+ segmentPrefetch.prefetchSegments(references[0]);
57
+ await expectSegmentsPrefetched(0);
58
+ const op = segmentPrefetch.getPrefetchedSegment(references[3]);
59
+ expect(op).toBeNull();
60
+ expect(fetchDispatcher).toHaveBeenCalledTimes(3);
61
+ });
62
+
63
+ it('prefetch last segment if position is at the end', async () => {
64
+ segmentPrefetch.prefetchSegments(references[3]);
65
+ const op = segmentPrefetch.getPrefetchedSegment(references[3]);
66
+ expect(op).toBeDefined();
67
+ const response = await op.promise;
68
+ const startTime = (3 * 10);
69
+ expect(response.uri).toBe(uri(startTime + '.' + (startTime + 10)));
70
+
71
+ for (let i = 0; i < 3; i++) {
72
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
73
+ expect(op).toBeNull();
74
+ }
75
+ expect(fetchDispatcher).toHaveBeenCalledTimes(1);
76
+ });
77
+
78
+ it('do not prefetch already fetched segment', async () => {
79
+ segmentPrefetch.prefetchSegments(references[1]);
80
+ // since 2 was alreay pre-fetched when prefetch 1, expect
81
+ // no extra fetch is made.
82
+ segmentPrefetch.prefetchSegments(references[2]);
83
+
84
+ expect(fetchDispatcher).toHaveBeenCalledTimes(3);
85
+ await expectSegmentsPrefetched(1);
86
+ });
87
+ });
88
+
89
+ describe('clearAll', () => {
90
+ it('clears all prefetched segments', () => {
91
+ segmentPrefetch.prefetchSegments(references[0]);
92
+ segmentPrefetch.clearAll();
93
+ for (let i = 0; i < 3; i++) {
94
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
95
+ expect(op).toBeNull();
96
+ }
97
+ expect(fetchDispatcher).toHaveBeenCalledTimes(3);
98
+ });
99
+
100
+ it('resets time pos so prefetch can happen again', () => {
101
+ segmentPrefetch.prefetchSegments(references[3]);
102
+ segmentPrefetch.clearAll();
103
+ for (let i = 0; i < 3; i++) {
104
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
105
+ expect(op).toBeNull();
106
+ }
107
+
108
+ segmentPrefetch.prefetchSegments(references[3]);
109
+ for (let i = 0; i < 3; i++) {
110
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
111
+ expect(op).toBeNull();
112
+ }
113
+ expect(segmentPrefetch.getPrefetchedSegment(references[3])).toBeDefined();
114
+ expect(fetchDispatcher).toHaveBeenCalledTimes(2);
115
+ });
116
+ });
117
+
118
+ describe('switchStream', () => {
119
+ it('clears all prefetched segments', () => {
120
+ segmentPrefetch.prefetchSegments(references[0]);
121
+ segmentPrefetch.switchStream(createStream());
122
+ for (let i = 0; i < 3; i++) {
123
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
124
+ expect(op).toBeNull();
125
+ }
126
+ expect(fetchDispatcher).toHaveBeenCalledTimes(3);
127
+ });
128
+
129
+ it('do nothing if its same stream', async () => {
130
+ segmentPrefetch.prefetchSegments(references[0]);
131
+ segmentPrefetch.switchStream(stream);
132
+ await expectSegmentsPrefetched(0);
133
+ });
134
+ });
135
+
136
+ describe('resetLimit', () => {
137
+ it('do nothing if the new limit is larger', async () => {
138
+ segmentPrefetch.prefetchSegments(references[0]);
139
+ segmentPrefetch.resetLimit(4);
140
+ await expectSegmentsPrefetched(0);
141
+ });
142
+
143
+ it('do nothing if the new limit is the same', async () => {
144
+ segmentPrefetch.prefetchSegments(references[0]);
145
+ segmentPrefetch.resetLimit(3);
146
+ await expectSegmentsPrefetched(0);
147
+ });
148
+
149
+ it('clears all prefetched segments beyond new limit', async () => {
150
+ segmentPrefetch.prefetchSegments(references[0]);
151
+ segmentPrefetch.resetLimit(1);
152
+ // expecting prefetched reference 0 is kept
153
+ expectSegmentsPrefetched(0, 1);
154
+ // expecting prefetched references 1 and 2 are removd
155
+ for (let i = 1; i < 3; i++) {
156
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
157
+ expect(op).toBeNull();
158
+ }
159
+
160
+ // clear all to test the new limit by re-fetching.
161
+ segmentPrefetch.clearAll();
162
+ // prefetch again.
163
+ segmentPrefetch.prefetchSegments(references[0]);
164
+ // expect only one is prefetched
165
+ await expectSegmentsPrefetched(0, 1);
166
+ // only dispatched fetch one more time.
167
+ expect(fetchDispatcher).toHaveBeenCalledTimes(3 + 1);
168
+ });
169
+ });
170
+ /**
171
+ * Creates a URI string.
172
+ *
173
+ * @param {string} x
174
+ * @return {string}
175
+ */
176
+ function uri(x) {
177
+ return 'http://example.com/video_' + x + '.m4s';
178
+ }
179
+
180
+ /**
181
+ * Creates a real SegmentReference.
182
+ *
183
+ * @param {string} uri
184
+ * @param {number} startTime
185
+ * @param {number} endTime
186
+ * @return {shaka.media.SegmentReference}
187
+ */
188
+ function makeReference(uri, startTime, endTime) {
189
+ return new shaka.media.SegmentReference(
190
+ startTime,
191
+ endTime,
192
+ /* getUris= */ () => [uri],
193
+ /* startByte= */ 0,
194
+ /* endByte= */ null,
195
+ /* initSegmentReference= */ null,
196
+ /* timestampOffset= */ 0,
197
+ /* appendWindowStart= */ 0,
198
+ /* appendWindowEnd= */ Infinity,
199
+ /* partialReferences= */ [],
200
+ /* tilesLayout= */ undefined,
201
+ /* tileDuration= */ undefined,
202
+ /* syncTime= */ undefined,
203
+ /* status= */ undefined,
204
+ /* hlsAes128Key= */ null);
205
+ }
206
+
207
+ /**
208
+ * Creates a stream.
209
+ * @return {shaka.extern.Stream}
210
+ */
211
+ function createStream() {
212
+ const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
213
+ manifest.presentationTimeline.setDuration(60);
214
+ manifest.addVariant(0, (variant) => {
215
+ variant.addVideo(11, (stream) => {
216
+ stream.useSegmentTemplate('video-11-%d.mp4', 10);
217
+ });
218
+ });
219
+ });
220
+
221
+ const videoStream = manifest.variants[0].video;
222
+ if (!videoStream) {
223
+ throw new Error('unexpected stream setup - variant.video is null');
224
+ }
225
+ return videoStream;
226
+ }
227
+
228
+ /**
229
+ * Expects segments have been prefetched within given range.
230
+ * @param {number} startPos
231
+ * @param {number} limit
232
+ */
233
+ async function expectSegmentsPrefetched(startPos, limit = 3) {
234
+ for (let i = startPos; i < startPos + limit; i++) {
235
+ const op = segmentPrefetch.getPrefetchedSegment(references[i]);
236
+ expect(op).not.toBeNull();
237
+ /* eslint-disable-next-line no-await-in-loop */
238
+ const response = await op.promise;
239
+ const startTime = (i * 10);
240
+ expect(response.uri).toBe(uri(startTime + '.' + (startTime + 10)));
241
+ }
242
+ }
243
+ });
@@ -255,7 +255,6 @@ describe('StreamingEngine', () => {
255
255
 
256
256
  function createStreamingEngine() {
257
257
  const playerInterface = {
258
- modifySegmentRequest: (request, segmentInfo) => {},
259
258
  getPresentationTime: () => playhead.getTime(),
260
259
  getBandwidthEstimate: () => 1e6,
261
260
  mediaSourceEngine: mediaSourceEngine,
@@ -267,6 +266,7 @@ describe('StreamingEngine', () => {
267
266
  onInitSegmentAppended: () => {},
268
267
  beforeAppendSegment: () => Promise.resolve(),
269
268
  onMetadata: () => {},
269
+ disableStream: (stream, time) => false,
270
270
  };
271
271
  streamingEngine = new shaka.media.StreamingEngine(
272
272
  /** @type {shaka.extern.Manifest} */(manifest), playerInterface);
@@ -360,10 +360,13 @@ describe('StreamingEngine', () => {
360
360
  await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 305);
361
361
 
362
362
  const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
363
+ const segmentContext = {
364
+ type: shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT,
365
+ };
363
366
  // firstSegmentNumber =
364
367
  // [(segmentAvailabilityEnd - rebufferingGoal) / segmentDuration] + 1
365
- netEngine.expectRequest('0_video_29', segmentType);
366
- netEngine.expectRequest('0_audio_29', segmentType);
368
+ netEngine.expectRequest('0_video_29', segmentType, segmentContext);
369
+ netEngine.expectRequest('0_audio_29', segmentType, segmentContext);
367
370
  });
368
371
 
369
372
  it('can handle seeks ahead of availability window', async () => {
@@ -595,6 +598,9 @@ describe('StreamingEngine', () => {
595
598
  textStreams: [],
596
599
  imageStreams: [],
597
600
  sequenceMode: false,
601
+ ignoreManifestTimestampsInSegmentsMode: false,
602
+ type: 'UNKNOWN',
603
+ serviceDescription: null,
598
604
  variants: [{
599
605
  id: 1,
600
606
  video: {