rx-player 4.0.0-beta.0 → 4.0.0-beta.2

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 (297) hide show
  1. package/.eslintrc.js +8 -0
  2. package/CHANGELOG.md +93 -0
  3. package/CONTRIBUTING.md +48 -168
  4. package/FILES.md +40 -92
  5. package/VERSION +1 -1
  6. package/dist/_esm5.processed/compat/browser_detection.d.ts +25 -12
  7. package/dist/_esm5.processed/compat/browser_detection.js +85 -38
  8. package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
  9. package/dist/_esm5.processed/compat/eme/close_session.js +2 -2
  10. package/dist/_esm5.processed/compat/eme/load_session.js +1 -1
  11. package/dist/_esm5.processed/compat/event_listeners.js +1 -1
  12. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
  13. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
  14. package/dist/_esm5.processed/config.d.ts +4 -0
  15. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +9 -6
  16. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
  17. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +106 -25
  18. package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
  19. package/dist/_esm5.processed/core/adaptive/network_analyzer.js +8 -5
  20. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
  21. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
  22. package/dist/_esm5.processed/core/api/debug/buffer_graph.d.ts +28 -0
  23. package/dist/_esm5.processed/core/api/debug/buffer_graph.js +175 -0
  24. package/dist/_esm5.processed/core/api/debug/buffer_size_graph.d.ts +10 -0
  25. package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +104 -0
  26. package/dist/_esm5.processed/core/api/debug/constants.d.ts +2 -0
  27. package/dist/_esm5.processed/core/api/debug/constants.js +2 -0
  28. package/dist/_esm5.processed/core/api/debug/index.d.ts +2 -0
  29. package/dist/_esm5.processed/core/api/debug/index.js +2 -0
  30. package/dist/_esm5.processed/core/api/debug/modules/general_info.d.ts +3 -0
  31. package/dist/_esm5.processed/core/api/debug/modules/general_info.js +180 -0
  32. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.d.ts +4 -0
  33. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +121 -0
  34. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.d.ts +3 -0
  35. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +35 -0
  36. package/dist/_esm5.processed/core/api/debug/render.d.ts +3 -0
  37. package/dist/_esm5.processed/core/api/debug/render.js +32 -0
  38. package/dist/_esm5.processed/core/api/debug/utils.d.ts +39 -0
  39. package/dist/_esm5.processed/core/api/debug/utils.js +57 -0
  40. package/dist/_esm5.processed/core/api/playback_observer.js +4 -2
  41. package/dist/_esm5.processed/core/api/public_api.d.ts +60 -3
  42. package/dist/_esm5.processed/core/api/public_api.js +280 -60
  43. package/dist/_esm5.processed/core/api/track_management/media_element_tracks_store.js +10 -1
  44. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.d.ts +13 -1
  45. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.js +30 -15
  46. package/dist/_esm5.processed/core/api/track_management/tracks_store.d.ts +3 -1
  47. package/dist/_esm5.processed/core/api/track_management/tracks_store.js +67 -152
  48. package/dist/_esm5.processed/core/api/utils.d.ts +10 -0
  49. package/dist/_esm5.processed/core/api/utils.js +23 -3
  50. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +27 -8
  51. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
  52. package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +1 -1
  53. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +1 -1
  54. package/dist/_esm5.processed/core/decrypt/find_key_system.js +29 -6
  55. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +42 -32
  56. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +4 -0
  57. package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +2 -0
  58. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +5 -1
  59. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +17 -8
  60. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +10 -6
  61. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +5 -4
  62. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +22 -5
  63. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +37 -21
  64. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +21 -23
  65. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +17 -7
  66. package/dist/_esm5.processed/core/init/directfile_content_initializer.js +2 -2
  67. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +74 -41
  68. package/dist/_esm5.processed/core/init/types.d.ts +9 -1
  69. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.d.ts +28 -1
  70. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +24 -11
  71. package/dist/_esm5.processed/core/init/utils/create_media_source.js +3 -12
  72. package/dist/_esm5.processed/core/init/utils/end_of_stream.js +6 -3
  73. package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +2 -1
  74. package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +9 -5
  75. package/dist/_esm5.processed/core/init/utils/initialize_content_decryption.js +2 -1
  76. package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +58 -0
  77. package/dist/_esm5.processed/core/init/utils/{media_duration_updater.js → media_source_duration_updater.js} +87 -86
  78. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.d.ts +36 -2
  79. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +83 -3
  80. package/dist/_esm5.processed/core/init/utils/stream_events_emitter/stream_events_emitter.js +6 -4
  81. package/dist/_esm5.processed/core/init/utils/throw_on_media_error.js +1 -1
  82. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -7
  83. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +38 -50
  84. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +8 -0
  85. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +16 -2
  86. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +8 -0
  87. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +12 -0
  88. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +11 -4
  89. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  90. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +13 -9
  91. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +30 -16
  92. package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.d.ts +47 -0
  93. package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +70 -0
  94. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +41 -20
  95. package/dist/_esm5.processed/core/stream/period/period_stream.js +12 -11
  96. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +37 -28
  97. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
  98. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +3 -3
  99. package/dist/_esm5.processed/core/stream/representation/utils/downloading_queue.js +16 -6
  100. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.d.ts +3 -2
  101. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +8 -8
  102. package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.d.ts +2 -2
  103. package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.js +2 -3
  104. package/dist/_esm5.processed/core/stream/utils/create_reload_request.js +1 -1
  105. package/dist/_esm5.processed/default_config.d.ts +41 -0
  106. package/dist/_esm5.processed/default_config.js +46 -2
  107. package/dist/_esm5.processed/errors/index.d.ts +2 -2
  108. package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
  109. package/dist/_esm5.processed/errors/media_error.js +18 -5
  110. package/dist/_esm5.processed/experimental/features/debug_element.d.ts +8 -0
  111. package/dist/_esm5.processed/experimental/features/debug_element.js +10 -0
  112. package/dist/_esm5.processed/experimental/features/index.d.ts +1 -0
  113. package/dist/_esm5.processed/experimental/features/index.js +1 -0
  114. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.d.ts +1 -1
  115. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.js +8 -7
  116. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +7 -4
  117. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +24 -12
  118. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/index.js +0 -2
  119. package/dist/_esm5.processed/features/features_object.js +1 -0
  120. package/dist/_esm5.processed/features/initialize_features.js +13 -10
  121. package/dist/_esm5.processed/features/types.d.ts +3 -0
  122. package/dist/_esm5.processed/manifest/adaptation.d.ts +21 -2
  123. package/dist/_esm5.processed/manifest/adaptation.js +80 -1
  124. package/dist/_esm5.processed/manifest/manifest.js +2 -0
  125. package/dist/_esm5.processed/manifest/period.js +2 -2
  126. package/dist/_esm5.processed/manifest/representation.d.ts +33 -2
  127. package/dist/_esm5.processed/manifest/representation.js +32 -4
  128. package/dist/_esm5.processed/manifest/utils.js +1 -3
  129. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +105 -137
  130. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +25 -5
  131. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
  132. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
  133. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
  134. package/dist/_esm5.processed/public_types.d.ts +13 -3
  135. package/dist/_esm5.processed/tools/TextTrackRenderer/text_track_renderer.js +1 -1
  136. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +15 -11
  137. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +2 -2
  138. package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
  139. package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -4
  140. package/dist/_esm5.processed/transports/local/segment_loader.js +13 -26
  141. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
  142. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
  143. package/dist/_esm5.processed/transports/smooth/segment_loader.js +4 -4
  144. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
  145. package/dist/_esm5.processed/utils/cancellable_sleep.js +4 -10
  146. package/dist/_esm5.processed/utils/create_cancellable_promise.d.ts +26 -0
  147. package/dist/_esm5.processed/utils/create_cancellable_promise.js +52 -0
  148. package/dist/_esm5.processed/utils/is_null_or_undefined.d.ts +1 -1
  149. package/dist/_esm5.processed/utils/is_null_or_undefined.js +1 -1
  150. package/dist/_esm5.processed/utils/reference.js +6 -0
  151. package/dist/_esm5.processed/utils/request/xhr.js +1 -1
  152. package/dist/_esm5.processed/utils/task_canceller.d.ts +34 -15
  153. package/dist/_esm5.processed/utils/task_canceller.js +55 -22
  154. package/dist/mpd-parser.wasm +0 -0
  155. package/dist/rx-player.js +5424 -4712
  156. package/dist/rx-player.min.js +1 -1
  157. package/jest.config.js +1 -5
  158. package/package.json +44 -40
  159. package/scripts/build/constants.d.ts +1 -0
  160. package/scripts/build/generate_build.js +1 -1
  161. package/scripts/fast_demo_build.js +40 -40
  162. package/scripts/generate_full_demo.js +1 -1
  163. package/sonar-project.properties +1 -1
  164. package/src/compat/browser_detection.ts +105 -52
  165. package/src/compat/can_reuse_media_keys.ts +5 -2
  166. package/src/compat/eme/close_session.ts +2 -2
  167. package/src/compat/eme/load_session.ts +1 -1
  168. package/src/compat/event_listeners.ts +1 -1
  169. package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
  170. package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
  171. package/src/core/adaptive/adaptive_representation_selector.ts +11 -6
  172. package/src/core/adaptive/buffer_based_chooser.ts +144 -26
  173. package/src/core/adaptive/guess_based_chooser.ts +9 -8
  174. package/src/core/adaptive/network_analyzer.ts +9 -4
  175. package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
  176. package/src/core/api/debug/buffer_graph.ts +247 -0
  177. package/src/core/api/debug/buffer_size_graph.ts +130 -0
  178. package/src/core/api/debug/constants.ts +2 -0
  179. package/src/core/api/debug/index.ts +3 -0
  180. package/src/core/api/debug/modules/general_info.ts +184 -0
  181. package/src/core/api/debug/modules/segment_buffer_content.ts +155 -0
  182. package/src/core/api/debug/modules/segment_buffer_size.ts +48 -0
  183. package/src/core/api/debug/render.ts +40 -0
  184. package/src/core/api/debug/utils.ts +103 -0
  185. package/src/core/api/playback_observer.ts +5 -2
  186. package/src/core/api/public_api.ts +334 -73
  187. package/src/core/api/track_management/media_element_tracks_store.ts +17 -8
  188. package/src/core/api/track_management/track_dispatcher.ts +37 -14
  189. package/src/core/api/track_management/tracks_store.ts +77 -167
  190. package/src/core/api/utils.ts +29 -3
  191. package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
  192. package/src/core/decrypt/attach_media_keys.ts +1 -1
  193. package/src/core/decrypt/content_decryptor.ts +1 -1
  194. package/src/core/decrypt/find_key_system.ts +25 -11
  195. package/src/core/decrypt/session_events_listener.ts +45 -39
  196. package/src/core/decrypt/utils/check_key_statuses.ts +6 -0
  197. package/src/core/decrypt/utils/clean_old_loaded_sessions.ts +2 -1
  198. package/src/core/decrypt/utils/loaded_sessions_store.ts +8 -1
  199. package/src/core/fetchers/cdn_prioritizer.ts +18 -9
  200. package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -4
  201. package/src/core/fetchers/segment/segment_fetcher.ts +36 -14
  202. package/src/core/fetchers/segment/task_prioritizer.ts +25 -30
  203. package/src/core/fetchers/utils/schedule_request.ts +18 -7
  204. package/src/core/init/directfile_content_initializer.ts +2 -1
  205. package/src/core/init/media_source_content_initializer.ts +89 -50
  206. package/src/core/init/types.ts +9 -1
  207. package/src/core/init/utils/content_time_boundaries_observer.ts +48 -12
  208. package/src/core/init/utils/create_media_source.ts +4 -16
  209. package/src/core/init/utils/end_of_stream.ts +6 -3
  210. package/src/core/init/utils/get_loaded_reference.ts +2 -1
  211. package/src/core/init/utils/initial_seek_and_play.ts +9 -5
  212. package/src/core/init/utils/initialize_content_decryption.ts +2 -1
  213. package/src/core/init/utils/{media_duration_updater.ts → media_source_duration_updater.ts} +103 -110
  214. package/src/core/init/utils/rebuffering_controller.ts +115 -4
  215. package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +6 -4
  216. package/src/core/init/utils/throw_on_media_error.ts +1 -1
  217. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +63 -66
  218. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +20 -2
  219. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +16 -0
  220. package/src/core/segment_buffers/implementations/types.ts +16 -4
  221. package/src/core/segment_buffers/index.ts +2 -0
  222. package/src/core/segment_buffers/segment_buffers_store.ts +16 -13
  223. package/src/core/stream/adaptation/adaptation_stream.ts +33 -19
  224. package/src/core/stream/adaptation/utils/create_representation_estimator.ts +114 -0
  225. package/src/core/stream/orchestrator/stream_orchestrator.ts +42 -20
  226. package/src/core/stream/period/period_stream.ts +13 -11
  227. package/src/core/stream/representation/representation_stream.ts +49 -37
  228. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +9 -4
  229. package/src/core/stream/representation/utils/downloading_queue.ts +16 -4
  230. package/src/core/stream/representation/utils/push_init_segment.ts +11 -6
  231. package/src/core/stream/representation/utils/push_media_segment.ts +3 -3
  232. package/src/core/stream/utils/create_reload_request.ts +1 -1
  233. package/src/default_config.ts +59 -11
  234. package/src/errors/__tests__/media_error.test.ts +6 -6
  235. package/src/errors/index.ts +4 -1
  236. package/src/errors/media_error.ts +67 -1
  237. package/src/experimental/features/__tests__/debug_element.test.ts +26 -0
  238. package/src/experimental/features/debug_element.ts +13 -0
  239. package/src/experimental/features/index.ts +1 -0
  240. package/src/experimental/tools/VideoThumbnailLoader/load_and_push_segment.ts +10 -7
  241. package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +7 -4
  242. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +25 -10
  243. package/src/experimental/tools/mediaCapabilitiesProber/index.ts +0 -4
  244. package/src/features/__tests__/initialize_features.test.ts +11 -0
  245. package/src/features/features_object.ts +1 -0
  246. package/src/features/initialize_features.ts +15 -10
  247. package/src/features/types.ts +9 -0
  248. package/src/manifest/__tests__/manifest.test.ts +7 -7
  249. package/src/manifest/__tests__/period.test.ts +90 -45
  250. package/src/manifest/adaptation.ts +96 -1
  251. package/src/manifest/manifest.ts +4 -0
  252. package/src/manifest/period.ts +4 -2
  253. package/src/manifest/representation.ts +77 -5
  254. package/src/manifest/utils.ts +1 -3
  255. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +116 -151
  256. package/src/parsers/manifest/dash/common/parse_representations.ts +21 -4
  257. package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
  258. package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
  259. package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
  260. package/src/public_types.ts +16 -1
  261. package/src/tools/TextTrackRenderer/text_track_renderer.ts +1 -1
  262. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +31 -22
  263. package/src/transports/dash/low_latency_segment_loader.ts +2 -2
  264. package/src/transports/dash/manifest_parser.ts +1 -1
  265. package/src/transports/dash/segment_loader.ts +4 -4
  266. package/src/transports/local/segment_loader.ts +14 -30
  267. package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
  268. package/src/transports/smooth/segment_loader.ts +4 -4
  269. package/src/transports/utils/call_custom_manifest_loader.ts +3 -3
  270. package/src/typings/globals.d.ts +21 -19
  271. package/src/utils/cancellable_sleep.ts +5 -14
  272. package/src/utils/create_cancellable_promise.ts +69 -0
  273. package/src/utils/is_null_or_undefined.ts +1 -1
  274. package/src/utils/reference.ts +6 -0
  275. package/src/utils/request/xhr.ts +1 -1
  276. package/src/utils/task_canceller.ts +63 -34
  277. package/tsconfig.json +1 -1
  278. package/tsconfig.modules.json +1 -1
  279. package/dist/_esm5.processed/core/init/utils/media_duration_updater.d.ts +0 -56
  280. package/locked_reps.js +0 -46
  281. package/scripts/doc-generator/construct_table_of_contents.js +0 -76
  282. package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
  283. package/scripts/doc-generator/create_documentation.js +0 -331
  284. package/scripts/doc-generator/create_documentation_page.js +0 -209
  285. package/scripts/doc-generator/create_page.js +0 -210
  286. package/scripts/doc-generator/generate_header_html.js +0 -147
  287. package/scripts/doc-generator/generate_page_html.js +0 -115
  288. package/scripts/doc-generator/generate_page_list_html.js +0 -92
  289. package/scripts/doc-generator/generate_sidebar_html.js +0 -85
  290. package/scripts/doc-generator/get_search_data_for_content.js +0 -137
  291. package/scripts/doc-generator/index.js +0 -34
  292. package/scripts/doc-generator/parse_doc_configs.js +0 -327
  293. package/scripts/doc-generator/scripts/lunr.js +0 -10
  294. package/scripts/doc-generator/scripts/script.js +0 -451
  295. package/scripts/doc-generator/styles/code.css +0 -99
  296. package/scripts/doc-generator/styles/style.css +0 -835
  297. package/scripts/doc-generator/utils.js +0 -74
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { IRepresentationMaintainabilityScore } from "./utils/representation_score_calculator";
16
17
  /**
17
18
  * Choose a bitrate based on the currently available buffer.
18
19
  *
@@ -24,11 +25,27 @@
24
25
  * "maintanable" or not.
25
26
  * If so, we may switch to a better quality, or conversely to a worse quality.
26
27
  *
28
+ * It also rely on mechanisms to avoid fluctuating too much between qualities.
29
+ *
27
30
  * @class BufferBasedChooser
28
31
  */
