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
@@ -141,9 +141,9 @@ export default function StreamOrchestrator(
141
141
  });
142
142
 
143
143
  // Create automatically the right `PeriodStream` for every possible types
144
- segmentBuffersStore.getBufferTypes().map((bufferType) => {
144
+ for (const bufferType of segmentBuffersStore.getBufferTypes()) {
145
145
  manageEveryStreams(bufferType, initialPeriod);
146
- });
146
+ }
147
147
 
148
148
  /**
149
149
  * Manage creation and removal of Streams for every Periods for a given type.
@@ -168,7 +168,8 @@ export default function StreamOrchestrator(
168
168
  let enableOutOfBoundsCheck = false;
169
169
 
170
170
  /** Cancels currently created `PeriodStream`s. */
171
- let currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
171
+ let currentCanceller = new TaskCanceller();
172
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
172
173
 
173
174
  // Restart the current Stream when the wanted time is in another period
174
175
  // than the ones already considered
@@ -187,7 +188,8 @@ export default function StreamOrchestrator(
187
188
  callbacks.periodStreamCleared({ type: bufferType, manifest, period });
188
189
  }
189
190
  currentCanceller.cancel();
190
- currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
191
+ currentCanceller = new TaskCanceller();
192
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
191
193
 
192
194
  const nextPeriod = manifest.getPeriodForTime(time) ??
193
195
  manifest.getNextPeriod(time);
@@ -199,7 +201,13 @@ export default function StreamOrchestrator(
199
201
  }, { clearSignal: orchestratorCancelSignal, includeLastObservation: true });
200
202
 
