rx-player 4.5.0-dev.2026033100 → 4.5.0-dev.2026041501

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 (251) hide show
  1. package/CHANGELOG.md +22 -5
  2. package/VERSION +1 -1
  3. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  4. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  5. package/dist/commonjs/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  6. package/dist/commonjs/__GENERATED_CODE/embedded_worker.js +1 -1
  7. package/dist/commonjs/compat/can_patch_out_pssh.d.ts +42 -0
  8. package/dist/commonjs/compat/can_patch_out_pssh.d.ts.map +1 -0
  9. package/dist/commonjs/compat/can_patch_out_pssh.js +53 -0
  10. package/dist/commonjs/compat/env_detector.d.ts +2 -0
  11. package/dist/commonjs/compat/env_detector.d.ts.map +1 -1
  12. package/dist/commonjs/compat/env_detector.js +5 -0
  13. package/dist/commonjs/core/adaptive/network_analyzer.d.ts +1 -2
  14. package/dist/commonjs/core/adaptive/network_analyzer.d.ts.map +1 -1
  15. package/dist/commonjs/core/adaptive/network_analyzer.js +3 -3
  16. package/dist/commonjs/core/adaptive/utils/representation_score_calculator.js +2 -2
  17. package/dist/commonjs/core/cmcd/cmcd_data_builder.d.ts.map +1 -1
  18. package/dist/commonjs/core/cmcd/cmcd_data_builder.js +9 -3
  19. package/dist/commonjs/core/entry/content_preparer.d.ts.map +1 -1
  20. package/dist/commonjs/core/entry/content_preparer.js +5 -7
  21. package/dist/commonjs/core/entry/core_entry.d.ts.map +1 -1
  22. package/dist/commonjs/core/entry/core_entry.js +6 -2
  23. package/dist/commonjs/core/entry/core_text_displayer_interface.js +3 -3
  24. package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.d.ts.map +1 -1
  25. package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.js +12 -0
  26. package/dist/commonjs/core/fetchers/thumbnails/thumbnail_fetcher.js +1 -1
  27. package/dist/commonjs/core/fetchers/utils/schedule_request.d.ts.map +1 -1
  28. package/dist/commonjs/core/fetchers/utils/schedule_request.js +4 -3
  29. package/dist/commonjs/core/segment_sinks/garbage_collector.d.ts +0 -2
  30. package/dist/commonjs/core/segment_sinks/garbage_collector.d.ts.map +1 -1
  31. package/dist/commonjs/core/segment_sinks/garbage_collector.js +0 -3
  32. package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.d.ts +1 -1
  33. package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.d.ts.map +1 -1
  34. package/dist/commonjs/core/segment_sinks/implementations/text/text_segment_sink.js +2 -2
  35. package/dist/commonjs/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
  36. package/dist/commonjs/core/stream/adaptation/adaptation_stream.js +6 -6
  37. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
  38. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +37 -40
  39. package/dist/commonjs/default_config.d.ts +5 -0
  40. package/dist/commonjs/default_config.d.ts.map +1 -1
  41. package/dist/commonjs/default_config.js +5 -0
  42. package/dist/commonjs/main_thread/api/public_api.d.ts.map +1 -1
  43. package/dist/commonjs/main_thread/api/public_api.js +23 -16
  44. package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  45. package/dist/commonjs/main_thread/decrypt/content_decryptor.js +4 -1
  46. package/dist/commonjs/main_thread/decrypt/session_events_listener.js +1 -1
  47. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts +2 -0
  48. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  49. package/dist/commonjs/main_thread/decrypt/set_server_certificate.js +4 -0
  50. package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts +0 -8
  51. package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
  52. package/dist/commonjs/main_thread/init/media_source_content_initializer.js +58 -50
  53. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +35 -5
  54. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
  55. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +60 -19
  56. package/dist/commonjs/main_thread/render_thumbnail.d.ts.map +1 -1
  57. package/dist/commonjs/main_thread/render_thumbnail.js +4 -0
  58. package/dist/commonjs/main_thread/tracks_store/media_element_tracks_store.d.ts.map +1 -1
  59. package/dist/commonjs/main_thread/tracks_store/media_element_tracks_store.js +1 -0
  60. package/dist/commonjs/main_thread/tracks_store/tracks_store.d.ts +1 -1
  61. package/dist/commonjs/main_thread/tracks_store/tracks_store.js +1 -1
  62. package/dist/{es2017/parsers/containers/isobmff/take_pssh_out.d.ts → commonjs/parsers/containers/isobmff/extract_pssh.d.ts} +6 -4
  63. package/dist/commonjs/parsers/containers/isobmff/extract_pssh.d.ts.map +1 -0
  64. package/dist/commonjs/parsers/containers/isobmff/{take_pssh_out.js → extract_pssh.js} +22 -17
  65. package/dist/commonjs/parsers/containers/isobmff/index.d.ts +2 -2
  66. package/dist/commonjs/parsers/containers/isobmff/index.d.ts.map +1 -1
  67. package/dist/commonjs/parsers/containers/isobmff/index.js +4 -4
  68. package/dist/commonjs/playback_observer/core_playback_observer.d.ts +4 -4
  69. package/dist/commonjs/playback_observer/core_playback_observer.d.ts.map +1 -1
  70. package/dist/commonjs/playback_observer/media_element_playback_observer.d.ts +1 -2
  71. package/dist/commonjs/playback_observer/media_element_playback_observer.d.ts.map +1 -1
  72. package/dist/commonjs/transports/dash/segment_parser.js +1 -1
  73. package/dist/commonjs/transports/local/segment_parser.js +1 -1
  74. package/dist/commonjs/utils/test-utils.d.ts +30 -0
  75. package/dist/commonjs/utils/test-utils.d.ts.map +1 -0
  76. package/dist/commonjs/utils/test-utils.js +79 -0
  77. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  78. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  79. package/dist/es2017/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  80. package/dist/es2017/__GENERATED_CODE/embedded_worker.js +1 -1
  81. package/dist/es2017/compat/can_patch_out_pssh.d.ts +42 -0
  82. package/dist/es2017/compat/can_patch_out_pssh.d.ts.map +1 -0
  83. package/dist/es2017/compat/can_patch_out_pssh.js +50 -0
  84. package/dist/es2017/compat/env_detector.d.ts +2 -0
  85. package/dist/es2017/compat/env_detector.d.ts.map +1 -1
  86. package/dist/es2017/compat/env_detector.js +5 -0
  87. package/dist/es2017/core/adaptive/network_analyzer.d.ts +1 -2
  88. package/dist/es2017/core/adaptive/network_analyzer.d.ts.map +1 -1
  89. package/dist/es2017/core/adaptive/network_analyzer.js +3 -3
  90. package/dist/es2017/core/adaptive/utils/representation_score_calculator.js +2 -2
  91. package/dist/es2017/core/cmcd/cmcd_data_builder.d.ts.map +1 -1
  92. package/dist/es2017/core/cmcd/cmcd_data_builder.js +9 -3
  93. package/dist/es2017/core/entry/content_preparer.d.ts.map +1 -1
  94. package/dist/es2017/core/entry/content_preparer.js +3 -5
  95. package/dist/es2017/core/entry/core_entry.d.ts.map +1 -1
  96. package/dist/es2017/core/entry/core_entry.js +6 -2
  97. package/dist/es2017/core/entry/core_text_displayer_interface.js +3 -3
  98. package/dist/es2017/core/fetchers/manifest/manifest_fetcher.d.ts.map +1 -1
  99. package/dist/es2017/core/fetchers/manifest/manifest_fetcher.js +12 -0
  100. package/dist/es2017/core/fetchers/thumbnails/thumbnail_fetcher.js +1 -1
  101. package/dist/es2017/core/fetchers/utils/schedule_request.d.ts.map +1 -1
  102. package/dist/es2017/core/fetchers/utils/schedule_request.js +2 -3
  103. package/dist/es2017/core/segment_sinks/garbage_collector.d.ts +0 -2
  104. package/dist/es2017/core/segment_sinks/garbage_collector.d.ts.map +1 -1
  105. package/dist/es2017/core/segment_sinks/garbage_collector.js +0 -3
  106. package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.d.ts +1 -1
  107. package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.d.ts.map +1 -1
  108. package/dist/es2017/core/segment_sinks/implementations/text/text_segment_sink.js +2 -2
  109. package/dist/es2017/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
  110. package/dist/es2017/core/stream/adaptation/adaptation_stream.js +6 -6
  111. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
  112. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +40 -39
  113. package/dist/es2017/default_config.d.ts +5 -0
  114. package/dist/es2017/default_config.d.ts.map +1 -1
  115. package/dist/es2017/default_config.js +5 -0
  116. package/dist/es2017/main_thread/api/public_api.d.ts.map +1 -1
  117. package/dist/es2017/main_thread/api/public_api.js +20 -13
  118. package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  119. package/dist/es2017/main_thread/decrypt/content_decryptor.js +4 -1
  120. package/dist/es2017/main_thread/decrypt/session_events_listener.js +1 -1
  121. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts +2 -0
  122. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  123. package/dist/es2017/main_thread/decrypt/set_server_certificate.js +4 -0
  124. package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts +0 -8
  125. package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
  126. package/dist/es2017/main_thread/init/media_source_content_initializer.js +58 -50
  127. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +35 -5
  128. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
  129. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +60 -19
  130. package/dist/es2017/main_thread/render_thumbnail.d.ts.map +1 -1
  131. package/dist/es2017/main_thread/render_thumbnail.js +4 -0
  132. package/dist/es2017/main_thread/tracks_store/media_element_tracks_store.d.ts.map +1 -1
  133. package/dist/es2017/main_thread/tracks_store/media_element_tracks_store.js +1 -0
  134. package/dist/es2017/main_thread/tracks_store/tracks_store.d.ts +1 -1
  135. package/dist/es2017/main_thread/tracks_store/tracks_store.js +1 -1
  136. package/dist/{commonjs/parsers/containers/isobmff/take_pssh_out.d.ts → es2017/parsers/containers/isobmff/extract_pssh.d.ts} +6 -4
  137. package/dist/es2017/parsers/containers/isobmff/extract_pssh.d.ts.map +1 -0
  138. package/dist/es2017/parsers/containers/isobmff/{take_pssh_out.js → extract_pssh.js} +21 -16
  139. package/dist/es2017/parsers/containers/isobmff/index.d.ts +2 -2
  140. package/dist/es2017/parsers/containers/isobmff/index.d.ts.map +1 -1
  141. package/dist/es2017/parsers/containers/isobmff/index.js +2 -2
  142. package/dist/es2017/playback_observer/core_playback_observer.d.ts +4 -4
  143. package/dist/es2017/playback_observer/core_playback_observer.d.ts.map +1 -1
  144. package/dist/es2017/playback_observer/media_element_playback_observer.d.ts +1 -2
  145. package/dist/es2017/playback_observer/media_element_playback_observer.d.ts.map +1 -1
  146. package/dist/es2017/transports/dash/segment_parser.js +2 -2
  147. package/dist/es2017/transports/local/segment_parser.js +2 -2
  148. package/dist/es2017/utils/test-utils.d.ts +30 -0
  149. package/dist/es2017/utils/test-utils.d.ts.map +1 -0
  150. package/dist/es2017/utils/test-utils.js +36 -0
  151. package/dist/mpd-parser.wasm +0 -0
  152. package/dist/worker.js +6 -6
  153. package/package.json +4 -2
  154. package/src/README.md +7 -7
  155. package/src/__GENERATED_CODE/embedded_dash_wasm.ts +1 -1
  156. package/src/__GENERATED_CODE/embedded_worker.ts +1 -1
  157. package/src/compat/__tests__/can_patch_out_pssh.test.ts +40 -0
  158. package/src/compat/can_patch_out_pssh.ts +53 -0
  159. package/src/compat/env_detector.ts +4 -0
  160. package/src/core/README.md +1 -1
  161. package/src/core/adaptive/README.md +3 -3
  162. package/src/core/adaptive/__tests__/adaptive_representation_selector.test.ts +181 -110
  163. package/src/core/adaptive/__tests__/guess_based_chooser.test.ts +229 -123
  164. package/src/core/adaptive/__tests__/mocks.ts +100 -0
  165. package/src/core/adaptive/__tests__/network_analyzer.test.ts +152 -59
  166. package/src/core/adaptive/network_analyzer.ts +4 -4
  167. package/src/core/adaptive/utils/__tests__/filter_by_bitrate.test.ts +11 -19
  168. package/src/core/adaptive/utils/__tests__/filter_by_resolution.test.ts +12 -12
  169. package/src/core/adaptive/utils/__tests__/last_estimate_storage.test.ts +25 -12
  170. package/src/core/adaptive/utils/__tests__/pending_requests_store.test.ts +13 -9
  171. package/src/core/adaptive/utils/__tests__/representation_score_calculator.test.ts +11 -11
  172. package/src/core/adaptive/utils/__tests__/select_optimal_representation.test.ts +13 -23
  173. package/src/core/adaptive/utils/representation_score_calculator.ts +2 -2
  174. package/src/core/cmcd/__tests__/cmcd_data_builder.test.ts +60 -15
  175. package/src/core/cmcd/cmcd_data_builder.ts +9 -3
  176. package/src/core/entry/README.md +2 -2
  177. package/src/core/entry/__tests__/core_text_displayer_interface.test.ts +20 -0
  178. package/src/core/entry/content_preparer.ts +2 -5
  179. package/src/core/entry/core_entry.ts +6 -2
  180. package/src/core/entry/core_text_displayer_interface.ts +3 -3
  181. package/src/core/fetchers/manifest/__tests__/manifest_fetcher.test.ts +52 -3
  182. package/src/core/fetchers/manifest/manifest_fetcher.ts +12 -0
  183. package/src/core/fetchers/thumbnails/__tests__/thumbnail_fetcher.test.ts +70 -0
  184. package/src/core/fetchers/thumbnails/thumbnail_fetcher.ts +1 -1
  185. package/src/core/fetchers/utils/schedule_request.ts +5 -3
  186. package/src/core/segment_sinks/__tests__/garbage_collector.test.ts +434 -0
  187. package/src/core/segment_sinks/__tests__/mocks.ts +49 -0
  188. package/src/core/segment_sinks/garbage_collector.ts +0 -3
  189. package/src/core/segment_sinks/implementations/text/__tests__/text_segment_sink.test.ts +177 -0
  190. package/src/core/segment_sinks/implementations/text/text_segment_sink.ts +2 -2
  191. package/src/core/segment_sinks/inventory/__tests__/buffered_history.test.ts +215 -0
  192. package/src/core/segment_sinks/inventory/__tests__/segment_inventory.test.ts +448 -0
  193. package/src/core/stream/adaptation/__tests__/adaptation_stream.test.ts +973 -0
  194. package/src/core/stream/adaptation/__tests__/get_representations_switch_strategy.test.ts +283 -374
  195. package/src/core/stream/adaptation/adaptation_stream.ts +6 -8
  196. package/src/core/stream/orchestrator/README.md +4 -4
  197. package/src/core/stream/orchestrator/__tests__/stream_orchestrator.test.ts +707 -0
  198. package/src/core/stream/orchestrator/stream_orchestrator.ts +41 -46
  199. package/src/core/stream/period/utils/__tests__/get_adaptation_switch_strategy.test.ts +290 -220
  200. package/src/core/stream/representation/__tests__/encryption_data_notifier.test.ts +93 -63
  201. package/src/core/stream/representation/utils/__tests__/append_segment_to_buffer.test.ts +106 -63
  202. package/src/core/stream/representation/utils/__tests__/check_for_discontinuity.test.ts +179 -204
  203. package/src/core/stream/representation/utils/__tests__/get_segment_priority.test.ts +7 -7
  204. package/src/core/stream/representation/utils/__tests__/push_init_segment.test.ts +103 -60
  205. package/src/core/stream/representation/utils/__tests__/push_media_segment.test.ts +231 -165
  206. package/src/default_config.ts +6 -0
  207. package/src/experimental/README.md +1 -1
  208. package/src/features/README.md +3 -3
  209. package/src/main_thread/api/README.md +6 -7
  210. package/src/main_thread/api/public_api.ts +16 -10
  211. package/src/main_thread/decrypt/README.md +4 -4
  212. package/src/main_thread/decrypt/__tests__/__global__/content_decryptor.test.ts +135 -0
  213. package/src/main_thread/decrypt/__tests__/__global__/get_license.test.ts +70 -0
  214. package/src/main_thread/decrypt/__tests__/__global__/server_certificate.test.ts +44 -0
  215. package/src/main_thread/decrypt/__tests__/__global__/utils.ts +2 -2
  216. package/src/main_thread/decrypt/content_decryptor.ts +6 -1
  217. package/src/main_thread/decrypt/session_events_listener.ts +1 -1
  218. package/src/main_thread/decrypt/set_server_certificate.ts +5 -0
  219. package/src/main_thread/init/media_source_content_initializer.ts +69 -55
  220. package/src/main_thread/init/utils/__tests__/stream_events_emitter.test.ts +175 -0
  221. package/src/main_thread/init/utils/stream_events_emitter/stream_events_emitter.ts +90 -26
  222. package/src/main_thread/render_thumbnail.ts +4 -0
  223. package/src/main_thread/tracks_store/README.md +12 -0
  224. package/src/main_thread/tracks_store/__tests__/media_element_tracks_store.test.ts +25 -18
  225. package/src/main_thread/tracks_store/media_element_tracks_store.ts +1 -0
  226. package/src/main_thread/tracks_store/tracks_store.ts +1 -1
  227. package/src/manifest/classes/__tests__/mocks.ts +202 -0
  228. package/src/parsers/containers/isobmff/__tests__/extract_pssh.test.ts +199 -0
  229. package/src/parsers/containers/isobmff/{take_pssh_out.ts → extract_pssh.ts} +21 -17
  230. package/src/parsers/containers/isobmff/index.ts +2 -2
  231. package/src/parsers/manifest/dash/wasm-parser/README.md +9 -9
  232. package/src/playback_observer/__tests__/mocks.ts +152 -0
  233. package/src/playback_observer/core_playback_observer.ts +4 -4
  234. package/src/playback_observer/media_element_playback_observer.ts +1 -1
  235. package/src/tools/README.md +2 -2
  236. package/src/transports/README.md +5 -5
  237. package/src/transports/dash/segment_parser.ts +2 -2
  238. package/src/transports/local/segment_parser.ts +2 -2
  239. package/src/transports/metaplaylist/README.md +4 -4
  240. package/src/utils/README.md +3 -3
  241. package/src/utils/test-utils.ts +50 -0
  242. package/dist/commonjs/core/entry/synchronize_sinks_on_observation.d.ts +0 -11
  243. package/dist/commonjs/core/entry/synchronize_sinks_on_observation.d.ts.map +0 -1
  244. package/dist/commonjs/core/entry/synchronize_sinks_on_observation.js +0 -20
  245. package/dist/commonjs/parsers/containers/isobmff/take_pssh_out.d.ts.map +0 -1
  246. package/dist/es2017/core/entry/synchronize_sinks_on_observation.d.ts +0 -11
  247. package/dist/es2017/core/entry/synchronize_sinks_on_observation.d.ts.map +0 -1
  248. package/dist/es2017/core/entry/synchronize_sinks_on_observation.js +0 -17
  249. package/dist/es2017/parsers/containers/isobmff/take_pssh_out.d.ts.map +0 -1
  250. package/src/core/adaptive/utils/__tests__/bandwith_estimator.test.ts +0 -117
  251. package/src/core/entry/synchronize_sinks_on_observation.ts +0 -22
