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
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Copyright 2015 CANAL+ Group
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { MediaError } from "../../../../errors";
17
+ import createSharedReference from "../../../../utils/reference";
18
+ /**
19
+ * Produce estimates to know which Representation should be played.
20
+ * @param {Object} content - The Manifest, Period and Adaptation wanted.
21
+ * @param {Object} representationEstimator - `IRepresentationEstimator` which
22
+ * will produce Representation estimates.
23
+ * @param {Object} currentRepresentation - Reference emitting the
24
+ * currently-loaded Representation.
25
+ * @param {Object} playbackObserver - Allows to observe the current playback
26
+ * conditions.
27
+ * @param {Function} onFatalError - Callback called when a fatal error was
28
+ * thrown. Once this callback is called, no estimate will be produced.
29
+ * @param {Object} cancellationSignal - `CancellationSignal` allowing to abort
30
+ * the production of estimates (and clean-up all linked resources).
31
+ * @returns {Object} - Returns an object with the following properties:
32
+ * - `estimateRef`: Reference emitting the last estimate
33
+ * - `abrCallbacks`: Callbacks allowing to report back network and playback
34
+ * activities to improve the estimates given.
35
+ */
36
+ export default function getRepresentationEstimate(content, representationEstimator, currentRepresentation, playbackObserver, onFatalError, cancellationSignal) {
37
+ var manifest = content.manifest, adaptation = content.adaptation;
38
+ var representations = createSharedReference([], cancellationSignal);
39
+ updateRepresentationsReference();
40
+ manifest.addEventListener("decipherabilityUpdate", updateRepresentationsReference);
41
+ var unregisterCleanUp = cancellationSignal.register(cleanUp);
42
+ var _a = representationEstimator(content, currentRepresentation, representations, playbackObserver, cancellationSignal), estimateRef = _a.estimates, abrCallbacks = _a.callbacks;
43
+ return { abrCallbacks: abrCallbacks, estimateRef: estimateRef };
44
+ function updateRepresentationsReference() {
45
+ /** Representations for which a `RepresentationStream` can be created. */
46
+ var newRepr = adaptation.getPlayableRepresentations();
47
+ if (newRepr.length === 0) {
48
+ var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
49
+ adaptation.type + " Adaptation can be played", { adaptation: adaptation });
50
+ cleanUp();
51
+ onFatalError(noRepErr);
52
+ return;
53
+ }
54
+ var prevRepr = representations.getValue();
55
+ if (prevRepr.length === newRepr.length) {
56
+ if (prevRepr.every(function (r, idx) { return r.id === newRepr[idx].id; })) {
57
+ return;
58
+ }
59
+ }
60
+ representations.setValue(newRepr);
61
+ }
62
+ /** Clean-up all resources taken here. */
63
+ function cleanUp() {
64
+ manifest.removeEventListener("decipherabilityUpdate", updateRepresentationsReference);
65
+ // check to protect against the case where it is not yet defined.
66
+ if (typeof unregisterCleanUp !== "undefined") {
67
+ unregisterCleanUp();
68
+ }
69
+ }
70
+ }
@@ -147,9 +147,10 @@ export default function StreamOrchestrator(content, playbackObserver, representa
147
147
  };
148
148
  });
149
149
  // Create automatically the right `PeriodStream` for every possible types
150
- segmentBuffersStore.getBufferTypes().map(function (bufferType) {
150
+ for (var _i = 0, _b = segmentBuffersStore.getBufferTypes(); _i < _b.length; _i++) {
151
+ var bufferType = _b[_i];
151
152
  manageEveryStreams(bufferType, initialPeriod);
152
- });
153
+ }
153
154
  /**
154
155
  * Manage creation and removal of Streams for every Periods for a given type.
155
156
  *
@@ -171,7 +172,8 @@ export default function StreamOrchestrator(content, playbackObserver, representa
171
172
  */
172
173
  var enableOutOfBoundsCheck = false;
173
174
  /** Cancels currently created `PeriodStream`s. */
174
- var currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
175
+ var currentCanceller = new TaskCanceller();
176
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
175
177
  // Restart the current Stream when the wanted time is in another period
176
178
  // than the ones already considered
