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,1394 +0,0 @@
1
- /*! @license
2
- * Shaka Player
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- /**
8
- * @typedef {{start: number, end: number}}
9
- *
10
- * @property {number} start
11
- * The start time of the range, in seconds.
12
- * @property {number} end
13
- * The end time of the range, in seconds.
14
- */
15
- let TimeRange;
16
-
17
-
18
- /**
19
- * @typedef {{
20
- * buffered: !Array.<TimeRange>,
21
- * start: number,
22
- * waitingAt: number,
23
- * expectedEndTime: number,
24
- * expectEvent: boolean,
25
- * }}
26
- *
27
- * @description
28
- * Parameters for a test where we start playing inside a buffered range and play
29
- * until the end of the buffer. Then, if we expect it, Playhead should jump
30
- * to the expected time. We should get a 'stalldetected' event when the Playhead
31
- * detects a stall through the StallDetector, and a 'gapjumped' event when the
32
- * Playhead jumps over a gap in the buffered range(s).
33
- *
34
- * @property {!Array.<TimeRange>} buffered
35
- * The buffered ranges for the test.
36
- * @property {number} start
37
- * The time to start playing at.
38
- * @property {number} waitingAt
39
- * The time to pause at and fire a 'waiting' event.
40
- * @property {number} expectedEndTime
41
- * The expected time at the end of the test.
42
- * @property {boolean} expectEvent
43
- * If true, expect either the 'stalldetected' or 'gapjumped' event to be
44
- * fired.
45
- */
46
- let PlayingTestInfo;
47
-
48
-
49
- /**
50
- * @typedef {{
51
- * buffered: !Array.<TimeRange>,
52
- * newBuffered: (!Array.<TimeRange>|undefined),
53
- * start: number,
54
- * seekTo: number,
55
- * expectedEndTime: number,
56
- * expectEvent: boolean,
57
- * }}
58
- *
59
- * @description
60
- * Parameters for a test where we start playing inside a buffered range and seek
61
- * to a given time, which may have different buffered ranges. If we are in a
62
- * gap, Playhead should jump the gap to the expected time.
63
- *
64
- * @property {!Array.<TimeRange>} buffered
65
- * The buffered ranges for the test.
66
- * @property {(!Array.<TimeRange>|undefined)} newBuffered
67
- * Used in the unbuffered seek tests. Represents the buffered ranges to
68
- * use after the seek.
69
- * @property {number} start
70
- * The time to start playing at.
71
- * @property {number} seekTo
72
- * The time to seek to.
73
- * @property {number} expectedEndTime
74
- * The expected time at the end of the test.
75
- * @property {boolean} expectEvent
76
- * If true, expect either the 'stalldetected' or 'gapjumped' event to be
77
- * fired.
78
- */
79
- let SeekTestInfo;
80
-
81
-
82
- describe('Playhead', () => {
83
- const Util = shaka.test.Util;
84
-
85
- /** @type {!shaka.test.FakeVideo} */
86
- let video;
87
- /** @type {!shaka.test.FakePresentationTimeline} */
88
- let timeline;
89
- /** @type {shaka.extern.Manifest} */
90
- let manifest;
91
- /** @type {!shaka.media.Playhead} */
92
- let playhead;
93
- /** @type {shaka.extern.StreamingConfiguration} */
94
- let config;
95
-
96
- // Callback to us from Playhead when a valid 'seeking' event occurs.
97
- /** @type {!jasmine.Spy} */
98
- let onSeek;
99
-
100
- // Callback to us from Playhead when an event should be sent to the app.
101
- /** @type {!jasmine.Spy} */
102
- let onEvent;
103
-
104
- beforeAll(() => {
105
- jasmine.clock().install();
106
- });
107
-
108
- afterAll(() => {
109
- jasmine.clock().uninstall();
110
- });
111
-
112
- beforeEach(() => {
113
- video = new shaka.test.FakeVideo();
114
- timeline = new shaka.test.FakePresentationTimeline();
115
-
116
- onSeek = jasmine.createSpy('onSeek');
117
- onEvent = jasmine.createSpy('onEvent');
118
-
119
- timeline.isLive.and.returnValue(false);
120
- timeline.getSeekRangeStart.and.returnValue(5);
121
- timeline.getSeekRangeEnd.and.returnValue(60);
122
- timeline.getDuration.and.returnValue(60);
123
-
124
- // These tests should not cause these methods to be invoked.
125
- timeline.getSegmentAvailabilityStart.and.throwError(new Error());
126
- timeline.getSegmentAvailabilityEnd.and.throwError(new Error());
127
- timeline.setDuration.and.throwError(new Error());
128
-
129
- manifest = {
130
- variants: [],
131
- textStreams: [],
132
- imageStreams: [],
133
- presentationTimeline: timeline,
134
- minBufferTime: 10,
135
- offlineSessionIds: [],
136
- sequenceMode: false,
137
- ignoreManifestTimestampsInSegmentsMode: false,
138
- type: 'UNKNOWN',
139
- serviceDescription: null,
140
- };
141
-
142
- config = shaka.util.PlayerConfiguration.createDefault().streaming;
143
- });
144
-
145
- afterEach(() => {
146
- playhead.release();
147
- });
148
-
149
- function setMockDate(seconds) {
150
- const minutes = Math.floor(seconds / 60);
151
- seconds %= 60;
152
- const mockDate = new Date(2013, 9, 23, 7, minutes, seconds);
153
- jasmine.clock().mockDate(mockDate);
154
- }
155
-
156
- describe('getTime', () => {
157
- it('returns current time when the video is paused', () => {
158
- video.readyState = HTMLMediaElement.HAVE_METADATA;
159
- playhead = new shaka.media.MediaSourcePlayhead(
160
- video,
161
- manifest,
162
- config,
163
- /* startTime= */ 5,
164
- Util.spyFunc(onSeek),
165
- Util.spyFunc(onEvent));
166
-
167
- playhead.ready();
168
-
169
- expect(video.currentTime).toBe(5);
170
- expect(playhead.getTime()).toBe(5);
171
-
172
- // Simulate pausing.
173
- video.paused = true;
174
- timeline.getSeekRangeStart.and.returnValue(10);
175
- timeline.getSeekRangeEnd.and.returnValue(70);
176
-
177
- expect(video.currentTime).toBe(5);
178
- expect(playhead.getTime()).toBe(5);
179
- });
180
-
181
- it('returns the correct time when readyState starts at 0', () => {
182
- playhead = new shaka.media.MediaSourcePlayhead(
183
- video,
184
- manifest,
185
- config,
186
- /* startTime= */ 5,
187
- Util.spyFunc(onSeek),
188
- Util.spyFunc(onEvent));
189
-
190
- playhead.ready();
191
-
192
- expect(video.addEventListener).toHaveBeenCalledWith(
193
- 'loadedmetadata', jasmine.any(Function), jasmine.anything());
194
- expect(video.addEventListener).not.toHaveBeenCalledWith(
195
- 'seeking', jasmine.any(Function), jasmine.anything());
196
-
197
- expect(playhead.getTime()).toBe(5);
198
- expect(video.currentTime).toBe(0);
199
-
200
- video.readyState = HTMLMediaElement.HAVE_METADATA;
201
- video.on['loadedmetadata']();
202
-
203
- expect(video.addEventListener).toHaveBeenCalledWith(
204
- 'seeking', jasmine.any(Function), jasmine.anything());
205
- video.on['seeking']();
206
-
207
- expect(playhead.getTime()).toBe(5);
208
- expect(video.currentTime).toBe(5);
209
-
210
- video.currentTime = 6;
211
- expect(playhead.getTime()).toBe(6);
212
-
213
- // getTime() should always clamp the time even if the video element
214
- // doesn't dispatch 'seeking' events.
215
- video.currentTime = 120;
216
- expect(playhead.getTime()).toBe(60);
217
-
218
- video.currentTime = 0;
219
- expect(playhead.getTime()).toBe(5);
220
- });
221
-
222
- it('returns the correct time when readyState starts at 1', () => {
223
- video.readyState = HTMLMediaElement.HAVE_METADATA;
224
-
225
- playhead = new shaka.media.MediaSourcePlayhead(
226
- video,
227
- manifest,
228
- config,
229
- /* startTime= */ 5,
230
- Util.spyFunc(onSeek),
231
- Util.spyFunc(onEvent));
232
-
233
- playhead.ready();
234
-
235
- video.on['seeking']();
236
- expect(playhead.getTime()).toBe(5);
237
- expect(video.currentTime).toBe(5);
238
-
239
- video.currentTime = 6;
240
- expect(playhead.getTime()).toBe(6);
241
- });
242
-
243
- it('allows using startTime of 0', () => {
244
- video.readyState = HTMLMediaElement.HAVE_METADATA;
245
- timeline.isLive.and.returnValue(true);
246
- timeline.getDuration.and.returnValue(Infinity);
247
- timeline.getSeekRangeStart.and.returnValue(0);
248
- timeline.getSeekRangeEnd.and.returnValue(60);
249
-
250
- playhead = new shaka.media.MediaSourcePlayhead(
251
- video,
252
- manifest,
253
- config,
254
- /* startTime= */ 0,
255
- Util.spyFunc(onSeek),
256
- Util.spyFunc(onEvent));
257
-
258
- expect(playhead.getTime()).toBe(0);
259
- });
260
-
261
- it('bumps startTime back from duration', () => {
262
- video.readyState = HTMLMediaElement.HAVE_METADATA;
263
- timeline.isLive.and.returnValue(false);
264
- timeline.getSeekRangeStart.and.returnValue(0);
265
- timeline.getSeekRangeEnd.and.returnValue(60);
266
- timeline.getDuration.and.returnValue(60);
267
-
268
- playhead = new shaka.media.MediaSourcePlayhead(
269
- video,
270
- manifest,
271
- config,
272
- /* startTime= */ 60,
273
- Util.spyFunc(onSeek),
274
- Util.spyFunc(onEvent));
275
-
276
- playhead.ready();
277
-
278
- expect(playhead.getTime()).toBe(59); // duration - durationBackoff
279
- expect(video.currentTime).toBe(59); // duration - durationBackoff
280
- });
281
-
282
- it('playback from a certain offset from live edge for live', () => {
283
- video.readyState = HTMLMediaElement.HAVE_METADATA;
284
- timeline.isLive.and.returnValue(true);
285
- timeline.getDuration.and.returnValue(Infinity);
286
- timeline.getSeekRangeStart.and.returnValue(0);
287
- timeline.getSeekRangeEnd.and.returnValue(60);
288
-
289
- playhead = new shaka.media.MediaSourcePlayhead(
290
- video,
291
- manifest,
292
- config,
293
- /* startTime= */ -15,
294
- Util.spyFunc(onSeek),
295
- Util.spyFunc(onEvent));
296
-
297
- expect(playhead.getTime()).toBe(45);
298
- });
299
-
300
- it('playback from segment seek range start time', () => {
301
- video.readyState = HTMLMediaElement.HAVE_METADATA;
302
- timeline.isLive.and.returnValue(true);
303
- timeline.getDuration.and.returnValue(Infinity);
304
- timeline.getSeekRangeStart.and.returnValue(30);
305
- timeline.getSeekRangeEnd.and.returnValue(60);
306
- // If the live stream's playback offset time is not available, start
307
- // playing from the seek range start time.
308
- playhead = new shaka.media.MediaSourcePlayhead(
309
- video,
310
- manifest,
311
- config,
312
- /* startTime= */ -40,
313
- Util.spyFunc(onSeek),
314
- Util.spyFunc(onEvent));
315
-
316
- playhead.ready();
317
-
318
- expect(playhead.getTime()).toBe(30);
319
- });
320
-
321
- it('does not change currentTime if it\'s not 0', () => {
322
- playhead = new shaka.media.MediaSourcePlayhead(
323
- video,
324
- manifest,
325
- config,
326
- /* startTime= */ 5,
327
- Util.spyFunc(onSeek),
328
- Util.spyFunc(onEvent));
329
-
330
- playhead.ready();
331
-
332
- expect(video.addEventListener).toHaveBeenCalledWith(
333
- 'loadedmetadata', jasmine.any(Function), jasmine.anything());
334
-
335
- expect(playhead.getTime()).toBe(5);
336
- expect(video.currentTime).toBe(0);
337
-
338
- video.currentTime = 8;
339
- video.readyState = HTMLMediaElement.HAVE_METADATA;
340
- video.on['loadedmetadata']();
341
-
342
- // Delay to let Playhead batch up changes to currentTime and observe.
343
- jasmine.clock().tick(1000);
344
- expect(video.currentTime).toBe(8);
345
- });
346
-
347
- // This is important for recovering from drift.
348
- // See: https://github.com/shaka-project/shaka-player/issues/1105
349
- // TODO: Re-evaluate after https://github.com/shaka-project/shaka-player/issues/999
350
- it('does not change once the initial position is set', () => {
351
- timeline.isLive.and.returnValue(true);
352
- timeline.getDuration.and.returnValue(Infinity);
353
- timeline.getSeekRangeStart.and.returnValue(0);
354
- timeline.getSeekRangeEnd.and.returnValue(60);
355
- timeline.getSeekRangeEnd.and.returnValue(60);
356
-
357
- playhead = new shaka.media.MediaSourcePlayhead(
358
- video,
359
- manifest,
360
- config,
361
- /* startTime= */ null,
362
- Util.spyFunc(onSeek),
363
- Util.spyFunc(onEvent));
364
-
365
- playhead.ready();
366
-
367
- expect(video.addEventListener).toHaveBeenCalledWith(
368
- 'loadedmetadata', jasmine.any(Function), jasmine.anything());
369
-
370
- expect(playhead.getTime()).toBe(60);
371
- expect(video.currentTime).toBe(0);
372
-
373
- // Simulate time passing and the live edge changing.
374
- timeline.getSeekRangeStart.and.returnValue(10);
375
- timeline.getSeekRangeEnd.and.returnValue(70);
376
- timeline.getSeekRangeEnd.and.returnValue(70);
377
-
378
- expect(playhead.getTime()).toBe(60);
379
- });
380
- }); // getTime
381
-
382
- it('clamps playhead after seeking for live', () => {
383
- video.readyState = HTMLMediaElement.HAVE_METADATA;
384
-
385
- video.buffered = createFakeBuffered([{start: 25, end: 55}]);
386
-
387
- timeline.isLive.and.returnValue(true);
388
- timeline.getDuration.and.returnValue(Infinity);
389
- timeline.getSeekRangeStart.and.returnValue(5);
390
- timeline.getSeekRangeEnd.and.returnValue(60);
391
-
392
- playhead = new shaka.media.MediaSourcePlayhead(
393
- video,
394
- manifest,
395
- config,
396
- /* startTime= */ 5,
397
- Util.spyFunc(onSeek),
398
- Util.spyFunc(onEvent));
399
-
400
- playhead.ready();
401
-
402
- // This has to periodically increment the mock date to allow the onSeeking_
403
- // handler to seek, if appropriate.
404
-
405
- // Calling on['seeking']() is like dispatching a 'seeking' event. So, each
406
- // time we change the video's current time or Playhead changes the video's
407
- // current time we must call on['seeking'](),
408
-
409
- setMockDate(0);
410
- video.on['seeking']();
411
- expect(video.currentTime).toBe(5);
412
- expect(playhead.getTime()).toBe(5);
413
-
414
- // safe = start + rebufferingGoal = 5 + 10 = 15
415
- // safeSeek = safeSeek + 5 = 15 + 5 = 20
416
-
417
- // Seek in safe region & in buffered region.
418
- setMockDate(10);
419
- video.currentTime = 26;
420
- video.on['seeking']();
421
- expect(video.currentTime).toBe(26);
422
- expect(playhead.getTime()).toBe(26);
423
- expect(onSeek).toHaveBeenCalled();
424
-
425
- onSeek.calls.reset();
426
-
427
- // Seek in safe region & in unbuffered region.
428
- setMockDate(20);
429
- video.currentTime = 24;
430
- video.on['seeking']();
431
- expect(video.currentTime).toBe(24);
432
- expect(playhead.getTime()).toBe(24);
433
- expect(onSeek).toHaveBeenCalled();
434
-
435
- onSeek.calls.reset();
436
-
437
- // Seek before start, start is unbuffered.
438
- setMockDate(30);
439
- video.currentTime = 1;
440
- video.on['seeking']();
441
- expect(video.currentTime).toBe(20);
442
- expect(playhead.getTime()).toBe(20);
443
- expect(onSeek).not.toHaveBeenCalled();
444
- setMockDate(40);
445
- video.on['seeking']();
446
- expect(onSeek).toHaveBeenCalled();
447
-
448
- onSeek.calls.reset();
449
-
450
- video.buffered = createFakeBuffered([{start: 10, end: 40}]);
451
-
452
- // Seek outside safe region & in buffered region.
453
- setMockDate(50);
454
- video.currentTime = 11;
455
- video.on['seeking']();
456
- expect(video.currentTime).toBe(11);
457
- expect(playhead.getTime()).toBe(11);
458
- expect(onSeek).toHaveBeenCalled();
459
-
460
- onSeek.calls.reset();
461
-
462
- // Seek outside safe region & in unbuffered region.
463
- setMockDate(60);
464
- video.currentTime = 9;
465
- video.on['seeking']();
466
- expect(video.currentTime).toBe(20);
467
- expect(playhead.getTime()).toBe(20);
468
- expect(onSeek).not.toHaveBeenCalled();
469
- setMockDate(70);
470
- video.on['seeking']();
471
- expect(onSeek).toHaveBeenCalled();
472
-
473
- onSeek.calls.reset();
474
-
475
- // Seek past end.
476
- setMockDate(80);
477
- video.currentTime = 120;
478
- video.on['seeking']();
479
- expect(video.currentTime).toBe(60);
480
- expect(playhead.getTime()).toBe(60);
481
- expect(onSeek).not.toHaveBeenCalled();
482
- setMockDate(90);
483
- video.on['seeking']();
484
- expect(onSeek).toHaveBeenCalled();
485
-
486
- onSeek.calls.reset();
487
-
488
- // Seek before start, start is buffered.
489
- setMockDate(100);
490
- video.currentTime = 1;
491
- video.on['seeking']();
492
- expect(video.currentTime).toBe(10);
493
- expect(playhead.getTime()).toBe(10);
494
- expect(onSeek).not.toHaveBeenCalled();
495
- setMockDate(110);
496
- video.on['seeking']();
497
- expect(onSeek).toHaveBeenCalled();
498
-
499
- onSeek.calls.reset();
500
-
501
- // Seek with safe == end
502
- timeline.getSeekRangeEnd.and.returnValue(12);
503
- timeline.getSafeSeekRangeStart.and.returnValue(12);
504
-
505
- // Seek before start
506
- setMockDate(120);
507
- video.currentTime = 4;
508
- video.on['seeking']();
509
- expect(video.currentTime).toBe(12);
510
- expect(playhead.getTime()).toBe(12);
511
- expect(onSeek).not.toHaveBeenCalled();
512
- setMockDate(130);
513
- video.on['seeking']();
514
- expect(onSeek).toHaveBeenCalled();
515
-
516
- onSeek.calls.reset();
517
-
518
- // Seek in window.
519
- setMockDate(140);
520
- video.currentTime = 8;
521
- video.on['seeking']();
522
- expect(video.currentTime).toBe(12);
523
- expect(playhead.getTime()).toBe(12);
524
- expect(onSeek).not.toHaveBeenCalled();
525
- setMockDate(150);
526
- video.on['seeking']();
527
- expect(onSeek).toHaveBeenCalled();
528
-
529
- onSeek.calls.reset();
530
-
531
- // Seek past end.
532
- setMockDate(160);
533
- video.currentTime = 13;
534
- video.on['seeking']();
535
- expect(video.currentTime).toBe(12);
536
- expect(playhead.getTime()).toBe(12);
537
- expect(onSeek).not.toHaveBeenCalled();
538
- setMockDate(170);
539
- video.on['seeking']();
540
- expect(onSeek).toHaveBeenCalled();
541
- }); // clamps playhead after seeking for live
542
-
543
- it('clamps playhead after seeking for VOD', () => {
544
- video.readyState = HTMLMediaElement.HAVE_METADATA;
545
-
546
- video.buffered = createFakeBuffered([{start: 25, end: 55}]);
547
-
548
- timeline.isLive.and.returnValue(false);
549
- timeline.getSeekRangeStart.and.returnValue(5);
550
- timeline.getSafeSeekRangeStart.and.returnValue(5);
551
- timeline.getSeekRangeEnd.and.returnValue(60);
552
- timeline.getDuration.and.returnValue(60);
553
-
554
- playhead = new shaka.media.MediaSourcePlayhead(
555
- video,
556
- manifest,
557
- config,
558
- /* startTime= */ 5,
559
- Util.spyFunc(onSeek),
560
- Util.spyFunc(onEvent));
561
-
562
- setMockDate(0);
563
- video.on['seeking']();
564
- expect(video.currentTime).toBe(5);
565
- expect(playhead.getTime()).toBe(5);
566
-
567
- // Seek past end.
568
- setMockDate(10);
569
- video.currentTime = 120;
570
- video.on['seeking']();
571
- expect(video.currentTime).toBe(59); // duration - durationBackoff
572
- expect(playhead.getTime()).toBe(59); // duration - durationBackoff
573
- expect(onSeek).not.toHaveBeenCalled();
574
- setMockDate(20);
575
- video.on['seeking']();
576
- expect(onSeek).toHaveBeenCalled();
577
-
578
- onSeek.calls.reset();
579
-
580
- // Seek before start.
581
- setMockDate(30);
582
- video.currentTime = 1;
583
- video.on['seeking']();
584
- expect(video.currentTime).toBe(5);
585
- expect(playhead.getTime()).toBe(5);
586
- expect(onSeek).not.toHaveBeenCalled();
587
- setMockDate(40);
588
- video.on['seeking']();
589
- expect(onSeek).toHaveBeenCalled();
590
- }); // clamps playhead after seeking for VOD
591
-
592
- it('doesn\'t repeatedly re-seek', () => {
593
- video.readyState = HTMLMediaElement.HAVE_METADATA;
594
-
595
- video.buffered = createFakeBuffered([{start: 25, end: 55}]);
596
-
597
- timeline.isLive.and.returnValue(false);
598
- timeline.getSeekRangeStart.and.returnValue(5);
599
- timeline.getSafeSeekRangeStart.and.returnValue(5);
600
- timeline.getSeekRangeEnd.and.returnValue(60);
601
- timeline.getDuration.and.returnValue(60);
602
-
603
- playhead = new shaka.media.MediaSourcePlayhead(
604
- video,
605
- manifest,
606
- config,
607
- /* startTime= */ 5,
608
- Util.spyFunc(onSeek),
609
- Util.spyFunc(onEvent));
610
-
611
- // First, seek to start time.
612
- video.currentTime = 0;
613
- video.on['seeking']();
614
-
615
- // The first time, it should re-seek without issue.
616
- setMockDate(0);
617
- video.currentTime = 0;
618
- video.on['seeking']();
619
- expect(video.currentTime).toBe(5);
620
- expect(playhead.getTime()).toBe(5);
621
- expect(onSeek).not.toHaveBeenCalled();
622
-
623
- onSeek.calls.reset();
624
-
625
- // No time passes, so it shouldn't be willing to re-seek.
626
- video.currentTime = 0;
627
- video.on['seeking']();
628
- expect(video.currentTime).toBe(0);
629
- // The playhead wanted to seek ahead to 5, but was unable to.
630
- expect(playhead.getTime()).toBe(5);
631
- expect(onSeek).toHaveBeenCalled();
632
-
633
- onSeek.calls.reset();
634
-
635
- // Wait 10 seconds, so it should be willing to re-seek.
636
- setMockDate(10);
637
- video.currentTime = 0;
638
- video.on['seeking']();
639
- expect(video.currentTime).toBe(5);
640
- expect(playhead.getTime()).toBe(5);
641
- expect(onSeek).not.toHaveBeenCalled();
642
- }); // doesn't repeatedly re-seek
643
-
644
- it('handles live manifests with no seek range', () => {
645
- video.buffered = createFakeBuffered([{start: 1000, end: 1030}]);
646
- video.readyState = HTMLMediaElement.HAVE_METADATA;
647
-
648
- timeline.isLive.and.returnValue(true);
649
- timeline.getDuration.and.returnValue(Infinity);
650
- timeline.getSeekRangeStart.and.returnValue(1000);
651
- timeline.getSeekRangeEnd.and.returnValue(1000);
652
-
653
- let currentTime = 0;
654
- let seekCount = 0;
655
- Object.defineProperty(video, 'currentTime', {
656
- get: () => currentTime,
657
- set: (val) => {
658
- currentTime = val;
659
- seekCount++;
660
- setTimeout(video.on['seeking'], 5);
661
- },
662
- });
663
-
664
- playhead = new shaka.media.MediaSourcePlayhead(
665
- video,
666
- manifest,
667
- config,
668
- /* startTime= */ 5,
669
- Util.spyFunc(onSeek),
670
- Util.spyFunc(onEvent));
671
- expect(currentTime).toBe(1000);
672
- seekCount = 0;
673
-
674
- playhead.ready();
675
-
676
- // The availability window slips ahead.
677
- timeline.getSeekRangeStart.and.returnValue(1030);
678
- timeline.getSeekRangeEnd.and.returnValue(1030);
679
- video.on['waiting']();
680
- jasmine.clock().tick(500);
681
- expect(currentTime).toBe(1030);
682
- expect(seekCount).toBe(1);
683
-
684
- // It should allow a small buffer around the seek range.
685
- seekCount = 0;
686
- currentTime = 1030.062441;
687
- jasmine.clock().tick(500);
688
- currentTime = 1027.9233;
689
- jasmine.clock().tick(500);
690
- expect(seekCount).toBe(0);
691
-
692
- // Got too far away.
693
- currentTime = 1026;
694
- jasmine.clock().tick(500);
695
- expect(currentTime).toBe(1030);
696
- expect(seekCount).toBe(1);
697
- }); // handles live manifests with no seek range
698
-
699
- describe('clamps playhead after resuming', () => {
700
- beforeEach(() => {
701
- video.readyState = HTMLMediaElement.HAVE_METADATA;
702
-
703
- video.buffered = createFakeBuffered([{start: 5, end: 35}]);
704
- });
705
-
706
- it('(live case)', () => {
707
- timeline.isLive.and.returnValue(true);
708
- timeline.getDuration.and.returnValue(Infinity);
709
- timeline.getSeekRangeStart.and.returnValue(5);
710
- timeline.getSeekRangeEnd.and.returnValue(60);
711
-
712
- playhead = new shaka.media.MediaSourcePlayhead(
713
- video,
714
- manifest,
715
- config,
716
- /* startTime= */ 5,
717
- Util.spyFunc(onSeek),
718
- Util.spyFunc(onEvent));
719
-
720
- playhead.ready();
721
-
722
- video.on['seeking']();
723
- expect(video.currentTime).toBe(5);
724
- expect(playhead.getTime()).toBe(5);
725
-
726
- // Simulate pausing.
727
- timeline.getSeekRangeStart.and.returnValue(10);
728
- timeline.getSeekRangeEnd.and.returnValue(70);
729
-
730
- // Because this is buffered, the playhead should move to (start + 5),
731
- // which will cause a 'seeking' event.
732
- jasmine.clock().tick(500);
733
- expect(video.currentTime).toBe(15);
734
- video.on['seeking']();
735
- expect(playhead.getTime()).toBe(15);
736
- expect(onSeek).toHaveBeenCalled();
737
- });
738
-
739
- it('(VOD case)', () => {
740
- timeline.isLive.and.returnValue(false);
741
- timeline.getSeekRangeStart.and.returnValue(5);
742
- timeline.getSafeSeekRangeStart.and.returnValue(5);
743
- timeline.getSeekRangeEnd.and.returnValue(60);
744
- timeline.getDuration.and.returnValue(60);
745
-
746
- playhead = new shaka.media.MediaSourcePlayhead(
747
- video,
748
- manifest,
749
- config,
750
- /* startTime= */ 5,
751
- Util.spyFunc(onSeek),
752
- Util.spyFunc(onEvent));
753
-
754
- playhead.ready();
755
-
756
- video.on['seeking']();
757
- expect(video.currentTime).toBe(5);
758
- expect(playhead.getTime()).toBe(5);
759
-
760
- // Simulate pausing.
761
- timeline.getSeekRangeStart.and.returnValue(10);
762
- timeline.getSafeSeekRangeStart.and.returnValue(10);
763
- timeline.getSeekRangeEnd.and.returnValue(70);
764
-
765
- jasmine.clock().tick(500);
766
- expect(video.currentTime).toBe(10);
767
- video.on['seeking']();
768
- expect(playhead.getTime()).toBe(10);
769
- expect(onSeek).toHaveBeenCalled();
770
- });
771
- }); // clamps playhead after resuming
772
-
773
- it('clamps playhead even before seeking completes', () => {
774
- video.readyState = HTMLMediaElement.HAVE_METADATA;
775
-
776
- video.buffered = createFakeBuffered([{start: 25, end: 55}]);
777
-
778
- timeline.isLive.and.returnValue(true);
779
- timeline.getDuration.and.returnValue(Infinity);
780
- timeline.getSeekRangeStart.and.returnValue(5);
781
- timeline.getSeekRangeEnd.and.returnValue(60);
782
-
783
- playhead = new shaka.media.MediaSourcePlayhead(
784
- video,
785
- manifest,
786
- config,
787
- /* startTime= */ 30,
788
- Util.spyFunc(onSeek),
789
- Util.spyFunc(onEvent));
790
-
791
- video.currentTime = 0;
792
- video.seeking = true;
793
-
794
- playhead.ready();
795
-
796
- // "video.seeking" stays true until the buffered range intersects with
797
- // "video.currentTime". Playhead should correct anyway.
798
- video.on['seeking']();
799
-
800
- // Let the Playhead poll the seek range and push us back inside it.
801
- jasmine.clock().tick(1000);
802
-
803
- // There is some "safety zone" at the front of the range, so we may seek to
804
- // anything >= the seek range start (5).
805
- expect(video.currentTime).not.toBeLessThan(5);
806
- expect(playhead.getTime()).not.toBeLessThan(5);
807
- }); // clamps playhead even before seeking completes
808
-
809
- // Regression test for:
810
- // - https://github.com/shaka-project/shaka-player/pull/2849
811
- // - https://github.com/shaka-project/shaka-player/issues/2748
812
- // - https://github.com/shaka-project/shaka-player/issues/2848
813
- it('does not apply seek range before initial seek has completed', () => {
814
- // These attributes allow the seek range callback to do its thing.
815
- video.readyState = HTMLMediaElement.HAVE_METADATA;
816
- video.paused = false;
817
-
818
- // Simulate a smart TV in which seeking is not immediately reflected.
819
- // In these scenarios, currentTime remains 0 long enough for the seek range
820
- // polling to kick in.
821
- const currentTimeSetterSpy = jasmine.createSpy('currentTimeSetter');
822
- Object.defineProperty(video, 'currentTime', {
823
- get: () => 0,
824
- set: Util.spyFunc(currentTimeSetterSpy),
825
- });
826
-
827
- timeline.isLive.and.returnValue(true);
828
- timeline.getDuration.and.returnValue(Infinity);
829
- timeline.getSeekRangeStart.and.returnValue(5);
830
- timeline.getSeekRangeEnd.and.returnValue(60);
831
-
832
- playhead = new shaka.media.MediaSourcePlayhead(
833
- video,
834
- manifest,
835
- config,
836
- /* startTime= */ 30,
837
- Util.spyFunc(onSeek),
838
- Util.spyFunc(onEvent));
839
-
840
- playhead.ready();
841
-
842
- /**
843
- * Prevent retries on the initial start time seek. This will ensure that
844
- * only one call is made for the initial seek, and that any additional calls
845
- * can be rightly attributed to the application of the seek range.
846
- * @suppress {accessControls}
847
- */
848
- function stopRetries() {
849
- const mediaSourcePlayhead =
850
- /** @type {shaka.media.MediaSourcePlayhead} */(playhead);
851
- mediaSourcePlayhead.videoWrapper_.mover_.timer_.stop();
852
- mediaSourcePlayhead.videoWrapper_.mover_.maxAttempts_ = 1;
853
- mediaSourcePlayhead.videoWrapper_.mover_.remainingAttempts_ = 1;
854
- }
855
- stopRetries();
856
-
857
- // Let the Playhead poll the seek range. It should NOT push us back inside
858
- // it, since the start time should be used instead of the current time.
859
- jasmine.clock().tick(1000);
860
- // The one and only call was for the initial seek to the start time.
861
- expect(currentTimeSetterSpy).toHaveBeenCalledTimes(1);
862
- }); // does not apply seek range before initial seek has completed
863
-
864
- describe('gap jumping', () => {
865
- beforeEach(() => {
866
- timeline.isLive.and.returnValue(false);
867
- timeline.getSafeSeekRangeStart.and.returnValue(0);
868
- timeline.getSeekRangeStart.and.returnValue(0);
869
- timeline.getSeekRangeEnd.and.returnValue(60);
870
- timeline.getDuration.and.returnValue(60);
871
- });
872
-
873
- describe('when playing', () => {
874
- describe('with small gaps', () => {
875
- playingTest('won\'t jump at end of single region', {
876
- buffered: [{start: 0, end: 10}],
877
- start: 3,
878
- waitingAt: 10,
879
- expectEvent: false,
880
- expectedEndTime: 10,
881
- });
882
-
883
- playingTest('won\'t jump at end of multiple regions', {
884
- buffered: [{start: 0, end: 10}, {start: 20, end: 30}],
885
- start: 24,
886
- waitingAt: 30,
887
- expectEvent: false,
888
- expectedEndTime: 30,
889
- });
890
-
891
- playingTest('will jump small gap', {
892
- buffered: [{start: 0, end: 10}, {start: 11, end: 20}],
893
- start: 5,
894
- waitingAt: 10,
895
- expectEvent: true,
896
- expectedEndTime: 11,
897
- });
898
-
899
- playingTest('won\'t skip a buffered range', {
900
- buffered:
901
- [{start: 0, end: 10}, {start: 11, end: 20}, {start: 21, end: 30}],
902
- start: 5,
903
- waitingAt: 10,
904
- expectEvent: true,
905
- expectedEndTime: 11,
906
- });
907
-
908
- playingTest('will jump gap into last buffer', {
909
- buffered:
910
- [{start: 0, end: 10}, {start: 11, end: 20}, {start: 21, end: 30}],
911
- start: 15,
912
- waitingAt: 20,
913
- expectEvent: true,
914
- expectedEndTime: 21,
915
- });
916
- }); // with small gaps
917
-
918
- describe('with large gaps', () => {
919
- playingTest('will jump large gaps if set', {
920
- buffered: [{start: 0, end: 10}, {start: 30, end: 40}],
921
- start: 5,
922
- waitingAt: 10,
923
- expectEvent: true,
924
- expectedEndTime: 30,
925
- });
926
-
927
- playingTest('will only jump one buffer', {
928
- buffered:
929
- [{start: 0, end: 10}, {start: 30, end: 40}, {start: 50, end: 60}],
930
- start: 5,
931
- waitingAt: 10,
932
- expectEvent: true,
933
- expectedEndTime: 30,
934
- });
935
-
936
- playingTest('will jump into last buffer', {
937
- buffered:
938
- [{start: 0, end: 10}, {start: 20, end: 30}, {start: 50, end: 60}],
939
- start: 24,
940
- waitingAt: 30,
941
- expectEvent: true,
942
- expectedEndTime: 50,
943
- });
944
- }); // with large gaps
945
-
946
- /**
947
- * @param {string} name
948
- * @param {PlayingTestInfo} data
949
- */
950
- function playingTest(name, data) {
951
- it(name, () => {
952
- video.buffered = createFakeBuffered(data.buffered);
953
- video.currentTime = data.start;
954
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
955
-
956
- onEvent.and.callFake((event) => {});
957
-
958
- playhead = new shaka.media.MediaSourcePlayhead(
959
- video,
960
- manifest,
961
- config,
962
- /* startTime= */ data.start,
963
- Util.spyFunc(onSeek),
964
- Util.spyFunc(onEvent));
965
-
966
- playhead.ready();
967
-
968
- jasmine.clock().tick(500);
969
- for (let time = data.start; time < data.waitingAt; time++) {
970
- // We don't want to run tick() for 1 second because it will trigger
971
- // the stall-detection, which will move the playhead; on the other
972
- // hand, we don't want to be 0.5 seconds from the gap because on
973
- // Edge/Tizen, gap jumping will treat that as in the gap.
974
- // See shaka.media.TimeRangesUtils.getGapIndex.
975
-
976
- video.currentTime = time;
977
- jasmine.clock().tick(400);
978
- // Make sure Playhead didn't adjust the time yet.
979
- expect(video.currentTime).toBe(time);
980
-
981
- video.currentTime = time + 0.4;
982
- jasmine.clock().tick(600);
983
- // Make sure Playhead didn't adjust the time yet.
984
- expect(video.currentTime).toBe(time + 0.4);
985
- }
986
-
987
- expect(onEvent).not.toHaveBeenCalled();
988
-
989
- video.currentTime = data.waitingAt;
990
- video.readyState = HTMLMediaElement.HAVE_CURRENT_DATA;
991
- video.on['waiting']();
992
- jasmine.clock().tick(500);
993
-
994
- expect(onEvent).toHaveBeenCalledTimes(data.expectEvent ? 1 : 0);
995
- expect(video.currentTime).toBe(data.expectedEndTime);
996
- });
997
- }
998
- }); // when playing
999
-
1000
- describe('with buffered seeks', () => {
1001
- describe('with small gaps', () => {
1002
- seekTest('won\'t seek when past the end', {
1003
- buffered: [{start: 0, end: 10}],
1004
- start: 4,
1005
- seekTo: 14,
1006
- expectEvent: false,
1007
- expectedEndTime: 14,
1008
- });
1009
-
1010
- seekTest('will jump when seeking into gap', {
1011
- buffered: [{start: 0, end: 10}, {start: 11, end: 20}],
1012
- start: 3,
1013
- seekTo: 10.4,
1014
- expectEvent: true,
1015
- expectedEndTime: 11,
1016
- });
1017
-
1018
- seekTest('won\'t jump multiple buffers', {
1019
- buffered:
1020
- [{start: 0, end: 10}, {start: 11, end: 20}, {start: 21, end: 30}],
1021
- start: 3,
1022
- seekTo: 10.4,
1023
- expectEvent: true,
1024
- expectedEndTime: 11,
1025
- });
1026
-
1027
- seekTest('will jump into last range with seeking', {
1028
- buffered:
1029
- [{start: 0, end: 10}, {start: 11, end: 20}, {start: 21, end: 30}],
1030
- start: 3,
1031
- seekTo: 20.5,
1032
- expectEvent: true,
1033
- expectedEndTime: 21,
1034
- });
1035
-
1036
- seekTest('treats large gaps as small if playhead near end', {
1037
- buffered: [{start: 0, end: 10}, {start: 30, end: 40}],
1038
- start: 3,
1039
- seekTo: 29.2,
1040
- expectEvent: true,
1041
- expectedEndTime: 30,
1042
- });
1043
- }); // with small gaps
1044
-
1045
- describe('with large gaps', () => {
1046
- seekTest('will jump large gaps', {
1047
- buffered: [{start: 0, end: 10}, {start: 30, end: 40}],
1048
- start: 5,
1049
- seekTo: 12,
1050
- expectEvent: true,
1051
- expectedEndTime: 30,
1052
- });
1053
- }); // with large gaps
1054
- }); // with buffered seeks
1055
-
1056
- describe('with unbuffered seeks', () => {
1057
- describe('with small gaps', () => {
1058
- seekTest('won\'t jump when seeking into buffered range', {
1059
- // [0-10], [20-30], [31-40]
1060
- buffered: [{start: 0, end: 10}],
1061
- newBuffered: [{start: 20, end: 30}, {start: 31, end: 40}],
1062
- start: 3,
1063
- seekTo: 22,
1064
- expectEvent: false,
1065
- expectedEndTime: 22,
1066
- });
1067
-
1068
- // Seeking to the beginning is considered an unbuffered seek even if
1069
- // there is a gap.
1070
- seekTest('will jump a small gap at the beginning', {
1071
- buffered: [{start: 0.2, end: 10}],
1072
- newBuffered: [{start: 0.2, end: 10}],
1073
- start: 4,
1074
- seekTo: 0,
1075
- expectEvent: true,
1076
- expectedEndTime: 0.2,
1077
- });
1078
-
1079
- seekTest('will jump when seeking into gap', {
1080
- // [0-10], [20-30], [31-40]
1081
- buffered: [{start: 0, end: 10}],
1082
- newBuffered: [{start: 20, end: 30}, {start: 31, end: 40}],
1083
- start: 3,
1084
- seekTo: 30.2,
1085
- expectEvent: true,
1086
- expectedEndTime: 31,
1087
- });
1088
-
1089
- seekTest('will jump when seeking to the end of a range', {
1090
- // [0-10], [20-30], [31-40]
1091
- buffered: [{start: 0, end: 10}],
1092
- newBuffered: [{start: 20, end: 30}, {start: 31, end: 40}],
1093
- start: 3,
1094
- seekTo: 30,
1095
- expectEvent: true,
1096
- expectedEndTime: 31,
1097
- });
1098
-
1099
- seekTest('won\'t jump when past end', {
1100
- // [0-10], [20-30]
1101
- buffered: [{start: 0, end: 10}],
1102
- newBuffered: [{start: 20, end: 30}],
1103
- start: 3,
1104
- seekTo: 34,
1105
- expectEvent: false,
1106
- expectedEndTime: 34,
1107
- });
1108
-
1109
- seekTest('won\'t jump when seeking backwards into buffered range', {
1110
- // [0-10], [20-30]
1111
- buffered: [{start: 20, end: 30}],
1112
- newBuffered: [{start: 0, end: 10}],
1113
- start: 24,
1114
- seekTo: 4,
1115
- expectEvent: false,
1116
- expectedEndTime: 4,
1117
- });
1118
-
1119
- seekTest('will wait to jump when seeking backwards', {
1120
- // [20-30]
1121
- buffered: [{start: 20, end: 30}],
1122
- // The lack of newBuffered means we won't append any segments, so we
1123
- // should still be waiting.
1124
- start: 24,
1125
- seekTo: 4,
1126
- expectEvent: false,
1127
- expectedEndTime: 4,
1128
- });
1129
-
1130
- seekTest('will jump when seeking backwards into gap', {
1131
- // [2-10], [20-30]
1132
- buffered: [{start: 20, end: 30}],
1133
- newBuffered: [{start: 2, end: 10}],
1134
- start: 24,
1135
- seekTo: 1.6,
1136
- expectEvent: true,
1137
- expectedEndTime: 2,
1138
- });
1139
- }); // with small gaps
1140
-
1141
- describe('with large gaps', () => {
1142
- seekTest('will jump large gap at beginning', {
1143
- buffered: [{start: 20, end: 30}],
1144
- newBuffered: [{start: 20, end: 30}],
1145
- start: 25,
1146
- seekTo: 0,
1147
- expectEvent: true,
1148
- expectedEndTime: 20,
1149
- });
1150
-
1151
- seekTest('will jump large gaps', {
1152
- // [0-10], [20-30], [40-50]
1153
- buffered: [{start: 0, end: 10}],
1154
- newBuffered: [{start: 20, end: 30}, {start: 40, end: 50}],
1155
- start: 3,
1156
- seekTo: 32,
1157
- expectEvent: true,
1158
- expectedEndTime: 40,
1159
- });
1160
- }); // with large gaps
1161
- }); // with unbuffered seeks
1162
-
1163
- it('doesn\'t gap jump if the seeking event is late', () => {
1164
- const buffered = [{start: 10, end: 20}];
1165
- video.buffered = createFakeBuffered(buffered);
1166
- video.currentTime = 12;
1167
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
1168
-
1169
- playhead = new shaka.media.MediaSourcePlayhead(
1170
- video,
1171
- manifest,
1172
- config,
1173
- /* startTime= */ 12,
1174
- Util.spyFunc(onSeek),
1175
- Util.spyFunc(onEvent));
1176
-
1177
- playhead.ready();
1178
-
1179
- jasmine.clock().tick(500);
1180
- expect(onEvent).not.toHaveBeenCalled();
1181
-
1182
- // Append a segment before seeking.
1183
- playhead.notifyOfBufferingChange();
1184
-
1185
- // Seek backwards but wait briefly to fire the seeking event.
1186
- video.currentTime = 3;
1187
- video.readyState = HTMLMediaElement.HAVE_METADATA;
1188
- video.seeking = true;
1189
- jasmine.clock().tick(500);
1190
- video.on['seeking']();
1191
-
1192
- // There should NOT have been a gap jump.
1193
- expect(video.currentTime).toBe(3);
1194
- });
1195
-
1196
- it('works with rounding errors when seeking', () => {
1197
- // If the browser sets the time to slightly before where we seek to, we
1198
- // shouldn't get stuck in an infinite loop trying to jump the tiny gap.
1199
- // https://github.com/shaka-project/shaka-player/issues/1309
1200
- const buffered = [{start: 10, end: 20}];
1201
- video.buffered = createFakeBuffered(buffered);
1202
- video.readyState = HTMLMediaElement.HAVE_METADATA;
1203
-
1204
- // Track the number of times we seeked.
1205
- let seekCount = 0;
1206
- let currentTime = 0;
1207
- Object.defineProperty(video, 'currentTime', {
1208
- get: () => currentTime - 0.00001,
1209
- set: (time) => {
1210
- seekCount++;
1211
- currentTime = time;
1212
- setTimeout(() => {
1213
- video.on['seeking']();
1214
- playhead.notifyOfBufferingChange();
1215
- }, 5);
1216
- },
1217
- });
1218
-
1219
- playhead = new shaka.media.MediaSourcePlayhead(
1220
- video,
1221
- manifest,
1222
- config,
1223
- /* startTime= */ 0,
1224
- Util.spyFunc(onSeek),
1225
- Util.spyFunc(onEvent));
1226
-
1227
- playhead.ready();
1228
-
1229
- playhead.notifyOfBufferingChange();
1230
- jasmine.clock().tick(500);
1231
-
1232
- expect(seekCount).toBe(1);
1233
- expect(currentTime).toBe(10);
1234
- });
1235
-
1236
- it('doesn\'t gap jump if paused', () => {
1237
- const buffered = [{start: 10, end: 20}];
1238
- video.buffered = createFakeBuffered(buffered);
1239
- video.currentTime = 5;
1240
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
1241
- video.paused = true;
1242
-
1243
- playhead = new shaka.media.MediaSourcePlayhead(
1244
- video,
1245
- manifest,
1246
- config,
1247
- /* startTime= */ 5,
1248
- Util.spyFunc(onSeek),
1249
- Util.spyFunc(onEvent));
1250
-
1251
- playhead.ready();
1252
-
1253
- playhead.notifyOfBufferingChange();
1254
- jasmine.clock().tick(500);
1255
-
1256
- // There should NOT have been a gap jump.
1257
- expect(video.currentTime).toBe(5);
1258
- });
1259
-
1260
- // Regression test for https://github.com/shaka-project/shaka-player/issues/2987
1261
- it('does gap jump if paused at 0 and has autoplay', () => {
1262
- const buffered = [{start: 10, end: 20}];
1263
- video.buffered = createFakeBuffered(buffered);
1264
- video.currentTime = 0;
1265
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
1266
- video.paused = true;
1267
- video.autoplay = true;
1268
-
1269
- playhead = new shaka.media.MediaSourcePlayhead(
1270
- video,
1271
- manifest,
1272
- config,
1273
- /* startTime= */ 0,
1274
- Util.spyFunc(onSeek),
1275
- Util.spyFunc(onEvent));
1276
-
1277
- playhead.ready();
1278
-
1279
- playhead.notifyOfBufferingChange();
1280
- jasmine.clock().tick(500);
1281
-
1282
- // There SHOULD have been a gap jump.
1283
- expect(video.currentTime).toBe(10);
1284
- });
1285
-
1286
- // Regression test for https://github.com/shaka-project/shaka-player/issues/3451
1287
- it('doesn\'t gap jump if paused at 0 and hasn\'t autoplay', () => {
1288
- const buffered = [{start: 10, end: 20}];
1289
- video.buffered = createFakeBuffered(buffered);
1290
- video.currentTime = 0;
1291
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
1292
- video.paused = true;
1293
- video.autoplay = false;
1294
-
1295
- playhead = new shaka.media.MediaSourcePlayhead(
1296
- video,
1297
- manifest,
1298
- config,
1299
- /* startTime= */ 0,
1300
- Util.spyFunc(onSeek),
1301
- Util.spyFunc(onEvent));
1302
-
1303
- playhead.ready();
1304
-
1305
- playhead.notifyOfBufferingChange();
1306
- jasmine.clock().tick(500);
1307
-
1308
- // There should NOT have been a gap jump.
1309
- expect(video.currentTime).toBe(0);
1310
- });
1311
-
1312
- /**
1313
- * @param {string} name
1314
- * @param {SeekTestInfo} data
1315
- */
1316
- function seekTest(name, data) {
1317
- it(name, () => {
1318
- video.buffered = createFakeBuffered(data.buffered);
1319
- video.currentTime = data.start;
1320
- video.readyState = HTMLMediaElement.HAVE_ENOUGH_DATA;
1321
-
1322
- onEvent.and.callFake((event) => {});
1323
-
1324
- playhead = new shaka.media.MediaSourcePlayhead(
1325
- video,
1326
- manifest,
1327
- config,
1328
- /* startTime= */ data.start,
1329
- Util.spyFunc(onSeek),
1330
- Util.spyFunc(onEvent));
1331
-
1332
- playhead.ready();
1333
-
1334
- jasmine.clock().tick(500);
1335
- expect(onEvent).not.toHaveBeenCalled();
1336
-
1337
- // Seek to the given position and update ready state.
1338
- video.currentTime = data.seekTo;
1339
- video.readyState = calculateReadyState(data.buffered, data.seekTo);
1340
- video.seeking = true;
1341
- video.on['seeking']();
1342
- if (video.readyState < HTMLMediaElement.HAVE_ENOUGH_DATA) {
1343
- video.on['waiting']();
1344
- } else {
1345
- video.seeking = false;
1346
- }
1347
- jasmine.clock().tick(500);
1348
-
1349
- if (data.newBuffered) {
1350
- // If we have a new buffer, first clear the buffer.
1351
- video.buffered = createFakeBuffered([]);
1352
- video.readyState = HTMLMediaElement.HAVE_METADATA;
1353
- jasmine.clock().tick(250);
1354
-
1355
- // Now StreamingEngine will buffer the new content and tell playhead
1356
- // about it.
1357
- expect(video.currentTime).toBe(data.seekTo);
1358
- video.buffered = createFakeBuffered(data.newBuffered);
1359
- video.readyState = calculateReadyState(data.newBuffered, data.seekTo);
1360
- if (video.readyState >= HTMLMediaElement.HAVE_ENOUGH_DATA) {
1361
- video.seeking = false;
1362
- }
1363
- playhead.notifyOfBufferingChange();
1364
- jasmine.clock().tick(250);
1365
- }
1366
-
1367
- expect(onEvent).toHaveBeenCalledTimes(data.expectEvent ? 1 : 0);
1368
- expect(video.currentTime).toBe(data.expectedEndTime);
1369
- });
1370
- }
1371
-
1372
- /**
1373
- * @param {!Array.<{start: number, end: number}>} buffers
1374
- * @param {number} time
1375
- * @return {number}
1376
- */
1377
- function calculateReadyState(buffers, time) {
1378
- // See: https://bit.ly/2JYh8WX
1379
- for (const buffer of buffers) {
1380
- if (time >= buffer.start) {
1381
- if (time == buffer.end) {
1382
- // The video has the current frame, but no data in the future.
1383
- return HTMLMediaElement.HAVE_CURRENT_DATA;
1384
- } else if (time < buffer.end) {
1385
- // The video has enough data to play forward.
1386
- return HTMLMediaElement.HAVE_ENOUGH_DATA;
1387
- }
1388
- }
1389
- }
1390
- // The video doesn't have any video data.
1391
- return HTMLMediaElement.HAVE_METADATA;
1392
- }
1393
- }); // gap jumping
1394
- });