@@ -1,7 +1,23 @@
1
1
  import { describe, it, expect, vi, afterEach } from "vitest";
2
- import noop from "../../../utils/noop";
2
+ import type { IAdaptation, IManifest, IRepresentation, IPeriod } from "../../../manifest";
3
+ import {
4
+ DummyManifest,
5
+ DummyPeriod,
6
+ DummyAdaptation,
7
+ DummyRepresentation,
8
+ createSegment,
9
+ } from "../../../manifest/classes/__tests__/mocks";
10
+ import {
11
+ makeReadyOnlyPlaybackObserver,
12
+ DummyObservationPosition,
13
+ } from "../../../playback_observer/__tests__/mocks";
3
14
  import SharedReference from "../../../utils/reference";
4
15
  import TaskCanceller from "../../../utils/task_canceller";
16
+ import type { IBufferType } from "../../segment_sinks";
17
+ import type {
18
+ IAdaptiveRepresentationSelectorArguments,
19
+ IRepresentationEstimatorPlaybackObservation,
20
+ } from "../adaptive_representation_selector";
5
21
  import createAdaptiveRepresentationSelector from "../adaptive_representation_selector";
6
22
  import BufferBasedChooser from "../buffer_based_chooser";
7
23
  import GuessBasedChooser from "../guess_based_chooser";