177
179
  playbackObserver.listen(function (_a) {
@@ -189,7 +191,8 @@ export default function StreamOrchestrator(content, playbackObserver, representa
189
191
  callbacks.periodStreamCleared({ type: bufferType, manifest: manifest, period: period });
190
192
  }
191
193
  currentCanceller.cancel();
192
- currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
194
+ currentCanceller = new TaskCanceller();
195
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
193
196
  var nextPeriod = (_c = manifest.getPeriodForTime(time)) !== null && _c !== void 0 ? _c : manifest.getNextPeriod(time);
194
197
  if (nextPeriod === undefined) {
195
198
  log.warn("Stream: The wanted position is not found in the Manifest.");
@@ -198,7 +201,13 @@ export default function StreamOrchestrator(content, playbackObserver, representa
198
201
  launchConsecutiveStreamsForPeriod(nextPeriod);
199
202
  }, { clearSignal: orchestratorCancelSignal, includeLastObservation: true });
200
203
  manifest.addEventListener("decipherabilityUpdate", function (evt) {
204
+ if (orchestratorCancelSignal.isCancelled()) {
205
+ return;
206
+ }
201
207
  onDecipherabilityUpdates(evt).catch(function (err) {
208
+ if (orchestratorCancelSignal.isCancelled()) {
209
+ return;
210
+ }
202
211
  currentCanceller.cancel();
203
212
  callbacks.error(err);
204
213
  });
@@ -265,8 +274,15 @@ export default function StreamOrchestrator(content, playbackObserver, representa
265
274
  segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
266
275
  ofCurrentType = updates
267
276
  .filter(function (update) { return update.adaptation.type === bufferType; });
268
- if (ofCurrentType.length === 0 || segmentBufferStatus.type !== "initialized") {
269
- return [2 /*return*/]; // no need to stop the current Streams.
277
+ if (
278
+ // No update concerns the current type of data
279
+ ofCurrentType.length === 0 ||
280
+ segmentBufferStatus.type !== "initialized" ||
281
+ // The update only notifies of now-decipherable streams
282
+ ofCurrentType.every(function (x) { return x.representation.decipherable === true; })) {
283
+ // Data won't have to be removed from the buffers, no need to stop the
284
+ // current Streams.
285
+ return [2 /*return*/];
270
286
  }
271
287
  segmentBuffer = segmentBufferStatus.value;
272
288
  resettedContent = ofCurrentType.filter(function (update) {
@@ -287,7 +303,8 @@ export default function StreamOrchestrator(content, playbackObserver, representa
287
303
  callbacks.periodStreamCleared({ type: bufferType, manifest: manifest, period: period });
288
304
  }
289
305
  currentCanceller.cancel();
290
- currentCanceller = new TaskCanceller({ cancelOn: orchestratorCancelSignal });
306
+ currentCanceller = new TaskCanceller();
307
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
291
308
  _i = 0, _a = __spreadArray(__spreadArray([], undecipherableRanges, true), rangesToRemove, true);
292
309
  _c.label = 1;
293
310
  case 1:
@@ -307,7 +324,7 @@ export default function StreamOrchestrator(content, playbackObserver, representa
307
324
  // was going to be emitted synchronously.
308
325
  nextTick(function () {
309
326
  var _a, _b;
310
- if (orchestratorCancelSignal.isCancelled) {
327
+ if (orchestratorCancelSignal.isCancelled()) {
311
328
  return;
312
329
  }
313
330
  var observation = playbackObserver.getReference().getValue();
@@ -316,13 +333,13 @@ export default function StreamOrchestrator(content, playbackObserver, representa
316
333
  callbacks.needsDecipherabilityFlush({ position: observation.position.last,
317
334
  autoPlay: shouldAutoPlay,
318
335
  duration: observation.duration });
319
- if (orchestratorCancelSignal.isCancelled) {
336
+ if (orchestratorCancelSignal.isCancelled()) {
320
337
  return;
321
338
  }
322
339
  }
323
340
  else if (needsFlushingAfterClean(observation, rangesToRemove)) {
324
341
  callbacks.needsBufferFlush();
325
- if (orchestratorCancelSignal.isCancelled) {
342
+ if (orchestratorCancelSignal.isCancelled()) {
326
343
  return;
327
344
  }
328
345
  }
@@ -379,7 +396,8 @@ export default function StreamOrchestrator(content, playbackObserver, representa
379
396
  */
380
397
  var nextStreamInfo = null;
381
398
  /** Emits when the `PeriodStream` linked to `basePeriod` should be destroyed. */
382
- var currentStreamCanceller = new TaskCanceller({ cancelOn: cancelSignal });
399
+ var currentStreamCanceller = new TaskCanceller();
400
+ currentStreamCanceller.linkToSignal(cancelSignal);
383
401
  // Stop current PeriodStream when the current position goes over the end of
384
402
  // that Period.
385
403
  playbackObserver.listen(function (_a, stopListeningObservations) {
@@ -396,12 +414,10 @@ export default function StreamOrchestrator(content, playbackObserver, representa
396
414
  var periodStreamArgs = { bufferType: bufferType, content: { manifest: manifest, period: basePeriod }, garbageCollectors: garbageCollectors, maxVideoBufferSize: maxVideoBufferSize, segmentFetcherCreator: segmentFetcherCreator, segmentBuffersStore: segmentBuffersStore, options: options, playbackObserver: playbackObserver, representationEstimator: representationEstimator, wantedBufferAhead: wantedBufferAhead };
397
415
  var periodStreamCallbacks = __assign(__assign({}, consecutivePeriodStreamCb), { streamStatusUpdate: function (value) {
398
416
  if (value.hasFinishedLoading) {
399
- if (nextStreamInfo === null) {
400
- var nextPeriod = manifest.getPeriodAfter(basePeriod);
401
- if (nextPeriod !== null) {
402
- // current Stream is full, create the next one if not
403
- createNextPeriodStream(nextPeriod);
404
- }
417
+ var nextPeriod = manifest.getPeriodAfter(basePeriod);
418
+ if (nextPeriod !== null) {
419
+ // current Stream is full, create the next one if not
420
+ checkOrCreateNextPeriodStream(nextPeriod);
405
421
  }
406
422
  }
407
423
  else if (nextStreamInfo !== null) {
@@ -427,13 +443,18 @@ export default function StreamOrchestrator(content, playbackObserver, representa
427
443
  * Create `PeriodStream` for the next Period, specified under `nextPeriod`.
428
444
  * @param {Object} nextPeriod
429
445
  */
430
- function createNextPeriodStream(nextPeriod) {
446
+ function checkOrCreateNextPeriodStream(nextPeriod) {
431
447
  if (nextStreamInfo !== null) {
432
- log.warn("Stream: Creating next `PeriodStream` while it was already created.");
448
+ if (nextStreamInfo.period.id === nextPeriod.id) {
449
+ return;
450
+ }
451
+ log.warn("Stream: Creating next `PeriodStream` while one was already created.", bufferType, nextPeriod.id, nextStreamInfo.period.id);
433
452
  consecutivePeriodStreamCb.periodStreamCleared({ type: bufferType, manifest: manifest, period: nextStreamInfo.period });
434
453
  nextStreamInfo.canceller.cancel();
435
454
  }
436
- nextStreamInfo = { canceller: new TaskCanceller({ cancelOn: cancelSignal }),
455
+ var nextStreamCanceller = new TaskCanceller();
456
+ nextStreamCanceller.linkToSignal(cancelSignal);
457
+ nextStreamInfo = { canceller: nextStreamCanceller,
437
458
  period: nextPeriod };
438
459
  manageConsecutivePeriodStreams(bufferType, nextPeriod, consecutivePeriodStreamCb, nextStreamInfo.canceller.signal);
439
460
  }
@@ -113,7 +113,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
113
113
  */
114
114
  var adaptationRef = createSharedReference(undefined, parentCancelSignal);
115
115
  callbacks.periodStreamReady({ type: bufferType, manifest: manifest, period: period, adaptationRef: adaptationRef });
116
- if (parentCancelSignal.isCancelled) {
116
+ if (parentCancelSignal.isCancelled()) {
117
117
  return;
118
118
  }
119
119
  var currentStreamCanceller;
@@ -129,7 +129,8 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
129
129
  if (choice === undefined) {
130
130
  return [2 /*return*/];
131
131
  }
132
- streamCanceller = new TaskCanceller({ cancelOn: parentCancelSignal });
132
+ streamCanceller = new TaskCanceller();
133
+ streamCanceller.linkToSignal(parentCancelSignal);
133
134
  currentStreamCanceller === null || currentStreamCanceller === void 0 ? void 0 : currentStreamCanceller.cancel(); // Cancel oreviously created stream if one
134
135
  currentStreamCanceller = streamCanceller;
135
136
  if (!(choice === null)) return [3 /*break*/, 7];
@@ -151,7 +152,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
151
152
  case 2: return [4 /*yield*/, segmentBufferStatus.value.removeBuffer(period.start, periodEnd, streamCanceller.signal)];
152
153
  case 3:
153
154
  _d.sent();
154
- if (streamCanceller.isUsed) {
155
+ if (streamCanceller.isUsed()) {
155
156
  return [2 /*return*/]; // The stream has been cancelled
156
157
  }
157
158
  _d.label = 4;
@@ -159,14 +160,14 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
159
160
  case 5:
160
161
  if (segmentBufferStatus.type === "uninitialized") {
161
162
  segmentBuffersStore.disableSegmentBuffer(bufferType);
162
- if (streamCanceller.isUsed) {
163
+ if (streamCanceller.isUsed()) {
163
164
  return [2 /*return*/]; // The stream has been cancelled
164
165
  }
165
166
  }
166
167
  _d.label = 6;
167
168
  case 6:
168
169
  callbacks.adaptationChange({ type: bufferType, adaptation: null, period: period });
169
- if (streamCanceller.isUsed) {
170
+ if (streamCanceller.isUsed()) {
170
171
  return [2 /*return*/]; // Previous call has provoken Stream cancellation by side-effect
171
172
  }
172
173
  return [2 /*return*/, createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, { period: period }, callbacks, streamCanceller.signal)];
@@ -209,7 +210,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
209
210
  adaptation = choice.adaptation, representations = choice.representations;
210
211
  log.info("Stream: Updating ".concat(bufferType, " adaptation"), "A: ".concat(adaptation.id), "P: ".concat(period.start));
211
212
  callbacks.adaptationChange({ type: bufferType, adaptation: adaptation, period: period });
212
- if (streamCanceller.isUsed) {
213
+ if (streamCanceller.isUsed()) {
213
214
  return [2 /*return*/]; // Previous call has provoken cancellation by side-effect
214
215
  }
215
216
  readyState = playbackObserver.getReadyState();
@@ -225,7 +226,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
225
226
  return [4 /*yield*/, segmentBuffersStore.waitForUsableBuffers(streamCanceller.signal)];
226
227
  case 8:
227
228
  _d.sent();
228
- if (streamCanceller.isUsed) {
229
+ if (streamCanceller.isUsed()) {
229
230
  return [2 /*return*/]; // The Stream has since been cancelled
230
231
  }
231
232
  if (!(strategy.type === "flush-buffer" || strategy.type === "clean-buffer")) return [3 /*break*/, 13];
@@ -237,7 +238,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
237
238
  return [4 /*yield*/, segmentBuffer.removeBuffer(start, end, streamCanceller.signal)];
238
239
  case 10:
239
240
  _d.sent();
240
- if (streamCanceller.isUsed) {
241
+ if (streamCanceller.isUsed()) {
241
242
  return [2 /*return*/]; // The Stream has since been cancelled
242
243
  }
243
244
  _d.label = 11;
@@ -247,7 +248,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
247
248
  case 12:
248
249
  if (strategy.type === "flush-buffer") {
249
250
  callbacks.needsBufferFlush();
250
- if (streamCanceller.isUsed) {
251
+ if (streamCanceller.isUsed()) {
251
252
  return [2 /*return*/]; // Previous callback cancelled the Stream by side-effect
252
253
  }
253
254
  }
@@ -287,7 +288,7 @@ export default function PeriodStream(_a, callbacks, parentCancelSignal) {
287
288
  defaultReason: "Unknown `AdaptationStream` error",
288
289
  });
289
290
  callbacks.warning(formattedError);
290
- if (cancelSignal.isCancelled) {
291
+ if (cancelSignal.isCancelled()) {
291
292
  return; // Previous callback cancelled the Stream by side-effect
292
293
  }
293
294
  return createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, { period: period }, callbacks, cancelSignal);
@@ -324,7 +325,7 @@ function getFirstDeclaredMimeType(adaptation) {
324
325
  var representations = adaptation.getPlayableRepresentations();
325
326
  if (representations.length === 0) {
326
327
  var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
327
- adaptation.type + " Adaptation can be played");
328
+ adaptation.type + " Adaptation can be played", { adaptation: adaptation });
328
329
  throw noRepErr;
329
330
  }
330
331
  return representations[0].getMimeTypeString();
@@ -72,21 +72,27 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
72
72
  var bufferGoal = options.bufferGoal, maxBufferSize = options.maxBufferSize, drmSystemId = options.drmSystemId, fastSwitchThreshold = options.fastSwitchThreshold;
73
73
  var bufferType = adaptation.type;
74
74
  /** `TaskCanceller` stopping ALL operations performed by the `RepresentationStream` */
75
- var globalCanceller = new TaskCanceller({ cancelOn: parentCancelSignal });
75
+ var globalCanceller = new TaskCanceller();
76
+ globalCanceller.linkToSignal(parentCancelSignal);
76
77
  /**
77
78
  * `TaskCanceller` allowing to only stop segment loading and checking operations.
78
79
  * This allows to stop only tasks linked to network resource usage, which is
79
80
  * often a limited resource, while still letting buffer operations to finish.
80
81
  */
81
- var segmentsLoadingCanceller = new TaskCanceller({
82
- cancelOn: globalCanceller.signal,
83
- });
82
+ var segmentsLoadingCanceller = new TaskCanceller();
83
+ segmentsLoadingCanceller.linkToSignal(globalCanceller.signal);
84
84
  /** Saved initialization segment state for this representation. */
85
85
  var initSegmentState = {
86
86
  segment: representation.index.getInitSegment(),
87
- segmentData: null,
87
+ uniqueId: null,
88
88
  isLoaded: false,
89
89
  };
90
+ globalCanceller.signal.register(function () {
91
+ // Free initialization segment if one has been declared
92
+ if (initSegmentState.uniqueId !== null) {
93
+ segmentBuffer.freeInitSegment(initSegmentState.uniqueId);
94
+ }
95
+ });
90
96
  /** Emit the last scheduled downloading queue for segments. */
91
97
  var lastSegmentQueue = createSharedReference({
92
98
  initSegment: null,
@@ -95,7 +101,6 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
95
101
  /** If `true`, the current Representation has a linked initialization segment. */
96
102
  var hasInitSegment = initSegmentState.segment !== null;
97
103
  if (!hasInitSegment) {
98
- initSegmentState.segmentData = null;
99
104
  initSegmentState.isLoaded = true;
100
105
  }
101
106
  /**
@@ -114,7 +119,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
114
119
  if (encryptionData.length > 0 && encryptionData.every(function (e) { return e.keyIds !== undefined; })) {
115
120
  hasSentEncryptionData = true;
116
121
  callbacks.encryptionDataEncountered(encryptionData.map(function (d) { return objectAssign({ content: content }, d); }));
117
- if (globalCanceller.isUsed) {
122
+ if (globalCanceller.isUsed()) {
118
123
  return; // previous callback has stopped everything by side-effect
119
124
  }
120
125
  }
@@ -122,7 +127,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
122
127
  /** Will load every segments in `lastSegmentQueue` */
123
128
  var downloadingQueue = new DownloadingQueue(content, lastSegmentQueue, segmentFetcher, hasInitSegment);
124
129
  downloadingQueue.addEventListener("error", function (err) {
125
- if (segmentsLoadingCanceller.signal.isCancelled) {
130
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
126
131
  return; // ignore post requests-cancellation loading-related errors,
127
132
  }
128
133
  globalCanceller.cancel(); // Stop every operations
@@ -133,7 +138,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
133
138
  downloadingQueue.addEventListener("emptyQueue", checkStatus);
134
139
  downloadingQueue.addEventListener("requestRetry", function (payload) {
135
140
  callbacks.warning(payload.error);
136
- if (segmentsLoadingCanceller.signal.isCancelled) {
141
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
137
142
  return; // If the previous callback led to loading operations being stopped, skip
138
143
  }
139
144
  var retriedSegment = payload.segment;
@@ -179,7 +184,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
179
184
  */
180
185
  function checkStatus() {
181
186
  var _a, _b;
182
- if (segmentsLoadingCanceller.isUsed) {
187
+ if (segmentsLoadingCanceller.isUsed()) {
183
188
  return; // Stop all buffer status checking if load operations are stopped
184
189
  }
185
190
  var observation = playbackObserver.getReference().getValue();
@@ -251,14 +256,14 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
251
256
  isEmptyStream: false,
252
257
  hasFinishedLoading: status.hasFinishedLoading,
253
258
  neededSegments: status.neededSegments });
254
- if (segmentsLoadingCanceller.signal.isCancelled) {
259
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
255
260
  return; // previous callback has stopped loading operations by side-effect
256
261
  }
257
262
  var UPTO_CURRENT_POSITION_CLEANUP = config.getCurrent().UPTO_CURRENT_POSITION_CLEANUP;
258
263
  if (status.isBufferFull) {
259
264
  var gcedPosition = Math.max(0, initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
260
265
  if (gcedPosition > 0) {
261
- segmentBuffer.removeBuffer(0, gcedPosition, segmentsLoadingCanceller.signal)
266
+ segmentBuffer.removeBuffer(0, gcedPosition, globalCanceller.signal)
262
267
  .catch(onFatalBufferError);
263
268
  }
264
269
  }
@@ -272,7 +277,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
272
277
  * @param {Object} evt
273
278
  */
274
279
  function onParsedChunk(evt) {
275
- if (globalCanceller.isUsed) {
280
+ if (globalCanceller.isUsed()) {
276
281
  // We should not do anything with segments if the `RepresentationStream`
277
282
  // is not running anymore.
278
283
  return;
@@ -293,7 +298,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
293
298
  callbacks.encryptionDataEncountered(allEncryptionData.map(function (p) { return objectAssign({ content: content }, p); }));
294
299
  hasSentEncryptionData = true;
295
300
  // previous callback could have lead to cancellation
296
- if (globalCanceller.isUsed) {
301
+ if (globalCanceller.isUsed()) {
297
302
  return;
298
303
  }
299
304
  }
@@ -303,16 +308,20 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
303
308
  evt.segmentList !== undefined) {
304
309
  representation.index.initialize(evt.segmentList);
305
310
  }
306
- initSegmentState.segmentData = evt.initializationData;
307
311
  initSegmentState.isLoaded = true;
308
- pushInitSegment({ playbackObserver: playbackObserver, content: content, segment: evt.segment,
309
- segmentData: evt.initializationData, segmentBuffer: segmentBuffer }, globalCanceller.signal)
310
- .then(function (result) {
311
- if (result !== null) {
312
- callbacks.addedSegment(result);
313
- }
314
- })
315
- .catch(onFatalBufferError);
312
+ if (evt.initializationData !== null) {
313
+ var initSegmentUniqueId = representation.uniqueId;
314
+ initSegmentState.uniqueId = initSegmentUniqueId;
315
+ segmentBuffer.declareInitSegment(initSegmentUniqueId, evt.initializationData);
316
+ pushInitSegment({ playbackObserver: playbackObserver, content: content, initSegmentUniqueId: initSegmentUniqueId, segment: evt.segment,
317
+ segmentData: evt.initializationData, segmentBuffer: segmentBuffer }, globalCanceller.signal)
318
+ .then(function (result) {
319
+ if (result !== null) {
320
+ callbacks.addedSegment(result);
321
+ }
322
+ })
323
+ .catch(onFatalBufferError);
324
+ }
316
325
  // Sometimes the segment list is only known once the initialization segment
317
326
  // is parsed. Thus we immediately re-check if there's new segments to load.
318
327
  checkStatus();
@@ -325,18 +334,18 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
325
334
  }
326
335
  if (needsManifestRefresh === true) {
327
336
  callbacks.needsManifestRefresh();
328
- if (globalCanceller.isUsed) {
337
+ if (globalCanceller.isUsed()) {
329
338
  return; // previous callback has stopped everything by side-effect
330
339
  }
331
340
  }
332
341
  if (inbandEvents !== undefined && inbandEvents.length > 0) {
333
342
  callbacks.inbandEvent(inbandEvents);
334
- if (globalCanceller.isUsed) {
343
+ if (globalCanceller.isUsed()) {
335
344
  return; // previous callback has stopped everything by side-effect
336
345
  }
337
346
  }
338
- var initSegmentData = initSegmentState.segmentData;
339
- pushMediaSegment({ playbackObserver: playbackObserver, content: content, initSegmentData: initSegmentData, parsedSegment: evt,
347
+ var initSegmentUniqueId = initSegmentState.uniqueId;
348
+ pushMediaSegment({ playbackObserver: playbackObserver, content: content, initSegmentUniqueId: initSegmentUniqueId, parsedSegment: evt,
340
349
  segment: evt.segment, segmentBuffer: segmentBuffer }, globalCanceller.signal)
341
350
  .then(function (result) {
342
351
  if (result !== null) {
@@ -353,7 +362,7 @@ export default function RepresentationStream(_a, callbacks, parentCancelSignal)
353
362
  * @param {*} err
354
363
  */
355
364
  function onFatalBufferError(err) {
356
- if (globalCanceller.isUsed && err instanceof CancellationError) {
365
+ if (globalCanceller.isUsed() && err instanceof CancellationError) {
357
366
  // The error is linked to cancellation AND we explicitely cancelled buffer
358
367
  // operations.
359
368
  // We can thus ignore it, it is very unlikely to lead to true buffer issues.
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { CancellationSignal } from "../../../../utils/task_canceller";
17
17
  import { IReadOnlyPlaybackObserver } from "../../../api";
18
- import { IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
18
+ import { IInsertedChunkInfos, IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
19
19
  import { IRepresentationStreamPlaybackObservation } from "../types";
20
20
  /**
21
21
  * Append a segment to the given segmentBuffer.
@@ -27,4 +27,6 @@ import { IRepresentationStreamPlaybackObservation } from "../types";
27
27
  * @param {Object} cancellationSignal
28
28
  * @returns {Promise}
29
29
  */
30
- export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T>, cancellationSignal: CancellationSignal): Promise<void>;
30
+ export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T> & {
31
+ inventoryInfos: IInsertedChunkInfos;
32
+ }, cancellationSignal: CancellationSignal): Promise<void>;
@@ -79,7 +79,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
79
79
  return [3 /*break*/, 8];
80
80
  case 2:
81
81
  appendError_1 = _b.sent();
82
- if (cancellationSignal.isCancelled && appendError_1 instanceof CancellationError) {
82
+ if (cancellationSignal.isCancelled() && appendError_1 instanceof CancellationError) {
83
83
  throw appendError_1;
84
84
  }
85
85
  else if (!(appendError_1 instanceof Error) ||
@@ -87,7 +87,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
87
87
  reason = appendError_1 instanceof Error ?
88
88
  appendError_1.toString() :
89
89
  "An unknown error happened when pushing content";
90
- throw new MediaError("BUFFER_APPEND_ERROR", reason);
90
+ throw new MediaError("BUFFER_APPEND_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
91
91
  }
92
92
  position = playbackObserver.getReference().getValue().position;
93
93
  currentPos = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
@@ -105,7 +105,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
105
105
  err2_1 = _b.sent();
106
106
  reason = err2_1 instanceof Error ? err2_1.toString() :
107
107
  "Could not clean the buffer";
108
- throw new MediaError("BUFFER_FULL_ERROR", reason);
108
+ throw new MediaError("BUFFER_FULL_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
109
109
  case 7: return [3 /*break*/, 8];
110
110
  case 8: return [2 /*return*/];
111
111
  }
@@ -31,6 +31,7 @@ var __extends = (this && this.__extends) || (function () {
31
31
  import log from "../../../../log";
32
32
  import assert from "../../../../utils/assert";
33
33
  import EventEmitter from "../../../../utils/event_emitter";
34
+ import noop from "../../../../utils/noop";
34
35
  import objectAssign from "../../../../utils/object_assign";
35
36
  import createSharedReference from "../../../../utils/reference";
36
37
  import TaskCanceller from "../../../../utils/task_canceller";
@@ -171,6 +172,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
171
172
  DownloadingQueue.prototype.stop = function () {
172
173
  var _a;
173
174
  (_a = this._currentCanceller) === null || _a === void 0 ? void 0 : _a.cancel();
175
+ this._currentCanceller = null;
174
176
  };
175
177
  /**
176
178
  * Internal logic performing media segment requests.
@@ -183,8 +185,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
183
185
  var segmentQueue = this._downloadQueue.getValue().segmentQueue;
184
186
  var currentNeededSegment = segmentQueue[0];
185
187
  var recursivelyRequestSegments = function (startingSegment) {
186
- var _a;
187
- if (_this._currentCanceller !== null && _this._currentCanceller.isUsed) {
188
+ if (_this._currentCanceller !== null && _this._currentCanceller.isUsed()) {
188
189
  _this._mediaSegmentRequest = null;
189
190
  return;
190
191
  }
@@ -193,7 +194,10 @@ var DownloadingQueue = /** @class */ (function (_super) {
193
194
  _this.trigger("emptyQueue", null);
194
195
  return;
195
196
  }
196
- var canceller = new TaskCanceller({ cancelOn: (_a = _this._currentCanceller) === null || _a === void 0 ? void 0 : _a.signal });
197
+ var canceller = new TaskCanceller();
198
+ var unlinkCanceller = _this._currentCanceller === null ?
199
+ noop :
200
+ canceller.linkToSignal(_this._currentCanceller.signal);
197
201
  var segment = startingSegment.segment, priority = startingSegment.priority;
198
202
  var context = objectAssign({ segment: segment }, _this._content);
199
203
  /**
@@ -289,6 +293,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
289
293
  * requests are scheduled. It is used to schedule the next segment.
290
294
  */
291
295
  beforeEnded: function () {
296
+ unlinkCanceller();
292
297
  _this._mediaSegmentRequest = null;
293
298
  if (isWaitingOnInitSegment) {
294
299
  _this._initSegmentInfoRef.waitUntilDefined(continueToNextSegment, { clearSignal: canceller.signal });
@@ -299,6 +304,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
299
304
  },
300
305
  }, canceller.signal);
301
306
  request.catch(function (error) {
307
+ unlinkCanceller();
302
308
  if (!isComplete) {
303
309
  isComplete = true;
304
310
  _this.stop();
@@ -315,8 +321,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
315
321
  */
316
322
  DownloadingQueue.prototype._restartInitSegmentDownloadingQueue = function (queuedInitSegment) {
317
323
  var _this = this;
318
- var _a;
319
- if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
324
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
320
325
  return;
321
326
  }
322
327
  if (this._initSegmentRequest !== null) {
@@ -325,7 +330,10 @@ var DownloadingQueue = /** @class */ (function (_super) {
325
330
  if (queuedInitSegment === null) {
326
331
  return;
327
332
  }
328
- var canceller = new TaskCanceller({ cancelOn: (_a = this._currentCanceller) === null || _a === void 0 ? void 0 : _a.signal });
333
+ var canceller = new TaskCanceller();
334
+ var unlinkCanceller = this._currentCanceller === null ?
335
+ noop :
336
+ canceller.linkToSignal(this._currentCanceller.signal);
329
337
  var segment = queuedInitSegment.segment, priority = queuedInitSegment.priority;
330
338
  var context = objectAssign({ segment: segment }, this._content);
331
339
  /**
@@ -341,6 +349,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
341
349
  log.info("Stream: init segment request interrupted temporarly.", segment.id);
342
350
  },
343
351
  beforeEnded: function () {
352
+ unlinkCanceller();
344
353
  _this._initSegmentRequest = null;
345
354
  isComplete = true;
346
355
  },
@@ -358,6 +367,7 @@ var DownloadingQueue = /** @class */ (function (_super) {
358
367
  },
359
368
  }, canceller.signal);
360
369
  request.catch(function (error) {
370
+ unlinkCanceller();
361
371
  if (!isComplete) {
362
372
  isComplete = true;
363
373
  _this.stop();
@@ -24,7 +24,7 @@ import { IRepresentationStreamPlaybackObservation, IStreamEventAddedSegmentPaylo
24
24
  * @param {Object} cancelSignal
25
25
  * @returns {Promise}
26
26
  */
27
- export default function pushInitSegment<T>({ playbackObserver, content, segment, segmentData, segmentBuffer, }: {
27
+ export default function pushInitSegment<T>({ playbackObserver, content, initSegmentUniqueId, segment, segmentData, segmentBuffer, }: {
28
28
  playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>;
29
29
  content: {
30
30
  adaptation: Adaptation;
@@ -32,7 +32,8 @@ export default function pushInitSegment<T>({ playbackObserver, content, segment,
32
32
  period: Period;
33
33
  representation: Representation;
34
34
  };
35
- segmentData: T | null;
35
+ initSegmentUniqueId: string;
36
+ segmentData: T;
36
37
  segment: ISegment;
37
38
  segmentBuffer: SegmentBuffer;
38
39
  }, cancelSignal: CancellationSignal): Promise<IStreamEventAddedSegmentPayload<T> | null>;