shaka-player 4.6.3 → 4.7.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 (608) hide show
  1. package/README.md +1 -0
  2. package/dist/controls.css +1 -1
  3. package/dist/controls.css.map +1 -1
  4. package/dist/deps.js +13 -9
  5. package/dist/locales.js +33 -33
  6. package/dist/shaka-player.compiled.d.ts +47 -4
  7. package/dist/shaka-player.compiled.debug.d.ts +47 -4
  8. package/dist/shaka-player.compiled.debug.externs.js +50 -2
  9. package/dist/shaka-player.compiled.debug.js +408 -376
  10. package/dist/shaka-player.compiled.debug.map +4 -4
  11. package/dist/shaka-player.compiled.externs.js +50 -2
  12. package/dist/shaka-player.compiled.js +1134 -1118
  13. package/dist/shaka-player.compiled.map +4 -4
  14. package/dist/shaka-player.ui.d.ts +69 -5
  15. package/dist/shaka-player.ui.debug.d.ts +69 -5
  16. package/dist/shaka-player.ui.debug.externs.js +82 -2
  17. package/dist/shaka-player.ui.debug.js +457 -420
  18. package/dist/shaka-player.ui.debug.map +4 -4
  19. package/dist/shaka-player.ui.externs.js +82 -2
  20. package/dist/shaka-player.ui.js +1305 -1289
  21. package/dist/shaka-player.ui.map +4 -4
  22. package/externs/mediasession.js +7 -0
  23. package/externs/shaka/abr_manager.js +8 -0
  24. package/externs/shaka/manifest.js +3 -3
  25. package/externs/shaka/player.js +59 -4
  26. package/lib/abr/simple_abr_manager.js +41 -15
  27. package/lib/ads/client_side_ad_manager.js +4 -0
  28. package/lib/ads/media_tailor_ad_manager.js +5 -0
  29. package/lib/ads/server_side_ad_manager.js +4 -0
  30. package/lib/cea/cea708_service.js +1 -1
  31. package/lib/cea/cea708_window.js +95 -7
  32. package/lib/dash/dash_parser.js +55 -11
  33. package/lib/hls/hls_parser.js +17 -5
  34. package/lib/media/adaptation_set_criteria.js +76 -10
  35. package/lib/media/drm_engine.js +0 -3
  36. package/lib/media/media_source_engine.js +42 -18
  37. package/lib/media/segment_reference.js +12 -0
  38. package/lib/media/streaming_engine.js +58 -5
  39. package/lib/media/video_wrapper.js +4 -3
  40. package/lib/player.js +95 -11
  41. package/lib/text/simple_text_displayer.js +8 -7
  42. package/lib/text/text_utils.js +39 -13
  43. package/lib/text/ui_text_displayer.js +20 -11
  44. package/lib/text/web_vtt_generator.js +1 -1
  45. package/lib/util/cmsd_manager.js +269 -0
  46. package/lib/util/content_steering_manager.js +5 -1
  47. package/lib/util/mime_utils.js +6 -2
  48. package/lib/util/periods.js +108 -39
  49. package/lib/util/player_configuration.js +19 -5
  50. package/lib/util/stream_utils.js +82 -13
  51. package/package.json +1 -1
  52. package/ui/audio_language_selection.js +3 -0
  53. package/ui/controls.js +60 -0
  54. package/ui/externs/ui.js +12 -1
  55. package/ui/hidden_fast_forward_button.js +32 -0
  56. package/ui/hidden_rewind_button.js +32 -0
  57. package/ui/hidden_seek_button.js +121 -0
  58. package/ui/less/buttons.less +50 -0
  59. package/ui/less/containers.less +18 -0
  60. package/ui/resolution_selection.js +2 -0
  61. package/ui/ui.js +2 -0
  62. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -75
  63. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -26
  64. package/.github/ISSUE_TEMPLATE/question.md +0 -26
  65. package/.github/config.yml +0 -1
  66. package/.github/workflows/appspot.yaml +0 -39
  67. package/.github/workflows/build-and-test.yaml +0 -222
  68. package/.github/workflows/compute-incremental-coverage.py +0 -265
  69. package/.github/workflows/custom-actions/prep-for-appspot/action.yaml +0 -56
  70. package/.github/workflows/custom-actions/set-commit-status/action.yaml +0 -37
  71. package/.github/workflows/deflake.yaml +0 -31
  72. package/.github/workflows/demo-version-index.yaml +0 -43
  73. package/.github/workflows/nightly-demo.yaml +0 -42
  74. package/.github/workflows/release-please.yaml +0 -193
  75. package/.github/workflows/report-incremental-coverage.yaml +0 -39
  76. package/.github/workflows/safari-homedir-launcher.sh +0 -18
  77. package/.github/workflows/selenium-lab-tests.yaml +0 -370
  78. package/.github/workflows/shaka-bot-commands/command-help.sh +0 -27
  79. package/.github/workflows/shaka-bot-commands/command-test.sh +0 -56
  80. package/.github/workflows/shaka-bot-commands/lib.sh +0 -83
  81. package/.github/workflows/shaka-bot-commands/main.sh +0 -51
  82. package/.github/workflows/sync-labels.yaml +0 -33
  83. package/.github/workflows/talk-to-shaka-bot.yaml +0 -29
  84. package/.github/workflows/update-issues.yaml +0 -31
  85. package/.github/workflows/update-screenshots.yaml +0 -142
  86. package/.github/workflows/validate-pr-title.yaml +0 -27
  87. package/CHANGELOG.md +0 -5764
  88. package/CODE_OF_CONDUCT.md +0 -93
  89. package/CONTRIBUTING.md +0 -76
  90. package/demo/TengwarTelcontar.woff2 +0 -0
  91. package/demo/app_logo_144.png +0 -0
  92. package/demo/app_logo_192.png +0 -0
  93. package/demo/app_logo_256.png +0 -0
  94. package/demo/app_logo_384.png +0 -0
  95. package/demo/app_logo_512.png +0 -0
  96. package/demo/app_manifest.json +0 -29
  97. package/demo/asset_card.js +0 -410
  98. package/demo/autoTemplate.txt +0 -61
  99. package/demo/cast_receiver/idle1.jpg +0 -0
  100. package/demo/cast_receiver/idle2.jpg +0 -0
  101. package/demo/cast_receiver/idle3.jpg +0 -0
  102. package/demo/cast_receiver/index.html +0 -75
  103. package/demo/cast_receiver/receiver_app.css +0 -111
  104. package/demo/cast_receiver/receiver_app.js +0 -158
  105. package/demo/close_button.js +0 -60
  106. package/demo/common/asset.js +0 -511
  107. package/demo/common/assets.js +0 -1635
  108. package/demo/config.js +0 -859
  109. package/demo/custom.js +0 -907
  110. package/demo/customWarning.txt +0 -8
  111. package/demo/demo.less +0 -591
  112. package/demo/demo_uncompiled.js +0 -11
  113. package/demo/demo_utils.js +0 -113
  114. package/demo/favicon.ico +0 -0
  115. package/demo/front.js +0 -156
  116. package/demo/icons/README.md +0 -4
  117. package/demo/icons/baseline-audiotrack-24px.svg +0 -1
  118. package/demo/icons/baseline-closed_caption-24px.svg +0 -1
  119. package/demo/icons/baseline-fast_forward-24px.svg +0 -1
  120. package/demo/icons/baseline-language-24px.svg +0 -1
  121. package/demo/icons/baseline-live_tv-24px.svg +0 -1
  122. package/demo/icons/baseline-subtitles-24px.svg +0 -1
  123. package/demo/icons/baseline-surround_sound-24px.svg +0 -1
  124. package/demo/icons/custom_ad.svg +0 -1
  125. package/demo/icons/custom_box_with_text.svg +0 -1
  126. package/demo/icons/custom_clear_key.svg +0 -1
  127. package/demo/icons/custom_high_definition.svg +0 -1
  128. package/demo/icons/custom_playready.svg +0 -1
  129. package/demo/icons/custom_ultra_high_definition.svg +0 -1
  130. package/demo/icons/custom_widevine.svg +0 -1
  131. package/demo/index.html +0 -173
  132. package/demo/input.js +0 -270
  133. package/demo/input_container.js +0 -218
  134. package/demo/load.js +0 -156
  135. package/demo/main.js +0 -1854
  136. package/demo/search.js +0 -452
  137. package/demo/service_worker.js +0 -355
  138. package/demo/shaka_logo_trans.png +0 -0
  139. package/demo/tooltip.js +0 -29
  140. package/demo/visualizer.js +0 -335
  141. package/demo/visualizer_button.js +0 -84
  142. package/dist/demo.compiled.debug.js +0 -340
  143. package/dist/demo.compiled.debug.map +0 -8
  144. package/dist/demo.compiled.js +0 -340
  145. package/dist/demo.compiled.map +0 -8
  146. package/dist/demo.css +0 -6
  147. package/dist/demo.css.map +0 -1
  148. package/dist/receiver.compiled.debug.js +0 -187
  149. package/dist/receiver.compiled.debug.map +0 -8
  150. package/dist/receiver.compiled.js +0 -187
  151. package/dist/receiver.compiled.map +0 -8
  152. package/docs/announcement-list-join-group.png +0 -0
  153. package/docs/api-mainpage.md +0 -28
  154. package/docs/design/REDESIGN.md +0 -283
  155. package/docs/design/architecture.md +0 -13
  156. package/docs/design/bg-fetch-after.gv +0 -29
  157. package/docs/design/bg-fetch-after.gv.png +0 -0
  158. package/docs/design/bg-fetch-before.gv +0 -18
  159. package/docs/design/bg-fetch-before.gv.png +0 -0
  160. package/docs/design/bg-fetch.md +0 -134
  161. package/docs/design/cast.gv +0 -35
  162. package/docs/design/cast.gv.png +0 -0
  163. package/docs/design/chromecast.md +0 -151
  164. package/docs/design/codec_preferences.md +0 -158
  165. package/docs/design/dash-audio-channels.md +0 -123
  166. package/docs/design/dash-manifests.md +0 -248
  167. package/docs/design/dash-timeline.svg +0 -4
  168. package/docs/design/dataflow.gv +0 -66
  169. package/docs/design/dataflow.gv.png +0 -0
  170. package/docs/design/export.md +0 -70
  171. package/docs/design/fuzzy-locale-matching.md +0 -40
  172. package/docs/design/gap-jumping.md +0 -151
  173. package/docs/design/lcevc-architecture.png +0 -0
  174. package/docs/design/lcevc-demo.png +0 -0
  175. package/docs/design/lcevc-integration.md +0 -72
  176. package/docs/design/locale_compatibility.svg +0 -1
  177. package/docs/design/locales_tree.svg +0 -1
  178. package/docs/design/localization-design-principles.md +0 -158
  179. package/docs/design/newdemo.gv +0 -83
  180. package/docs/design/newdemo.gv.png +0 -0
  181. package/docs/design/offline.gv +0 -43
  182. package/docs/design/offline.gv.png +0 -0
  183. package/docs/design/offline.md +0 -153
  184. package/docs/design/ownership.gv +0 -76
  185. package/docs/design/ownership.gv.png +0 -0
  186. package/docs/design/preload.md +0 -299
  187. package/docs/design/preload.png +0 -0
  188. package/docs/design/talking-about-languages.md +0 -46
  189. package/docs/design/timeline.svg +0 -152
  190. package/docs/design/ui.md +0 -31
  191. package/docs/design/ui_player_relationships.svg +0 -1
  192. package/docs/jsdoc-plugin.js +0 -74
  193. package/docs/jsdoc-template/README.md +0 -1
  194. package/docs/jsdoc-template/publish.js +0 -879
  195. package/docs/jsdoc-template/static/fonts/OpenSans-Bold-webfont.eot +0 -0
  196. package/docs/jsdoc-template/static/fonts/OpenSans-Bold-webfont.svg +0 -1830
  197. package/docs/jsdoc-template/static/fonts/OpenSans-Bold-webfont.woff +0 -0
  198. package/docs/jsdoc-template/static/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  199. package/docs/jsdoc-template/static/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  200. package/docs/jsdoc-template/static/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  201. package/docs/jsdoc-template/static/fonts/OpenSans-Italic-webfont.eot +0 -0
  202. package/docs/jsdoc-template/static/fonts/OpenSans-Italic-webfont.svg +0 -1830
  203. package/docs/jsdoc-template/static/fonts/OpenSans-Italic-webfont.woff +0 -0
  204. package/docs/jsdoc-template/static/fonts/OpenSans-Light-webfont.eot +0 -0
  205. package/docs/jsdoc-template/static/fonts/OpenSans-Light-webfont.svg +0 -1831
  206. package/docs/jsdoc-template/static/fonts/OpenSans-Light-webfont.woff +0 -0
  207. package/docs/jsdoc-template/static/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  208. package/docs/jsdoc-template/static/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  209. package/docs/jsdoc-template/static/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  210. package/docs/jsdoc-template/static/fonts/OpenSans-Regular-webfont.eot +0 -0
  211. package/docs/jsdoc-template/static/fonts/OpenSans-Regular-webfont.svg +0 -1831
  212. package/docs/jsdoc-template/static/fonts/OpenSans-Regular-webfont.woff +0 -0
  213. package/docs/jsdoc-template/static/scripts/linenumber.js +0 -44
  214. package/docs/jsdoc-template/static/scripts/show-widget.js +0 -55
  215. package/docs/jsdoc-template/static/styles/jsdoc-default.css +0 -438
  216. package/docs/jsdoc-template/tmpl/augments.tmpl +0 -10
  217. package/docs/jsdoc-template/tmpl/container.tmpl +0 -205
  218. package/docs/jsdoc-template/tmpl/details.tmpl +0 -152
  219. package/docs/jsdoc-template/tmpl/example.tmpl +0 -2
  220. package/docs/jsdoc-template/tmpl/examples.tmpl +0 -13
  221. package/docs/jsdoc-template/tmpl/exceptions.tmpl +0 -32
  222. package/docs/jsdoc-template/tmpl/layout.tmpl +0 -50
  223. package/docs/jsdoc-template/tmpl/mainpage.tmpl +0 -14
  224. package/docs/jsdoc-template/tmpl/members.tmpl +0 -47
  225. package/docs/jsdoc-template/tmpl/method.tmpl +0 -140
  226. package/docs/jsdoc-template/tmpl/modifies.tmpl +0 -14
  227. package/docs/jsdoc-template/tmpl/params.tmpl +0 -131
  228. package/docs/jsdoc-template/tmpl/properties.tmpl +0 -125
  229. package/docs/jsdoc-template/tmpl/returns.tmpl +0 -19
  230. package/docs/jsdoc-template/tmpl/source.tmpl +0 -8
  231. package/docs/jsdoc-template/tmpl/tutorial.tmpl +0 -21
  232. package/docs/jsdoc-template/tmpl/type.tmpl +0 -7
  233. package/docs/jsdoc.conf.json +0 -38
  234. package/docs/shaka-player-logo.png +0 -0
  235. package/docs/style.md +0 -174
  236. package/docs/tutorials/a11y.md +0 -64
  237. package/docs/tutorials/ad_monetization.md +0 -292
  238. package/docs/tutorials/application-level-redirects.md +0 -94
  239. package/docs/tutorials/architecture.md +0 -32
  240. package/docs/tutorials/basic-usage.md +0 -89
  241. package/docs/tutorials/blob-url.md +0 -15
  242. package/docs/tutorials/config.md +0 -148
  243. package/docs/tutorials/debugging.md +0 -189
  244. package/docs/tutorials/drm-config.md +0 -274
  245. package/docs/tutorials/errors.md +0 -95
  246. package/docs/tutorials/fairplay.md +0 -242
  247. package/docs/tutorials/faq.md +0 -252
  248. package/docs/tutorials/index.json +0 -29
  249. package/docs/tutorials/lcevc.md +0 -118
  250. package/docs/tutorials/license-server-auth.md +0 -248
  251. package/docs/tutorials/license-wrapping.md +0 -168
  252. package/docs/tutorials/manifest-parser.md +0 -365
  253. package/docs/tutorials/network-and-buffering-config.md +0 -119
  254. package/docs/tutorials/offline.md +0 -683
  255. package/docs/tutorials/plugins.md +0 -184
  256. package/docs/tutorials/selenium-grid-config.md +0 -174
  257. package/docs/tutorials/service-worker.md +0 -106
  258. package/docs/tutorials/ui-customization.md +0 -288
  259. package/docs/tutorials/ui.md +0 -230
  260. package/docs/tutorials/upgrade-manifest.md +0 -281
  261. package/docs/tutorials/upgrade.md +0 -104
  262. package/docs/tutorials/welcome.md +0 -108
  263. package/docs/tutorials/widevine-service-certs.md +0 -45
  264. package/karma.conf.js +0 -879
  265. package/maintained-branches.md +0 -15
  266. package/roadmap.md +0 -186
  267. package/test/abr/simple_abr_manager_unit.js +0 -398
  268. package/test/ads/ad_manager_unit.js +0 -260
  269. package/test/assumptions/uint8_array_unit.js +0 -22
  270. package/test/cast/cast_proxy_unit.js +0 -736
  271. package/test/cast/cast_receiver_integration.js +0 -488
  272. package/test/cast/cast_receiver_unit.js +0 -1183
  273. package/test/cast/cast_sender_unit.js +0 -973
  274. package/test/cast/cast_utils_unit.js +0 -311
  275. package/test/cea/cea608_memory_unit.js +0 -411
  276. package/test/cea/cea708_service_unit.js +0 -674
  277. package/test/cea/cea708_window_unit.js +0 -373
  278. package/test/cea/cea_decoder_unit.js +0 -615
  279. package/test/cea/dtvcc_packet_builder_unit.js +0 -158
  280. package/test/cea/dtvcc_packet_unit.js +0 -60
  281. package/test/cea/mp4_cea_parser_unit.js +0 -127
  282. package/test/codec_switching/codec_switching_integration.js +0 -182
  283. package/test/dash/dash_parser_content_protection_unit.js +0 -998
  284. package/test/dash/dash_parser_integration.js +0 -74
  285. package/test/dash/dash_parser_live_unit.js +0 -1542
  286. package/test/dash/dash_parser_manifest_unit.js +0 -3121
  287. package/test/dash/dash_parser_segment_base_unit.js +0 -421
  288. package/test/dash/dash_parser_segment_list_unit.js +0 -380
  289. package/test/dash/dash_parser_segment_template_unit.js +0 -910
  290. package/test/dash/mpd_utils_unit.js +0 -794
  291. package/test/demo/demo_unit.js +0 -108
  292. package/test/deprecate/enforcer_unit.js +0 -74
  293. package/test/deprecate/version_unit.js +0 -57
  294. package/test/hls/hls_live_unit.js +0 -1330
  295. package/test/hls/hls_parser_unit.js +0 -5276
  296. package/test/hls/manifest_text_parser_unit.js +0 -545
  297. package/test/media/adaptation_set_criteria_unit.js +0 -806
  298. package/test/media/adaptation_set_unit.js +0 -229
  299. package/test/media/buffering_observer_unit.js +0 -143
  300. package/test/media/closed_caption_parser_unit.js +0 -18
  301. package/test/media/content_workarounds_unit.js +0 -43
  302. package/test/media/drm_engine_integration.js +0 -356
  303. package/test/media/drm_engine_unit.js +0 -2778
  304. package/test/media/media_source_engine_integration.js +0 -691
  305. package/test/media/media_source_engine_unit.js +0 -1512
  306. package/test/media/mp4_segment_index_parser_unit.js +0 -80
  307. package/test/media/play_rate_controller_unit.js +0 -69
  308. package/test/media/playhead_unit.js +0 -1394
  309. package/test/media/presentation_timeline_unit.js +0 -477
  310. package/test/media/quality_observer_unit.js +0 -138
  311. package/test/media/region_observer_unit.js +0 -374
  312. package/test/media/region_timeline_unit.js +0 -139
  313. package/test/media/segment_index_unit.js +0 -1080
  314. package/test/media/segment_prefetch_unit.js +0 -243
  315. package/test/media/segment_reference_unit.js +0 -63
  316. package/test/media/stall_detector_unit.js +0 -184
  317. package/test/media/streaming_engine_integration.js +0 -632
  318. package/test/media/streaming_engine_unit.js +0 -4211
  319. package/test/media/time_ranges_utils_unit.js +0 -123
  320. package/test/media/webm_segment_index_parser_unit.js +0 -90
  321. package/test/mss/mss_parser_content_protection_unit.js +0 -49
  322. package/test/mss/mss_parser_unit.js +0 -474
  323. package/test/mss/mss_player_integration.js +0 -124
  324. package/test/net/data_uri_plugin_unit.js +0 -105
  325. package/test/net/http_plugin_unit.js +0 -439
  326. package/test/net/networking_engine_unit.js +0 -1236
  327. package/test/net/networking_utils_unit.js +0 -37
  328. package/test/offline/download_progress_estimator_unit.js +0 -90
  329. package/test/offline/indexeddb_storage_unit.js +0 -192
  330. package/test/offline/manifest_convert_unit.js +0 -622
  331. package/test/offline/offline_integration.js +0 -168
  332. package/test/offline/offline_manifest_parser_unit.js +0 -231
  333. package/test/offline/offline_scheme_unit.js +0 -154
  334. package/test/offline/offline_uri_unit.js +0 -59
  335. package/test/offline/storage_compatibility_unit.js +0 -344
  336. package/test/offline/storage_integration.js +0 -1858
  337. package/test/player_external.js +0 -237
  338. package/test/player_integration.js +0 -1371
  339. package/test/player_load_graph_integration.js +0 -865
  340. package/test/player_src_equals_external.js +0 -154
  341. package/test/player_src_equals_integration.js +0 -527
  342. package/test/player_unit.js +0 -4434
  343. package/test/polyfill/media_capabilities_unit.js +0 -277
  344. package/test/polyfill/patchedmediakeys_apple_unit.js +0 -130
  345. package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
  346. package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
  347. package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
  348. package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
  349. package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
  350. package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
  351. package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
  352. package/test/test/assets/3675/dash_0.mpd +0 -30
  353. package/test/test/assets/3675/dash_1.mpd +0 -30
  354. package/test/test/assets/3675/dash_2.mpd +0 -30
  355. package/test/test/assets/3675/dash_3.mpd +0 -30
  356. package/test/test/assets/3675/dash_4.mpd +0 -30
  357. package/test/test/assets/3675/dash_5.mpd +0 -26
  358. package/test/test/assets/3675/init-stream0.m4s +0 -0
  359. package/test/test/assets/audio-xhe-aac.mp4 +0 -0
  360. package/test/test/assets/audio.ts +0 -0
  361. package/test/test/assets/captions-test.ts +0 -0
  362. package/test/test/assets/cea-init.mp4 +0 -0
  363. package/test/test/assets/cea-segment.mp4 +0 -0
  364. package/test/test/assets/chapters.srt +0 -11
  365. package/test/test/assets/chapters.vtt +0 -10
  366. package/test/test/assets/chapters2.vtt +0 -10
  367. package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
  368. package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
  369. package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
  370. package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
  371. package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
  372. package/test/test/assets/dash-aes-128/dash.mpd +0 -18
  373. package/test/test/assets/dash-aes-128/license +0 -1
  374. package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
  375. package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
  376. package/test/test/assets/dash-multi-codec/dash.mpd +0 -32
  377. package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
  378. package/test/test/assets/db-dump-v1.json +0 -1
  379. package/test/test/assets/db-dump-v2-broken.json +0 -1
  380. package/test/test/assets/db-dump-v2-clean.json +0 -1
  381. package/test/test/assets/db-dump-v3.json +0 -1
  382. package/test/test/assets/db-dump-v4-broken.json +0 -1
  383. package/test/test/assets/db-dump-v5.json +0 -1
  384. package/test/test/assets/empty_caption_video_init.mp4 +0 -0
  385. package/test/test/assets/empty_caption_video_segment.mp4 +0 -0
  386. package/test/test/assets/encrypted-sintel-audio-init.mp4 +0 -0
  387. package/test/test/assets/encrypted-sintel-audio-segment.mp4 +0 -0
  388. package/test/test/assets/encrypted-sintel-video-init.mp4 +0 -0
  389. package/test/test/assets/encrypted-sintel-video-segment.mp4 +0 -0
  390. package/test/test/assets/green-pixel.mp4 +0 -0
  391. package/test/test/assets/green-pixel.txt +0 -15
  392. package/test/test/assets/h265-cea-init.mp4 +0 -0
  393. package/test/test/assets/h265-cea-segment.mp4 +0 -0
  394. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  395. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  396. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  397. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  398. package/test/test/assets/hls-raw-aac/manifest.m3u8 +0 -4
  399. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +0 -14
  400. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  401. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  402. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  403. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  404. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  405. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  406. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  407. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  408. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +0 -31
  409. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  410. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  411. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  412. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  413. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  414. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  415. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  416. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  417. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +0 -31
  418. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +0 -13
  419. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  420. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  421. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  422. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  423. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +0 -4
  424. package/test/test/assets/hls-ts-aac/playlist.m3u8 +0 -23
  425. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  426. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  427. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  428. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  429. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  430. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  431. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  432. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  433. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  434. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  435. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  436. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  437. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  438. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  439. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +0 -19
  440. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  441. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  442. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  443. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  444. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  445. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  446. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +0 -19
  447. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  448. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  449. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  450. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  451. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  452. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  453. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +0 -25
  454. package/test/test/assets/hls-ts-h265/0.ts +0 -0
  455. package/test/test/assets/hls-ts-h265/hevc.m3u8 +0 -6
  456. package/test/test/assets/hls-ts-h265/index.m3u8 +0 -7
  457. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +0 -13
  458. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  459. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  460. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  461. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  462. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +0 -17
  463. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  464. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  465. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  466. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  467. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  468. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  469. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +0 -4
  470. package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
  471. package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
  472. package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +0 -9
  473. package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +0 -24
  474. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
  475. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
  476. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
  477. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
  478. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
  479. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
  480. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
  481. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
  482. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
  483. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
  484. package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +0 -14
  485. package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +0 -23
  486. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
  487. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
  488. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
  489. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
  490. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
  491. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
  492. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
  493. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
  494. package/test/test/assets/id3-metadata.aac +0 -0
  495. package/test/test/assets/id3-metadata.ts +0 -0
  496. package/test/test/assets/index-segment.mp4 +0 -0
  497. package/test/test/assets/index-segment.webm +0 -0
  498. package/test/test/assets/init-segment.webm +0 -0
  499. package/test/test/assets/large_file.mpd +0 -4930
  500. package/test/test/assets/multidrm-audio-init.mp4 +0 -0
  501. package/test/test/assets/multidrm-audio-segment.mp4 +0 -0
  502. package/test/test/assets/multidrm-video-init.mp4 +0 -0
  503. package/test/test/assets/multidrm-video-segment.mp4 +0 -0
  504. package/test/test/assets/multiple-trun-init.mp4 +0 -0
  505. package/test/test/assets/multiple-trun-segment.mp4 +0 -0
  506. package/test/test/assets/sintel-audio-init.mp4 +0 -0
  507. package/test/test/assets/sintel-audio-segment.mp4 +0 -0
  508. package/test/test/assets/sintel-video-init.mp4 +0 -0
  509. package/test/test/assets/sintel-video-segment.mp4 +0 -0
  510. package/test/test/assets/small.mp4 +0 -0
  511. package/test/test/assets/text-clip-alt.vtt +0 -63
  512. package/test/test/assets/text-clip.vtt +0 -63
  513. package/test/test/assets/thumbnails-sprites.vtt +0 -10
  514. package/test/test/assets/thumbnails.vtt +0 -10
  515. package/test/test/assets/ttml-init.mp4 +0 -0
  516. package/test/test/assets/ttml-segment-multiplemdat.mp4 +0 -0
  517. package/test/test/assets/ttml-segment.mp4 +0 -0
  518. package/test/test/assets/video.ts +0 -0
  519. package/test/test/assets/vtt-init.mp4 +0 -0
  520. package/test/test/assets/vtt-segment-multi-payload.mp4 +0 -0
  521. package/test/test/assets/vtt-segment-no-duration.mp4 +0 -0
  522. package/test/test/assets/vtt-segment-settings.mp4 +0 -0
  523. package/test/test/assets/vtt-segment.mp4 +0 -0
  524. package/test/test/boot.js +0 -495
  525. package/test/test/externs/filters.js +0 -44
  526. package/test/test/externs/fontfaceonload.js +0 -29
  527. package/test/test/externs/jasmine.js +0 -670
  528. package/test/test/externs/karma.js +0 -26
  529. package/test/test/externs/require.js +0 -21
  530. package/test/test/externs/sprintf.js +0 -18
  531. package/test/test/namespace.js +0 -10
  532. package/test/test/util/canned_idb.js +0 -379
  533. package/test/test/util/cea_utils.js +0 -60
  534. package/test/test/util/dash_parser_util.js +0 -329
  535. package/test/test/util/fake_ad.js +0 -321
  536. package/test/test/util/fake_ad_manager.js +0 -122
  537. package/test/test/util/fake_demo_main.js +0 -144
  538. package/test/test/util/fake_drm_engine.js +0 -103
  539. package/test/test/util/fake_media_source_engine.js +0 -464
  540. package/test/test/util/fake_networking_engine.js +0 -381
  541. package/test/test/util/fake_segment_prefetch.js +0 -84
  542. package/test/test/util/fake_text_displayer.js +0 -60
  543. package/test/test/util/id3_generator.js +0 -100
  544. package/test/test/util/indexeddb_utils.js +0 -124
  545. package/test/test/util/jasmine_fetch.js +0 -382
  546. package/test/test/util/layout_tests.js +0 -434
  547. package/test/test/util/loader.js +0 -88
  548. package/test/test/util/manifest_generator.js +0 -705
  549. package/test/test/util/manifest_parser_util.js +0 -101
  550. package/test/test/util/mss_parser_util.js +0 -119
  551. package/test/test/util/offline_utils.js +0 -105
  552. package/test/test/util/simple_fakes.js +0 -535
  553. package/test/test/util/stream_generator.js +0 -676
  554. package/test/test/util/streaming_engine_util.js +0 -506
  555. package/test/test/util/test_scheme.js +0 -778
  556. package/test/test/util/ttml_utils.js +0 -77
  557. package/test/test/util/ui_utils.js +0 -183
  558. package/test/test/util/util.js +0 -374
  559. package/test/test/util/waiter.js +0 -406
  560. package/test/text/cue_integration.js +0 -51
  561. package/test/text/lrc_text_parser_unit.js +0 -98
  562. package/test/text/mp4_ttml_parser_unit.js +0 -171
  563. package/test/text/mp4_vtt_parser_unit.js +0 -195
  564. package/test/text/sbv_text_parser_unit.js +0 -81
  565. package/test/text/simple_text_displayer_unit.js +0 -468
  566. package/test/text/srt_text_parser_unit.js +0 -163
  567. package/test/text/ssa_text_parser_unit.js +0 -382
  568. package/test/text/text_displayer_layout_unit.js +0 -323
  569. package/test/text/text_engine_unit.js +0 -500
  570. package/test/text/text_track_integration.js +0 -186
  571. package/test/text/ttml_text_parser_unit.js +0 -2176
  572. package/test/text/ui_text_displayer_unit.js +0 -608
  573. package/test/text/vtt_text_parser_unit.js +0 -1363
  574. package/test/text/web_vtt_generator_unit.js +0 -144
  575. package/test/text/web_vtt_layout_integration.js +0 -524
  576. package/test/transmuxer/transmuxer_engine_integration.js +0 -69
  577. package/test/transmuxer/transmuxer_integration.js +0 -443
  578. package/test/ui/ad_ui_unit.js +0 -369
  579. package/test/ui/localization_unit.js +0 -508
  580. package/test/ui/ui_customization_unit.js +0 -208
  581. package/test/ui/ui_integration.js +0 -669
  582. package/test/ui/ui_unit.js +0 -902
  583. package/test/util/abortable_operation_unit.js +0 -624
  584. package/test/util/array_utils_unit.js +0 -58
  585. package/test/util/buffer_utils_unit.js +0 -185
  586. package/test/util/cmcd_manager_unit.js +0 -440
  587. package/test/util/content_steering_manager_unit.js +0 -427
  588. package/test/util/data_view_reader_unit.js +0 -254
  589. package/test/util/ebml_parser_unit.js +0 -297
  590. package/test/util/event_manager_unit.js +0 -185
  591. package/test/util/fake_event_target_unit.js +0 -123
  592. package/test/util/id3_utils_unit.js +0 -168
  593. package/test/util/iterables_unit.js +0 -68
  594. package/test/util/language_utils_unit.js +0 -240
  595. package/test/util/manifest_parser_utils_unit.js +0 -55
  596. package/test/util/mime_utils_unit.js +0 -64
  597. package/test/util/mp4_box_parsers_unit.js +0 -246
  598. package/test/util/mp4_parser_unit.js +0 -373
  599. package/test/util/multi_map_unit.js +0 -94
  600. package/test/util/object_utils_unit.js +0 -79
  601. package/test/util/periods_unit.js +0 -1623
  602. package/test/util/pssh_unit.js +0 -226
  603. package/test/util/state_history_unit.js +0 -101
  604. package/test/util/stream_utils_unit.js +0 -1068
  605. package/test/util/string_utils_unit.js +0 -166
  606. package/test/util/text_parser_unit.js +0 -165
  607. package/test/util/ts_parser_unit.js +0 -77
  608. package/test/util/xml_utils_unit.js +0 -444