@@ -11,54 +27,52 @@ import BandwidthEstimator from "../utils/bandwidth_estimator";
11
27
  import PendingRequestsStore from "../utils/pending_requests_store";
12
28
  import RepresentationScoreCalculator from "../utils/representation_score_calculator";
13
29
 
14
- /* eslint-disable @typescript-eslint/no-explicit-any */
15
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
16
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
17
-
18
30
  vi.mock("../../../log", () => ({
19
31
  default: { debug: vi.fn(), warn: vi.fn(), info: vi.fn(), error: vi.fn() },
20
32
  }));
21
33
 
22
- function makeRepresentation(id: string, bitrate: number) {
23
- return { id, bitrate, width: undefined, height: undefined } as any;
24
- }
25
-
26
- function makeObservationPosition(wanted: number) {
27
- return { getWanted: () => wanted } as any;
28
- }
29
-
30
- function makePlaybackObservation(overrides: Partial<any> = {}) {
31
- return {
32
- bufferGap: 0,
33
- position: makeObservationPosition(10),
34
+ /** Dummy object that will be used as the `PlaybackObserver` instance */
35
+ const mockedPlaybackObserver =
36
+ makeReadyOnlyPlaybackObserver<IRepresentationEstimatorPlaybackObservation>({
37
+ bufferGap: 10,
38
+ position: makeObservationPosition(0),
34
39
  speed: 1,
35
- duration: 300,
36
- maximumPosition: 300,
37
- ...overrides,
38
- };
39
- }
40
+ duration: 10000,
41
+ maximumPosition: 10000,
42
+ });
40
43
 