201
203
  manifest.addEventListener("decipherabilityUpdate", (evt) => {
204
+ if (orchestratorCancelSignal.isCancelled()) {
205
+ return;
206
+ }
202
207
  onDecipherabilityUpdates(evt).catch(err => {
208
+ if (orchestratorCancelSignal.isCancelled()) {
209
+ return;
210
+ }
203
211
  currentCanceller.cancel();
204
212
  callbacks.error(err);
205
213
  });
@@ -276,8 +284,16 @@ export default function StreamOrchestrator(
276
284
  const segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
277
285
  const ofCurrentType = updates
278
286
  .filter(update => update.adaptation.type === bufferType);
279
- if (ofCurrentType.length === 0 || segmentBufferStatus.type !== "initialized") {
280
- return ; // no need to stop the current Streams.
287
+ if (
288
+ // No update concerns the current type of data
289
+ ofCurrentType.length === 0 ||
290
+ segmentBufferStatus.type !== "initialized" ||
291
+ // The update only notifies of now-decipherable streams
292
+ ofCurrentType.every(x => x.representation.decipherable === true)
293
+ ) {
294
+ // Data won't have to be removed from the buffers, no need to stop the
295
+ // current Streams.
296
+ return ;
281
297
  }
282
298
 
283
299
  const segmentBuffer = segmentBufferStatus.value;
@@ -317,7 +333,8 @@ export default function StreamOrchestrator(
317
333
  }
318
334
 
319
335
  currentCanceller.cancel();
320
- currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
336
+ currentCanceller = new TaskCanceller();
337
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
321
338
 
322
339
  /** Remove from the `SegmentBuffer` all the concerned time ranges. */
323
340
  for (const { start, end } of [...undecipherableRanges, ...rangesToRemove]) {
@@ -330,7 +347,7 @@ export default function StreamOrchestrator(
330
347
  // to reduce the risk of race conditions where the next observation
331
348
  // was going to be emitted synchronously.
332
349
  nextTick(() => {
333
- if (orchestratorCancelSignal.isCancelled) {
350
+ if (orchestratorCancelSignal.isCancelled()) {
334
351
  return ;
335
352
  }
336
353
  const observation = playbackObserver.getReference().getValue();
@@ -340,12 +357,12 @@ export default function StreamOrchestrator(
340
357
  callbacks.needsDecipherabilityFlush({ position: observation.position.last,
341
358
  autoPlay: shouldAutoPlay,
342
359
  duration: observation.duration });
343
- if (orchestratorCancelSignal.isCancelled) {
360
+ if (orchestratorCancelSignal.isCancelled()) {
344
361
  return ;
345
362
  }
346
363
  } else if (needsFlushingAfterClean(observation, rangesToRemove)) {
347
364
  callbacks.needsBufferFlush();
348
- if (orchestratorCancelSignal.isCancelled) {
365
+ if (orchestratorCancelSignal.isCancelled()) {
349
366
  return ;
350
367
  }
351
368
  }
@@ -418,7 +435,8 @@ export default function StreamOrchestrator(
418
435
  } | null = null;
419
436
 
420
437
  /** Emits when the `PeriodStream` linked to `basePeriod` should be destroyed. */
421
- const currentStreamCanceller = new TaskCanceller({ cancelOn: cancelSignal });
438
+ const currentStreamCanceller = new TaskCanceller();
439
+ currentStreamCanceller.linkToSignal(cancelSignal);
422
440
 
423
441
  // Stop current PeriodStream when the current position goes over the end of
424
442
  // that Period.
@@ -453,12 +471,10 @@ export default function StreamOrchestrator(
453
471
  ...consecutivePeriodStreamCb,
454
472
  streamStatusUpdate(value : IStreamStatusPayload) : void {
455
473
  if (value.hasFinishedLoading) {
456
- if (nextStreamInfo === null) {
457
- const nextPeriod = manifest.getPeriodAfter(basePeriod);
458
- if (nextPeriod !== null) {
459
- // current Stream is full, create the next one if not
460
- createNextPeriodStream(nextPeriod);
461
- }
474
+ const nextPeriod = manifest.getPeriodAfter(basePeriod);
475
+ if (nextPeriod !== null) {
476
+ // current Stream is full, create the next one if not
477
+ checkOrCreateNextPeriodStream(nextPeriod);
462
478
  }
463
479
  } else if (nextStreamInfo !== null) {
464
480
  // current Stream is active, destroy next Stream if created
@@ -490,15 +506,21 @@ export default function StreamOrchestrator(
490
506
  * Create `PeriodStream` for the next Period, specified under `nextPeriod`.
491
507
  * @param {Object} nextPeriod
492
508
  */
493
- function createNextPeriodStream(nextPeriod : Period) : void {
509
+ function checkOrCreateNextPeriodStream(nextPeriod : Period) : void {
494
510
  if (nextStreamInfo !== null) {
495
- log.warn("Stream: Creating next `PeriodStream` while it was already created.");
511
+ if (nextStreamInfo.period.id === nextPeriod.id) {
512
+ return;
513
+ }
514
+ log.warn("Stream: Creating next `PeriodStream` while one was already created.",
515
+ bufferType, nextPeriod.id, nextStreamInfo.period.id);
496
516
  consecutivePeriodStreamCb.periodStreamCleared({ type: bufferType,
497
517
  manifest,
498
518
  period: nextStreamInfo.period });
499
519
  nextStreamInfo.canceller.cancel();
500
520
  }
501
- nextStreamInfo = { canceller: new TaskCanceller({ cancelOn: cancelSignal }),
521
+ const nextStreamCanceller = new TaskCanceller();
522
+ nextStreamCanceller.linkToSignal(cancelSignal);
523
+ nextStreamInfo = { canceller: nextStreamCanceller,
502
524
  period: nextPeriod };
503
525
  manageConsecutivePeriodStreams(bufferType,
504
526
  nextPeriod,
@@ -111,7 +111,7 @@ export default function PeriodStream(
111
111
  );
112
112
 
113
113
  callbacks.periodStreamReady({ type: bufferType, manifest, period, adaptationRef });
114
- if (parentCancelSignal.isCancelled) {
114
+ if (parentCancelSignal.isCancelled()) {
115
115
  return;
116
116
  }
117
117
 
@@ -124,7 +124,8 @@ export default function PeriodStream(
124
124
  if (choice === undefined) {
125
125
  return;
126
126
  }
127
- const streamCanceller = new TaskCanceller({ cancelOn: parentCancelSignal });
127
+ const streamCanceller = new TaskCanceller();
128
+ streamCanceller.linkToSignal(parentCancelSignal);
128
129
  currentStreamCanceller?.cancel(); // Cancel oreviously created stream if one
129
130
  currentStreamCanceller = streamCanceller;
130
131
 
@@ -147,20 +148,20 @@ export default function PeriodStream(
147
148
  await segmentBufferStatus.value.removeBuffer(period.start,
148
149
  periodEnd,
149
150
  streamCanceller.signal);
150
- if (streamCanceller.isUsed) {
151
+ if (streamCanceller.isUsed()) {
151
152
  return; // The stream has been cancelled
152
153
  }
153
154
  }
154
155
  }
155
156
  } else if (segmentBufferStatus.type === "uninitialized") {
156
157
  segmentBuffersStore.disableSegmentBuffer(bufferType);
157
- if (streamCanceller.isUsed) {
158
+ if (streamCanceller.isUsed()) {
158
159
  return; // The stream has been cancelled
159
160
  }
160
161
  }
161
162
 
162
163
  callbacks.adaptationChange({ type: bufferType, adaptation: null, period });
163
- if (streamCanceller.isUsed) {
164
+ if (streamCanceller.isUsed()) {
164
165
  return; // Previous call has provoken Stream cancellation by side-effect
165
166
  }
166
167
 
@@ -220,7 +221,7 @@ export default function PeriodStream(
220
221
  `P: ${period.start}`);
221
222
 
222
223
  callbacks.adaptationChange({ type: bufferType, adaptation, period });
223
- if (streamCanceller.isUsed) {
224
+ if (streamCanceller.isUsed()) {
224
225
  return; // Previous call has provoken cancellation by side-effect
225
226
  }
226
227
 
@@ -244,19 +245,19 @@ export default function PeriodStream(
244
245
  }
245
246
 
246
247
  await segmentBuffersStore.waitForUsableBuffers(streamCanceller.signal);
247
- if (streamCanceller.isUsed) {
248
+ if (streamCanceller.isUsed()) {
248
249
  return; // The Stream has since been cancelled
249
250
  }
250
251
  if (strategy.type === "flush-buffer" || strategy.type === "clean-buffer") {
251
252
  for (const { start, end } of strategy.value) {
252
253
  await segmentBuffer.removeBuffer(start, end, streamCanceller.signal);
253
- if (streamCanceller.isUsed) {
254
+ if (streamCanceller.isUsed()) {
254
255
  return; // The Stream has since been cancelled
255
256
  }
256
257
  }
257
258
  if (strategy.type === "flush-buffer") {
258
259
  callbacks.needsBufferFlush();
259
- if (streamCanceller.isUsed) {
260
+ if (streamCanceller.isUsed()) {
260
261
  return ; // Previous callback cancelled the Stream by side-effect
261
262
  }
262
263
  }
@@ -319,7 +320,7 @@ export default function PeriodStream(
319
320
  defaultReason: "Unknown `AdaptationStream` error",
320
321
  });
321
322
  callbacks.warning(formattedError);
322
- if (cancelSignal.isCancelled) {
323
+ if (cancelSignal.isCancelled()) {
323
324
  return ; // Previous callback cancelled the Stream by side-effect
324
325
  }
325
326
 
@@ -371,7 +372,8 @@ function getFirstDeclaredMimeType(adaptation : Adaptation) : string {
371
372
  if (representations.length === 0) {
372
373
  const noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION",
373
374
  "No Representation in the chosen " +
374
- adaptation.type + " Adaptation can be played");
375
+ adaptation.type + " Adaptation can be played",
376
+ { adaptation });
375
377
  throw noRepErr;
376
378
  }
377
379
  return representations[0].getMimeTypeString();
@@ -97,23 +97,29 @@ export default function RepresentationStream<TSegmentDataType>(
97
97
  const bufferType = adaptation.type;
98
98
 
99
99
  /** `TaskCanceller` stopping ALL operations performed by the `RepresentationStream` */
100
- const globalCanceller = new TaskCanceller({ cancelOn: parentCancelSignal });
100
+ const globalCanceller = new TaskCanceller();
101
+ globalCanceller.linkToSignal(parentCancelSignal);
101
102
 
102
103
  /**
103
104
  * `TaskCanceller` allowing to only stop segment loading and checking operations.
104
105
  * This allows to stop only tasks linked to network resource usage, which is
105
106
  * often a limited resource, while still letting buffer operations to finish.
106
107
  */
107
- const segmentsLoadingCanceller = new TaskCanceller({
108
- cancelOn: globalCanceller.signal,
109
- });
108
+ const segmentsLoadingCanceller = new TaskCanceller();
109
+ segmentsLoadingCanceller.linkToSignal(globalCanceller.signal);
110
110
 
111
111
  /** Saved initialization segment state for this representation. */
112
- const initSegmentState : IInitSegmentState<TSegmentDataType> = {
112
+ const initSegmentState : IInitSegmentState = {
113
113
  segment: representation.index.getInitSegment(),
114
- segmentData: null,
114
+ uniqueId: null,
115
115
  isLoaded: false,
116
116
  };
117
+ globalCanceller.signal.register(() => {
118
+ // Free initialization segment if one has been declared
119
+ if (initSegmentState.uniqueId !== null) {
120
+ segmentBuffer.freeInitSegment(initSegmentState.uniqueId);
121
+ }
122
+ });
117
123
 
118
124
  /** Emit the last scheduled downloading queue for segments. */
119
125
  const lastSegmentQueue = createSharedReference<IDownloadQueueItem>({
@@ -125,7 +131,6 @@ export default function RepresentationStream<TSegmentDataType>(
125
131
  const hasInitSegment = initSegmentState.segment !== null;
126
132
 
127
133
  if (!hasInitSegment) {
128
- initSegmentState.segmentData = null;
129
134
  initSegmentState.isLoaded = true;
130
135
  }
131
136
 
@@ -149,7 +154,7 @@ export default function RepresentationStream<TSegmentDataType>(
149
154
  callbacks.encryptionDataEncountered(
150
155
  encryptionData.map(d => objectAssign({ content }, d))
151
156
  );
152
- if (globalCanceller.isUsed) {
157
+ if (globalCanceller.isUsed()) {
153
158
  return ; // previous callback has stopped everything by side-effect
154
159
  }
155
160
  }
@@ -161,7 +166,7 @@ export default function RepresentationStream<TSegmentDataType>(
161
166
  segmentFetcher,
162
167
  hasInitSegment);
163
168
  downloadingQueue.addEventListener("error", (err) => {
164
- if (segmentsLoadingCanceller.signal.isCancelled) {
169
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
165
170
  return; // ignore post requests-cancellation loading-related errors,
166
171
  }
167
172
  globalCanceller.cancel(); // Stop every operations
@@ -172,7 +177,7 @@ export default function RepresentationStream<TSegmentDataType>(
172
177
  downloadingQueue.addEventListener("emptyQueue", checkStatus);
173
178
  downloadingQueue.addEventListener("requestRetry", (payload) => {
174
179
  callbacks.warning(payload.error);
175
- if (segmentsLoadingCanceller.signal.isCancelled) {
180
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
176
181
  return; // If the previous callback led to loading operations being stopped, skip
177
182
  }
178
183
  const retriedSegment = payload.segment;
@@ -218,7 +223,7 @@ export default function RepresentationStream<TSegmentDataType>(
218
223
  * issues at the current time, calling the right callbacks if necessary.
219
224
  */
220
225
  function checkStatus() : void {
221
- if (segmentsLoadingCanceller.isUsed) {
226
+ if (segmentsLoadingCanceller.isUsed()) {
222
227
  return ; // Stop all buffer status checking if load operations are stopped
223
228
  }
224
229
  const observation = playbackObserver.getReference().getValue();
@@ -305,7 +310,7 @@ export default function RepresentationStream<TSegmentDataType>(
305
310
  isEmptyStream: false,
306
311
  hasFinishedLoading: status.hasFinishedLoading,
307
312
  neededSegments: status.neededSegments });
308
- if (segmentsLoadingCanceller.signal.isCancelled) {
313
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
309
314
  return ; // previous callback has stopped loading operations by side-effect
310
315
  }
311
316
  const { UPTO_CURRENT_POSITION_CLEANUP } = config.getCurrent();
@@ -314,7 +319,7 @@ export default function RepresentationStream<TSegmentDataType>(
314
319
  0,
315
320
  initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
316
321
  if (gcedPosition > 0) {
317
- segmentBuffer.removeBuffer(0, gcedPosition, segmentsLoadingCanceller.signal)
322
+ segmentBuffer.removeBuffer(0, gcedPosition, globalCanceller.signal)
318
323
  .catch(onFatalBufferError);
319
324
  }
320
325
  }
@@ -332,7 +337,7 @@ export default function RepresentationStream<TSegmentDataType>(
332
337
  evt : IParsedInitSegmentPayload<TSegmentDataType> |
333
338
  IParsedSegmentPayload<TSegmentDataType>
334
339
  ) : void {
335
- if (globalCanceller.isUsed) {
340
+ if (globalCanceller.isUsed()) {
336
341
  // We should not do anything with segments if the `RepresentationStream`
337
342
  // is not running anymore.
338
343
  return ;
@@ -359,7 +364,7 @@ export default function RepresentationStream<TSegmentDataType>(
359
364
  hasSentEncryptionData = true;
360
365
 
361
366
  // previous callback could have lead to cancellation
362
- if (globalCanceller.isUsed) {
367
+ if (globalCanceller.isUsed()) {
363
368
  return ;
364
369
  }
365
370
  }
@@ -371,21 +376,27 @@ export default function RepresentationStream<TSegmentDataType>(
371
376
  {
372
377
  representation.index.initialize(evt.segmentList);
373
378
  }
374
- initSegmentState.segmentData = evt.initializationData;
375
379
  initSegmentState.isLoaded = true;
376
380
 
377
- pushInitSegment({ playbackObserver,
378
- content,
379
- segment: evt.segment,
380
- segmentData: evt.initializationData,
381
- segmentBuffer },
382
- globalCanceller.signal)
383
- .then((result) => {
384
- if (result !== null) {
385
- callbacks.addedSegment(result);
386
- }
387
- })
388
- .catch(onFatalBufferError);
381
+ if (evt.initializationData !== null) {
382
+ const initSegmentUniqueId = representation.uniqueId;
383
+ initSegmentState.uniqueId = initSegmentUniqueId;
384
+ segmentBuffer.declareInitSegment(initSegmentUniqueId,
385
+ evt.initializationData);
386
+ pushInitSegment({ playbackObserver,
387
+ content,
388
+ initSegmentUniqueId,
389
+ segment: evt.segment,
390
+ segmentData: evt.initializationData,
391
+ segmentBuffer },
392
+ globalCanceller.signal)
393
+ .then((result) => {
394
+ if (result !== null) {
395
+ callbacks.addedSegment(result);
396
+ }
397
+ })
398
+ .catch(onFatalBufferError);
399
+ }
389
400
 
390
401
  // Sometimes the segment list is only known once the initialization segment
391
402
  // is parsed. Thus we immediately re-check if there's new segments to load.
@@ -401,21 +412,21 @@ export default function RepresentationStream<TSegmentDataType>(
401
412
 
402
413
  if (needsManifestRefresh === true) {
403
414
  callbacks.needsManifestRefresh();
404
- if (globalCanceller.isUsed) {
415
+ if (globalCanceller.isUsed()) {
405
416
  return ; // previous callback has stopped everything by side-effect
406
417
  }
407
418
  }
408
419
  if (inbandEvents !== undefined && inbandEvents.length > 0) {
409
420
  callbacks.inbandEvent(inbandEvents);
410
- if (globalCanceller.isUsed) {
421
+ if (globalCanceller.isUsed()) {
411
422
  return ; // previous callback has stopped everything by side-effect
412
423
  }
413
424
  }
414
425
 
415
- const initSegmentData = initSegmentState.segmentData;
426
+ const initSegmentUniqueId = initSegmentState.uniqueId;
416
427
  pushMediaSegment({ playbackObserver,
417
428
  content,
418
- initSegmentData,
429
+ initSegmentUniqueId,
419
430
  parsedSegment: evt,
420
431
  segment: evt.segment,
421
432
  segmentBuffer },
@@ -436,7 +447,7 @@ export default function RepresentationStream<TSegmentDataType>(
436
447
  * @param {*} err
437
448
  */
438
449
  function onFatalBufferError(err : unknown) : void {
439
- if (globalCanceller.isUsed && err instanceof CancellationError) {
450
+ if (globalCanceller.isUsed() && err instanceof CancellationError) {
440
451
  // The error is linked to cancellation AND we explicitely cancelled buffer
441
452
  // operations.
442
453
  // We can thus ignore it, it is very unlikely to lead to true buffer issues.
@@ -451,17 +462,18 @@ export default function RepresentationStream<TSegmentDataType>(
451
462
  * Information about the initialization segment linked to the Representation
452
463
  * which the RepresentationStream try to download segments for.
453
464
  */
454
- interface IInitSegmentState<T> {
465
+ interface IInitSegmentState {
455
466
  /**
456
467
  * Segment Object describing that initialization segment.
457
468
  * `null` if there's no initialization segment for that Representation.
458
469
  */
459
470
  segment : ISegment | null;
460
471
  /**
461
- * Initialization segment data.
462
- * `null` either when it doesn't exist or when it has not been loaded yet.
472
+ * Unique identifier used to identify the initialization segment data, used by
473
+ * the `SegmentBuffer`.
474
+ * `null` either when it doesn't exist or when it has not been declared yet.
463
475
  */
464
- segmentData : T | null;
476
+ uniqueId : string | null;
465
477
  /** `true` if the initialization segment has been loaded and parsed. */
466
478
  isLoaded : boolean;
467
479
  }
@@ -22,6 +22,7 @@ import { MediaError } from "../../../../errors";
22
22
  import { CancellationError, CancellationSignal } from "../../../../utils/task_canceller";
23
23
  import { IReadOnlyPlaybackObserver } from "../../../api";
24
24
  import {
25
+ IInsertedChunkInfos,
25
26
  IPushChunkInfos,
26
27
  SegmentBuffer,
27
28
  } from "../../../segment_buffers";
@@ -41,13 +42,13 @@ import forceGarbageCollection from "./force_garbage_collection";
41
42
  export default async function appendSegmentToBuffer<T>(
42
43
  playbackObserver : IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>,
43
44
  segmentBuffer : SegmentBuffer,
44
- dataInfos : IPushChunkInfos<T>,
45
+ dataInfos : IPushChunkInfos<T> & { inventoryInfos: IInsertedChunkInfos },
45
46
  cancellationSignal : CancellationSignal
46
47
  ) : Promise<void> {
47
48
  try {
48
49
  await segmentBuffer.pushChunk(dataInfos, cancellationSignal);
49
50
  } catch (appendError : unknown) {
50
- if (cancellationSignal.isCancelled && appendError instanceof CancellationError) {
51
+ if (cancellationSignal.isCancelled() && appendError instanceof CancellationError) {
51
52
  throw appendError;
52
53
  } else if (!(appendError instanceof Error) ||
53
54
  appendError.name !== "QuotaExceededError")
@@ -55,7 +56,9 @@ export default async function appendSegmentToBuffer<T>(
55
56
  const reason = appendError instanceof Error ?
56
57
  appendError.toString() :
57
58
  "An unknown error happened when pushing content";
58
- throw new MediaError("BUFFER_APPEND_ERROR", reason);
59
+ throw new MediaError("BUFFER_APPEND_ERROR",
60
+ reason,
61
+ { adaptation: dataInfos.inventoryInfos.adaptation });
59
62
  }
60
63
  const { position } = playbackObserver.getReference().getValue();
61
64
  const currentPos = position.pending ?? position.last;
@@ -66,7 +69,9 @@ export default async function appendSegmentToBuffer<T>(
66
69
  const reason = err2 instanceof Error ? err2.toString() :
67
70
  "Could not clean the buffer";
68
71
 
69
- throw new MediaError("BUFFER_FULL_ERROR", reason);
72
+ throw new MediaError("BUFFER_FULL_ERROR",
73
+ reason,
74
+ { adaptation: dataInfos.inventoryInfos.adaptation });
70
75
  }
71
76
  }
72
77
  }
@@ -28,6 +28,7 @@ import {
28
28
  } from "../../../../transports";
29
29
  import assert from "../../../../utils/assert";
30
30
  import EventEmitter from "../../../../utils/event_emitter";
31
+ import noop from "../../../../utils/noop";
31
32
  import objectAssign from "../../../../utils/object_assign";
32
33
  import createSharedReference, {
33
34
  IReadOnlySharedReference,
@@ -231,6 +232,7 @@ export default class DownloadingQueue<T>
231
232
 
232
233
  public stop() {
233
234
  this._currentCanceller?.cancel();
235
+ this._currentCanceller = null;
234
236
  }
235
237
 
236
238
  /**
@@ -245,7 +247,7 @@ export default class DownloadingQueue<T>
245
247
  const recursivelyRequestSegments = (
246
248
  startingSegment : IQueuedSegment | undefined
247
249
  ) : void => {
248
- if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
250
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
249
251
  this._mediaSegmentRequest = null;
250
252
  return;
251
253
  }
@@ -254,7 +256,10 @@ export default class DownloadingQueue<T>
254
256
  this.trigger("emptyQueue", null);
255
257
  return;
256
258
  }
257
- const canceller = new TaskCanceller({ cancelOn: this._currentCanceller?.signal });
259
+ const canceller = new TaskCanceller();
260
+ const unlinkCanceller = this._currentCanceller === null ?
261
+ noop :
262
+ canceller.linkToSignal(this._currentCanceller.signal);
258
263
 
259
264
  const { segment, priority } = startingSegment;
260
265
  const context = objectAssign({ segment }, this._content);
@@ -368,6 +373,7 @@ export default class DownloadingQueue<T>
368
373
  * requests are scheduled. It is used to schedule the next segment.
369
374
  */
370
375
  beforeEnded: () : void => {
376
+ unlinkCanceller();
371
377
  this._mediaSegmentRequest = null;
372
378
 
373
379
  if (isWaitingOnInitSegment) {
@@ -381,6 +387,7 @@ export default class DownloadingQueue<T>
381
387
  }, canceller.signal);
382
388
 
383
389
  request.catch((error : unknown) => {
390
+ unlinkCanceller();
384
391
  if (!isComplete) {
385
392
  isComplete = true;
386
393
  this.stop();
@@ -400,7 +407,7 @@ export default class DownloadingQueue<T>
400
407
  private _restartInitSegmentDownloadingQueue(
401
408
  queuedInitSegment : IQueuedSegment | null
402
409
  ) : void {
403
- if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
410
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
404
411
  return;
405
412
  }
406
413
  if (this._initSegmentRequest !== null) {
@@ -410,7 +417,10 @@ export default class DownloadingQueue<T>
410
417
  return ;
411
418
  }
412
419
 
413
- const canceller = new TaskCanceller({ cancelOn: this._currentCanceller?.signal });
420
+ const canceller = new TaskCanceller();
421
+ const unlinkCanceller = this._currentCanceller === null ?
422
+ noop :
423
+ canceller.linkToSignal(this._currentCanceller.signal);
414
424
  const { segment, priority } = queuedInitSegment;
415
425
  const context = objectAssign({ segment }, this._content);
416
426
 
@@ -428,6 +438,7 @@ export default class DownloadingQueue<T>
428
438
  log.info("Stream: init segment request interrupted temporarly.", segment.id);
429
439
  },
430
440
  beforeEnded: () => {
441
+ unlinkCanceller();
431
442
  this._initSegmentRequest = null;
432
443
  isComplete = true;
433
444
  },
@@ -446,6 +457,7 @@ export default class DownloadingQueue<T>
446
457
  }, canceller.signal);
447
458
 
448
459
  request.catch((error : unknown) => {
460
+ unlinkCanceller();
449
461
  if (!isComplete) {
450
462
  isComplete = true;
451
463
  this.stop();
@@ -20,6 +20,7 @@ import Manifest, {
20
20
  Period,
21
21
  Representation,
22
22
  } from "../../../../manifest";
23
+ import objectAssign from "../../../../utils/object_assign";
23
24
  import { CancellationSignal } from "../../../../utils/task_canceller";
24
25
  import { IReadOnlyPlaybackObserver } from "../../../api";
25
26
  import {
@@ -42,6 +43,7 @@ export default async function pushInitSegment<T>(
42
43
  {
43
44
  playbackObserver,
44
45
  content,
46
+ initSegmentUniqueId,
45
47
  segment,
46
48
  segmentData,
47
49
  segmentBuffer,
@@ -53,27 +55,30 @@ export default async function pushInitSegment<T>(
53
55
  manifest : Manifest;
54
56
  period : Period;
55
57
  representation : Representation; };
56
- segmentData : T | null;
58
+ initSegmentUniqueId : string;
59
+ segmentData : T;
57
60
  segment : ISegment;
58
61
  segmentBuffer : SegmentBuffer;
59
62
  },
60
63
  cancelSignal : CancellationSignal
61
64
  ) : Promise< IStreamEventAddedSegmentPayload<T> | null > {
62
- if (segmentData === null) {
63
- return null;
64
- }
65
65
  if (cancelSignal.cancellationError !== null) {
66
66
  throw cancelSignal.cancellationError;
67
67
  }
68
68
  const codec = content.representation.getMimeTypeString();
69
- const data : IPushedChunkData<T> = { initSegment: segmentData,
69
+ const data : IPushedChunkData<T> = { initSegmentUniqueId,
70
70
  chunk: null,
71
71
  timestampOffset: 0,
72
72
  appendWindow: [ undefined, undefined ],
73
73
  codec };
74
+ const inventoryInfos = objectAssign({ segment,
75
+ chunkSize: undefined,
76
+ start: 0,
77
+ end: 0 },
78
+ content);
74
79
  await appendSegmentToBuffer(playbackObserver,
75
80
  segmentBuffer,
76
- { data, inventoryInfos: null },
81
+ { data, inventoryInfos },
77
82
  cancelSignal);
78
83
  const buffered = segmentBuffer.getBufferedRanges();
79
84
  return { content, segment, buffered, segmentData };
@@ -41,7 +41,7 @@ import appendSegmentToBuffer from "./append_segment_to_buffer";
41
41
  export default async function pushMediaSegment<T>(
42
42
  { playbackObserver,
43
43
  content,
44
- initSegmentData,
44
+ initSegmentUniqueId,
45
45
  parsedSegment,
46
46
  segment,
47
47
  segmentBuffer } :
@@ -52,7 +52,7 @@ export default async function pushMediaSegment<T>(
52
52
  manifest : Manifest;
53
53
  period : Period;
54
54
  representation : Representation; };
55
- initSegmentData : T | null;
55
+ initSegmentUniqueId : string | null;
56
56
  parsedSegment : ISegmentParserParsedMediaChunk<T>;
57
57
  segment : ISegment;
58
58
  segmentBuffer : SegmentBuffer; },
@@ -83,7 +83,7 @@ export default async function pushMediaSegment<T>(
83
83
  undefined,
84
84
  ];
85
85
 
86
- const data = { initSegment: initSegmentData,
86
+ const data = { initSegmentUniqueId,
87
87
  chunk: chunkData,
88
88
  timestampOffset: chunkOffset,
89
89
  appendWindow: safeAppendWindow,