@@ -1,1542 +0,0 @@
1
- /*! @license
2
- * Shaka Player
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- describe('DashParser Live', () => {
8
- const Util = shaka.test.Util;
9
- const ManifestParser = shaka.test.ManifestParser;
10
-
11
- const oldNow = Date.now;
12
- const updateTime = 5;
13
- const originalUri = 'http://example.com/';
14
-
15
-
16
- /** @type {!shaka.test.FakeNetworkingEngine} */
17
- let fakeNetEngine;
18
- /** @type {!shaka.dash.DashParser} */
19
- let parser;
20
- /** @type {shaka.extern.ManifestParser.PlayerInterface} */
21
- let playerInterface;
22
-
23
- beforeEach(() => {
24
- fakeNetEngine = new shaka.test.FakeNetworkingEngine();
25
- parser = new shaka.dash.DashParser();
26
- parser.configure(shaka.util.PlayerConfiguration.createDefault().manifest);
27
- playerInterface = {
28
- networkingEngine: fakeNetEngine,
29
- filter: (manifest) => Promise.resolve(),
30
- makeTextStreamsForClosedCaptions: (manifest) => {},
31
- onTimelineRegionAdded: fail, // Should not have any EventStream elements.
32
- onEvent: fail,
33
- onError: fail,
34
- isLowLatencyMode: () => false,
35
- isAutoLowLatencyMode: () => false,
36
- enableLowLatencyMode: () => {},
37
- updateDuration: () => {},
38
- newDrmInfo: (stream) => {},
39
- onManifestUpdated: () => {},
40
- getBandwidthEstimate: () => 1e6,
41
- };
42
- });
43
-
44
- afterEach(() => {
45
- // Dash parser stop is synchronous.
46
- parser.stop();
47
- Date.now = oldNow;
48
- });
49
-
50
- /**
51
- * Trigger a manifest update.
52
- * @suppress {accessControls}
53
- */
54
- async function updateManifest() {
55
- if (parser.updateTimer_) {
56
- parser.updateTimer_.tickNow();
57
- }
58
- await Util.shortDelay(); // Allow update to complete.
59
- }
60
-
61
- /**
62
- * Gets a spy on the function that sets the update period.
63
- * @return {!jasmine.Spy}
64
- * @suppress {accessControls}
65
- */
66
- function updateTickSpy() {
67
- return spyOn(parser.updateTimer_, 'tickAfter');
68
- }
69
-
70
- /**
71
- * Makes a simple live manifest with the given representation contents.
72
- *
73
- * @param {!Array.<string>} lines
74
- * @param {number?} updateTime
75
- * @param {number=} duration
76
- * @return {string}
77
- */
78
- function makeSimpleLiveManifestText(lines, updateTime, duration) {
79
- const updateAttr = updateTime != null ?
80
- 'minimumUpdatePeriod="PT' + updateTime + 'S"' : '';
81
- const durationAttr = duration != undefined ?
82
- 'duration="PT' + duration + 'S"' : '';
83
- const template = [
84
- '<MPD type="dynamic" %(updateAttr)s',
85
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
86
- ' <Period id="1" %(durationAttr)s>',
87
- ' <AdaptationSet mimeType="video/mp4">',
88
- ' <Representation id="3" bandwidth="500">',
89
- ' <BaseURL>http://example.com</BaseURL>',
90
- '%(contents)s',
91
- ' </Representation>',
92
- ' </AdaptationSet>',
93
- ' </Period>',
94
- '</MPD>',
95
- ].join('\n');
96
- const text = sprintf(template, {
97
- updateAttr: updateAttr,
98
- durationAttr: durationAttr,
99
- contents: lines.join('\n'),
100
- updateTime: updateTime,
101
- });
102
- return text;
103
- }
104
-
105
- /**
106
- * Make clones of a list of references so that they can be modified without
107
- * affecting the originals.
108
- *
109
- * @param {!Array.<!shaka.media.SegmentReference>} references
110
- * @return {!Array.<!shaka.media.SegmentReference>}
111
- */
112
- function cloneRefs(references) {
113
- return references.map((ref) => {
114
- return new shaka.media.SegmentReference(
115
- ref.startTime,
116
- ref.endTime,
117
- ref.getUrisInner,
118
- ref.startByte,
119
- ref.endByte,
120
- ref.initSegmentReference,
121
- ref.timestampOffset,
122
- ref.appendWindowStart,
123
- ref.appendWindowEnd);
124
- });
125
- }
126
-
127
- /**
128
- * Creates tests that test the behavior common between SegmentList and
129
- * SegmentTemplate.
130
- *
131
- * @param {!Array.<string>} basicLines
132
- * @param {!Array.<!shaka.media.SegmentReference>} basicRefs
133
- * @param {!Array.<string>} updateLines
134
- * @param {!Array.<!shaka.media.SegmentReference>} updateRefs
135
- * @param {!Array.<string>} partialUpdateLines
136
- */
137
- function testCommonBehaviors(
138
- basicLines, basicRefs, updateLines, updateRefs, partialUpdateLines) {
139
- /**
140
- * Tests that an update will show the given references.
141
- *
142
- * @param {!Array.<string>} firstLines The Representation contents for the
143
- * first manifest.
144
- * @param {!Array.<!shaka.media.SegmentReference>} firstReferences The media
145
- * references for the first parse.
146
- * @param {!Array.<string>} secondLines The Representation contents for the
147
- * updated manifest.
148
- * @param {!Array.<!shaka.media.SegmentReference>} secondReferences The
149
- * media references for the updated manifest.
150
- */
151
- async function testBasicUpdate(
152
- firstLines, firstReferences, secondLines, secondReferences) {
153
- const firstManifest = makeSimpleLiveManifestText(firstLines, updateTime);
154
- const secondManifest =
155
- makeSimpleLiveManifestText(secondLines, updateTime);
156
-
157
- fakeNetEngine.setResponseText('dummy://foo', firstManifest);
158
- const manifest = await parser.start('dummy://foo', playerInterface);
159
- const stream = manifest.variants[0].video;
160
- await stream.createSegmentIndex();
161
- ManifestParser.verifySegmentIndex(stream, firstReferences);
162
-
163
- fakeNetEngine.setResponseText('dummy://foo', secondManifest);
164
- await updateManifest();
165
- ManifestParser.verifySegmentIndex(stream, secondReferences);
166
- }
167
-
168
- it('basic support', async () => {
169
- await testBasicUpdate(basicLines, basicRefs, updateLines, updateRefs);
170
- });
171
-
172
- it('new manifests don\'t need to include old references', async () => {
173
- await testBasicUpdate(
174
- basicLines, basicRefs, partialUpdateLines, updateRefs);
175
- });
176
-
177
- it('evicts old references for single-period live stream', async () => {
178
- const template = [
179
- '<MPD type="dynamic" minimumUpdatePeriod="PT%(updateTime)dS"',
180
- ' timeShiftBufferDepth="PT30S"',
181
- ' suggestedPresentationDelay="PT5S"',
182
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
183
- ' <Period id="1">',
184
- ' <AdaptationSet mimeType="video/mp4">',
185
- ' <Representation id="3" bandwidth="500">',
186
- ' <BaseURL>http://example.com</BaseURL>',
187
- '%(contents)s',
188
- ' </Representation>',
189
- ' </AdaptationSet>',
190
- ' </Period>',
191
- '</MPD>',
192
- ].join('\n');
193
- const text = sprintf(
194
- template, {updateTime: updateTime, contents: basicLines.join('\n')});
195
-
196
- fakeNetEngine.setResponseText('dummy://foo', text);
197
- const baseTime = new Date(2015, 11, 30);
198
- Date.now = () => baseTime.getTime();
199
- const manifest = await parser.start('dummy://foo', playerInterface);
200
-
201
- expect(manifest).toBeTruthy();
202
- const stream = manifest.variants[0].video;
203
- expect(stream).toBeTruthy();
204
-
205
- await stream.createSegmentIndex();
206
- expect(stream.segmentIndex).toBeTruthy();
207
- const firstPosition = stream.segmentIndex.find(0);
208
- ManifestParser.verifySegmentIndex(stream, basicRefs);
209
-
210
- // The 30 second availability window is initially full in all cases
211
- // (SegmentTemplate+Timeline, etc.) The first segment is always 10
212
- // seconds long in all of these cases. So 11 seconds after the
213
- // manifest was parsed, the first segment should have fallen out of
214
- // the availability window.
215
- Date.now = () => baseTime.getTime() + (11 * 1000);
216
- await updateManifest();
217
- // The first reference should have been evicted.
218
- expect(stream.segmentIndex.find(0)).toBe(firstPosition + 1);
219
- ManifestParser.verifySegmentIndex(stream, basicRefs.slice(1));
220
- });
221
-
222
- it('evicts old references for multi-period live stream', async () => {
223
- const template = [
224
- '<MPD type="dynamic" minimumUpdatePeriod="PT%(updateTime)dS"',
225
- ' timeShiftBufferDepth="PT60S"',
226
- ' suggestedPresentationDelay="PT5S"',
227
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
228
- ' <Period id="1">',
229
- ' <AdaptationSet mimeType="video/mp4">',
230
- ' <Representation id="3" bandwidth="500">',
231
- ' <BaseURL>http://example.com</BaseURL>',
232
- '%(contents)s',
233
- ' </Representation>',
234
- ' </AdaptationSet>',
235
- ' </Period>',
236
- ' <Period id="2" start="PT%(pStart)dS">',
237
- ' <AdaptationSet mimeType="video/mp4">',
238
- ' <Representation id="4" bandwidth="500">',
239
- ' <BaseURL>http://example.com</BaseURL>',
240
- '%(contents)s',
241
- ' </Representation>',
242
- ' </AdaptationSet>',
243
- ' </Period>',
244
- '</MPD>',
245
- ].join('\n');
246
- // Set the period start to the sum of the durations of the references
247
- // in the previous period.
248
- const durs = basicRefs.map((r) => {
249
- return r.endTime - r.startTime;
250
- });
251
- const pStart = durs.reduce((p, d) => p + d, 0);
252
- const args = {
253
- updateTime: updateTime,
254
- pStart: pStart,
255
- contents: basicLines.join('\n'),
256
- };
257
- const text = sprintf(template, args);
258
-
259
- fakeNetEngine.setResponseText('dummy://foo', text);
260
- Date.now = () => 0;
261
- const manifest = await parser.start('dummy://foo', playerInterface);
262
-
263
- /** @const {!Array.<!shaka.media.SegmentReference>} */
264
- const period1Refs = cloneRefs(basicRefs);
265
- /** @const {!Array.<!shaka.media.SegmentReference>} */
266
- const period2Refs = cloneRefs(basicRefs);
267
- for (const ref of period2Refs) {
268
- ref.timestampOffset = pStart;
269
- ref.startTime += pStart;
270
- ref.endTime += pStart;
271
- ref.trueEndTime += pStart;
272
- }
273
- /** @const {!Array.<!shaka.media.SegmentReference>} */
274
- const allRefs = period1Refs.concat(period2Refs);
275
-
276
- const stream1 = manifest.variants[0].video;
277
- await stream1.createSegmentIndex();
278
- ManifestParser.verifySegmentIndex(stream1, allRefs);
279
-
280
- // The 60 second availability window is initially full in all cases
281
- // (SegmentTemplate+Timeline, etc.) The first segment is always 10
282
- // seconds long in all of these cases. So 11 seconds after the
283
- // manifest was parsed, the first segment should have fallen out of
284
- // the availability window.
285
- Date.now = () => 11 * 1000;
286
- await updateManifest();
287
- // The first reference should have been evicted.
288
- ManifestParser.verifySegmentIndex(stream1, allRefs.slice(1));
289
-
290
- // Same as above, but 1 period length later
291
- Date.now = () => (11 + pStart) * 1000;
292
- await updateManifest();
293
- ManifestParser.verifySegmentIndex(stream1, period2Refs.slice(1));
294
- });
295
-
296
- it('sets infinite duration for single-period live streams', async () => {
297
- const template = [
298
- '<MPD type="dynamic" minimumUpdatePeriod="PT%(updateTime)dS"',
299
- ' timeShiftBufferDepth="PT1S"',
300
- ' suggestedPresentationDelay="PT5S"',
301
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
302
- ' <Period id="1">',
303
- ' <AdaptationSet mimeType="video/mp4">',
304
- ' <Representation id="3" bandwidth="500">',
305
- ' <BaseURL>http://example.com</BaseURL>',
306
- '%(contents)s',
307
- ' </Representation>',
308
- ' </AdaptationSet>',
309
- ' </Period>',
310
- '</MPD>',
311
- ].join('\n');
312
- const text = sprintf(
313
- template, {updateTime: updateTime, contents: basicLines.join('\n')});
314
-
315
- fakeNetEngine.setResponseText('dummy://foo', text);
316
- Date.now = () => 0;
317
- const manifest = await parser.start('dummy://foo', playerInterface);
318
-
319
- const timeline = manifest.presentationTimeline;
320
- expect(timeline.getDuration()).toBe(Infinity);
321
- });
322
-
323
- it('sets infinite duration for multi-period live streams', async () => {
324
- const template = [
325
- '<MPD type="dynamic" minimumUpdatePeriod="PT%(updateTime)dS"',
326
- ' timeShiftBufferDepth="PT1S"',
327
- ' suggestedPresentationDelay="PT5S"',
328
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
329
- ' <Period id="1">',
330
- ' <AdaptationSet mimeType="video/mp4">',
331
- ' <Representation id="3" bandwidth="500">',
332
- ' <BaseURL>http://example.com</BaseURL>',
333
- '%(contents)s',
334
- ' </Representation>',
335
- ' </AdaptationSet>',
336
- ' </Period>',
337
- ' <Period id="2" start="PT60S">',
338
- ' <AdaptationSet mimeType="video/mp4">',
339
- ' <Representation id="4" bandwidth="500">',
340
- ' <BaseURL>http://example.com</BaseURL>',
341
- '%(contents)s',
342
- ' </Representation>',
343
- ' </AdaptationSet>',
344
- ' </Period>',
345
- '</MPD>',
346
- ].join('\n');
347
- const text = sprintf(
348
- template, {updateTime: updateTime, contents: basicLines.join('\n')});
349
-
350
- fakeNetEngine.setResponseText('dummy://foo', text);
351
- Date.now = () => 0;
352
- const manifest = await parser.start('dummy://foo', playerInterface);
353
-
354
- const timeline = manifest.presentationTimeline;
355
- expect(timeline.getDuration()).toBe(Infinity);
356
- });
357
- }
358
-
359
- it('can add Periods with SegmentTemplate', async () => {
360
- const template1 = [
361
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
362
- ' suggestedPresentationDelay="PT5S"',
363
- ' minimumUpdatePeriod="PT%(updateTime)dS">',
364
- ' <Period id="1">',
365
- ' <AdaptationSet mimeType="video/mp4">',
366
- ' <Representation id="1" bandwidth="500">',
367
- ' <BaseURL>http://example.com</BaseURL>',
368
- ' <SegmentTemplate media="s$Number$.mp4">',
369
- ' <SegmentTimeline>',
370
- ' <S t="0" d="2" r="1" />',
371
- ' </SegmentTimeline>',
372
- ' </SegmentTemplate>',
373
- ' </Representation>',
374
- ' </AdaptationSet>',
375
- ' </Period>',
376
- '</MPD>',
377
- ].join('\n');
378
- const template2 = [
379
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
380
- ' suggestedPresentationDelay="PT5S"',
381
- ' minimumUpdatePeriod="PT%(updateTime)dS">',
382
- ' <Period id="1" duration="PT10S">',
383
- ' <AdaptationSet mimeType="video/mp4">',
384
- ' <Representation id="1" bandwidth="500">',
385
- ' <BaseURL>http://example.com</BaseURL>',
386
- ' <SegmentTemplate media="s$Number$.mp4">',
387
- ' <SegmentTimeline>',
388
- ' <S t="0" d="2" r="4" />',
389
- ' </SegmentTimeline>',
390
- ' </SegmentTemplate>',
391
- ' </Representation>',
392
- ' </AdaptationSet>',
393
- ' </Period>',
394
- ' <Period id="2">',
395
- ' <AdaptationSet mimeType="video/mp4">',
396
- ' <Representation id="2" bandwidth="500">',
397
- ' <BaseURL>http://example.com</BaseURL>',
398
- ' <SegmentTemplate media="s$Number$.mp4">',
399
- ' <SegmentTimeline>',
400
- ' <S t="0" d="2" r="1" />',
401
- ' </SegmentTimeline>',
402
- ' </SegmentTemplate>',
403
- ' </Representation>',
404
- ' </AdaptationSet>',
405
- ' </Period>',
406
- '</MPD>',
407
- ].join('\n');
408
- const firstManifest = sprintf(template1, {updateTime: updateTime});
409
- const secondManifest = sprintf(template2, {updateTime: updateTime});
410
-
411
- fakeNetEngine.setResponseText('dummy://foo', firstManifest);
412
- // First two segments should exist
413
- Date.now = () => 5;
414
-
415
- const manifest = await parser.start('dummy://foo', playerInterface);
416
- const variant = manifest.variants[0];
417
- const stream = variant.video;
418
- await stream.createSegmentIndex();
419
-
420
- // First two segments exist, but not the third.
421
- expect(stream.segmentIndex.find(3)).not.toBe(null);
422
- expect(stream.segmentIndex.find(5)).toBe(null);
423
-
424
- fakeNetEngine.setResponseText('dummy://foo', secondManifest);
425
- // First period (10s) is complete, plus first two segments of next period
426
- Date.now = () => 15;
427
-
428
- await updateManifest();
429
-
430
- // The update should have affected the same variant object we captured
431
- // before. Now the entire first period should exist (0-10s), plus the next
432
- // two segments (10-14s).
433
- expect(stream.segmentIndex.find(9)).not.toBe(null);
434
- expect(stream.segmentIndex.find(13)).not.toBe(null);
435
-
436
- stream.closeSegmentIndex();
437
- await stream.createSegmentIndex();
438
-
439
- expect(stream.segmentIndex.find(9)).not.toBe(null);
440
- expect(stream.segmentIndex.find(13)).not.toBe(null);
441
- });
442
-
443
- it('can add Periods with SegmentList', async () => {
444
- const list1 = [
445
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
446
- ' suggestedPresentationDelay="PT5S"',
447
- ' minimumUpdatePeriod="PT%(updateTime)dS">',
448
- ' <Period id="1">',
449
- ' <AdaptationSet mimeType="video/mp4">',
450
- ' <Representation id="1" bandwidth="500">',
451
- ' <BaseURL>http://example.com</BaseURL>',
452
- ' <SegmentList>',
453
- ' <SegmentURL media="s1.mp4" />',
454
- ' <SegmentURL media="s2.mp4" />',
455
- ' <SegmentURL media="s3.mp4" />',
456
- ' <SegmentTimeline>',
457
- ' <S d="10" t="0" r="2"/>',
458
- ' </SegmentTimeline>',
459
- ' </SegmentList>',
460
- ' </Representation>',
461
- ' </AdaptationSet>',
462
- ' </Period>',
463
- '</MPD>',
464
- ].join('\n');
465
- const list2 = [
466
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
467
- ' suggestedPresentationDelay="PT5S"',
468
- ' minimumUpdatePeriod="PT%(updateTime)dS">',
469
- ' <Period id="1" duration="PT40S">',
470
- ' <AdaptationSet mimeType="video/mp4">',
471
- ' <Representation id="1" bandwidth="500">',
472
- ' <BaseURL>http://example.com</BaseURL>',
473
- ' <SegmentList>',
474
- ' <SegmentURL media="s1.mp4" />',
475
- ' <SegmentURL media="s2.mp4" />',
476
- ' <SegmentURL media="s3.mp4" />',
477
- ' <SegmentURL media="s4.mp4" />',
478
- ' <SegmentTimeline>',
479
- ' <S d="10" t="0" r="3"/>',
480
- ' </SegmentTimeline>',
481
- ' </SegmentList>',
482
- ' </Representation>',
483
- ' </AdaptationSet>',
484
- ' </Period>',
485
- ' <Period id="2">',
486
- ' <AdaptationSet mimeType="video/mp4">',
487
- ' <Representation id="2" bandwidth="500">',
488
- ' <BaseURL>http://example.com</BaseURL>',
489
- ' <SegmentList>',
490
- ' <SegmentURL media="s1.mp4" />',
491
- ' <SegmentURL media="s2.mp4" />',
492
- ' <SegmentTimeline>',
493
- ' <S d="10" t="0" r="1"/>',
494
- ' </SegmentTimeline>',
495
- ' </SegmentList>',
496
- ' </Representation>',
497
- ' </AdaptationSet>',
498
- ' </Period>',
499
- '</MPD>',
500
- ].join('\n');
501
- const firstManifest = sprintf(list1, {updateTime: updateTime});
502
- const secondManifest = sprintf(list2, {updateTime: updateTime});
503
-
504
- fakeNetEngine.setResponseText('dummy://foo', firstManifest);
505
- // First three segments should exist.
506
- Date.now = () => 5;
507
-
508
- const manifest = await parser.start('dummy://foo', playerInterface);
509
- const variant = manifest.variants[0];
510
- const stream = variant.video;
511
- await stream.createSegmentIndex();
512
-
513
- // First three segments exist, but not the fourth.
514
- expect(stream.segmentIndex.find(25)).not.toBe(null);
515
- expect(stream.segmentIndex.find(45)).toBe(null);
516
-
517
- fakeNetEngine.setResponseText('dummy://foo', secondManifest);
518
- Date.now = () => 25;
519
-
520
- await updateManifest();
521
-
522
- // The update should have affected the same variant object we captured
523
- // before. Now the entire first period should exist (0-40s), plus the next
524
- // two segments of the second period(40-60s).
525
- expect(stream.segmentIndex.find(25)).not.toBe(null);
526
- expect(stream.segmentIndex.find(45)).not.toBe(null);
527
-
528
- stream.closeSegmentIndex();
529
- await stream.createSegmentIndex();
530
-
531
- expect(stream.segmentIndex.find(25)).not.toBe(null);
532
- expect(stream.segmentIndex.find(45)).not.toBe(null);
533
- });
534
-
535
- it('uses redirect URL for manifest BaseURL and updates', async () => {
536
- const template = [
537
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
538
- ' suggestedPresentationDelay="PT5S"',
539
- ' minimumUpdatePeriod="PT%(updateTime)dS">',
540
- ' <Period id="1" duration="PT30S">',
541
- ' <AdaptationSet mimeType="video/mp4">',
542
- ' <Representation id="3" bandwidth="500">',
543
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4">',
544
- ' <SegmentTimeline>',
545
- ' <S d="10" t="0" />',
546
- ' <S d="5" />',
547
- ' <S d="15" />',
548
- ' </SegmentTimeline>',
549
- ' </SegmentTemplate>',
550
- ' </Representation>',
551
- ' </AdaptationSet>',
552
- ' </Period>',
553
- '</MPD>',
554
- ].join('\n');
555
- const manifestText = sprintf(template, {updateTime: updateTime});
556
- const manifestData = shaka.util.StringUtils.toUTF8(manifestText);
557
- const redirectedUri = 'http://redirected.com/';
558
-
559
- // The initial manifest request will be redirected.
560
- fakeNetEngine.request.and.returnValue(
561
- shaka.util.AbortableOperation.completed({
562
- uri: redirectedUri,
563
- data: manifestData,
564
- }));
565
-
566
- const manifest = await parser.start(originalUri, playerInterface);
567
-
568
- // The manifest request was made to the original URL.
569
- // But includes a redirect
570
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
571
- const netRequest = fakeNetEngine.request.calls.argsFor(0)[1];
572
- expect(netRequest.uris).toEqual([redirectedUri, originalUri]);
573
-
574
- // Since the manifest request was redirected, the segment refers to
575
- // the redirected base.
576
- const stream = manifest.variants[0].video;
577
- await stream.createSegmentIndex();
578
- goog.asserts.assert(stream.segmentIndex != null, 'Null segmentIndex!');
579
-
580
- const ref = Array.from(stream.segmentIndex)[0];
581
- const segmentUri = ref.getUris()[0];
582
- expect(segmentUri).toBe(redirectedUri + 's1.mp4');
583
- });
584
-
585
- it('calls the error callback if an update fails', async () => {
586
- const lines = [
587
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
588
- ];
589
- const manifestText = makeSimpleLiveManifestText(lines, updateTime);
590
- /** @type {!jasmine.Spy} */
591
- const onError = jasmine.createSpy('onError');
592
- playerInterface.onError = Util.spyFunc(onError);
593
-
594
- const updateTick = updateTickSpy();
595
-
596
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
597
- await parser.start('dummy://foo', playerInterface);
598
-
599
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
600
-
601
- const error = new shaka.util.Error(
602
- shaka.util.Error.Severity.CRITICAL,
603
- shaka.util.Error.Category.NETWORK,
604
- shaka.util.Error.Code.BAD_HTTP_STATUS);
605
- const operation = shaka.util.AbortableOperation.failed(error);
606
- fakeNetEngine.request.and.returnValue(operation);
607
-
608
- await updateManifest();
609
- expect(onError).toHaveBeenCalledTimes(1);
610
- expect(updateTick).toHaveBeenCalledTimes(2);
611
- });
612
-
613
- it('fatal error on manifest update request failure when ' +
614
- 'raiseFatalErrorOnManifestUpdateRequestFailure is true', async () => {
615
- const manifestConfig =
616
- shaka.util.PlayerConfiguration.createDefault().manifest;
617
- manifestConfig.raiseFatalErrorOnManifestUpdateRequestFailure = true;
618
- parser.configure(manifestConfig);
619
-
620
- const updateTick = updateTickSpy();
621
-
622
- const lines = [
623
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2"/>',
624
- ];
625
- const manifestText = makeSimpleLiveManifestText(lines, updateTime);
626
- /** @type {!jasmine.Spy} */
627
- const onError = jasmine.createSpy('onError');
628
- playerInterface.onError = Util.spyFunc(onError);
629
-
630
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
631
- await parser.start('dummy://foo', playerInterface);
632
-
633
- const error = new shaka.util.Error(
634
- shaka.util.Error.Severity.CRITICAL,
635
- shaka.util.Error.Category.NETWORK,
636
- shaka.util.Error.Code.BAD_HTTP_STATUS);
637
- const operation = shaka.util.AbortableOperation.failed(error);
638
- fakeNetEngine.request.and.returnValue(operation);
639
-
640
- await updateManifest();
641
- expect(onError).toHaveBeenCalledWith(error);
642
- expect(updateTick).toHaveBeenCalledTimes(1);
643
- });
644
-
645
- it('uses @minimumUpdatePeriod', async () => {
646
- const lines = [
647
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
648
- ];
649
- // updateTime parameter sets @minimumUpdatePeriod in the manifest.
650
- const manifestText = makeSimpleLiveManifestText(lines, updateTime);
651
-
652
- /** @type {!jasmine.Spy} */
653
- const tickAfter = updateTickSpy();
654
- Date.now = () => 0;
655
-
656
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
657
- await parser.start('dummy://foo', playerInterface);
658
-
659
- expect(tickAfter).toHaveBeenCalledTimes(1);
660
- const delay = tickAfter.calls.mostRecent().args[0];
661
- expect(delay).toBe(updateTime);
662
- });
663
-
664
- it('does not update when @minimumUpdatePeriod is missing', async () => {
665
- const lines = [
666
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
667
- ];
668
- // updateTime parameter sets @minimumUpdatePeriod in the manifest.
669
- const manifestText =
670
- makeSimpleLiveManifestText(lines, /* updateTime= */ null);
671
-
672
- /** @type {!jasmine.Spy} */
673
- const tickAfter = updateTickSpy();
674
-
675
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
676
- await parser.start('dummy://foo', playerInterface);
677
-
678
- expect(tickAfter).not.toHaveBeenCalled();
679
- });
680
-
681
- it('delays subsequent updates when an update is slow', async () => {
682
- const lines = [
683
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
684
- ];
685
- const extraWaitTime = 15.0;
686
- const manifestText = makeSimpleLiveManifestText(lines, 3);
687
-
688
- let now = 0;
689
- Date.now = () => now;
690
- /** @type {!jasmine.Spy} */
691
- const tickAfter = updateTickSpy();
692
-
693
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
694
- /** @type {!shaka.util.PublicPromise} */
695
- const delay = fakeNetEngine.delayNextRequest();
696
- const p = parser.start('dummy://foo', playerInterface);
697
- now += extraWaitTime * 1000; // Make the update appear to take longer.
698
- delay.resolve();
699
- await p;
700
-
701
- // Check the last update was scheduled close to how long the update took.
702
- const realDelay = tickAfter.calls.mostRecent().args[0];
703
- expect(realDelay).toBeCloseTo(extraWaitTime, 0);
704
- });
705
-
706
- it('uses Mpd.Location', async () => {
707
- const manifestText = [
708
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
709
- ' suggestedPresentationDelay="PT5S"',
710
- ' minimumUpdatePeriod="PT' + updateTime + 'S">',
711
- ' <Location>http://foobar</Location>',
712
- ' <Location>http://foobar2</Location>',
713
- ' <Location>foobar3</Location>',
714
- ' <Period id="1" duration="PT10S">',
715
- ' <AdaptationSet mimeType="video/mp4">',
716
- ' <Representation id="3" bandwidth="500">',
717
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
718
- ' </Representation>',
719
- ' </AdaptationSet>',
720
- ' </Period>',
721
- '</MPD>',
722
- ].join('\n');
723
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
724
-
725
- const manifestRequest = shaka.net.NetworkingEngine.RequestType.MANIFEST;
726
- const manifestContext = {
727
- type: shaka.net.NetworkingEngine.AdvancedRequestType.MPD,
728
- };
729
- await parser.start('dummy://foo', playerInterface);
730
-
731
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
732
- fakeNetEngine.expectRequest('dummy://foo', manifestRequest, manifestContext);
733
- fakeNetEngine.request.calls.reset();
734
-
735
- // Create a mock so we can verify it gives two URIs.
736
- // The third location is a relative url, and should be resolved as an
737
- // absolute url.
738
- fakeNetEngine.request.and.callFake((type, request, context) => {
739
- expect(type).toBe(manifestRequest);
740
- expect(context).toEqual(manifestContext);
741
- expect(request.uris).toEqual(
742
- ['http://foobar', 'http://foobar2', 'dummy://foo/foobar3']);
743
- const data = shaka.util.StringUtils.toUTF8(manifestText);
744
- return shaka.util.AbortableOperation.completed(
745
- {uri: request.uris[0], data: data, headers: {}});
746
- });
747
-
748
- await updateManifest();
749
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
750
- });
751
-
752
- it('uses @suggestedPresentationDelay', async () => {
753
- const manifestText = [
754
- '<MPD type="dynamic" suggestedPresentationDelay="PT60S"',
755
- ' minimumUpdatePeriod="PT5S"',
756
- ' timeShiftBufferDepth="PT2M"',
757
- ' maxSegmentDuration="PT10S"',
758
- ' availabilityStartTime="1970-01-01T00:05:00Z">',
759
- ' <Period id="1">',
760
- ' <AdaptationSet mimeType="video/mp4">',
761
- ' <Representation id="3" bandwidth="500">',
762
- ' <BaseURL>http://example.com</BaseURL>',
763
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
764
- ' </Representation>',
765
- ' </AdaptationSet>',
766
- ' </Period>',
767
- '</MPD>',
768
- ].join('\n');
769
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
770
-
771
- Date.now = () => 600000; /* 10 minutes */
772
- const manifest = await parser.start('dummy://foo', playerInterface);
773
-
774
- expect(manifest).toBeTruthy();
775
- const timeline = manifest.presentationTimeline;
776
- expect(timeline).toBeTruthy();
777
-
778
- // We are 5 minutes into the presentation, with a
779
- // @timeShiftBufferDepth of 120 seconds and a @maxSegmentDuration of
780
- // 10 seconds, the start will be 2:50.
781
- expect(timeline.getSegmentAvailabilityStart()).toBe(170);
782
- // Normally the end should be 4:50; but with a 60 second
783
- // @suggestedPresentationDelay it will be 3:50 minutes.
784
- expect(timeline.getSegmentAvailabilityEnd()).toBe(290);
785
- expect(timeline.getSeekRangeEnd()).toBe(230);
786
- });
787
-
788
- it('parses availabilityTimeOffset', async () => {
789
- const manifestText = [
790
- '<MPD type="dynamic" suggestedPresentationDelay="PT0S"',
791
- ' minimumUpdatePeriod="PT5S"',
792
- ' timeShiftBufferDepth="PT2M"',
793
- ' maxSegmentDuration="PT10S"',
794
- ' availabilityStartTime="1970-01-01T00:05:00Z">',
795
- ' <Period id="1">',
796
- ' <AdaptationSet mimeType="video/mp4">',
797
- ' <Representation id="3" bandwidth="500">',
798
- ' <BaseURL availabilityTimeOffset="6">http://example.com',
799
- ' </BaseURL>',
800
- ' <SegmentTemplate availabilityTimeOffset="6.00" ',
801
- ' startNumber="1" media="s$Number$.mp4" duration="2" />',
802
- ' </Representation>',
803
- ' </AdaptationSet>',
804
- ' </Period>',
805
- '</MPD>',
806
- ].join('\n');
807
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
808
- playerInterface.isLowLatencyMode = () => true;
809
-
810
- Date.now = () => 600000; /* 10 minutes */
811
- const manifest = await parser.start('dummy://foo', playerInterface);
812
-
813
- expect(manifest).toBeTruthy();
814
- const timeline = manifest.presentationTimeline;
815
- expect(timeline).toBeTruthy();
816
-
817
- // We are 5 minutes into the presentation, with a @timeShiftBufferDepth of
818
- // 120 seconds and a @maxSegmentDuration of 10 seconds, the start will be
819
- // 2:50. With the availabilityTimeOffset of 6+6 seconds, it will be 3:02.
820
- expect(timeline.getSegmentAvailabilityStart()).toBe(182);
821
- // Normally the end should be 4:50; with the availabilityTimeOffset of
822
- // 12 seconds, it will be 5:02.
823
- expect(timeline.getSegmentAvailabilityEnd()).toBe(302);
824
- expect(timeline.getSeekRangeEnd()).toBe(302);
825
- });
826
-
827
- describe('availabilityWindowOverride', () => {
828
- it('overrides @timeShiftBufferDepth', async () => {
829
- const manifestText = [
830
- '<MPD type="dynamic" suggestedPresentationDelay="PT60S"',
831
- ' minimumUpdatePeriod="PT5S"',
832
- ' timeShiftBufferDepth="PT2M"',
833
- ' maxSegmentDuration="PT10S"',
834
- ' availabilityStartTime="1970-01-01T00:05:00Z">',
835
- ' <Period id="1">',
836
- ' <AdaptationSet mimeType="video/mp4">',
837
- ' <Representation id="3" bandwidth="500">',
838
- ' <BaseURL>http://example.com</BaseURL>',
839
- ' <SegmentTemplate media="s$Number$.mp4" duration="2" />',
840
- ' </Representation>',
841
- ' </AdaptationSet>',
842
- ' </Period>',
843
- '</MPD>',
844
- ].join('\n');
845
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
846
-
847
- const config = shaka.util.PlayerConfiguration.createDefault().manifest;
848
- config.availabilityWindowOverride = 4 * 60;
849
- parser.configure(config);
850
-
851
- Date.now = () => 600000; /* 10 minutes */
852
- const manifest = await parser.start('dummy://foo', playerInterface);
853
-
854
- expect(manifest).toBeTruthy();
855
- const timeline = manifest.presentationTimeline;
856
- expect(timeline).toBeTruthy();
857
-
858
- // The parser was configured to have a manifest availability window
859
- // of 4 minutes.
860
- const end = timeline.getSegmentAvailabilityEnd();
861
- const start = timeline.getSegmentAvailabilityStart();
862
- expect(end - start).toBe(4 * 60);
863
- });
864
- });
865
-
866
- describe('maxSegmentDuration', () => {
867
- it('uses @maxSegmentDuration', async () => {
868
- const manifestText = [
869
- '<MPD type="dynamic" suggestedPresentationDelay="PT0S"',
870
- ' minimumUpdatePeriod="PT5S"',
871
- ' timeShiftBufferDepth="PT2M"',
872
- ' maxSegmentDuration="PT15S"',
873
- ' availabilityStartTime="1970-01-01T00:05:00Z">',
874
- ' <Period id="1">',
875
- ' <AdaptationSet id="2" mimeType="video/mp4">',
876
- ' <Representation id="3" bandwidth="500">',
877
- ' <BaseURL>http://example.com</BaseURL>',
878
- '<SegmentTemplate media="s$Number$.mp4" duration="2" />',
879
- ' </Representation>',
880
- ' </AdaptationSet>',
881
- ' </Period>',
882
- '</MPD>',
883
- ].join('\n');
884
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
885
-
886
- Date.now = () => 600000; /* 10 minutes */
887
- const manifest = await parser.start('dummy://foo', playerInterface);
888
-
889
- expect(manifest).toBeTruthy();
890
- const timeline = manifest.presentationTimeline;
891
- expect(timeline).toBeTruthy();
892
- expect(timeline.getMaxSegmentDuration()).toBe(15);
893
- });
894
-
895
- it('derived from SegmentTemplate w/ SegmentTimeline', async () => {
896
- const lines = [
897
- '<SegmentTemplate media="s$Number$.mp4">',
898
- ' <SegmentTimeline>',
899
- ' <S t="0" d="7" />',
900
- ' <S d="8" />',
901
- ' <S d="6" />',
902
- ' </SegmentTimeline>',
903
- '</SegmentTemplate>',
904
- ];
905
- await testDerived(lines);
906
- });
907
-
908
- it('derived from SegmentTemplate w/ @duration', async () => {
909
- const lines = [
910
- '<SegmentTemplate media="s$Number$.mp4" duration="8" />',
911
- ];
912
- await testDerived(lines);
913
- });
914
-
915
- it('derived from SegmentList', async () => {
916
- const lines = [
917
- '<SegmentList duration="8">',
918
- ' <SegmentURL media="s1.mp4" />',
919
- ' <SegmentURL media="s2.mp4" />',
920
- '</SegmentList>',
921
- ];
922
- await testDerived(lines);
923
- });
924
-
925
- it('derived from SegmentList w/ SegmentTimeline', async () => {
926
- const lines = [
927
- '<SegmentList duration="8">',
928
- ' <SegmentTimeline>',
929
- ' <S t="0" d="5" />',
930
- ' <S d="4" />',
931
- ' <S d="8" />',
932
- ' </SegmentTimeline>',
933
- ' <SegmentURL media="s1.mp4" />',
934
- ' <SegmentURL media="s2.mp4" />',
935
- '</SegmentList>',
936
- ];
937
- await testDerived(lines);
938
- });
939
-
940
- async function testDerived(lines) {
941
- const template = [
942
- '<MPD type="dynamic" suggestedPresentationDelay="PT0S"',
943
- ' minimumUpdatePeriod="PT5S"',
944
- ' timeShiftBufferDepth="PT2M"',
945
- ' availabilityStartTime="1970-01-01T00:05:00Z">',
946
- ' <Period id="1">',
947
- ' <AdaptationSet id="2" mimeType="video/mp4">',
948
- ' <Representation id="3" bandwidth="500">',
949
- ' <BaseURL>http://example.com</BaseURL>',
950
- '%(contents)s',
951
- ' </Representation>',
952
- ' </AdaptationSet>',
953
- ' </Period>',
954
- '</MPD>',
955
- ].join('\n');
956
- const manifestText = sprintf(template, {contents: lines.join('\n')});
957
-
958
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
959
- Date.now = () => 600000; /* 10 minutes */
960
- const manifest = await parser.start('dummy://foo', playerInterface);
961
-
962
- expect(manifest).toBeTruthy();
963
- const timeline = manifest.presentationTimeline;
964
- expect(timeline).toBeTruthy();
965
-
966
- // NOTE: the largest segment is 8 seconds long in each test.
967
- expect(timeline.getMaxSegmentDuration()).toBe(8);
968
- }
969
- }); // describe('maxSegmentDuration')
970
-
971
- describe('stop', () => {
972
- const manifestRequestType = shaka.net.NetworkingEngine.RequestType.MANIFEST;
973
- const manifestContext = {
974
- type: shaka.net.NetworkingEngine.AdvancedRequestType.MPD,
975
- };
976
- const dateRequestType = shaka.net.NetworkingEngine.RequestType.TIMING;
977
- const manifestUri = 'dummy://foo';
978
- const dateUri = 'http://foo.bar/date';
979
-
980
- beforeEach(() => {
981
- const manifest = [
982
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
983
- ' minimumUpdatePeriod="PT' + updateTime + 'S">',
984
- ' <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-xsdate:2014"',
985
- ' value="http://foo.bar/date" />',
986
- ' <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-xsdate:2014"',
987
- ' value="http://foo.bar/date" />',
988
- ' <Period id="1">',
989
- ' <AdaptationSet mimeType="video/mp4">',
990
- ' <Representation id="3" bandwidth="500">',
991
- ' <BaseURL>http://example.com</BaseURL>',
992
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
993
- ' duration="2" />',
994
- ' </Representation>',
995
- ' </AdaptationSet>',
996
- ' </Period>',
997
- '</MPD>',
998
- ].join('\n');
999
- fakeNetEngine
1000
- .setResponseText('http://foo.bar/date', '1970-01-01T00:00:30Z')
1001
- .setResponseText('dummy://foo', manifest);
1002
- });
1003
-
1004
- it('stops updates', async () => {
1005
- await parser.start(manifestUri, playerInterface);
1006
-
1007
- fakeNetEngine.expectRequest(
1008
- manifestUri, manifestRequestType, manifestContext);
1009
- fakeNetEngine.request.calls.reset();
1010
-
1011
- parser.stop();
1012
- await updateManifest();
1013
- expect(fakeNetEngine.request).not.toHaveBeenCalled();
1014
- });
1015
-
1016
- it('stops initial parsing', async () => {
1017
- const expectation =
1018
- expectAsync(parser.start('dummy://foo', playerInterface))
1019
- .toBeRejected();
1020
- // start will only begin the network request, calling stop here will be
1021
- // after the request has started but before any parsing has been done.
1022
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
1023
- parser.stop();
1024
- await expectation;
1025
-
1026
- fakeNetEngine.expectRequest(
1027
- manifestUri, manifestRequestType, manifestContext);
1028
- fakeNetEngine.request.calls.reset();
1029
- await updateManifest();
1030
- // An update should not occur.
1031
- expect(fakeNetEngine.request).not.toHaveBeenCalled();
1032
- });
1033
-
1034
- it('interrupts manifest updates', async () => {
1035
- const manifest = await parser.start('dummy://foo', playerInterface);
1036
-
1037
- expect(manifest).toBeTruthy();
1038
- fakeNetEngine.expectRequest(
1039
- manifestUri, manifestRequestType, manifestContext);
1040
- fakeNetEngine.request.calls.reset();
1041
- /** @type {!shaka.util.PublicPromise} */
1042
- const delay = fakeNetEngine.delayNextRequest();
1043
-
1044
- await updateManifest();
1045
- // The request was made but should not be resolved yet.
1046
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
1047
- fakeNetEngine.expectRequest(
1048
- manifestUri, manifestRequestType, manifestContext);
1049
- fakeNetEngine.request.calls.reset();
1050
- parser.stop();
1051
- delay.resolve();
1052
-
1053
- // Wait for another update period.
1054
- await updateManifest();
1055
- // A second update should not occur.
1056
- expect(fakeNetEngine.request).not.toHaveBeenCalled();
1057
- });
1058
-
1059
- it('interrupts UTCTiming requests', async () => {
1060
- /** @type {!shaka.util.PublicPromise} */
1061
- let delay = fakeNetEngine.delayNextRequest();
1062
- const expectation =
1063
- expectAsync(parser.start('dummy://foo', playerInterface))
1064
- .toBeRejected();
1065
-
1066
- await Util.shortDelay();
1067
- // This is the initial manifest request.
1068
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
1069
- fakeNetEngine.expectRequest(
1070
- manifestUri, manifestRequestType, manifestContext);
1071
- fakeNetEngine.request.calls.reset();
1072
- // Resolve the manifest request and wait on the UTCTiming request.
1073
- delay.resolve();
1074
- delay = fakeNetEngine.delayNextRequest();
1075
- await Util.shortDelay();
1076
-
1077
- // This is the first UTCTiming request.
1078
- expect(fakeNetEngine.request).toHaveBeenCalledTimes(1);
1079
- fakeNetEngine.expectRequest(dateUri, dateRequestType);
1080
- fakeNetEngine.request.calls.reset();
1081
- // Interrupt the parser, then fail the request.
1082
- parser.stop();
1083
- delay.reject();
1084
- await expectation;
1085
-
1086
- // Wait for another update period.
1087
- await updateManifest();
1088
-
1089
- // No more updates should occur.
1090
- expect(fakeNetEngine.request).not.toHaveBeenCalled();
1091
- });
1092
- });
1093
-
1094
- describe('SegmentTemplate w/ SegmentTimeline', () => {
1095
- const basicLines = [
1096
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4">',
1097
- ' <SegmentTimeline>',
1098
- ' <S d="10" t="0" />',
1099
- ' <S d="5" />',
1100
- ' <S d="15" />',
1101
- ' </SegmentTimeline>',
1102
- '</SegmentTemplate>',
1103
- ];
1104
- const basicRefs = [
1105
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1106
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 15, originalUri),
1107
- shaka.test.ManifestParser.makeReference('s3.mp4', 15, 30, originalUri),
1108
- ];
1109
- const updateLines = [
1110
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4">',
1111
- ' <SegmentTimeline>',
1112
- ' <S d="10" t="0" />',
1113
- ' <S d="5" />',
1114
- ' <S d="15" />',
1115
- ' <S d="10" />',
1116
- ' </SegmentTimeline>',
1117
- '</SegmentTemplate>',
1118
- ];
1119
- const updateRefs = [
1120
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1121
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 15, originalUri),
1122
- shaka.test.ManifestParser.makeReference('s3.mp4', 15, 30, originalUri),
1123
- shaka.test.ManifestParser.makeReference('s4.mp4', 30, 40, originalUri),
1124
- ];
1125
- const partialUpdateLines = [
1126
- '<SegmentTemplate startNumber="3" media="s$Number$.mp4">',
1127
- ' <SegmentTimeline>',
1128
- ' <S d="15" t="15" />',
1129
- ' <S d="10" />',
1130
- ' </SegmentTimeline>',
1131
- '</SegmentTemplate>',
1132
- ];
1133
-
1134
- testCommonBehaviors(
1135
- basicLines, basicRefs, updateLines, updateRefs, partialUpdateLines);
1136
- });
1137
-
1138
- describe('SegmentList w/ SegmentTimeline', () => {
1139
- const basicLines = [
1140
- '<SegmentList>',
1141
- ' <SegmentURL media="s1.mp4" />',
1142
- ' <SegmentURL media="s2.mp4" />',
1143
- ' <SegmentURL media="s3.mp4" />',
1144
- ' <SegmentTimeline>',
1145
- ' <S d="10" t="0" />',
1146
- ' <S d="5" />',
1147
- ' <S d="15" />',
1148
- ' </SegmentTimeline>',
1149
- '</SegmentList>',
1150
- ];
1151
- const basicRefs = [
1152
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1153
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 15, originalUri),
1154
- shaka.test.ManifestParser.makeReference('s3.mp4', 15, 30, originalUri),
1155
- ];
1156
- const updateLines = [
1157
- '<SegmentList>',
1158
- ' <SegmentURL media="s1.mp4" />',
1159
- ' <SegmentURL media="s2.mp4" />',
1160
- ' <SegmentURL media="s3.mp4" />',
1161
- ' <SegmentURL media="s4.mp4" />',
1162
- ' <SegmentTimeline>',
1163
- ' <S d="10" t="0" />',
1164
- ' <S d="5" />',
1165
- ' <S d="15" />',
1166
- ' <S d="10" />',
1167
- ' </SegmentTimeline>',
1168
- '</SegmentList>',
1169
- ];
1170
- const updateRefs = [
1171
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1172
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 15, originalUri),
1173
- shaka.test.ManifestParser.makeReference('s3.mp4', 15, 30, originalUri),
1174
- shaka.test.ManifestParser.makeReference('s4.mp4', 30, 40, originalUri),
1175
- ];
1176
- const partialUpdateLines = [
1177
- '<SegmentList startNumber="3">',
1178
- ' <SegmentURL media="s3.mp4" />',
1179
- ' <SegmentURL media="s4.mp4" />',
1180
- ' <SegmentTimeline>',
1181
- ' <S d="15" t="15" />',
1182
- ' <S d="10" />',
1183
- ' </SegmentTimeline>',
1184
- '</SegmentList>',
1185
- ];
1186
-
1187
- testCommonBehaviors(
1188
- basicLines, basicRefs, updateLines, updateRefs, partialUpdateLines);
1189
- });
1190
-
1191
- describe('SegmentList w/ @duration', () => {
1192
- const basicLines = [
1193
- '<SegmentList duration="10">',
1194
- ' <SegmentURL media="s1.mp4" />',
1195
- ' <SegmentURL media="s2.mp4" />',
1196
- ' <SegmentURL media="s3.mp4" />',
1197
- '</SegmentList>',
1198
- ];
1199
- const basicRefs = [
1200
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1201
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 20, originalUri),
1202
- shaka.test.ManifestParser.makeReference('s3.mp4', 20, 30, originalUri),
1203
- ];
1204
- const updateLines = [
1205
- '<SegmentList duration="10">',
1206
- ' <SegmentURL media="s1.mp4" />',
1207
- ' <SegmentURL media="s2.mp4" />',
1208
- ' <SegmentURL media="s3.mp4" />',
1209
- ' <SegmentURL media="s4.mp4" />',
1210
- '</SegmentList>',
1211
- ];
1212
- const updateRefs = [
1213
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 10, originalUri),
1214
- shaka.test.ManifestParser.makeReference('s2.mp4', 10, 20, originalUri),
1215
- shaka.test.ManifestParser.makeReference('s3.mp4', 20, 30, originalUri),
1216
- shaka.test.ManifestParser.makeReference('s4.mp4', 30, 40, originalUri),
1217
- ];
1218
- const partialUpdateLines = [
1219
- '<SegmentList startNumber="3" duration="10">',
1220
- ' <SegmentURL media="s3.mp4" />',
1221
- ' <SegmentURL media="s4.mp4" />',
1222
- '</SegmentList>',
1223
- ];
1224
-
1225
- testCommonBehaviors(
1226
- basicLines, basicRefs, updateLines, updateRefs, partialUpdateLines);
1227
- });
1228
-
1229
- describe('SegmentTemplate w/ duration', () => {
1230
- const templateLines = [
1231
- '<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
1232
- ];
1233
-
1234
- it('produces sane references without assertions', async () => {
1235
- const manifestText =
1236
- makeSimpleLiveManifestText(templateLines, updateTime);
1237
-
1238
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
1239
- const manifest = await parser.start('dummy://foo', playerInterface);
1240
-
1241
- const stream = manifest.variants[0].video;
1242
- await stream.createSegmentIndex();
1243
-
1244
- const liveEdge =
1245
- manifest.presentationTimeline.getSegmentAvailabilityEnd();
1246
-
1247
- // In https://github.com/shaka-project/shaka-player/issues/1204, a get on
1248
- // the final segment failed an assertion and returned endTime == 0.
1249
- // Find the last segment by looking just before the live edge. Looking
1250
- // right on the live edge creates test flake, and the segments are 2
1251
- // seconds in duration.
1252
- const idx = stream.segmentIndex.find(liveEdge - 0.5);
1253
- goog.asserts.assert(idx != null, 'Live edge not found!');
1254
-
1255
- // This should not throw an assertion.
1256
- const ref = stream.segmentIndex.get(idx);
1257
- // The segment's endTime should definitely not be 0.
1258
- expect(ref.endTime).toBeGreaterThan(0);
1259
- });
1260
- });
1261
-
1262
- describe('EventStream', () => {
1263
- const originalManifest = [
1264
- '<MPD type="dynamic" minimumUpdatePeriod="PT' + updateTime + 'S"',
1265
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
1266
- ' <Period id="1" duration="PT60S" start="PT10S">',
1267
- ' <EventStream schemeIdUri="http://example.com" value="foobar"',
1268
- ' timescale="100">',
1269
- ' <Event duration="5000" />',
1270
- ' <Event id="abc" presentationTime="300" duration="1000" />',
1271
- ' </EventStream>',
1272
- ' <AdaptationSet mimeType="video/mp4">',
1273
- ' <Representation bandwidth="1">',
1274
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
1275
- ' duration="2" />',
1276
- ' </Representation>',
1277
- ' </AdaptationSet>',
1278
- ' </Period>',
1279
- '</MPD>',
1280
- ].join('\n');
1281
-
1282
- /** @type {!jasmine.Spy} */
1283
- let onTimelineRegionAddedSpy;
1284
-
1285
- beforeEach(() => {
1286
- onTimelineRegionAddedSpy = jasmine.createSpy('onTimelineRegionAdded');
1287
- playerInterface.onTimelineRegionAdded =
1288
- shaka.test.Util.spyFunc(onTimelineRegionAddedSpy);
1289
- });
1290
-
1291
- it('will parse EventStream nodes', async () => {
1292
- fakeNetEngine.setResponseText('dummy://foo', originalManifest);
1293
- await parser.start('dummy://foo', playerInterface);
1294
-
1295
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(2);
1296
-
1297
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith({
1298
- schemeIdUri: 'http://example.com',
1299
- value: 'foobar',
1300
- startTime: 10,
1301
- endTime: 60,
1302
- id: '',
1303
- eventElement: jasmine.any(Element),
1304
- });
1305
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith({
1306
- schemeIdUri: 'http://example.com',
1307
- value: 'foobar',
1308
- startTime: 13,
1309
- endTime: 23,
1310
- id: 'abc',
1311
- eventElement: jasmine.any(Element),
1312
- });
1313
- });
1314
-
1315
- it('will add timeline regions on manifest update', async () => {
1316
- const newManifest = [
1317
- '<MPD type="dynamic" minimumUpdatePeriod="PT' + updateTime + 'S"',
1318
- ' availabilityStartTime="1970-01-01T00:00:00Z">',
1319
- ' <Period id="1" duration="PT30S">',
1320
- ' <EventStream schemeIdUri="http://example.com" timescale="100">',
1321
- ' <Event id="100" />',
1322
- ' </EventStream>',
1323
- ' <AdaptationSet mimeType="video/mp4">',
1324
- ' <Representation bandwidth="1">',
1325
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
1326
- ' duration="2" />',
1327
- ' </Representation>',
1328
- ' </AdaptationSet>',
1329
- ' </Period>',
1330
- '</MPD>',
1331
- ].join('\n');
1332
-
1333
- fakeNetEngine.setResponseText('dummy://foo', originalManifest);
1334
- await parser.start('dummy://foo', playerInterface);
1335
-
1336
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(2);
1337
- onTimelineRegionAddedSpy.calls.reset();
1338
-
1339
- fakeNetEngine.setResponseText('dummy://foo', newManifest);
1340
- await updateManifest();
1341
-
1342
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(1);
1343
- });
1344
-
1345
- it('will not let an event exceed the Period duration', async () => {
1346
- const newManifest = [
1347
- '<MPD>',
1348
- ' <Period id="1" duration="PT30S">',
1349
- ' <EventStream schemeIdUri="http://example.com" timescale="1">',
1350
- ' <Event presentationTime="10" duration="15"/>',
1351
- ' <Event presentationTime="25" duration="50"/>',
1352
- ' <Event presentationTime="50" duration="10"/>',
1353
- ' </EventStream>',
1354
- ' <AdaptationSet mimeType="video/mp4">',
1355
- ' <Representation bandwidth="1">',
1356
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
1357
- ' duration="2" />',
1358
- ' </Representation>',
1359
- ' </AdaptationSet>',
1360
- ' </Period>',
1361
- '</MPD>',
1362
- ].join('\n');
1363
-
1364
- fakeNetEngine.setResponseText('dummy://foo', newManifest);
1365
- await parser.start('dummy://foo', playerInterface);
1366
-
1367
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(3);
1368
- expect(onTimelineRegionAddedSpy)
1369
- .toHaveBeenCalledWith(
1370
- jasmine.objectContaining({startTime: 10, endTime: 25}));
1371
- expect(onTimelineRegionAddedSpy)
1372
- .toHaveBeenCalledWith(
1373
- jasmine.objectContaining({startTime: 25, endTime: 30}));
1374
- expect(onTimelineRegionAddedSpy)
1375
- .toHaveBeenCalledWith(
1376
- jasmine.objectContaining({startTime: 30, endTime: 30}));
1377
- });
1378
-
1379
- it('will parse multiple events at same offset', async () => {
1380
- const newManifest = [
1381
- '<MPD>',
1382
- ' <Period id="1" duration="PT30S">',
1383
- ' <EventStream schemeIdUri="http://example.com" timescale="1">',
1384
- ' <Event id="1" presentationTime="10" duration="15"/>',
1385
- ' <Event id="2" presentationTime="10" duration="15"/>',
1386
- ' </EventStream>',
1387
- ' <AdaptationSet mimeType="video/mp4">',
1388
- ' <Representation bandwidth="1">',
1389
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
1390
- ' duration="2" />',
1391
- ' </Representation>',
1392
- ' </AdaptationSet>',
1393
- ' </Period>',
1394
- '</MPD>',
1395
- ].join('\n');
1396
-
1397
- fakeNetEngine.setResponseText('dummy://foo', newManifest);
1398
- await parser.start('dummy://foo', playerInterface);
1399
-
1400
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(2);
1401
- expect(onTimelineRegionAddedSpy)
1402
- .toHaveBeenCalledWith(
1403
- jasmine.objectContaining({id: '1', startTime: 10, endTime: 25}));
1404
- expect(onTimelineRegionAddedSpy)
1405
- .toHaveBeenCalledWith(
1406
- jasmine.objectContaining({id: '2', startTime: 10, endTime: 25}));
1407
- });
1408
-
1409
- it('will not add timeline regions outside the DVR window', async () => {
1410
- const manifest = [
1411
- '<MPD type="dynamic" minimumUpdatePeriod="PT' + updateTime + 'S"',
1412
- ' availabilityStartTime="1970-01-01T00:00:00Z"',
1413
- ' suggestedPresentationDelay="PT0S"',
1414
- ' timeShiftBufferDepth="PT30S">',
1415
- ' <Period id="1">',
1416
- ' <EventStream schemeIdUri="http://example.com" timescale="1">',
1417
- ' <Event id="0" presentationTime="0" duration="10"/>',
1418
- ' <Event id="1" presentationTime="10" duration="10"/>',
1419
- ' <Event id="2" presentationTime="20" duration="10"/>',
1420
- ' <Event id="3" presentationTime="30" duration="10"/>',
1421
- ' <Event id="4" presentationTime="40" duration="10"/>',
1422
- ' </EventStream>',
1423
- ' <AdaptationSet mimeType="video/mp4">',
1424
- ' <Representation bandwidth="1">',
1425
- ' <SegmentTemplate startNumber="1" media="s$Number$.mp4"',
1426
- ' duration="2" />',
1427
- ' </Representation>',
1428
- ' </AdaptationSet>',
1429
- ' </Period>',
1430
- '</MPD>',
1431
- ].join('\n');
1432
-
1433
- // 45 seconds after the epoch, which is also 45 seconds after the
1434
- // presentation started. Only the last 30 seconds are available, from
1435
- // time 15 to 45.
1436
- Date.now = () => 45 * 1000;
1437
-
1438
- fakeNetEngine.setResponseText('dummy://foo', manifest);
1439
- await parser.start('dummy://foo', playerInterface);
1440
-
1441
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledTimes(4);
1442
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith(
1443
- jasmine.objectContaining({id: '1'}));
1444
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith(
1445
- jasmine.objectContaining({id: '2'}));
1446
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith(
1447
- jasmine.objectContaining({id: '3'}));
1448
- expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith(
1449
- jasmine.objectContaining({id: '4'}));
1450
- });
1451
- });
1452
-
1453
- it('honors clockSyncUri for in-progress recordings', async () => {
1454
- const manifestText = [
1455
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:05:00Z"',
1456
- ' mediaPresentationDuration="PT3600S">',
1457
- ' <Period id="1">',
1458
- ' <AdaptationSet mimeType="video/mp4">',
1459
- ' <Representation id="3" bandwidth="500">',
1460
- ' <BaseURL>http://example.com</BaseURL>',
1461
- ' <SegmentTemplate media="s$Number$.mp4" duration="2" />',
1462
- ' </Representation>',
1463
- ' </AdaptationSet>',
1464
- ' </Period>',
1465
- '</MPD>',
1466
- ].join('\n');
1467
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
1468
-
1469
- // Simulate a realistic clock sync URI.
1470
- fakeNetEngine.setResponseText('dummy://time', '');
1471
- fakeNetEngine.setHeaders('dummy://time', {
1472
- 'date': (new Date()).toUTCString(),
1473
- });
1474
-
1475
- const config = shaka.util.PlayerConfiguration.createDefault().manifest;
1476
- config.dash.clockSyncUri = 'dummy://time';
1477
- parser.configure(config);
1478
-
1479
- const manifest = await parser.start('dummy://foo', playerInterface);
1480
-
1481
- // Make sure we're testing what we think we're testing.
1482
- // This should be seen as in-progress.
1483
- expect(manifest.presentationTimeline.isInProgress()).toBe(true);
1484
-
1485
- // Now make sure we made the time sync request.
1486
- const timingRequest = shaka.net.NetworkingEngine.RequestType.TIMING;
1487
- fakeNetEngine.expectRequest('dummy://time', timingRequest);
1488
- });
1489
-
1490
- it('adds segments to in-progress recordings', async () => {
1491
- const manifestText = [
1492
- '<MPD type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z"',
1493
- ' mediaPresentationDuration="PT10S">',
1494
- ' <Period id="1">',
1495
- ' <AdaptationSet mimeType="video/mp4">',
1496
- ' <Representation id="3" bandwidth="500">',
1497
- ' <BaseURL>http://example.com</BaseURL>',
1498
- ' <SegmentTemplate media="s$Number$.mp4" duration="2" />',
1499
- ' </Representation>',
1500
- ' </AdaptationSet>',
1501
- ' </Period>',
1502
- '</MPD>',
1503
- ].join('\n');
1504
- fakeNetEngine.setResponseText('dummy://foo', manifestText);
1505
-
1506
- // The presentation started just over 4 seconds ago. There should be 2
1507
- // segments so far.
1508
- Date.now = () => 4.1 * 1000;
1509
- const manifest = await parser.start('dummy://foo', playerInterface);
1510
-
1511
- // Make sure we're testing what we think we're testing.
1512
- // This should be seen as in-progress.
1513
- expect(manifest.presentationTimeline.isInProgress()).toBe(true);
1514
-
1515
- const stream = manifest.variants[0].video;
1516
- expect(stream).toBeTruthy();
1517
-
1518
- await stream.createSegmentIndex();
1519
- expect(stream.segmentIndex).toBeTruthy();
1520
-
1521
- // Check for the 2 initial segments we're expecting.
1522
- ManifestParser.verifySegmentIndex(stream, [
1523
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 2, originalUri),
1524
- shaka.test.ManifestParser.makeReference('s2.mp4', 2, 4, originalUri),
1525
- ]);
1526
-
1527
- // Just over 10 seconds after the presentation started, we should now have
1528
- // all 5 segments. In order to trick the system into updating, we must both
1529
- // fake the current time and wait long enough for the timer to fire and
1530
- // update the references.
1531
- Date.now = () => 10.1 * 1000;
1532
- await shaka.test.Util.delay(2.1); // A little longer than the segments are.
1533
-
1534
- ManifestParser.verifySegmentIndex(stream, [
1535
- shaka.test.ManifestParser.makeReference('s1.mp4', 0, 2, originalUri),
1536
- shaka.test.ManifestParser.makeReference('s2.mp4', 2, 4, originalUri),
1537
- shaka.test.ManifestParser.makeReference('s3.mp4', 4, 6, originalUri),
1538
- shaka.test.ManifestParser.makeReference('s4.mp4', 6, 8, originalUri),
1539
- shaka.test.ManifestParser.makeReference('s5.mp4', 8, 10, originalUri),
1540
- ]);
1541
- });
1542
- });