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
@@ -22,20 +22,47 @@ import {
22
22
  IParsedRepresentation,
23
23
  } from "../parsers/manifest";
24
24
  import {
25
+ IAudioRepresentation,
25
26
  ITrackType,
26
27
  IHDRInformation,
28
+ IVideoRepresentation,
27
29
  } from "../public_types";
28
30
  import areArraysOfNumbersEqual from "../utils/are_arrays_of_numbers_equal";
31
+ import idGenerator from "../utils/id_generator";
29
32
  import { IRepresentationIndex } from "./representation_index";
30
33
 
34
+ const generateRepresentationUniqueId = idGenerator();
35
+
31
36
  /**
32
37
  * Normalized Representation structure.
33
38
  * @class Representation
34
39
  */
35
40
  class Representation {
36
- /** ID uniquely identifying the Representation in the Adaptation. */
41
+ /**
42
+ * ID uniquely identifying the `Representation` in its parent `Adaptation`.
43
+ *
44
+ * This identifier might be linked to an identifier present in the original
45
+ * Manifest file, it is thus the identifier to use to determine if a
46
+ * `Representation` from a refreshed `Manifest` is actually the same one than
47
+ * one in the previously loaded Manifest (as long as the `Adaptation` and
48
+ * `Period` are also the same).
49
+ *
50
+ * For a globally unique identifier regardless of the `Adaptation`, `Period`
51
+ * or even `Manifest`, you can rely on `uniqueId` instead.
52
+ */
37
53
  public readonly id : string;
38
54
 
55
+ /**
56
+ * Globally unique identifier for this `Representation` object.
57
+ *
58
+ * This identifier is guaranteed to be unique for any `Representation`s of all
59
+ * `Manifest` objects created in the current JS Realm.
60
+ * As such, it can be used as an identifier for the JS object itself, whereas
61
+ * `id` is the identifier for the original Manifest's Representation in the
62
+ * scope of its parent `Adaptation`.
63
+ */
64
+ public readonly uniqueId : string;
65
+
39
66
  /**
40
67
  * Interface allowing to get information about segments available for this
41
68
  * Representation.
@@ -115,6 +142,7 @@ class Representation {
115
142
  */
116
143
  constructor(args : IParsedRepresentation, opts : { type : ITrackType }) {
117
144
  this.id = args.id;
145
+ this.uniqueId = generateRepresentationUniqueId();
118
146
  this.bitrate = args.bitrate;
119
147
  this.codec = args.codecs;
120
148
 
@@ -145,10 +173,16 @@ class Representation {
145
173
  this.cdnMetadata = args.cdnMetadata;
146
174
 
147
175
  this.index = args.index;
148
- this.isSupported = opts.type === "audio" ||
149
- opts.type === "video" ?
150
- isCodecSupported(this.getMimeTypeString()) :
151
- true; // TODO for other types
176
+ if (opts.type === "audio" || opts.type === "video") {
177
+ const mimeTypeStr = this.getMimeTypeString();
178
+ const isSupported = isCodecSupported(mimeTypeStr);
179
+ if (!isSupported) {
180
+ log.info("Unsupported Representation", mimeTypeStr, this.id, this.bitrate);
181
+ }
182
+ this.isSupported = isSupported;
183
+ } else {
184
+ this.isSupported = true; // TODO for other types
185
+ }
152
186
  }
153
187
 
154
188
  /**
@@ -329,6 +363,44 @@ class Representation {
329
363
  return true;
330
364
  }
331
365
 
366
+ /**
367
+ * Format Representation as an `IAudioRepresentation`.
368
+ * @returns {Object}
369
+ */
370
+ public toAudioRepresentation(): IAudioRepresentation {
371
+ const { id, bitrate, codec, isSupported, decipherable } = this;
372
+ return { id,
373
+ bitrate,
374
+ codec,
375
+ isCodecSupported: isSupported,
376
+ seemsDecipherable: decipherable };
377
+ }
378
+
379
+ /**
380
+ * Format Representation as an `IVideoRepresentation`.
381
+ * @returns {Object}
382
+ */
383
+ public toVideoRepresentation(): IVideoRepresentation {
384
+ const { id,
385
+ bitrate,
386
+ frameRate,
387
+ width,
388
+ height,
389
+ codec,
390
+ hdrInfo,
391
+ isSupported,
392
+ decipherable } = this;
393
+ return { id,
394
+ bitrate,
395
+ frameRate,
396
+ width,
397
+ height,
398
+ codec,
399
+ hdrInfo,
400
+ isCodecSupported: isSupported,
401
+ seemsDecipherable: decipherable };
402
+ }
403
+
332
404
  /**
333
405
  * Returns `true` if this Representation can be played (that is: not
334
406
  * undecipherable and with a supported codec).
@@ -37,9 +37,7 @@ export function areSameContent(
37
37
  content2: IBufferedChunkInfos
38
38
  ): boolean {
39
39
  return (content1.segment.id === content2.segment.id &&
40
- content1.representation.id === content2.representation.id &&
41
- content1.adaptation.id === content2.adaptation.id &&
42
- content1.period.id === content2.period.id);
40
+ content1.representation.uniqueId === content2.representation.uniqueId);
43
41
  }
44
42
 
45
43
  /**
@@ -270,15 +270,6 @@ export default function parseAdaptationSets(
270
270
 
271
271
  const parsedAdaptationsIDs : string[] = [];
272
272
 
273
- /**
274
- * Index of the last parsed Video AdaptationSet with a Role set as "main" in
275
- * `parsedAdaptations.video`.
276
- * `-1` if not yet encountered.
277
- * Used as we merge all main video AdaptationSet due to a comprehension of the
278
- * DASH-IF IOP.
279
- */
280
- let lastMainVideoAdapIdx = -1;
281
-
282
273
  for (let adaptationIdx = 0; adaptationIdx < adaptationsIR.length; adaptationIdx++) {
283
274
  const adaptation = adaptationsIR[adaptationIdx];
284
275
  const adaptationChildren = adaptation.children;
@@ -315,7 +306,6 @@ export default function parseAdaptationSets(
315
306
 
316
307
  const priority = adaptation.attributes.selectionPriority ?? 1;
317
308
  const originalID = adaptation.attributes.id;
318
- let newID : string;
319
309
  const adaptationSetSwitchingIDs = getAdaptationSetSwitchingIDs(adaptation);
320
310
  const parentSegmentTemplates = [];
321
311
  if (context.segmentTemplate !== undefined) {
@@ -354,161 +344,136 @@ export default function parseAdaptationSets(
354
344
 
355
345
  const isTrickModeTrack = trickModeAttachedAdaptationIds !== undefined;
356
346
 
357
- if (type === "video" &&
358
- isMainAdaptation &&
359
- lastMainVideoAdapIdx >= 0 &&
360
- parsedAdaptations.video.length > lastMainVideoAdapIdx &&
361
- !isTrickModeTrack)
347
+ const { accessibilities } = adaptationChildren;
348
+
349
+ let isDub : boolean|undefined;
350
+ if (roles !== undefined &&
351
+ roles.some((role) => role.value === "dub"))
362
352
  {
363
- const videoMainAdaptation = parsedAdaptations.video[lastMainVideoAdapIdx][0];
364
- reprCtxt.unsafelyBaseOnPreviousAdaptation = context
365
- .unsafelyBaseOnPreviousPeriod?.getAdaptation(videoMainAdaptation.id) ?? null;
366
- const representations = parseRepresentations(representationsIR,
367
- adaptation,
368
- reprCtxt);
369
- videoMainAdaptation.representations.push(...representations);
370
- newID = videoMainAdaptation.id;
371
- } else {
372
- const { accessibilities } = adaptationChildren;
353
+ isDub = true;
354
+ }
373
355
 
374
- let isDub : boolean|undefined;
375
- if (roles !== undefined &&
376
- roles.some((role) => role.value === "dub"))
377
- {
378
- isDub = true;
379
- }
356
+ let isClosedCaption;
357
+ if (type !== "text") {
358
+ isClosedCaption = false;
359
+ } else {
360
+ isClosedCaption = isCaptionning(accessibilities, roles);
361
+ }
380
362
 
381
- let isClosedCaption;
382
- if (type !== "text") {
383
- isClosedCaption = false;
384
- } else {
385
- isClosedCaption = isCaptionning(accessibilities, roles);
386
- }
363
+ let isForcedSubtitle;
364
+ if (type === "text" &&
365
+ roles !== undefined &&
366
+ roles.some((role) => role.value === "forced-subtitle" ||
367
+ role.value === "forced_subtitle"))
368
+ {
369
+ isForcedSubtitle = true;
370
+ }
387
371
 
388
- let isForcedSubtitle;
389
- if (type === "text" &&
390
- roles !== undefined &&
391
- roles.some((role) => role.value === "forced-subtitle" ||
392
- role.value === "forced_subtitle"))
393
- {
394
- isForcedSubtitle = true;
395
- }
372
+ let isAudioDescription;
373
+ if (type !== "audio") {
374
+ isAudioDescription = false;
375
+ } else if (accessibilities !== undefined) {
376
+ isAudioDescription = accessibilities.some(isVisuallyImpaired);
377
+ }
396
378
 
397
- let isAudioDescription;
398
- if (type !== "audio") {
399
- isAudioDescription = false;
400
- } else if (accessibilities !== undefined) {
401
- isAudioDescription = accessibilities.some(isVisuallyImpaired);
402
- }
379
+ let isSignInterpreted;
380
+ if (type !== "video") {
381
+ isSignInterpreted = false;
382
+ } else if (accessibilities !== undefined) {
383
+ isSignInterpreted = accessibilities.some(hasSignLanguageInterpretation);
384
+ }
403
385
 
404
- let isSignInterpreted;
405
- if (type !== "video") {
406
- isSignInterpreted = false;
407
- } else if (accessibilities !== undefined) {
408
- isSignInterpreted = accessibilities.some(hasSignLanguageInterpretation);
409
- }
386
+ let adaptationID = getAdaptationID(adaptation,
387
+ { isAudioDescription,
388
+ isForcedSubtitle,
389
+ isClosedCaption,
390
+ isSignInterpreted,
391
+ isTrickModeTrack,
392
+ type });
393
+
394
+ // Avoid duplicate IDs
395
+ while (arrayIncludes(parsedAdaptationsIDs, adaptationID)) {
396
+ adaptationID += "-dup";
397
+ }
410
398
 
411
- let adaptationID = getAdaptationID(adaptation,
412
- { isAudioDescription,
413
- isForcedSubtitle,
414
- isClosedCaption,
415
- isSignInterpreted,
416
- isTrickModeTrack,
417
- type });
418
-
419
- // Avoid duplicate IDs
420
- while (arrayIncludes(parsedAdaptationsIDs, adaptationID)) {
421
- adaptationID += "-dup";
422
- }
399
+ const newID = adaptationID;
400
+ parsedAdaptationsIDs.push(adaptationID);
401
+
402
+ reprCtxt.unsafelyBaseOnPreviousAdaptation = context
403
+ .unsafelyBaseOnPreviousPeriod?.getAdaptation(adaptationID) ?? null;
404
+
405
+ const representations = parseRepresentations(representationsIR,
406
+ adaptation,
407
+ reprCtxt);
408
+ const parsedAdaptationSet : IParsedAdaptation =
409
+ { id: adaptationID,
410
+ representations,
411
+ type,
412
+ isTrickModeTrack };
413
+ if (adaptation.attributes.language != null) {
414
+ parsedAdaptationSet.language = adaptation.attributes.language;
415
+ }
416
+ if (isClosedCaption != null) {
417
+ parsedAdaptationSet.closedCaption = isClosedCaption;
418
+ }
419
+ if (isAudioDescription != null) {
420
+ parsedAdaptationSet.audioDescription = isAudioDescription;
421
+ }
422
+ if (isDub === true) {
423
+ parsedAdaptationSet.isDub = true;
424
+ }
425
+ if (isForcedSubtitle !== undefined) {
426
+ parsedAdaptationSet.forcedSubtitles = isForcedSubtitle;
427
+ }
428
+ if (isSignInterpreted === true) {
429
+ parsedAdaptationSet.isSignInterpreted = true;
430
+ }
423
431
 
424
- newID = adaptationID;
425
- parsedAdaptationsIDs.push(adaptationID);
426
-
427
- reprCtxt.unsafelyBaseOnPreviousAdaptation = context
428
- .unsafelyBaseOnPreviousPeriod?.getAdaptation(adaptationID) ?? null;
429
-
430
- const representations = parseRepresentations(representationsIR,
431
- adaptation,
432
- reprCtxt);
433
- const parsedAdaptationSet : IParsedAdaptation =
434
- { id: adaptationID,
435
- representations,
436
- type,
437
- isTrickModeTrack };
438
- if (adaptation.attributes.language != null) {
439
- parsedAdaptationSet.language = adaptation.attributes.language;
440
- }
441
- if (isClosedCaption != null) {
442
- parsedAdaptationSet.closedCaption = isClosedCaption;
443
- }
444
- if (isAudioDescription != null) {
445
- parsedAdaptationSet.audioDescription = isAudioDescription;
446
- }
447
- if (isDub === true) {
448
- parsedAdaptationSet.isDub = true;
449
- }
450
- if (isForcedSubtitle !== undefined) {
451
- parsedAdaptationSet.forcedSubtitles = isForcedSubtitle;
452
- }
453
- if (isSignInterpreted === true) {
454
- parsedAdaptationSet.isSignInterpreted = true;
455
- }
432
+ if (label !== undefined) {
433
+ parsedAdaptationSet.label = label;
434
+ }
456
435
 
457
- if (label !== undefined) {
458
- parsedAdaptationSet.label = label;
459
- }
436
+ if (trickModeAttachedAdaptationIds !== undefined) {
437
+ trickModeAdaptations.push({ adaptation: parsedAdaptationSet,
438
+ trickModeAttachedAdaptationIds });
439
+ } else {
460
440
 
461
- if (trickModeAttachedAdaptationIds !== undefined) {
462
- trickModeAdaptations.push({ adaptation: parsedAdaptationSet,
463
- trickModeAttachedAdaptationIds });
464
- } else {
465
-
466
- // look if we have to merge this into another Adaptation
467
- let mergedIntoIdx = -1;
468
- for (const id of adaptationSetSwitchingIDs) {
469
- const switchingInfos = adaptationSwitchingInfos[id];
470
- if (switchingInfos !== undefined &&
471
- switchingInfos.newID !== newID &&
472
- arrayIncludes(switchingInfos.adaptationSetSwitchingIDs, originalID))
441
+ // look if we have to merge this into another Adaptation
442
+ let mergedIntoIdx = -1;
443
+ for (const id of adaptationSetSwitchingIDs) {
444
+ const switchingInfos = adaptationSwitchingInfos[id];
445
+ if (switchingInfos !== undefined &&
446
+ switchingInfos.newID !== newID &&
447
+ arrayIncludes(switchingInfos.adaptationSetSwitchingIDs, originalID))
448
+ {
449
+ mergedIntoIdx = arrayFindIndex(parsedAdaptations[type],
450
+ (a) => a[0].id === id);
451
+ const mergedInto = parsedAdaptations[type][mergedIntoIdx];
452
+ if (mergedInto !== undefined &&
453
+ mergedInto[0].audioDescription ===
454
+ parsedAdaptationSet.audioDescription &&
455
+ mergedInto[0].closedCaption ===
456
+ parsedAdaptationSet.closedCaption &&
457
+ mergedInto[0].language === parsedAdaptationSet.language)
473
458
  {
474
- mergedIntoIdx = arrayFindIndex(parsedAdaptations[type],
475
- (a) => a[0].id === id);
476
- const mergedInto = parsedAdaptations[type][mergedIntoIdx];
477
- if (mergedInto !== undefined &&
478
- mergedInto[0].audioDescription ===
479
- parsedAdaptationSet.audioDescription &&
480
- mergedInto[0].closedCaption ===
481
- parsedAdaptationSet.closedCaption &&
482
- mergedInto[0].language === parsedAdaptationSet.language)
483
- {
484
- log.info("DASH Parser: merging \"switchable\" AdaptationSets",
485
- originalID, id);
486
- mergedInto[0].representations.push(...parsedAdaptationSet.representations);
487
- if (type === "video" &&
488
- isMainAdaptation &&
489
- !mergedInto[1].isMainAdaptation)
490
- {
491
- lastMainVideoAdapIdx = Math.max(lastMainVideoAdapIdx, mergedIntoIdx);
492
- }
493
- mergedInto[1] = {
494
- priority: Math.max(priority, mergedInto[1].priority),
495
- isMainAdaptation: isMainAdaptation ||
496
- mergedInto[1].isMainAdaptation,
497
- indexInMpd: Math.min(adaptationIdx, mergedInto[1].indexInMpd),
498
- };
499
- }
459
+ log.info("DASH Parser: merging \"switchable\" AdaptationSets",
460
+ originalID, id);
461
+ mergedInto[0].representations.push(...parsedAdaptationSet.representations);
462
+ mergedInto[1] = {
463
+ priority: Math.max(priority, mergedInto[1].priority),
464
+ isMainAdaptation: isMainAdaptation ||
465
+ mergedInto[1].isMainAdaptation,
466
+ indexInMpd: Math.min(adaptationIdx, mergedInto[1].indexInMpd),
467
+ };
500
468
  }
501
469
  }
470
+ }
502
471
 
503
- if (mergedIntoIdx < 0) {
504
- parsedAdaptations[type].push([ parsedAdaptationSet,
505
- { priority,
506
- isMainAdaptation,
507
- indexInMpd: adaptationIdx }]);
508
- if (type === "video" && isMainAdaptation) {
509
- lastMainVideoAdapIdx = parsedAdaptations.video.length - 1;
510
- }
511
- }
472
+ if (mergedIntoIdx < 0) {
473
+ parsedAdaptations[type].push([ parsedAdaptationSet,
474
+ { priority,
475
+ isMainAdaptation,
476
+ indexInMpd: adaptationIdx }]);
512
477
  }
513
478
  }
514
479
 
@@ -66,16 +66,17 @@ function combineInbandEventStreams(
66
66
  */
67
67
  function getHDRInformation(
68
68
  { adaptationProfiles,
69
+ essentialProperties,
70
+ supplementalProperties,
69
71
  manifestProfiles,
70
72
  codecs,
71
73
  }: { adaptationProfiles?: string | undefined;
74
+ essentialProperties? : IScheme[] | undefined;
75
+ supplementalProperties? : IScheme[] | undefined;
72
76
  manifestProfiles?: string | undefined;
73
77
  codecs?: string | undefined; }
74
78
  ): undefined | IHDRInformation {
75
79
  const profiles = (adaptationProfiles ?? "") + (manifestProfiles ?? "");
76
- if (codecs === undefined) {
77
- return undefined;
78
- }
79
80
  if (
80
81
  profiles.indexOf(
81
82
  "http://dashif.org/guidelines/dash-if-uhd#hevc-hdr-pq10") !== -1
@@ -87,7 +88,20 @@ function getHDRInformation(
87
88
  colorSpace: "rec2020" };
88
89
  }
89
90
  }
90
- if (/^vp(08|09|10)/.exec(codecs)) {
91
+ const transferCharacteristicScheme = arrayFind(
92
+ [...(essentialProperties ?? []), ...(supplementalProperties ?? [])],
93
+ (p) => p.schemeIdUri === "urn:mpeg:mpegB:cicp:TransferCharacteristics");
94
+ if (transferCharacteristicScheme !== undefined) {
95
+ switch (transferCharacteristicScheme.value) {
96
+ case "15":
97
+ return undefined; // SDR
98
+ case "16":
99
+ return { eotf: "pq" };
100
+ case "18":
101
+ return { eotf: "hlg" };
102
+ }
103
+ }
104
+ if (codecs !== undefined && /^vp(08|09|10)/.exec(codecs)) {
91
105
  return getWEBMHDRInformation(codecs);
92
106
  }
93
107
  }
@@ -273,6 +287,9 @@ export default function parseRepresentations(
273
287
 
274
288
  parsedRepresentation.hdrInfo =
275
289
  getHDRInformation({ adaptationProfiles: adaptation.attributes.profiles,
290
+ supplementalProperties: adaptation.children
291
+ .supplementalProperties,
292
+ essentialProperties: adaptation.children.essentialProperties,
276
293
  manifestProfiles: context.manifestProfiles,
277
294
  codecs });
278
295
 
@@ -32,7 +32,7 @@ import {
32
32
 
33
33
  /**
34
34
  * Parse MPD through the JS parser, on a `Document` instance.
35
- * @param {Document} manifest - Original manifest as returned by the server
35
+ * @param {Document} document - Original manifest as returned by the server
36
36
  * @param {Object} args - Various parsing options and information.
37
37
  * @returns {Object} - Response returned by the DASH-JS parser.
38
38
  */
@@ -199,6 +199,7 @@ export default class DashWasmParser {
199
199
  "Unknown error";
200
200
  log.warn("DW: Could not create DASH-WASM parser:", message);
201
201
  this.status = "failure";
202
+ throw err;
202
203
  });
203
204
 
204
205
  return this._initProm;
@@ -95,7 +95,7 @@ export default function parseTTMLString(
95
95
 
96
96
  if (xml !== null && xml !== undefined) {
97
97
  const tts = xml.getElementsByTagName("tt");
98
- let tt = tts[0];
98
+ let tt: Element = tts[0];
99
99
  if (tt === undefined) {
100
100
  // EBU-TT sometimes namespaces tt, by "tt:"
101
101
  // Just catch all namespaces to play it safe
@@ -22,6 +22,7 @@ import {
22
22
  IPersistentSessionInfoV4,
23
23
  } from "./core/decrypt";
24
24
  import {
25
+ IMediaErrorTrackContext,
25
26
  EncryptedMediaError,
26
27
  MediaError,
27
28
  NetworkError,
@@ -31,6 +32,8 @@ import Manifest from "./manifest";
31
32
  import { ILocalManifest } from "./parsers/manifest/local";
32
33
  import { IMetaPlaylist } from "./parsers/manifest/metaplaylist/metaplaylist_parser";
33
34
 
35
+ export { IMediaErrorTrackContext };
36
+
34
37
  /**
35
38
  * This file defines and exports types we want to expose to library users.
36
39
  * Those types are considered as part of the API.
@@ -693,6 +696,8 @@ export interface IAudioRepresentation {
693
696
  id : string|number;
694
697
  bitrate? : number | undefined;
695
698
  codec? : string | undefined;
699
+ isCodecSupported? : boolean | undefined;
700
+ seemsDecipherable? : boolean | undefined;
696
701
  }
697
702
 
698
703
  /** Audio track returned by the RxPlayer. */
@@ -720,7 +725,7 @@ export interface ITextTrack {
720
725
  * Kept equal to `language` if the attempt failed.
721
726
  */
722
727
  normalized : string;
723
- forced? : boolean | undefined;
728
+ forced : boolean | undefined;
724
729
  closedCaption : boolean;
725
730
  label? : string | undefined;
726
731
  id : number|string;
@@ -738,6 +743,8 @@ export interface IVideoRepresentation {
738
743
  codec? : string | undefined;
739
744
  frameRate? : number | undefined;
740
745
  hdrInfo?: IHDRInformation | undefined;
746
+ isCodecSupported? : boolean | undefined;
747
+ seemsDecipherable? : boolean | undefined;
741
748
  }
742
749
 
743
750
  /** Video track returned by the RxPlayer. */
@@ -916,6 +923,14 @@ export interface ITrackUpdateEventPayload {
916
923
  "manual" | // Manually and explicitely updated
917
924
  "trickmode-enabled" | // Video trickmode tracks being enabled
918
925
  "trickmode-disabled" | // Video trickmode tracks being disabled
926
+ "no-playable-representation" | // Previous track had no playable Representation
927
+ string;
928
+ }
929
+
930
+ export interface IRepresentationListUpdateContext {
931
+ period : IPeriod;
932
+ trackType : ITrackType;
933
+ reason : "decipherability-update" |
919
934
  string;
920
935
  }
921
936
 
@@ -79,7 +79,7 @@ export default class TextTrackRenderer {
79
79
  args.timeOffset :
80
80
  0;
81
81
  this._segmentBuffer.pushChunkSync({ inventoryInfos: null,
82
- data: { initSegment: null,
82
+ data: { initSegmentUniqueId: null,
83
83
  codec: args.type,
84
84
  timestampOffset,
85
85
  appendWindow: [0, Infinity],
@@ -31,11 +31,9 @@ export default function addSegmentIntegrityChecks<T>(
31
31
  ) : ISegmentLoader<T> {
32
32
  return (url, context, loaderOptions, initialCancelSignal, callbacks) => {
33
33
  return new Promise((resolve, reject) => {
34
- const requestCanceller = new TaskCanceller({ cancelOn: initialCancelSignal });
35
-
36
- // Reject the `CancellationError` when `requestCanceller`'s signal emits
37
- // `stopRejectingOnCancel` here is a function allowing to stop this mechanism
38
- const stopRejectingOnCancel = requestCanceller.signal.register(reject);
34
+ const requestCanceller = new TaskCanceller();
35
+ const unlinkCanceller = requestCanceller.linkToSignal(initialCancelSignal);
36
+ requestCanceller.signal.register(reject);
39
37
 
40
38
  segmentLoader(url, context, loaderOptions, requestCanceller.signal, {
41
39
  ...callbacks,
@@ -45,31 +43,42 @@ export default function addSegmentIntegrityChecks<T>(
45
43
  callbacks.onNewChunk(data);
46
44
  } catch (err) {
47
45
  // Do not reject with a `CancellationError` after cancelling the request
48
- stopRejectingOnCancel();
46
+ cleanUpCancellers();
47
+
49
48
  // Cancel the request
50
49
  requestCanceller.cancel();
50
+
51
51
  // Reject with thrown error
52
52
  reject(err);
53
53
  }
54
54
  },
55
- }).then((info) => {
56
- if (requestCanceller.isUsed) {
57
- return;
58
- }
59
- stopRejectingOnCancel();
60
- if (info.resultType === "segment-loaded") {
61
- try {
62
- trowOnIntegrityError(info.resultData.responseData);
63
- } catch (err) {
55
+ })
56
+ .then(
57
+ (info) => {
58
+ cleanUpCancellers();
59
+ if (requestCanceller.isUsed()) {
60
+ return;
61
+ }
62
+ if (info.resultType === "segment-loaded") {
63
+ try {
64
+ trowOnIntegrityError(info.resultData.responseData);
65
+ } catch (err) {
66
+ reject(err);
67
+ return;
68
+ }
69
+ }
70
+ resolve(info);
71
+ },
72
+ (err : unknown) => {
73
+ cleanUpCancellers();
64
74
  reject(err);
65
- return;
66
75
  }
67
- }
68
- resolve(info);
69
- }, (error : unknown) => {
70
- stopRejectingOnCancel();
71
- reject(error);
72
- });
76
+ );
77
+
78
+ function cleanUpCancellers() {
79
+ requestCanceller.signal.deregister(reject);
80
+ unlinkCanceller();
81
+ }
73
82
  });
74
83
 
75
84
  /**