29
32
  export default class BufferBasedChooser {
30
33
  private _levelsMap;
31
34
  private _bitrates;
35
+ /**
36
+ * Laast timestamp, in terms of `performance.now`, at which the current
37
+ * quality was seen as too high by this algorithm.
38
+ * Begins at `undefined`.
39
+ */
40
+ private _lastUnsuitableQualityTimestamp;
41
+ /**
42
+ * After lowering in quality, we forbid raising during a set amount of time.
43
+ * This amount is adaptive may continue to raise if it seems that quality
44
+ * is switching too much between low and high qualities.
45
+ *
46
+ * `_blockRaiseDelay` represents this time in milliseconds.
47
+ */
48
+ private _blockRaiseDelay;
32
49
  /**
33
50
  * @param {Array.<number>} bitrates
34
51
  */
@@ -50,7 +67,7 @@ export interface IBufferBasedChooserPlaybackObservation {
50
67
  /** The bitrate of the currently downloaded segments, in bps. */
51
68
  currentBitrate?: number | undefined;
52
69
  /** The "maintainability score" of the currently downloaded segments. */
53
- currentScore?: number | undefined;
70
+ currentScore?: IRepresentationMaintainabilityScore | undefined;
54
71
  /** Playback rate wanted (e.g. `1` is regular playback, `2` is double speed etc.). */
55
72
  speed: number;
56
73
  }
@@ -16,6 +16,45 @@
16
16
  import log from "../../log";
17
17
  import arrayFindIndex from "../../utils/array_find_index";
18
18
  import getBufferLevels from "./utils/get_buffer_levels";
19
+ /**
20
+ * Minimum amount of time, in milliseconds, during which we are blocked from
21
+ * raising in quality after it had been considered as too high.
22
+ */
23
+ var MINIMUM_BLOCK_RAISE_DELAY = 6000;
24
+ /**
25
+ * Maximum amount of time, in milliseconds, during which we are blocked from
26
+ * raising in quality after it had been considered as too high.
27
+ */
28
+ var MAXIMUM_BLOCK_RAISE_DELAY = 15000;
29
+ /**
30
+ * Amount of time, in milliseconds, with which the blocking time in raising
31
+ * the quality will be incremented if the current quality estimate is seen
32
+ * as too unstable.
33
+ */
34
+ var RAISE_BLOCKING_DELAY_INCREMENT = 3000;
35
+ /**
36
+ * Amount of time, in milliseconds, with which the blocking time in raising
37
+ * the quality will be dcremented if the current quality estimate is seen
38
+ * as relatively stable, until `MINIMUM_BLOCK_RAISE_DELAY` is reached.
39
+ */
40
+ var RAISE_BLOCKING_DELAY_DECREMENT = 1000;
41
+ /**
42
+ * Amount of time, in milliseconds, after the "raise blocking delay" currently
43
+ * in place (during which it is forbidden to raise up in quality), during which
44
+ * we might want to raise the "raise blocking delay" if the last chosen quality
45
+ * seems unsuitable.
46
+ *
47
+ * For example, let's consider that the current raise blocking delay is at
48
+ * `4000`, or 4 seconds, and that this `STABILITY_CHECK_DELAY` is at `5000`, or
49
+ * 5 seconds.
50
+ * Here it means that if the estimated quality is found to be unsuitable less
51
+ * than 4+5 = 9 seconds after it last was, we will increment the raise blocking
52
+ * delay by `RAISE_BLOCKING_DELAY_INCREMENT` (unless `MAXIMUM_BLOCK_RAISE_DELAY`
53
+ * is reached).
54
+ * Else, if takes more than 9 seconds, the raise blocking delay might be
55
+ * decremented.
56
+ */
57
+ var STABILITY_CHECK_DELAY = 9000;
19
58
  /**
20
59
  * Choose a bitrate based on the currently available buffer.
21
60
  *
@@ -27,6 +66,8 @@ import getBufferLevels from "./utils/get_buffer_levels";
27
66
  * "maintanable" or not.
28
67
  * If so, we may switch to a better quality, or conversely to a worse quality.
29
68
  *
69
+ * It also rely on mechanisms to avoid fluctuating too much between qualities.
70
+ *
30
71
  * @class BufferBasedChooser
31
72
  */
32
73
  var BufferBasedChooser = /** @class */ (function () {
@@ -34,8 +75,13 @@ var BufferBasedChooser = /** @class */ (function () {
34
75
  * @param {Array.<number>} bitrates
35
76
  */
36
77
  function BufferBasedChooser(bitrates) {
37
- this._levelsMap = getBufferLevels(bitrates);
78
+ this._levelsMap = getBufferLevels(bitrates).map(function (bl) {
79
+ return bl + 4; // Add some buffer security as it will be used conjointly with
80
+ // other algorithms anyway
81
+ });
38
82
  this._bitrates = bitrates;
83
+ this._lastUnsuitableQualityTimestamp = undefined;
84
+ this._blockRaiseDelay = MINIMUM_BLOCK_RAISE_DELAY;
39
85
  log.debug("ABR: Steps for buffer based chooser.", this._levelsMap.map(function (l, i) { return "bufferLevel: ".concat(l, ", bitrate: ").concat(bitrates[i]); })
40
86
  .join(" ,"));
41
87
  }
@@ -50,40 +96,75 @@ var BufferBasedChooser = /** @class */ (function () {
50
96
  if (currentBitrate == null) {
51
97
  return bitrates[0];
52
98
  }
53
- var currentBitrateIndex = arrayFindIndex(bitrates, function (b) { return b === currentBitrate; });
99
+ var currentBitrateIndex = -1;
100
+ for (var i = 0; i < bitrates.length; i++) {
101
+ // There could be bitrate duplicates. Only take the last one to simplify
102
+ var bitrate = bitrates[i];
103
+ if (bitrate === currentBitrate) {
104
+ currentBitrateIndex = i;
105
+ }
106
+ else if (bitrate > currentBitrate) {
107
+ break;
108
+ }
109
+ }
54
110
  if (currentBitrateIndex < 0 || bitrates.length !== bufferLevels.length) {
55
111
  log.error("ABR: Current Bitrate not found in the calculated levels");
56
112
  return bitrates[0];
57
113
  }
58
114
  var scaledScore;
59
- if (currentScore != null) {
60
- scaledScore = speed === 0 ? currentScore : (currentScore / speed);
115
+ if (currentScore !== undefined) {
116
+ scaledScore = speed === 0 ? currentScore.score : (currentScore.score / speed);
61
117
  }
62
- if (scaledScore != null && scaledScore > 1) {
63
- var currentBufferLevel_1 = bufferLevels[currentBitrateIndex];
64
- var nextIndex = (function () {
65
- for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) {
66
- if (bufferLevels[i] > currentBufferLevel_1) {
67
- return i;
68
- }
69
- }
70
- })();
71
- if (nextIndex != null) {
72
- var nextBufferLevel = bufferLevels[nextIndex];
73
- if (bufferGap >= nextBufferLevel) {
74
- return bitrates[nextIndex];
118
+ var actualBufferGap = isFinite(bufferGap) ?
119
+ bufferGap :
120
+ 0;
121
+ var now = performance.now();
122
+ if (actualBufferGap < bufferLevels[currentBitrateIndex] ||
123
+ (scaledScore !== undefined && scaledScore < 1 &&
124
+ (currentScore === null || currentScore === void 0 ? void 0 : currentScore.confidenceLevel) === 1 /* ScoreConfidenceLevel.HIGH */)) {
125
+ var timeSincePrev = this._lastUnsuitableQualityTimestamp === undefined ?
126
+ -1 :
127
+ now - this._lastUnsuitableQualityTimestamp;
128
+ if (timeSincePrev < this._blockRaiseDelay + STABILITY_CHECK_DELAY) {
129
+ var newDelay = this._blockRaiseDelay + RAISE_BLOCKING_DELAY_INCREMENT;
130
+ this._blockRaiseDelay = Math.min(newDelay, MAXIMUM_BLOCK_RAISE_DELAY);
131
+ log.debug("ABR: Incrementing blocking raise in BufferBasedChooser due " +
132
+ "to unstable quality", this._blockRaiseDelay);
133
+ }
134
+ else {
135
+ var newDelay = this._blockRaiseDelay - RAISE_BLOCKING_DELAY_DECREMENT;
136
+ this._blockRaiseDelay = Math.max(MINIMUM_BLOCK_RAISE_DELAY, newDelay);
137
+ log.debug("ABR: Lowering quality in BufferBasedChooser", this._blockRaiseDelay);
138
+ }
139
+ this._lastUnsuitableQualityTimestamp = now;
140
+ // Security if multiple bitrates are equal, we now take the first one
141
+ var baseIndex = arrayFindIndex(bitrates, function (b) { return b === currentBitrate; });
142
+ for (var i = baseIndex - 1; i >= 0; i--) {
143
+ if (actualBufferGap >= bufferLevels[i]) {
144
+ return bitrates[i];
75
145
  }
76
146
  }
147
+ return bitrates[0];
77
148
  }
78
- if (scaledScore == null || scaledScore < 1.15) {
79
- var currentBufferLevel = bufferLevels[currentBitrateIndex];
80
- if (bufferGap < currentBufferLevel) {
81
- for (var i = currentBitrateIndex - 1; i >= 0; i--) {
82
- if (bitrates[i] < currentBitrate) {
83
- return bitrates[i];
84
- }
149
+ if ((this._lastUnsuitableQualityTimestamp !== undefined &&
150
+ now - this._lastUnsuitableQualityTimestamp < this._blockRaiseDelay) ||
151
+ scaledScore === undefined || scaledScore < 1.15 ||
152
+ (currentScore === null || currentScore === void 0 ? void 0 : currentScore.confidenceLevel) !== 1 /* ScoreConfidenceLevel.HIGH */) {
153
+ return currentBitrate;
154
+ }
155
+ var currentBufferLevel = bufferLevels[currentBitrateIndex];
156
+ var nextIndex = (function () {
157
+ for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) {
158
+ if (bufferLevels[i] > currentBufferLevel) {
159
+ return i;
85
160
  }
86
- return currentBitrate;
161
+ }
162
+ })();
163
+ if (nextIndex !== undefined) {
164
+ var nextBufferLevel = bufferLevels[nextIndex];
165
+ if (bufferGap >= nextBufferLevel) {
166
+ log.debug("ABR: Raising quality in BufferBasedChooser", bitrates[nextIndex]);
167
+ return bitrates[nextIndex];
87
168
  }
88
169
  }
89
170
  return currentBitrate;
@@ -127,10 +127,10 @@ var GuessBasedChooser = /** @class */ (function () {
127
127
  * @returns {boolean}
128
128
  */
129
129
  GuessBasedChooser.prototype._canGuessHigher = function (bufferGap, speed, _a) {
130
- var score = _a[0], scoreConfidenceLevel = _a[1];
130
+ var score = _a.score, confidenceLevel = _a.confidenceLevel;
131
131
  return isFinite(bufferGap) && bufferGap >= 2.5 &&
132
132
  performance.now() > this._blockGuessesUntil &&
133
- scoreConfidenceLevel === 1 /* ScoreConfidenceLevel.HIGH */ &&
133
+ confidenceLevel === 1 /* ScoreConfidenceLevel.HIGH */ &&
134
134
  score / speed > 1.01;
135
135
  };
136
136
  /**
@@ -143,10 +143,10 @@ var GuessBasedChooser = /** @class */ (function () {
143
143
  * @returns {boolean}
144
144
  */
145
145
  GuessBasedChooser.prototype._shouldStopGuess = function (lastGuess, scoreData, bufferGap, requests) {
146
- if (scoreData !== undefined && scoreData[0] < 1.01) {
146
+ if (scoreData !== undefined && scoreData.score < 1.01) {
147
147
  return true;
148
148
  }
149
- else if ((scoreData === undefined || scoreData[0] < 1.2) && bufferGap < 0.6) {
149
+ else if ((scoreData === undefined || scoreData.score < 1.2) && bufferGap < 0.6) {
150
150
  return true;
151
151
  }
152
152
  var guessedRepresentationRequests = requests.filter(function (req) {
@@ -175,8 +175,8 @@ var GuessBasedChooser = /** @class */ (function () {
175
175
  };
176
176
  GuessBasedChooser.prototype._isLastGuessValidated = function (lastGuess, incomingBestBitrate, scoreData) {
177
177
  if (scoreData !== undefined &&
178
- scoreData[1] === 1 /* ScoreConfidenceLevel.HIGH */ &&
179
- scoreData[0] > 1.5) {
178
+ scoreData.confidenceLevel === 1 /* ScoreConfidenceLevel.HIGH */ &&
179
+ scoreData.score > 1.5) {
180
180
  return true;
181
181
  }
182
182
  return incomingBestBitrate >= lastGuess.bitrate &&
@@ -126,6 +126,12 @@ function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRep
126
126
  }
127
127
  var concernedRequest = concernedRequests[0];
128
128
  var now = performance.now();
129
+ var minimumRequestTime = concernedRequest.content.segment.duration * 1.5;
130
+ minimumRequestTime = Math.min(minimumRequestTime, 3000);
131
+ minimumRequestTime = Math.max(minimumRequestTime, 12000);
132
+ if (now - concernedRequest.requestTimestamp < minimumRequestTime) {
133
+ return undefined;
134
+ }
129
135
  var lastProgressEvent = concernedRequest.progress.length > 0 ?
130
136
  concernedRequest.progress[concernedRequest.progress.length - 1] :
131
137
  undefined;
@@ -138,7 +144,7 @@ function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRep
138
144
  // Calculate estimated time spent rebuffering if we continue doing that request.
139
145
  var expectedRebufferingTime = remainingTime -
140
146
  (realBufferGap / speed);
141
- if (expectedRebufferingTime > 2000) {
147
+ if (expectedRebufferingTime > 2500) {
142
148
  return bandwidthEstimate;
143
149
  }
144
150
  }
@@ -320,12 +326,9 @@ var NetworkAnalyzer = /** @class */ (function () {
320
326
  if (currentRepresentation === null) {
321
327
  return true;
322
328
  }
323
- else if (bitrate === currentRepresentation.bitrate) {
329
+ else if (bitrate >= currentRepresentation.bitrate) {
324
330
  return false;
325
331
  }
326
- else if (bitrate > currentRepresentation.bitrate) {
327
- return !this._inStarvationMode;
328
- }
329
332
  return shouldDirectlySwitchToLowBitrate(playbackInfo, currentRequests, this._lowLatencyMode);
330
333
  };
331
334
  return NetworkAnalyzer;
@@ -14,6 +14,24 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { Representation } from "../../../manifest";
17
+ /**
18
+ * Object representing a maintainability score as calculated by the
19
+ * `RepresentationScoreCalculator`.
20
+ */
21
+ export interface IRepresentationMaintainabilityScore {
22
+ /**
23
+ * Weighted mean of dividing the loaded segment's duration by the time to make
24
+ * their request.
25
+ */
26
+ score: number;
27
+ /**
28
+ * The confidence we have on the calculated `score` in reflecting a useful
29
+ * maintainability hint for the concerned Representation.
30
+ *
31
+ * Basically, the more segments have been loaded, the higher the confidence.
32
+ */
33
+ confidenceLevel: ScoreConfidenceLevel;
34
+ }
17
35
  /**
18
36
  * Calculate the "maintainability score" of a given Representation:
19
37
  * - A score higher than 1 means that the Representation can theorically
@@ -62,7 +80,7 @@ export default class RepresentationScoreCalculator {
62
80
  * @param {Representation} representation
63
81
  * @returns {number|undefined}
64
82
  */
65
- getEstimate(representation: Representation): [number, ScoreConfidenceLevel] | undefined;
83
+ getEstimate(representation: Representation): IRepresentationMaintainabilityScore | undefined;
66
84
  /**
67
85
  * Returns last Representation which had reached a score superior to 1.
68
86
  * This Representation is the last known one which could be maintained.
@@ -96,7 +96,7 @@ var RepresentationScoreCalculator = /** @class */ (function () {
96
96
  var confidenceLevel = loadedSegments >= 5 &&
97
97
  loadedDuration >= 10 ? 1 /* ScoreConfidenceLevel.HIGH */ :
98
98
  0 /* ScoreConfidenceLevel.LOW */;
99
- return [estimate, confidenceLevel];
99
+ return { score: estimate, confidenceLevel: confidenceLevel };
100
100
  };
101
101
  /**
102
102
  * Returns last Representation which had reached a score superior to 1.
@@ -0,0 +1,28 @@
1
+ import { IBufferedChunk } from "../../segment_buffers";
2
+ export interface ISegmentBufferGrapUpdateData {
3
+ currentTime: number;
4
+ inventory: IBufferedChunk[];
5
+ width: number;
6
+ height: number;
7
+ minimumPosition: number | undefined;
8
+ maximumPosition: number | undefined;
9
+ }
10
+ export default class SegmentBufferGraph {
11
+ /** Link buffered Representation to their corresponding color. */
12
+ private readonly _colorMap;
13
+ /** Current amount of colors chosen to represent the various Representation. */
14
+ private _currNbColors;
15
+ /** Canvas that will contain the buffer graph itself. */
16
+ private readonly _canvasElt;
17
+ private readonly _canvasCtxt;
18
+ constructor(canvasElt: HTMLCanvasElement);
19
+ clear(): void;
20
+ update(data: ISegmentBufferGrapUpdateData): void;
21
+ /**
22
+ * Paint a given range in the canvas
23
+ * @param {Object} rangeScaled - Buffered segment information with added
24
+ * "scaling" information to know where it fits in the canvas.
25
+ */
26
+ private _paintRange;
27
+ private _getColorForRepresentation;
28
+ }
@@ -0,0 +1,175 @@
1
+ var BUFFER_WIDTH_IN_SECONDS = 10000;
2
+ var COLORS = [
3
+ "#2ab7ca",
4
+ "#fed766",
5
+ "#4dd248",
6
+ "#a22c28",
7
+ "#556b2f",
8
+ "#add8e6",
9
+ "#90ee90",
10
+ "#444444",
11
+ "#40bfc1",
12
+ "#57557e",
13
+ "#fbe555",
14
+ ];
15
+ var SegmentBufferGraph = /** @class */ (function () {
16
+ function SegmentBufferGraph(canvasElt) {
17
+ this._colorMap = new WeakMap();
18
+ this._currNbColors = 0;
19
+ this._canvasElt = canvasElt;
20
+ this._canvasCtxt = this._canvasElt.getContext("2d");
21
+ this.clear();
22
+ }
23
+ SegmentBufferGraph.prototype.clear = function () {
24
+ if (this._canvasCtxt !== null) {
25
+ this._canvasCtxt.clearRect(0, 0, this._canvasElt.width, this._canvasElt.height);
26
+ }
27
+ };
28
+ SegmentBufferGraph.prototype.update = function (data) {
29
+ var _a, _b, _c, _d;
30
+ if (this._canvasCtxt === null) {
31
+ return;
32
+ }
33
+ var inventory = data.inventory, currentTime = data.currentTime, width = data.width, height = data.height;
34
+ this._canvasElt.style.width = "".concat(width, "px");
35
+ this._canvasElt.style.height = "".concat(height, "px");
36
+ this._canvasElt.width = width;
37
+ this._canvasElt.height = height;
38
+ this.clear();
39
+ var minimumPoint;
40
+ if (data.minimumPosition !== undefined) {
41
+ if (inventory.length > 0) {
42
+ minimumPoint = Math.min(data.minimumPosition, inventory[0].start);
43
+ }
44
+ else {
45
+ minimumPoint = data.minimumPosition;
46
+ }
47
+ }
48
+ else {
49
+ minimumPoint = (_b = (_a = inventory[0]) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : 0;
50
+ }
51
+ var maximumPoint;
52
+ if (data.maximumPosition !== undefined) {
53
+ if (inventory.length > 0) {
54
+ maximumPoint = Math.max(data.maximumPosition, inventory[inventory.length - 1].end);
55
+ }
56
+ else {
57
+ maximumPoint = data.maximumPosition;
58
+ }
59
+ }
60
+ else {
61
+ maximumPoint = (_d = (_c = inventory[inventory.length - 1]) === null || _c === void 0 ? void 0 : _c.end) !== null && _d !== void 0 ? _d : 1000;
62
+ }
63
+ minimumPoint = Math.min(currentTime, minimumPoint);
64
+ maximumPoint = Math.max(currentTime, maximumPoint);
65
+ var minimumPosition;
66
+ var maximumPosition;
67
+ if (maximumPoint - minimumPoint > BUFFER_WIDTH_IN_SECONDS) {
68
+ if (currentTime === undefined) {
69
+ minimumPosition = minimumPoint;
70
+ maximumPosition = maximumPoint;
71
+ }
72
+ else if (maximumPoint - currentTime < BUFFER_WIDTH_IN_SECONDS / 2) {
73
+ maximumPosition = maximumPoint;
74
+ minimumPosition = maximumPoint - BUFFER_WIDTH_IN_SECONDS;
75
+ }
76
+ else if (currentTime - minimumPoint < BUFFER_WIDTH_IN_SECONDS / 2) {
77
+ minimumPosition = minimumPoint;
78
+ maximumPosition = minimumPoint + BUFFER_WIDTH_IN_SECONDS;
79
+ }
80
+ else {
81
+ minimumPosition = currentTime - BUFFER_WIDTH_IN_SECONDS / 2;
82
+ maximumPosition = currentTime + BUFFER_WIDTH_IN_SECONDS / 2;
83
+ }
84
+ }
85
+ else {
86
+ minimumPosition = minimumPoint;
87
+ maximumPosition = maximumPoint;
88
+ }
89
+ if (minimumPosition >= maximumPosition) {
90
+ this.clear();
91
+ return;
92
+ }
93
+ var currentRangesScaled = scaleSegments(inventory, minimumPosition, maximumPosition);
94
+ for (var i = 0; i < currentRangesScaled.length; i++) {
95
+ this._paintRange(currentRangesScaled[i], width, height);
96
+ }
97
+ if (currentTime !== undefined) {
98
+ paintCurrentPosition(currentTime, minimumPosition, maximumPosition, this._canvasCtxt, width, height);
99
+ }
100
+ };
101
+ /**
102
+ * Paint a given range in the canvas
103
+ * @param {Object} rangeScaled - Buffered segment information with added
104
+ * "scaling" information to know where it fits in the canvas.
105
+ */
106
+ SegmentBufferGraph.prototype._paintRange = function (rangeScaled, width, height) {
107
+ if (this._canvasCtxt === null) {
108
+ return;
109
+ }
110
+ var startX = rangeScaled.scaledStart * width;
111
+ var endX = rangeScaled.scaledEnd * width;
112
+ this._canvasCtxt.fillStyle = this._getColorForRepresentation(rangeScaled.info.infos.representation);
113
+ this._canvasCtxt.fillRect(Math.ceil(startX), 0, Math.ceil(endX - startX), height);
114
+ };
115
+ SegmentBufferGraph.prototype._getColorForRepresentation = function (representation) {
116
+ var color = this._colorMap.get(representation);
117
+ if (color !== undefined) {
118
+ return color;
119
+ }
120
+ var newColor = COLORS[this._currNbColors % COLORS.length];
121
+ this._currNbColors++;
122
+ this._colorMap.set(representation, newColor);
123
+ return newColor;
124
+ };
125
+ return SegmentBufferGraph;
126
+ }());
127
+ export default SegmentBufferGraph;
128
+ /**
129
+ * Represent the current position in the canvas.
130
+ * @param {number|undefined} position - The current position
131
+ * @param {number} minimumPosition - minimum possible position represented in
132
+ * the canvas.
133
+ * @param {number} maximumPosition - maximum possible position represented in
134
+ * the canvas.
135
+ * @param {Object} canvasCtx - The canvas' 2D context
136
+ */
137
+ function paintCurrentPosition(position, minimumPosition, maximumPosition, canvasCtx, width, height) {
138
+ if (typeof position === "number" &&
139
+ position >= minimumPosition &&
140
+ position < maximumPosition) {
141
+ var lengthCanvas = maximumPosition - minimumPosition;
142
+ canvasCtx.fillStyle = "#FF0000";
143
+ canvasCtx.fillRect(Math.ceil((position - minimumPosition) /
144
+ lengthCanvas * width) - 1, 5, 5, height);
145
+ }
146
+ }
147
+ /**
148
+ * Scale given bufferedData in terms of percentage between the minimum and
149
+ * maximum position. Filter out ranges which are not part of it.
150
+ * @param {Array.<Object>} bufferedData
151
+ * @param {number} minimumPosition
152
+ * @param {number} maximumPosition
153
+ * @returns {Array.<Object>}
154
+ */
155
+ function scaleSegments(bufferedData, minimumPosition, maximumPosition) {
156
+ var scaledSegments = [];
157
+ var wholeDuration = maximumPosition - minimumPosition;
158
+ for (var i = 0; i < bufferedData.length; i++) {
159
+ var info = bufferedData[i];
160
+ var start = info.bufferedStart === undefined ?
161
+ info.start :
162
+ info.bufferedStart;
163
+ var end = info.bufferedEnd === undefined ?
164
+ info.end :
165
+ info.bufferedEnd;
166
+ if (end > minimumPosition && start < maximumPosition) {
167
+ var startPoint = Math.max(start - minimumPosition, 0);
168
+ var endPoint = Math.min(end - minimumPosition, maximumPosition);
169
+ var scaledStart = startPoint / wholeDuration;
170
+ var scaledEnd = endPoint / wholeDuration;
171
+ scaledSegments.push({ scaledStart: scaledStart, scaledEnd: scaledEnd, info: info });
172
+ }
173
+ }
174
+ return scaledSegments;
175
+ }
@@ -0,0 +1,10 @@
1
+ export default class BufferSizeGraph {
2
+ private _history;
3
+ /** Canvas that will contain the buffer size graph itself. */
4
+ private readonly _canvasElt;
5
+ private readonly _canvasCtxt;
6
+ constructor(canvasElt: HTMLCanvasElement);
7
+ pushBufferSize(bufferSize: number): void;
8
+ clear(): void;
9
+ reRender(width: number, height: number): void;
10
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Maximum history of the buffer size that will be displayed, in milliseconds.
3
+ * For example, a value of `3000` indicates that we will just show at most the
4
+ * buffer size evolution during the last 3 seconds.
5
+ */
6
+ var TIME_SAMPLES_MS = 30000;
7
+ /**
8
+ * At minimum, that value will be taken in the chart as a maximum buffer size,
9
+ * in seconds.
10
+ * If samples go higher than this size, the chart will adapt automatically to
11
+ * a higher scale.
12
+ * However if values go below that value, the chart won't scale down more than
13
+ * this.
14
+ */
15
+ var MINIMUM_MAX_BUFFER_SIZE = 20;
16
+ var BufferSizeGraph = /** @class */ (function () {
17
+ function BufferSizeGraph(canvasElt) {
18
+ this._canvasElt = canvasElt;
19
+ this._canvasCtxt = this._canvasElt.getContext("2d");
20
+ this._history = [];
21
+ }
22
+ BufferSizeGraph.prototype.pushBufferSize = function (bufferSize) {
23
+ var now = performance.now();
24
+ this._history.push({ timestamp: now, bufferSize: bufferSize });
25
+ if (this._history.length > 0) {
26
+ var minimumTime = now - TIME_SAMPLES_MS;
27
+ var i = void 0;
28
+ for (i = this._history.length - 1; i >= 1; i--) {
29
+ if (this._history[i].timestamp <= minimumTime) {
30
+ break;
31
+ }
32
+ }
33
+ this._history = this._history.slice(i);
34
+ }
35
+ else {
36
+ this._history = [];
37
+ }
38
+ };
39
+ BufferSizeGraph.prototype.clear = function () {
40
+ if (this._canvasCtxt !== null) {
41
+ this._canvasCtxt.clearRect(0, 0, this._canvasElt.width, this._canvasElt.height);
42
+ }
43
+ };
44
+ BufferSizeGraph.prototype.reRender = function (width, height) {
45
+ this._canvasElt.style.width = "".concat(width, "px");
46
+ this._canvasElt.style.height = "".concat(height, "px");
47
+ this._canvasElt.width = width;
48
+ this._canvasElt.height = height;
49
+ this.clear();
50
+ var history = this._history;
51
+ var canvasCtx = this._canvasCtxt;
52
+ if (history.length === 0) {
53
+ return;
54
+ }
55
+ var currentMaxSize = getNewMaxBufferSize();
56
+ var minDate = history[0].timestamp;
57
+ var gridHeight = height / currentMaxSize;
58
+ var gridWidth = width / TIME_SAMPLES_MS;
59
+ drawData();
60
+ /**
61
+ * Get more appropriate maximum buffer size to put on top of the graph
62
+ * according to current history.
63
+ */
64
+ function getNewMaxBufferSize() {
65
+ var maxPoint = Math.max.apply(Math, history.map(function (d) { return d.bufferSize; }));
66
+ return Math.max(maxPoint + 5, MINIMUM_MAX_BUFFER_SIZE);
67
+ }
68
+ /**
69
+ * Draw all data contained in `history` in the canvas given.
70
+ */
71
+ function drawData() {
72
+ if (canvasCtx === null) {
73
+ return;
74
+ }
75
+ canvasCtx.beginPath();
76
+ canvasCtx.fillStyle = "rgb(200, 100, 200)";
77
+ for (var i = 1; i < history.length; i++) {
78
+ var diff = dateToX(history[i].timestamp) -
79
+ dateToX(history[i - 1].timestamp);
80
+ var y = height - bufferValueToHeight(history[i].bufferSize);
81
+ canvasCtx.fillRect(dateToX(history[i - 1].timestamp), y, diff, height);
82
+ }
83
+ canvasCtx.stroke();
84
+ }
85
+ /**
86
+ * Convert a value of a given data point, to a u coordinate in the canvas.
87
+ * @param {number} bufferVal - Value to convert
88
+ * @returns {number} - y coordinate
89
+ */
90
+ function bufferValueToHeight(bufferVal) {
91
+ return height - (currentMaxSize - bufferVal) * gridHeight;
92
+ }
93
+ /**
94
+ * Convert a date of a given data point, to a x coordinate in the canvas.
95
+ * @param {number} date - Date to convert, in milliseconds
96
+ * @returns {number} - x coordinate
97
+ */
98
+ function dateToX(date) {
99
+ return (date - minDate) * gridWidth;
100
+ }
101
+ };
102
+ return BufferSizeGraph;
103
+ }());
104
+ export default BufferSizeGraph;
@@ -0,0 +1,2 @@
1
+ /** Interval at which the various debug metrics will be refreshed. */
2
+ export declare const DEFAULT_REFRESH_INTERVAL = 1000;
@@ -0,0 +1,2 @@
1
+ /** Interval at which the various debug metrics will be refreshed. */
2
+ export var DEFAULT_REFRESH_INTERVAL = 1000;
@@ -0,0 +1,2 @@
1
+ import renderDebugElement from "./render";
2
+ export default renderDebugElement;
@@ -0,0 +1,2 @@
1
+ import renderDebugElement from "./render";
2
+ export default renderDebugElement;