41
- /** Build a minimal playback observer around a single observation value. */
42
- function makePlaybackObserver(obs: any) {
43
- const ref = new SharedReference(obs);
44
+ /**
45
+ * Create a dummy `context` argument as taken by an
46
+ * `AdaptativeRepresentationSelector`.
47
+ */
48
+ function makeContext(
49
+ isDynamic: boolean = false,
50
+ bufferType: IBufferType = "video",
51
+ ): {
52
+ manifest: IManifest;
53
+ adaptation: IAdaptation;
54
+ period: IPeriod;
55
+ } {
44
56
  return {
45
- getReference: () => ref,
46
- listen: vi.fn(
47
- // nothing tests will trigger manually via returned ref if needed
48
- noop,
49
- ),
50
- } as any;
57
+ manifest: new DummyManifest({ isDynamic }),
58
+ period: new DummyPeriod(),
59
+ adaptation: new DummyAdaptation({ type: bufferType }),
60
+ };
51
61
  }
52
62
 
53
- function makeContext(isDynamic = false) {
54
- return {
55
- manifest: { isDynamic },
56
- period: {},
57
- adaptation: { type: "video" as const },
58
- } as any;
63
+ /** Simple util to make a `Representation` with a specific `id` and/or bitrate. */
64
+ function makeRepresentation(id: string = "foo", bitrate: number = 1000): IRepresentation {
65
+ return new DummyRepresentation({
66
+ id,
67
+ bitrate,
68
+ });
59
69
  }
60
70
 
61
- function makeOptions() {
71
+ /**
72
+ * Create default options for the `createAdaptiveRepresentationSelector`
73
+ * function.
74
+ */
75
+ function makeAbrOptions(): IAdaptiveRepresentationSelectorArguments {
62
76
  return {
63
77
  initialBitrates: { video: 1000 },
64
78
  lowLatencyMode: false,
@@ -69,29 +83,50 @@ function makeOptions() {
69
83
  };
70
84
  }
71
85
 
86
+ /** Emit a new playback observation through `mockedPlaybackObserver`. */
87
+ function emitObservation(
88
+ overrides: Partial<IRepresentationEstimatorPlaybackObservation> = {},
89
+ ) {
90
+ mockedPlaybackObserver.emit({
91
+ bufferGap: 0,
92
+ position: makeObservationPosition(10),
93
+ speed: 1,
94
+ duration: 300,
95
+ maximumPosition: 300,
96
+ ...overrides,
97
+ });
98
+ }
99
+
100
+ /** Create the `position` attribute for a playback observation. */
101
+ function makeObservationPosition(wanted: number) {
102
+ return new DummyObservationPosition({
103
+ getWanted: () => wanted,
104
+ });
105
+ }
106
+
72
107
  describe("createAdaptiveRepresentationSelector", () => {
73
108
  afterEach(() => {
74
- vi.restoreAllMocks();
109
+ mockedPlaybackObserver.reset();
110
+ vi.resetAllMocks();
75
111
  });
76
112
 
77
113
  it("returns a function (IRepresentationEstimator)", () => {
78
- const selector = createAdaptiveRepresentationSelector(makeOptions());
114
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
79
115
  expect(typeof selector).toBe("function");
80
116
  });
81
117
 
82
118
  it("should be instantiable", () => {
83
- const selector = createAdaptiveRepresentationSelector(makeOptions());
119
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
84
120
  const rep = makeRepresentation("r1", 500);
85
121
  const canceller = new TaskCanceller("test");
86
122
  const currentRepRef = new SharedReference(null);
87
123
  const repsRef = new SharedReference([rep]);
88
- const obs = makePlaybackObservation({ bufferGap: 0 });
89
- const observer = makePlaybackObserver(obs);
124
+ emitObservation({ bufferGap: 0 });
90
125
  const result = selector(
91
126
  makeContext(),
92
127
  currentRepRef,
93
128
  repsRef,
94
- observer,
129
+ mockedPlaybackObserver.observer,
95
130
  canceller.signal,
96
131
  );
97
132
  expect(result).not.toBeNull();
@@ -100,24 +135,23 @@ describe("createAdaptiveRepresentationSelector", () => {
100
135
 
101
136
  it("reuses the same BandwidthEstimator for the same buffer type across calls", () => {
102
137
  const mockAddSample = vi.spyOn(BandwidthEstimator.prototype, "addSample");
103
- const selector = createAdaptiveRepresentationSelector(makeOptions());
138
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
104
139
  const rep = makeRepresentation("r1", 500);
105
140
  const canceller = new TaskCanceller("test");
106
- const obs = makePlaybackObservation();
107
141
  const ctx = makeContext();
108
142
 
109
143
  const result1 = selector(
110
144
  ctx,
111
145
  new SharedReference(null),
112
146
  new SharedReference([rep]),
113
- makePlaybackObserver(obs),
147
+ mockedPlaybackObserver.observer,
114
148
  canceller.signal,
115
149
  );
116
150
  const result2 = selector(
117
151
  ctx,
118
152
  new SharedReference(null),
119
153
  new SharedReference([rep]),
120
- makePlaybackObserver(obs),
154
+ mockedPlaybackObserver.observer,
121
155
  canceller.signal,
122
156
  );
123
157
 
@@ -126,9 +160,15 @@ describe("createAdaptiveRepresentationSelector", () => {
126
160
  size: 50000,
127
161
  segmentDuration: 4,
128
162
  content: {
163
+ manifest: new DummyManifest(),
164
+ period: new DummyPeriod(),
165
+ adaptation: new DummyAdaptation({ type: "video" }),
129
166
  representation: rep,
130
- adaptation: {} as any,
131
- segment: { isInit: false, complete: true, duration: 4 } as any,
167
+ segment: createSegment({
168
+ isInit: false,
169
+ complete: true,
170
+ duration: 4,
171
+ }),
132
172
  },
133
173
  };
134
174
 
@@ -149,34 +189,25 @@ describe("createAdaptiveRepresentationSelector", () => {
149
189
 
150
190
  it("creates separate BandwidthEstimators for different buffer types", () => {
151
191
  const mockAddSample = vi.spyOn(BandwidthEstimator.prototype, "addSample");
152
- const selector = createAdaptiveRepresentationSelector(makeOptions());
192
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
153
193
  const rep = makeRepresentation("r1", 500);
154
194
  const canceller = new TaskCanceller("test");
155
- const obs = makePlaybackObservation();
156
-
157
- const videoCtx = {
158
- manifest: { isDynamic: false },
159
- period: {},
160
- adaptation: { type: "video" },
161
- } as any;
162
- const audioCtx = {
163
- manifest: { isDynamic: false },
164
- period: {},
165
- adaptation: { type: "audio" },
166
- } as any;
195
+
196
+ const videoCtx = makeContext(false, "video");
197
+ const audioCtx = makeContext(false, "audio");
167
198
 
168
199
  const videoResult = selector(
169
200
  videoCtx,
170
201
  new SharedReference(null),
171
202
  new SharedReference([rep]),
172
- makePlaybackObserver(obs),
203
+ mockedPlaybackObserver.observer,
173
204
  canceller.signal,
174
205
  );
175
206
  const audioResult = selector(
176
207
  audioCtx,
177
208
  new SharedReference(null),
178
209
  new SharedReference([rep]),
179
- makePlaybackObserver(obs),
210
+ mockedPlaybackObserver.observer,
180
211
  canceller.signal,
181
212
  );
182
213
 
@@ -185,9 +216,15 @@ describe("createAdaptiveRepresentationSelector", () => {
185
216
  size: 50000,
186
217
  segmentDuration: 4,
187
218
  content: {
219
+ manifest: new DummyManifest(),
220
+ period: new DummyPeriod(),
221
+ adaptation: new DummyAdaptation({ type: "video" }),
188
222
  representation: rep,
189
- adaptation: {} as any,
190
- segment: { isInit: false, complete: true, duration: 4 } as any,
223
+ segment: createSegment({
224
+ isInit: false,
225
+ complete: true,
226
+ duration: 4,
227
+ }),
191
228
  },
192
229
  };
193
230
 
@@ -206,20 +243,18 @@ describe("createAdaptiveRepresentationSelector", () => {
206
243
 
207
244
  describe("getEstimates (single representation)", () => {
208
245
  it("immediately returns the only representation without bandwidth logic", () => {
209
- const selector = createAdaptiveRepresentationSelector(makeOptions());
246
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
210
247
  const rep = makeRepresentation("r1", 500);
211
248
  const canceller = new TaskCanceller("test");
212
249
 
213
250
  const currentRepRef = new SharedReference(null);
214
251
  const repsRef = new SharedReference([rep]);
215
- const obs = makePlaybackObservation();
216
- const observer = makePlaybackObserver(obs);
217
252
 
218
253
  const { estimates } = selector(
219
254
  makeContext(),
220
255
  currentRepRef,
221
256
  repsRef,
222
- observer,
257
+ mockedPlaybackObserver.observer,
223
258
  canceller.signal,
224
259
  );
225
260
  const estimate = estimates.getValue();
@@ -235,14 +270,14 @@ describe("createAdaptiveRepresentationSelector", () => {
235
270
  describe("getEstimates (multiple representations)", () => {
236
271
  function setupMultiRep(
237
272
  overrides: {
238
- obs?: Partial<any>;
273
+ obs?: Partial<IRepresentationEstimatorPlaybackObservation>;
239
274
  lowLatencyMode?: boolean;
240
275
  isDynamic?: boolean;
241
276
  bitrateChosen?: number;
242
277
  bandwidthEstimate?: number;
243
278
  bufferBasedEstimate?: number | undefined;
244
- guessResult?: any;
245
- currentRep?: any;
279
+ guessResult?: IRepresentation;
280
+ currentRep?: IRepresentation;
246
281
  } = {},
247
282
  ) {
248
283
  const mockGetBandwidthEstimate = vi.spyOn(
@@ -284,18 +319,18 @@ describe("createAdaptiveRepresentationSelector", () => {
284
319
  const canceller = new TaskCanceller("test");
285
320
  const currentRepRef = new SharedReference(currentRep);
286
321
  const repsRef = new SharedReference([repLow, repMid, repHigh]);
287
- const obs = makePlaybackObservation(obsOverrides);
288
- const observer = makePlaybackObserver(obs);
322
+
323
+ emitObservation(obsOverrides);
289
324
 
290
325
  const result = selector(
291
326
  makeContext(isDynamic),
292
327
  currentRepRef,
293
328
  repsRef,
294
- observer,
329
+ mockedPlaybackObserver.observer,
295
330
  canceller.signal,
296
331
  );
297
332
 
298
- return { result, canceller, repLow, repMid, repHigh, obs };
333
+ return { result, canceller, repLow, repMid, repHigh };
299
334
  }
300
335
 
301
336
  it("returns bandwidth-based estimate by default", () => {
@@ -439,17 +474,15 @@ describe("createAdaptiveRepresentationSelector", () => {
439
474
  const currentRep = makeRepresentation("high", 1200);
440
475
  const currentRepRef = new SharedReference(currentRep);
441
476
  const repsRef = new SharedReference([makeRepresentation("low", 100), repHigh]);
442
- const obs = makePlaybackObservation({
477
+ emitObservation({
443
478
  maximumPosition: 50,
444
479
  position: makeObservationPosition(20),
445
480
  });
446
- const observer = makePlaybackObserver(obs);
447
-
448
481
  const { estimates } = selector(
449
482
  makeContext(true),
450
483
  currentRepRef,
451
484
  repsRef,
452
- observer,
485
+ mockedPlaybackObserver.observer,
453
486
  canceller.signal,
454
487
  );
455
488
 
@@ -461,21 +494,19 @@ describe("createAdaptiveRepresentationSelector", () => {
461
494
 
462
495
  describe("callbacks", () => {
463
496
  function getCallbackSetup() {
464
- const selector = createAdaptiveRepresentationSelector(makeOptions());
497
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
465
498
  const repLow = makeRepresentation("low", 300);
466
499
  const repHigh = makeRepresentation("high", 1200);
467
500
 
468
501
  const canceller = new TaskCanceller("test");
469
502
  const currentRepRef = new SharedReference(null);
470
503
  const repsRef = new SharedReference([repLow, repHigh]);
471
- const obs = makePlaybackObservation();
472
- const observer = makePlaybackObserver(obs);
473
504
 
474
505
  const { callbacks } = selector(
475
506
  makeContext(),
476
507
  currentRepRef,
477
508
  repsRef,
478
- observer,
509
+ mockedPlaybackObserver.observer,
479
510
  canceller.signal,
480
511
  );
481
512
 
@@ -490,9 +521,16 @@ describe("createAdaptiveRepresentationSelector", () => {
490
521
  size: 50000,
491
522
  segmentDuration: 4,
492
523
  content: {
493
- representation: makeRepresentation("r", 500),
494
- adaptation: {} as any,
495
- segment: { isInit: false, complete: true, duration: 4 } as any,
524
+ representation: new DummyRepresentation({
525
+ id: "r",
526
+ bitrate: 500,
527
+ }),
528
+ segment: createSegment({
529
+ isInit: false,
530
+ complete: true,
531
+ duration: 4,
532
+ }),
533
+ adaptation: new DummyAdaptation(),
496
534
  },
497
535
  });
498
536
  expect(mockAddSample).toHaveBeenCalledWith(200, 50000);
@@ -511,8 +549,12 @@ describe("createAdaptiveRepresentationSelector", () => {
511
549
  segmentDuration: undefined,
512
550
  content: {
513
551
  representation: makeRepresentation("r", 500),
514
- adaptation: {} as any,
515
- segment: { isInit: true, complete: false, duration: 0 } as any,
552
+ adaptation: new DummyAdaptation(),
553
+ segment: createSegment({
554
+ isInit: true,
555
+ complete: false,
556
+ duration: 0,
557
+ }),
516
558
  },
517
559
  });
518
560
  expect(mockScoreAddSample).not.toHaveBeenCalled();
@@ -532,8 +574,12 @@ describe("createAdaptiveRepresentationSelector", () => {
532
574
  segmentDuration: 4,
533
575
  content: {
534
576
  representation: rep,
535
- adaptation: {} as any,
536
- segment: { isInit: false, complete: true, duration: 4 } as any,
577
+ adaptation: new DummyAdaptation({}),
578
+ segment: createSegment({
579
+ isInit: false,
580
+ complete: true,
581
+ duration: 4,
582
+ }),
537
583
  },
538
584
  });
539
585
  expect(mockScoreAddSample).toHaveBeenCalledWith(rep, 0.2, 4);
@@ -543,7 +589,16 @@ describe("createAdaptiveRepresentationSelector", () => {
543
589
  it("requestBegin callback delegates to requestsStore.add", () => {
544
590
  const mockRequestAdd = vi.spyOn(PendingRequestsStore.prototype, "add");
545
591
  const { callbacks, canceller } = getCallbackSetup();
546
- const payload = { id: "req1", time: 0, requestTimestamp: 0, content: {} } as any;
592
+ const payload = {
593
+ id: "req1",
594
+ time: 0,
595
+ requestTimestamp: 0,
596
+ content: {
597
+ ...makeContext(),
598
+ representation: makeRepresentation(),
599
+ segment: createSegment(),
600
+ },
601
+ };
547
602
  callbacks.requestBegin(payload);
548
603
  expect(mockRequestAdd).toHaveBeenCalledWith(payload);
549
604
  canceller.cancel("done");
@@ -555,7 +610,16 @@ describe("createAdaptiveRepresentationSelector", () => {
555
610
  "addProgress",
556
611
  );
557
612
  const { callbacks, canceller } = getCallbackSetup();
558
- const payloadAdd = { id: "req1", time: 0, requestTimestamp: 0, content: {} as any };
613
+ const payloadAdd = {
614
+ id: "req1",
615
+ time: 0,
616
+ requestTimestamp: 0,
617
+ content: {
618
+ ...makeContext(),
619
+ representation: makeRepresentation(),
620
+ segment: createSegment(),
621
+ },
622
+ };
559
623
  const payloadProgress = {
560
624
  id: "req1",
561
625
  size: 1000,
@@ -572,7 +636,16 @@ describe("createAdaptiveRepresentationSelector", () => {
572
636
  it("requestEnd callback delegates to requestsStore.remove", () => {
573
637
  const mockRequestRemove = vi.spyOn(PendingRequestsStore.prototype, "remove");
574
638
  const { callbacks, canceller } = getCallbackSetup();
575
- const payloadAdd = { id: "req1", time: 0, requestTimestamp: 0, content: {} as any };
639
+ const payloadAdd = {
640
+ id: "req1",
641
+ time: 0,
642
+ requestTimestamp: 0,
643
+ content: {
644
+ ...makeContext(),
645
+ representation: makeRepresentation(),
646
+ segment: createSegment(),
647
+ },
648
+ };
576
649
  callbacks.requestBegin(payloadAdd);
577
650
  callbacks.requestEnd({ id: "req1" });
578
651
  expect(mockRequestRemove).toHaveBeenCalledWith("req1");
@@ -605,7 +678,7 @@ describe("createAdaptiveRepresentationSelector", () => {
605
678
  "getBandwidthEstimate",
606
679
  );
607
680
  mockGetLastStableRepresentation.mockReturnValue(null);
608
- const selector = createAdaptiveRepresentationSelector(makeOptions());
681
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
609
682
  const reps = [makeRepresentation("low", 300), makeRepresentation("high", 900)];
610
683
  mockGetBandwidthEstimate.mockReturnValue({
611
684
  bandwidthEstimate: 800,
@@ -617,7 +690,7 @@ describe("createAdaptiveRepresentationSelector", () => {
617
690
  makeContext(),
618
691
  new SharedReference(null),
619
692
  new SharedReference(reps),
620
- makePlaybackObserver(makePlaybackObservation()),
693
+ mockedPlaybackObserver.observer,
621
694
  canceller.signal,
622
695
  );
623
696
 
@@ -636,7 +709,7 @@ describe("createAdaptiveRepresentationSelector", () => {
636
709
  );
637
710
  const stableRep = makeRepresentation("stable", 600);
638
711
  mockGetLastStableRepresentation.mockReturnValue(stableRep);
639
- const selector = createAdaptiveRepresentationSelector(makeOptions());
712
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
640
713
  const reps = [makeRepresentation("low", 300), makeRepresentation("high", 900)];
641
714
  mockGetBandwidthEstimate.mockReturnValue({
642
715
  bandwidthEstimate: 800,
@@ -644,11 +717,12 @@ describe("createAdaptiveRepresentationSelector", () => {
644
717
  });
645
718
 
646
719
  const canceller = new TaskCanceller("test");
720
+ emitObservation({ speed: 2 });
647
721
  const { estimates } = selector(
648
722
  makeContext(),
649
723
  new SharedReference(null),
650
724
  new SharedReference(reps),
651
- makePlaybackObserver(makePlaybackObservation({ speed: 2 })),
725
+ mockedPlaybackObserver.observer,
652
726
  canceller.signal,
653
727
  );
654
728
 
@@ -668,7 +742,7 @@ describe("createAdaptiveRepresentationSelector", () => {
668
742
  );
669
743
  const stableRep = makeRepresentation("stable", 600);
670
744
  mockGetLastStableRepresentation.mockReturnValue(stableRep);
671
- const selector = createAdaptiveRepresentationSelector(makeOptions());
745
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
672
746
  const reps = [makeRepresentation("low", 300), makeRepresentation("high", 900)];
673
747
  mockGetBandwidthEstimate.mockReturnValue({
674
748
  bandwidthEstimate: 800,
@@ -676,11 +750,12 @@ describe("createAdaptiveRepresentationSelector", () => {
676
750
  });
677
751
 
678
752
  const canceller = new TaskCanceller("test");
753
+ emitObservation({ speed: 0 });
679
754
  const { estimates } = selector(
680
755
  makeContext(),
681
756
  new SharedReference(null),
682
757
  new SharedReference(reps),
683
- makePlaybackObserver(makePlaybackObservation({ speed: 0 })),
758
+ mockedPlaybackObserver.observer,
684
759
  canceller.signal,
685
760
  );
686
761
 
@@ -695,7 +770,7 @@ describe("createAdaptiveRepresentationSelector", () => {
695
770
  NetworkAnalyzer.prototype,
696
771
  "getBandwidthEstimate",
697
772
  );
698
- const selector = createAdaptiveRepresentationSelector(makeOptions());
773
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
699
774
  const repLow = makeRepresentation("low", 300);
700
775
  const repHigh = makeRepresentation("high", 1200);
701
776
  mockGetBandwidthEstimate.mockReturnValue({
@@ -706,14 +781,12 @@ describe("createAdaptiveRepresentationSelector", () => {
706
781
  const canceller = new TaskCanceller("test");
707
782
  const currentRepRef = new SharedReference(null);
708
783
  const repsRef = new SharedReference([repLow]);
709
- const obs = makePlaybackObservation();
710
- const observer = makePlaybackObserver(obs);
711
784
 
712
785
  const { estimates } = selector(
713
786
  makeContext(),
714
787
  currentRepRef,
715
788
  repsRef,
716
- observer,
789
+ mockedPlaybackObserver.observer,
717
790
  canceller.signal,
718
791
  );
719
792
 
@@ -741,7 +814,7 @@ describe("createAdaptiveRepresentationSelector", () => {
741
814
  NetworkAnalyzer.prototype,
742
815
  "getBandwidthEstimate",
743
816
  );
744
- const selector = createAdaptiveRepresentationSelector(makeOptions());
817
+ const selector = createAdaptiveRepresentationSelector(makeAbrOptions());
745
818
  const rep = makeRepresentation("r1", 500);
746
819
  mockGetBandwidthEstimate.mockReturnValue({
747
820
  bandwidthEstimate: 800,
@@ -751,14 +824,12 @@ describe("createAdaptiveRepresentationSelector", () => {
751
824
  const canceller = new TaskCanceller("test");
752
825
  const currentRepRef = new SharedReference(null);
753
826
  const repsRef = new SharedReference([rep]);
754
- const obs = makePlaybackObservation();
755
- const observer = makePlaybackObserver(obs);
756
827
 
757
828
  const { estimates } = selector(
758
829
  makeContext(),
759
830
  currentRepRef,
760
831
  repsRef,
761
- observer,
832
+ mockedPlaybackObserver.observer,
762
833
  canceller.signal,
763
834
  );
764
835
  const valueBefore = estimates.getValue();