rx-player 3.26.3-dev.2022021400 → 3.27.0-dev.20220317

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 (340) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/FILES.md +5 -4
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/browser_detection.d.ts +4 -2
  5. package/dist/_esm5.processed/compat/browser_detection.js +4 -2
  6. package/dist/_esm5.processed/compat/eme/close_session.d.ts +11 -5
  7. package/dist/_esm5.processed/compat/eme/close_session.js +144 -36
  8. package/dist/_esm5.processed/compat/eme/custom_media_keys/index.d.ts +3 -5
  9. package/dist/_esm5.processed/compat/eme/custom_media_keys/index.js +21 -22
  10. package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +53 -34
  11. package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +43 -41
  12. package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +2 -3
  13. package/dist/_esm5.processed/compat/eme/generate_key_request.js +22 -26
  14. package/dist/_esm5.processed/compat/eme/load_session.d.ts +1 -2
  15. package/dist/_esm5.processed/compat/eme/load_session.js +68 -17
  16. package/dist/_esm5.processed/compat/event_listeners.js +2 -1
  17. package/dist/_esm5.processed/compat/should_favour_custom_safari_EME.js +2 -2
  18. package/dist/_esm5.processed/config.d.ts +166 -1080
  19. package/dist/_esm5.processed/config.js +17 -1119
  20. package/dist/_esm5.processed/core/abr/bandwidth_estimator.js +4 -1
  21. package/dist/_esm5.processed/core/abr/network_analyzer.js +2 -1
  22. package/dist/_esm5.processed/core/api/get_player_state.js +1 -1
  23. package/dist/_esm5.processed/core/api/index.d.ts +2 -1
  24. package/dist/_esm5.processed/core/api/media_element_track_choice_manager.js +2 -1
  25. package/dist/_esm5.processed/core/api/option_utils.d.ts +3 -1
  26. package/dist/_esm5.processed/core/api/option_utils.js +19 -6
  27. package/dist/_esm5.processed/core/api/playback_observer.js +5 -1
  28. package/dist/_esm5.processed/core/api/public_api.d.ts +82 -71
  29. package/dist/_esm5.processed/core/api/public_api.js +72 -33
  30. package/dist/_esm5.processed/core/{eme → decrypt}/__tests__/__global__/utils.d.ts +7 -49
  31. package/dist/_esm5.processed/core/{eme → decrypt}/__tests__/__global__/utils.js +25 -65
  32. package/dist/_esm5.processed/core/{eme → decrypt}/attach_media_keys.d.ts +12 -12
  33. package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +104 -0
  34. package/dist/_esm5.processed/core/{eme/clear_eme_session.d.ts → decrypt/clear_on_stop.d.ts} +3 -4
  35. package/dist/_esm5.processed/core/decrypt/clear_on_stop.js +41 -0
  36. package/dist/_esm5.processed/core/decrypt/content_decryptor.d.ts +216 -0
  37. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +866 -0
  38. package/dist/_esm5.processed/core/{eme/get_session.d.ts → decrypt/create_or_load_session.d.ts} +28 -26
  39. package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +124 -0
  40. package/dist/_esm5.processed/core/{eme → decrypt}/create_session.d.ts +22 -19
  41. package/dist/_esm5.processed/core/decrypt/create_session.js +174 -0
  42. package/dist/_esm5.processed/core/decrypt/dispose_decryption_resources.d.ts +21 -0
  43. package/dist/_esm5.processed/core/decrypt/dispose_decryption_resources.js +81 -0
  44. package/dist/_esm5.processed/core/{eme → decrypt}/find_key_system.d.ts +11 -14
  45. package/dist/_esm5.processed/core/decrypt/find_key_system.js +300 -0
  46. package/dist/_esm5.processed/core/{eme → decrypt}/get_current_key_system.d.ts +0 -0
  47. package/dist/_esm5.processed/core/{eme → decrypt}/get_current_key_system.js +1 -1
  48. package/dist/_esm5.processed/core/{eme → decrypt}/get_media_keys.d.ts +13 -5
  49. package/dist/_esm5.processed/core/decrypt/get_media_keys.js +153 -0
  50. package/dist/_esm5.processed/core/{eme → decrypt}/index.d.ts +5 -6
  51. package/dist/_esm5.processed/core/{eme → decrypt}/index.js +5 -5
  52. package/dist/_esm5.processed/core/{eme → decrypt}/init_media_keys.d.ts +6 -4
  53. package/dist/_esm5.processed/core/decrypt/init_media_keys.js +82 -0
  54. package/dist/_esm5.processed/core/decrypt/session_events_listener.d.ts +77 -0
  55. package/dist/_esm5.processed/core/{eme → decrypt}/session_events_listener.js +25 -24
  56. package/dist/_esm5.processed/core/{eme → decrypt}/set_server_certificate.d.ts +15 -6
  57. package/dist/_esm5.processed/core/decrypt/set_server_certificate.js +141 -0
  58. package/dist/_esm5.processed/core/{eme → decrypt}/types.d.ts +119 -241
  59. package/dist/_esm5.processed/core/{eme → decrypt}/types.js +0 -0
  60. package/dist/_esm5.processed/core/{eme → decrypt}/utils/are_init_values_compatible.d.ts +3 -3
  61. package/dist/_esm5.processed/core/{eme → decrypt}/utils/are_init_values_compatible.js +5 -5
  62. package/dist/_esm5.processed/core/{eme → decrypt/utils}/check_key_statuses.d.ts +2 -2
  63. package/dist/_esm5.processed/core/{eme → decrypt/utils}/check_key_statuses.js +4 -3
  64. package/dist/_esm5.processed/core/{eme/utils/close_session.d.ts → decrypt/utils/clean_old_loaded_sessions.d.ts} +8 -7
  65. package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +85 -0
  66. package/dist/_esm5.processed/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.d.ts +1 -1
  67. package/dist/_esm5.processed/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.js +2 -2
  68. package/dist/_esm5.processed/core/{eme → decrypt/utils}/get_drm_system_id.d.ts +0 -0
  69. package/dist/_esm5.processed/core/{eme → decrypt/utils}/get_drm_system_id.js +1 -1
  70. package/dist/_esm5.processed/core/decrypt/utils/init_data_values_container.d.ts +69 -0
  71. package/dist/_esm5.processed/core/decrypt/utils/init_data_values_container.js +99 -0
  72. package/dist/_esm5.processed/core/{eme → decrypt}/utils/is_session_usable.d.ts +0 -1
  73. package/dist/_esm5.processed/core/{eme → decrypt}/utils/is_session_usable.js +4 -5
  74. package/dist/_esm5.processed/core/decrypt/utils/key_id_comparison.d.ts +44 -0
  75. package/dist/_esm5.processed/core/decrypt/utils/key_id_comparison.js +77 -0
  76. package/dist/_esm5.processed/core/decrypt/utils/key_session_record.d.ts +104 -0
  77. package/dist/_esm5.processed/core/decrypt/utils/key_session_record.js +155 -0
  78. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +108 -0
  79. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +303 -0
  80. package/dist/_esm5.processed/core/{eme → decrypt/utils}/media_keys_infos_store.d.ts +4 -4
  81. package/dist/_esm5.processed/core/{eme → decrypt/utils}/media_keys_infos_store.js +0 -0
  82. package/dist/_esm5.processed/core/{eme → decrypt}/utils/persistent_sessions_store.d.ts +8 -18
  83. package/dist/_esm5.processed/core/{eme → decrypt}/utils/persistent_sessions_store.js +119 -97
  84. package/dist/_esm5.processed/core/{eme/utils/init_data_container.d.ts → decrypt/utils/serializable_bytes.d.ts} +8 -5
  85. package/dist/_esm5.processed/core/{eme/utils/init_data_container.js → decrypt/utils/serializable_bytes.js} +9 -9
  86. package/dist/_esm5.processed/core/{eme → decrypt/utils}/server_certificate_store.d.ts +1 -1
  87. package/dist/_esm5.processed/core/{eme → decrypt/utils}/server_certificate_store.js +1 -1
  88. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +2 -2
  89. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +1 -1
  90. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +1 -1
  91. package/dist/_esm5.processed/core/init/get_initial_time.js +1 -1
  92. package/dist/_esm5.processed/core/init/initialize_directfile.d.ts +1 -1
  93. package/dist/_esm5.processed/core/init/initialize_directfile.js +11 -17
  94. package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +4 -2
  95. package/dist/_esm5.processed/core/init/initialize_media_source.js +18 -69
  96. package/dist/_esm5.processed/core/init/link_drm_and_content.d.ts +61 -0
  97. package/dist/_esm5.processed/core/init/link_drm_and_content.js +94 -0
  98. package/dist/_esm5.processed/core/init/manifest_update_scheduler.js +2 -1
  99. package/dist/_esm5.processed/core/init/stall_avoider.js +1 -1
  100. package/dist/_esm5.processed/core/init/stream_events_emitter/stream_events_emitter.js +1 -1
  101. package/dist/_esm5.processed/core/init/types.d.ts +2 -4
  102. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +1 -1
  103. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +3 -1
  104. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +17 -1
  105. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +22 -5
  106. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.d.ts +2 -1
  107. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +6 -3
  108. package/dist/_esm5.processed/core/stream/events_generators.d.ts +8 -3
  109. package/dist/_esm5.processed/core/stream/events_generators.js +3 -2
  110. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.d.ts +1 -0
  111. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +3 -3
  112. package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.js +2 -1
  113. package/dist/_esm5.processed/core/stream/period/get_adaptation_switch_strategy.js +1 -1
  114. package/dist/_esm5.processed/core/stream/period/period_stream.d.ts +2 -1
  115. package/dist/_esm5.processed/core/stream/period/period_stream.js +3 -3
  116. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +2 -2
  117. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +6 -1
  118. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +12 -9
  119. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +19 -14
  120. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +86 -10
  121. package/dist/_esm5.processed/core/stream/representation/get_segment_priority.js +1 -1
  122. package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +3 -3
  123. package/dist/_esm5.processed/core/stream/representation/representation_stream.d.ts +6 -0
  124. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +19 -8
  125. package/dist/_esm5.processed/core/stream/types.d.ts +1 -1
  126. package/dist/_esm5.processed/default_config.d.ts +1114 -0
  127. package/dist/_esm5.processed/default_config.js +1145 -0
  128. package/dist/_esm5.processed/experimental/index.d.ts +2 -0
  129. package/dist/_esm5.processed/experimental/index.js +2 -0
  130. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.d.ts +1 -0
  131. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +1 -1
  132. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/DRMInfos.js +1 -2
  133. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/HDCPPolicy.js +1 -2
  134. package/dist/_esm5.processed/features/features_object.js +1 -1
  135. package/dist/_esm5.processed/features/initialize_features.js +1 -1
  136. package/dist/_esm5.processed/features/list/eme.d.ts +3 -3
  137. package/dist/_esm5.processed/features/list/eme.js +5 -5
  138. package/dist/_esm5.processed/features/types.d.ts +3 -3
  139. package/dist/_esm5.processed/manifest/manifest.d.ts +1 -14
  140. package/dist/_esm5.processed/manifest/manifest.js +10 -74
  141. package/dist/_esm5.processed/manifest/representation.d.ts +35 -3
  142. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/is_period_fulfilled.js +1 -2
  143. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +1 -2
  144. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +1 -1
  145. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +87 -75
  146. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +1 -2
  147. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +1 -0
  148. package/dist/_esm5.processed/public_types.d.ts +2 -2
  149. package/dist/_esm5.processed/transports/dash/image_pipelines.js +3 -0
  150. package/dist/_esm5.processed/transports/dash/segment_parser.js +6 -3
  151. package/dist/_esm5.processed/transports/dash/text_parser.js +8 -2
  152. package/dist/_esm5.processed/transports/local/segment_parser.js +4 -1
  153. package/dist/_esm5.processed/transports/local/text_parser.js +8 -2
  154. package/dist/_esm5.processed/transports/smooth/pipelines.js +68 -10
  155. package/dist/_esm5.processed/transports/types.d.ts +22 -0
  156. package/dist/_esm5.processed/utils/deep_merge.d.ts +12 -0
  157. package/dist/_esm5.processed/utils/deep_merge.js +53 -0
  158. package/dist/_esm5.processed/utils/reference.d.ts +29 -0
  159. package/dist/_esm5.processed/utils/reference.js +72 -24
  160. package/dist/_esm5.processed/utils/request/fetch.js +1 -2
  161. package/dist/_esm5.processed/utils/request/xhr.js +1 -1
  162. package/dist/_esm5.processed/utils/rx-from_cancellable_promise.js +7 -2
  163. package/dist/_esm5.processed/utils/task_canceller.d.ts +5 -3
  164. package/dist/_esm5.processed/utils/task_canceller.js +3 -3
  165. package/dist/rx-player.js +5002 -3033
  166. package/dist/rx-player.min.js +1 -1
  167. package/dummy +1 -0
  168. package/{dist/_esm5.processed/core/eme/dispose_eme.d.ts → experimental/index.d.ts} +1 -4
  169. package/{dist/_esm5.processed/core/eme/dispose_media_keys.d.ts → experimental/index.js} +1 -6
  170. package/package.json +32 -34
  171. package/scripts/build/templates/experimental/index.d.ts +16 -0
  172. package/scripts/build/templates/experimental/index.js +16 -0
  173. package/sonar-project.properties +1 -1
  174. package/src/README.md +6 -6
  175. package/src/compat/__tests__/should_favour_custom_safari_EME.test.ts +45 -5
  176. package/src/compat/browser_detection.ts +4 -2
  177. package/src/compat/eme/close_session.ts +90 -56
  178. package/src/compat/eme/custom_media_keys/index.ts +21 -38
  179. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +63 -46
  180. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +51 -49
  181. package/src/compat/eme/generate_key_request.ts +25 -33
  182. package/src/compat/eme/load_session.ts +29 -31
  183. package/src/compat/event_listeners.ts +2 -1
  184. package/src/compat/should_favour_custom_safari_EME.ts +5 -2
  185. package/src/config.ts +17 -1210
  186. package/src/core/README.md +1 -1
  187. package/src/core/abr/bandwidth_estimator.ts +4 -4
  188. package/src/core/abr/network_analyzer.ts +5 -6
  189. package/src/core/api/__tests__/get_player_state.test.ts +3 -3
  190. package/src/core/api/__tests__/option_utils.test.ts +17 -17
  191. package/src/core/api/get_player_state.ts +1 -1
  192. package/src/core/api/index.ts +3 -0
  193. package/src/core/api/option_utils.ts +37 -20
  194. package/src/core/api/playback_observer.ts +12 -8
  195. package/src/core/api/public_api.ts +151 -111
  196. package/src/core/decrypt/README.md +22 -0
  197. package/src/core/decrypt/__tests__/__global__/get_license.test.ts +418 -0
  198. package/src/core/decrypt/__tests__/__global__/init_data.test.ts +675 -0
  199. package/src/core/{eme → decrypt}/__tests__/__global__/media_key_system_access.test.ts +99 -92
  200. package/src/core/decrypt/__tests__/__global__/media_keys.test.ts +156 -0
  201. package/src/core/decrypt/__tests__/__global__/server_certificate.test.ts +262 -0
  202. package/src/core/{eme → decrypt}/__tests__/__global__/utils.ts +31 -93
  203. package/src/core/{eme → decrypt}/attach_media_keys.ts +49 -56
  204. package/src/core/decrypt/clear_on_stop.ts +48 -0
  205. package/src/core/decrypt/content_decryptor.ts +1158 -0
  206. package/src/core/decrypt/create_or_load_session.ts +130 -0
  207. package/src/core/decrypt/create_session.ts +175 -0
  208. package/src/core/decrypt/dispose_decryption_resources.ts +39 -0
  209. package/src/core/{eme → decrypt}/find_key_system.ts +112 -122
  210. package/src/core/{eme → decrypt}/get_current_key_system.ts +1 -1
  211. package/src/core/decrypt/get_media_keys.ts +145 -0
  212. package/src/core/{eme → decrypt}/index.ts +11 -8
  213. package/src/core/decrypt/init_media_keys.ts +51 -0
  214. package/src/core/{eme → decrypt}/session_events_listener.ts +93 -55
  215. package/src/core/decrypt/set_server_certificate.ts +104 -0
  216. package/src/core/{eme → decrypt}/types.ts +128 -258
  217. package/src/core/{eme → decrypt}/utils/__tests__/are_init_values_compatible.test.ts +1 -1
  218. package/src/core/{eme → decrypt/utils}/__tests__/clean_old_loaded_sessions.test.ts +29 -71
  219. package/src/core/{eme → decrypt/utils}/__tests__/clean_old_stored_persistent_info.test.ts +6 -6
  220. package/src/core/{eme → decrypt}/utils/are_init_values_compatible.ts +9 -9
  221. package/src/core/{eme → decrypt/utils}/check_key_statuses.ts +6 -5
  222. package/{dist/_esm5.processed/core/eme/clean_old_loaded_sessions.js → src/core/decrypt/utils/clean_old_loaded_sessions.ts} +20 -20
  223. package/src/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.ts +3 -3
  224. package/src/core/{eme → decrypt/utils}/get_drm_system_id.ts +1 -1
  225. package/src/core/decrypt/utils/init_data_values_container.ts +119 -0
  226. package/src/core/{eme → decrypt}/utils/is_session_usable.ts +4 -5
  227. package/src/core/decrypt/utils/key_id_comparison.ts +82 -0
  228. package/src/core/decrypt/utils/key_session_record.ts +175 -0
  229. package/src/core/decrypt/utils/loaded_sessions_store.ts +318 -0
  230. package/src/core/{eme → decrypt/utils}/media_keys_infos_store.ts +4 -4
  231. package/src/core/{eme → decrypt}/utils/persistent_sessions_store.ts +122 -104
  232. package/src/core/{eme/utils/init_data_container.ts → decrypt/utils/serializable_bytes.ts} +8 -5
  233. package/src/core/{eme → decrypt/utils}/server_certificate_store.ts +2 -2
  234. package/src/core/fetchers/manifest/manifest_fetcher.ts +4 -4
  235. package/src/core/fetchers/segment/segment_fetcher.ts +4 -4
  236. package/src/core/fetchers/segment/segment_fetcher_creator.ts +2 -2
  237. package/src/core/init/.initialize_media_source.ts.un~ +0 -0
  238. package/src/core/init/get_initial_time.ts +2 -1
  239. package/src/core/init/initialize_directfile.ts +17 -20
  240. package/src/core/init/initialize_media_source.ts +42 -105
  241. package/src/core/init/link_drm_and_content.ts +176 -0
  242. package/src/core/init/manifest_update_scheduler.ts +5 -3
  243. package/src/core/init/stall_avoider.ts +6 -5
  244. package/src/core/init/stream_events_emitter/stream_events_emitter.ts +2 -1
  245. package/src/core/init/types.ts +1 -39
  246. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +2 -1
  247. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +3 -4
  248. package/src/core/segment_buffers/inventory/segment_inventory.ts +42 -8
  249. package/src/core/stream/adaptation/adaptation_stream.ts +7 -1
  250. package/src/core/stream/events_generators.ts +9 -4
  251. package/src/core/stream/orchestrator/stream_orchestrator.ts +9 -4
  252. package/src/core/stream/period/create_empty_adaptation_stream.ts +2 -1
  253. package/src/core/stream/period/get_adaptation_switch_strategy.ts +1 -1
  254. package/src/core/stream/period/period_stream.ts +5 -2
  255. package/src/core/stream/representation/force_garbage_collection.ts +2 -2
  256. package/src/core/stream/representation/get_buffer_status.ts +28 -16
  257. package/src/core/stream/representation/get_needed_segments.ts +124 -28
  258. package/src/core/stream/representation/get_segment_priority.ts +1 -2
  259. package/src/core/stream/representation/push_media_segment.ts +3 -2
  260. package/src/core/stream/representation/representation_stream.ts +30 -7
  261. package/src/core/stream/types.ts +1 -1
  262. package/src/default_config.ts +1241 -0
  263. package/src/experimental/index.ts +5 -0
  264. package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +1 -0
  265. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +2 -1
  266. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/DRMInfos.test.ts +3 -10
  267. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/HDCPPolicy.test.ts +4 -4
  268. package/src/experimental/tools/mediaCapabilitiesProber/probers/DRMInfos.ts +1 -2
  269. package/src/experimental/tools/mediaCapabilitiesProber/probers/HDCPPolicy.ts +1 -2
  270. package/src/features/__tests__/initialize_features.test.ts +2 -2
  271. package/src/features/features_object.ts +1 -1
  272. package/src/features/initialize_features.ts +1 -1
  273. package/src/features/list/__tests__/eme.test.ts +5 -5
  274. package/src/features/list/eme.ts +5 -5
  275. package/src/features/types.ts +3 -10
  276. package/src/manifest/manifest.ts +6 -76
  277. package/src/manifest/representation.ts +36 -3
  278. package/src/parsers/manifest/dash/common/indexes/is_period_fulfilled.ts +1 -2
  279. package/src/parsers/manifest/dash/common/indexes/template.ts +1 -2
  280. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +1 -1
  281. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +109 -64
  282. package/src/parsers/manifest/dash/common/parse_mpd.ts +1 -2
  283. package/src/parsers/manifest/smooth/create_parser.ts +1 -0
  284. package/src/parsers/texttracks/webvtt/html/__tests__/create_styled_element.test.ts +1 -0
  285. package/src/public_types.ts +5 -1
  286. package/src/transports/dash/image_pipelines.ts +3 -0
  287. package/src/transports/dash/segment_parser.ts +5 -0
  288. package/src/transports/dash/text_parser.ts +8 -0
  289. package/src/transports/local/segment_parser.ts +4 -0
  290. package/src/transports/local/text_parser.ts +8 -0
  291. package/src/transports/smooth/pipelines.ts +22 -9
  292. package/src/transports/types.ts +22 -0
  293. package/src/utils/__tests__/deep_merge.test.ts +48 -0
  294. package/src/utils/deep_merge.ts +46 -0
  295. package/src/utils/reference.ts +116 -23
  296. package/src/utils/request/fetch.ts +1 -2
  297. package/src/utils/request/xhr.ts +2 -1
  298. package/src/utils/rx-from_cancellable_promise.ts +7 -2
  299. package/src/utils/task_canceller.ts +6 -4
  300. package/dist/_esm5.processed/core/eme/attach_media_keys.js +0 -57
  301. package/dist/_esm5.processed/core/eme/clean_old_loaded_sessions.d.ts +0 -59
  302. package/dist/_esm5.processed/core/eme/clear_eme_session.js +0 -50
  303. package/dist/_esm5.processed/core/eme/create_session.js +0 -126
  304. package/dist/_esm5.processed/core/eme/dispose_eme.js +0 -23
  305. package/dist/_esm5.processed/core/eme/dispose_media_keys.js +0 -36
  306. package/dist/_esm5.processed/core/eme/eme_manager.d.ts +0 -31
  307. package/dist/_esm5.processed/core/eme/eme_manager.js +0 -278
  308. package/dist/_esm5.processed/core/eme/find_key_system.js +0 -253
  309. package/dist/_esm5.processed/core/eme/get_media_keys.js +0 -85
  310. package/dist/_esm5.processed/core/eme/get_session.js +0 -68
  311. package/dist/_esm5.processed/core/eme/init_media_keys.js +0 -66
  312. package/dist/_esm5.processed/core/eme/session_events_listener.d.ts +0 -41
  313. package/dist/_esm5.processed/core/eme/set_server_certificate.js +0 -85
  314. package/dist/_esm5.processed/core/eme/utils/close_session.js +0 -81
  315. package/dist/_esm5.processed/core/eme/utils/init_data_store.d.ts +0 -115
  316. package/dist/_esm5.processed/core/eme/utils/init_data_store.js +0 -181
  317. package/dist/_esm5.processed/core/eme/utils/loaded_sessions_store.d.ts +0 -123
  318. package/dist/_esm5.processed/core/eme/utils/loaded_sessions_store.js +0 -173
  319. package/dist/_esm5.processed/core/init/create_eme_manager.d.ts +0 -34
  320. package/dist/_esm5.processed/core/init/create_eme_manager.js +0 -52
  321. package/src/core/eme/README.md +0 -26
  322. package/src/core/eme/__tests__/__global__/get_license.test.ts +0 -414
  323. package/src/core/eme/__tests__/__global__/init_data.test.ts +0 -908
  324. package/src/core/eme/__tests__/__global__/media_keys.test.ts +0 -266
  325. package/src/core/eme/__tests__/__global__/server_certificate.test.ts +0 -364
  326. package/src/core/eme/__tests__/init_media_keys.test.ts +0 -182
  327. package/src/core/eme/clean_old_loaded_sessions.ts +0 -96
  328. package/src/core/eme/clear_eme_session.ts +0 -62
  329. package/src/core/eme/create_session.ts +0 -187
  330. package/src/core/eme/dispose_eme.ts +0 -25
  331. package/src/core/eme/dispose_media_keys.ts +0 -46
  332. package/src/core/eme/eme_manager.ts +0 -387
  333. package/src/core/eme/get_media_keys.ts +0 -141
  334. package/src/core/eme/get_session.ts +0 -135
  335. package/src/core/eme/init_media_keys.ts +0 -106
  336. package/src/core/eme/set_server_certificate.ts +0 -115
  337. package/src/core/eme/utils/close_session.ts +0 -113
  338. package/src/core/eme/utils/init_data_store.ts +0 -234
  339. package/src/core/eme/utils/loaded_sessions_store.ts +0 -235
  340. package/src/core/init/create_eme_manager.ts +0 -95
@@ -32,7 +32,6 @@ import EVENTS from "../events_generators";
32
32
  import reloadAfterSwitch from "../reload_after_switch";
33
33
  import RepresentationStream from "../representation";
34
34
  import createRepresentationEstimator from "./create_representation_estimator";
35
- var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
36
35
  /**
37
36
  * Create new AdaptationStream Observable, which task will be to download the
38
37
  * media data for a given Adaptation (i.e. "track").
@@ -48,7 +47,7 @@ var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
48
47
  * @returns {Observable}
49
48
  */
50
49
  export default function AdaptationStream(_a) {
51
- var abrManager = _a.abrManager, playbackObserver = _a.playbackObserver, content = _a.content, options = _a.options, segmentBuffer = _a.segmentBuffer, segmentFetcherCreator = _a.segmentFetcherCreator, wantedBufferAhead = _a.wantedBufferAhead;
50
+ var abrManager = _a.abrManager, playbackObserver = _a.playbackObserver, content = _a.content, options = _a.options, segmentBuffer = _a.segmentBuffer, segmentFetcherCreator = _a.segmentFetcherCreator, wantedBufferAhead = _a.wantedBufferAhead, maxVideoBufferSize = _a.maxVideoBufferSize;
52
51
  var directManualBitrateSwitching = options.manualBitrateSwitchingMode === "direct";
53
52
  var manifest = content.manifest, period = content.period, adaptation = content.adaptation;
54
53
  /**
@@ -120,6 +119,7 @@ export default function AdaptationStream(_a) {
120
119
  if (directManualBitrateSwitching &&
121
120
  fromEstimate.manual &&
122
121
  !isFirstEstimate) {
122
+ var DELTA_POSITION_AFTER_RELOAD = config.getCurrent().DELTA_POSITION_AFTER_RELOAD;
123
123
  return reloadAfterSwitch(period, adaptation.type, playbackObserver, DELTA_POSITION_AFTER_RELOAD.bitrateSwitch);
124
124
  }
125
125
  /**
@@ -187,9 +187,12 @@ export default function AdaptationStream(_a) {
187
187
  1;
188
188
  bufferGoalRatioMap[representation.id] = bufferGoalRatio;
189
189
  var bufferGoal$ = wantedBufferAhead.asObservable().pipe(map(function (wba) { return wba * bufferGoalRatio; }));
190
+ // eslint-disable-next-line max-len
191
+ var maxBufferSize$ = adaptation.type === "video" ? maxVideoBufferSize.asObservable() :
192
+ observableOf(Infinity);
190
193
  log.info("Stream: changing representation", adaptation.type, representation.id, representation.bitrate);
191
194
  return RepresentationStream({ playbackObserver: playbackObserver, content: { representation: representation, adaptation: adaptation, period: period, manifest: manifest }, segmentBuffer: segmentBuffer, segmentFetcher: segmentFetcher, terminate$: terminateCurrentStream$,
192
- options: { bufferGoal$: bufferGoal$, drmSystemId: options.drmSystemId, fastSwitchThreshold$: fastSwitchThreshold$ } })
195
+ options: { bufferGoal$: bufferGoal$, maxBufferSize$: maxBufferSize$, drmSystemId: options.drmSystemId, fastSwitchThreshold$: fastSwitchThreshold$ } })
193
196
  .pipe(catchError(function (err) {
194
197
  var formattedError = formatError(err, {
195
198
  defaultCode: "NONE",
@@ -15,8 +15,8 @@
15
15
  */
16
16
  import { Subject } from "rxjs";
17
17
  import { ICustomError } from "../../errors";
18
- import { Adaptation, ISegment, Period, Representation } from "../../manifest";
19
- import { IContentProtection } from "../eme";
18
+ import Manifest, { Adaptation, ISegment, Period, Representation } from "../../manifest";
19
+ import { IRepresentationProtectionData } from "../../manifest/representation";
20
20
  import { IBufferType } from "../segment_buffers";
21
21
  import { IActivePeriodChangedEvent, IAdaptationChangeEvent, IBitrateEstimationChangeEvent, ICompletedStreamEvent, IEncryptionDataEncounteredEvent, IEndOfStreamEvent, ILockedStreamEvent, INeedsBufferFlushEvent, INeedsDecipherabilityFlush, INeedsMediaSourceReload, IPeriodStreamClearedEvent, IPeriodStreamReadyEvent, IRepresentationChangeEvent, IResumeStreamEvent, IStreamEventAddedSegment, IStreamManifestMightBeOutOfSync, IStreamNeedsManifestRefresh, IStreamTerminatingEvent, IStreamWarningEvent, IWaitingMediaSourceReloadInternalEvent } from "./types";
22
22
  declare const EVENTS: {
@@ -52,7 +52,12 @@ declare const EVENTS: {
52
52
  needsDecipherabilityFlush(position: number, autoPlay: boolean, duration: number): INeedsDecipherabilityFlush;
53
53
  periodStreamReady(type: IBufferType, period: Period, adaptation$: Subject<Adaptation | null>): IPeriodStreamReadyEvent;
54
54
  periodStreamCleared(type: IBufferType, period: Period): IPeriodStreamClearedEvent;
55
- encryptionDataEncountered(initDataInfo: IContentProtection): IEncryptionDataEncounteredEvent;
55
+ encryptionDataEncountered(reprProtData: IRepresentationProtectionData, content: {
56
+ manifest: Manifest;
57
+ period: Period;
58
+ adaptation: Adaptation;
59
+ representation: Representation;
60
+ }): IEncryptionDataEncounteredEvent;
56
61
  representationChange(type: IBufferType, period: Period, representation: Representation): IRepresentationChangeEvent;
57
62
  streamTerminating(): IStreamTerminatingEvent;
58
63
  resumeStream(): IResumeStreamEvent;
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import objectAssign from "../../utils/object_assign";
16
17
  var EVENTS = {
17
18
  activePeriodChanged: function (period) {
18
19
  return { type: "activePeriodChanged",
@@ -84,9 +85,9 @@ var EVENTS = {
84
85
  return { type: "periodStreamCleared",
85
86
  value: { type: type, period: period } };
86
87
  },
87
- encryptionDataEncountered: function (initDataInfo) {
88
+ encryptionDataEncountered: function (reprProtData, content) {
88
89
  return { type: "encryption-data-encountered",
89
- value: initDataInfo };
90
+ value: objectAssign({ content: content }, reprProtData) };
90
91
  },
91
92
  representationChange: function (type, period, representation) {
92
93
  return { type: "representationChange",
@@ -26,6 +26,7 @@ export declare type IStreamOrchestratorPlaybackObservation = IPeriodStreamPlayba
26
26
  /** Options tweaking the behavior of the StreamOrchestrator. */
27
27
  export declare type IStreamOrchestratorOptions = IPeriodStreamOptions & {
28
28
  wantedBufferAhead: IReadOnlySharedReference<number>;
29
+ maxVideoBufferSize: IReadOnlySharedReference<number>;
29
30
  maxBufferAhead: IReadOnlySharedReference<number>;
30
31
  maxBufferBehind: IReadOnlySharedReference<number>;
31
32
  };
@@ -37,7 +37,6 @@ import PeriodStream from "../period";
37
37
  import ActivePeriodEmitter from "./active_period_emitter";
38
38
  import areStreamsComplete from "./are_streams_complete";
39
39
  import getBlacklistedRanges from "./get_blacklisted_ranges";
40
- var MAXIMUM_MAX_BUFFER_AHEAD = config.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = config.MAXIMUM_MAX_BUFFER_BEHIND;
41
40
  /**
42
41
  * Create and manage the various Stream Observables needed for the content to
43
42
  * play:
@@ -65,7 +64,8 @@ var MAXIMUM_MAX_BUFFER_AHEAD = config.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFF
65
64
  */
66
65
  export default function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffersStore, segmentFetcherCreator, options) {
67
66
  var manifest = content.manifest, initialPeriod = content.initialPeriod;
68
- var maxBufferAhead = options.maxBufferAhead, maxBufferBehind = options.maxBufferBehind, wantedBufferAhead = options.wantedBufferAhead;
67
+ var maxBufferAhead = options.maxBufferAhead, maxBufferBehind = options.maxBufferBehind, wantedBufferAhead = options.wantedBufferAhead, maxVideoBufferSize = options.maxVideoBufferSize;
68
+ var _a = config.getCurrent(), MAXIMUM_MAX_BUFFER_AHEAD = _a.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = _a.MAXIMUM_MAX_BUFFER_BEHIND;
69
69
  // Keep track of a unique BufferGarbageCollector created per
70
70
  // SegmentBuffer.
71
71
  var garbageCollectors = new WeakMapMemory(function (segmentBuffer) {
@@ -315,7 +315,7 @@ export default function StreamOrchestrator(content, playbackObserver, abrManager
315
315
  );
316
316
  // Will emit when the current Stream should be destroyed.
317
317
  var killCurrentStream$ = observableMerge(endOfCurrentStream$, destroyAll$);
318
- var periodStream$ = PeriodStream({ abrManager: abrManager, bufferType: bufferType, content: { manifest: manifest, period: basePeriod }, garbageCollectors: garbageCollectors, segmentFetcherCreator: segmentFetcherCreator, segmentBuffersStore: segmentBuffersStore, options: options, playbackObserver: playbackObserver, wantedBufferAhead: wantedBufferAhead }).pipe(mergeMap(function (evt) {
318
+ var periodStream$ = PeriodStream({ abrManager: abrManager, bufferType: bufferType, content: { manifest: manifest, period: basePeriod }, garbageCollectors: garbageCollectors, segmentFetcherCreator: segmentFetcherCreator, segmentBuffersStore: segmentBuffersStore, options: options, playbackObserver: playbackObserver, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize }).pipe(mergeMap(function (evt) {
319
319
  if (evt.type === "stream-status") {
320
320
  if (evt.value.hasFinishedLoading) {
321
321
  var nextPeriod = manifest.getPeriodAfter(basePeriod);
@@ -31,7 +31,8 @@ export default function createEmptyAdaptationStream(playbackObserver, wantedBuff
31
31
  var hasFinishedLoading = false;
32
32
  var wantedBufferAhead$ = wantedBufferAhead.asObservable();
33
33
  var observation$ = playbackObserver.observe(true);
34
- return observableCombineLatest([observation$, wantedBufferAhead$]).pipe(mergeMap(function (_a) {
34
+ return observableCombineLatest([observation$,
35
+ wantedBufferAhead$]).pipe(mergeMap(function (_a) {
35
36
  var observation = _a[0], wba = _a[1];
36
37
  var position = observation.position;
37
38
  if (period.end !== undefined && position + wba >= period.end) {
@@ -16,7 +16,6 @@
16
16
  import config from "../../../config";
17
17
  import areCodecsCompatible from "../../../utils/are_codecs_compatible";
18
18
  import { convertToRanges, excludeFromRanges, isTimeInRange, isTimeInRanges, keepRangeIntersection, } from "../../../utils/ranges";
19
- var ADAPTATION_SWITCH_BUFFER_PADDINGS = config.ADAPTATION_SWITCH_BUFFER_PADDINGS;
20
19
  /**
21
20
  * Find out what to do when switching Adaptation, based on the current
22
21
  * situation.
@@ -92,6 +91,7 @@ export default function getAdaptationSwitchStrategy(segmentBuffer, period, adapt
92
91
  }
93
92
  // Next, exclude data around current position to avoid decoding issues
94
93
  var bufferType = adaptation.type;
94
+ var ADAPTATION_SWITCH_BUFFER_PADDINGS = config.getCurrent().ADAPTATION_SWITCH_BUFFER_PADDINGS;
95
95
  /** Ranges that won't be cleaned from the current buffer. */
96
96
  var paddingBefore = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].before;
97
97
  if (paddingBefore == null) {
@@ -60,6 +60,7 @@ export interface IPeriodStreamArguments {
60
60
  playbackObserver: IReadOnlyPlaybackObserver<IPeriodStreamPlaybackObservation>;
61
61
  options: IPeriodStreamOptions;
62
62
  wantedBufferAhead: IReadOnlySharedReference<number>;
63
+ maxVideoBufferSize: IReadOnlySharedReference<number>;
63
64
  }
64
65
  /** Options tweaking the behavior of the PeriodStream. */
65
66
  export declare type IPeriodStreamOptions = IAdaptationStreamOptions & {
@@ -89,4 +90,4 @@ export declare type IPeriodStreamOptions = IAdaptationStreamOptions & {
89
90
  * @param {Object} args
90
91
  * @returns {Observable}
91
92
  */
92
- export default function PeriodStream({ abrManager, bufferType, content, garbageCollectors, playbackObserver, segmentFetcherCreator, segmentBuffersStore, options, wantedBufferAhead, }: IPeriodStreamArguments): Observable<IPeriodStreamEvent>;
93
+ export default function PeriodStream({ abrManager, bufferType, content, garbageCollectors, playbackObserver, segmentFetcherCreator, segmentBuffersStore, options, wantedBufferAhead, maxVideoBufferSize, }: IPeriodStreamArguments): Observable<IPeriodStreamEvent>;
@@ -25,7 +25,6 @@ import EVENTS from "../events_generators";
25
25
  import reloadAfterSwitch from "../reload_after_switch";
26
26
  import createEmptyStream from "./create_empty_adaptation_stream";
27
27
  import getAdaptationSwitchStrategy from "./get_adaptation_switch_strategy";
28
- var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
29
28
  /**
30
29
  * Create single PeriodStream Observable:
31
30
  * - Lazily create (or reuse) a SegmentBuffer for the given type.
@@ -37,7 +36,7 @@ var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
37
36
  * @returns {Observable}
38
37
  */
39
38
  export default function PeriodStream(_a) {
40
- var abrManager = _a.abrManager, bufferType = _a.bufferType, content = _a.content, garbageCollectors = _a.garbageCollectors, playbackObserver = _a.playbackObserver, segmentFetcherCreator = _a.segmentFetcherCreator, segmentBuffersStore = _a.segmentBuffersStore, options = _a.options, wantedBufferAhead = _a.wantedBufferAhead;
39
+ var abrManager = _a.abrManager, bufferType = _a.bufferType, content = _a.content, garbageCollectors = _a.garbageCollectors, playbackObserver = _a.playbackObserver, segmentFetcherCreator = _a.segmentFetcherCreator, segmentBuffersStore = _a.segmentBuffersStore, options = _a.options, wantedBufferAhead = _a.wantedBufferAhead, maxVideoBufferSize = _a.maxVideoBufferSize;
41
40
  var period = content.period;
42
41
  // Emits the chosen Adaptation for the current type.
43
42
  // `null` when no Adaptation is chosen (e.g. no subtitles)
@@ -50,6 +49,7 @@ export default function PeriodStream(_a) {
50
49
  * This value contains this relative position, in seconds.
51
50
  * @see reloadAfterSwitch
52
51
  */
52
+ var DELTA_POSITION_AFTER_RELOAD = config.getCurrent().DELTA_POSITION_AFTER_RELOAD;
53
53
  var relativePosAfterSwitch = switchNb === 0 ? 0 :
54
54
  bufferType === "audio" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio :
55
55
  bufferType === "video" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.video :
@@ -118,7 +118,7 @@ export default function PeriodStream(_a) {
118
118
  function createAdaptationStream(adaptation, segmentBuffer) {
119
119
  var manifest = content.manifest;
120
120
  var adaptationPlaybackObserver = createAdaptationStreamPlaybackObserver(playbackObserver, segmentBuffer);
121
- return AdaptationStream({ abrManager: abrManager, content: { manifest: manifest, period: period, adaptation: adaptation }, options: options, playbackObserver: adaptationPlaybackObserver, segmentBuffer: segmentBuffer, segmentFetcherCreator: segmentFetcherCreator, wantedBufferAhead: wantedBufferAhead }).pipe(catchError(function (error) {
121
+ return AdaptationStream({ abrManager: abrManager, content: { manifest: manifest, period: period, adaptation: adaptation }, options: options, playbackObserver: adaptationPlaybackObserver, segmentBuffer: segmentBuffer, segmentFetcherCreator: segmentFetcherCreator, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize }).pipe(catchError(function (error) {
122
122
  // Stream linked to a non-native media buffer should not impact the
123
123
  // stability of the player. ie: if a text buffer sends an error, we want
124
124
  // to continue playing without any subtitles
@@ -17,8 +17,6 @@ import { concatAll, defer as observableDefer, from as observableFrom, } from "rx
17
17
  import config from "../../../config";
18
18
  import log from "../../../log";
19
19
  import { getInnerAndOuterTimeRanges } from "../../../utils/ranges";
20
- var GC_GAP_CALM = config.BUFFER_GC_GAPS.CALM;
21
- var GC_GAP_BEEFY = config.BUFFER_GC_GAPS.BEEFY;
22
20
  /**
23
21
  * Run the garbage collector.
24
22
  *
@@ -31,6 +29,8 @@ var GC_GAP_BEEFY = config.BUFFER_GC_GAPS.BEEFY;
31
29
  */
32
30
  export default function forceGarbageCollection(currentPosition, bufferingQueue) {
33
31
  return observableDefer(function () {
32
+ var GC_GAP_CALM = config.getCurrent().BUFFER_GC_GAPS.CALM;
33
+ var GC_GAP_BEEFY = config.getCurrent().BUFFER_GC_GAPS.BEEFY;
34
34
  log.warn("Stream: Running garbage collector");
35
35
  var buffered = bufferingQueue.getBufferedRanges();
36
36
  var cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_CALM);
@@ -42,6 +42,11 @@ export interface IBufferStatus {
42
42
  * on which segments should be loaded.
43
43
  */
44
44
  shouldRefreshManifest: boolean;
45
+ /**
46
+ * If 'true', the buffer memory is saturated before being able to download
47
+ * at least MIN_REQUIRED_BUFFER_AHEAD ( default : 10sec )
48
+ */
49
+ isBufferFull: boolean;
45
50
  }
46
51
  /**
47
52
  * Checks on the current buffered data for the given type and Period
@@ -62,4 +67,4 @@ export default function getBufferStatus(content: {
62
67
  manifest: Manifest;
63
68
  period: Period;
64
69
  representation: Representation;
65
- }, wantedStartPosition: number, playbackObserver: IReadOnlyPlaybackObserver<unknown>, fastSwitchThreshold: number | undefined, bufferGoal: number, segmentBuffer: SegmentBuffer): IBufferStatus;
70
+ }, wantedStartPosition: number, playbackObserver: IReadOnlyPlaybackObserver<unknown>, fastSwitchThreshold: number | undefined, bufferGoal: number, maxBufferSize: number, segmentBuffer: SegmentBuffer): IBufferStatus;
@@ -18,7 +18,6 @@ import { SegmentBufferOperation, } from "../../segment_buffers";
18
18
  import checkForDiscontinuity from "./check_for_discontinuity";
19
19
  import getNeededSegments from "./get_needed_segments";
20
20
  import getSegmentPriority from "./get_segment_priority";
21
- var MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
22
21
  /**
23
22
  * Checks on the current buffered data for the given type and Period
24
23
  * and returns what should be done to fill the buffer according to the buffer
@@ -33,7 +32,7 @@ var MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
33
32
  * @param {Object} segmentBuffer
34
33
  * @returns {Object}
35
34
  */
36
- export default function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, segmentBuffer) {
35
+ export default function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer) {
37
36
  var _a;
38
37
  var period = content.period, representation = content.representation;
39
38
  segmentBuffer.synchronizeInventory();
@@ -56,8 +55,11 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
56
55
  /** Callback allowing to retrieve a segment's history in the buffer. */
57
56
  var getBufferedHistory = segmentBuffer.getSegmentHistory.bind(segmentBuffer);
58
57
  /** List of segments we will need to download. */
59
- var neededSegments = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed })
60
- .map(function (segment) { return ({ priority: getSegmentPriority(segment.time, wantedStartPosition), segment: segment }); });
58
+ var _b = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed, maxBufferSize: maxBufferSize }), neededSegments = _b.neededSegments, isBufferFull = _b.isBufferFull;
59
+ var prioritizedNeededSegments = neededSegments.map(function (segment) { return ({
60
+ priority: getSegmentPriority(segment.time, wantedStartPosition),
61
+ segment: segment,
62
+ }); });
61
63
  /**
62
64
  * `true` if the current `RepresentationStream` has loaded all the
63
65
  * needed segments for this Representation until the end of the Period.
@@ -66,7 +68,7 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
66
68
  var lastPosition = representation.index.getLastPosition();
67
69
  if (!representation.index.isInitialized() ||
68
70
  period.end === undefined ||
69
- neededSegments.length > 0) {
71
+ prioritizedNeededSegments.length > 0) {
70
72
  hasFinishedLoading = false;
71
73
  }
72
74
  else {
@@ -110,14 +112,14 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
110
112
  if (segmentsBeingPushed.length > 0) {
111
113
  nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { return info.segment.time; }));
112
114
  }
113
- if (neededSegments.length > 0) {
115
+ if (prioritizedNeededSegments.length > 0) {
114
116
  nextSegmentStart = nextSegmentStart !== null ?
115
- Math.min(nextSegmentStart, neededSegments[0].segment.time) :
116
- neededSegments[0].segment.time;
117
+ Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) :
118
+ prioritizedNeededSegments[0].segment.time;
117
119
  }
118
120
  imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments);
119
121
  }
120
- return { imminentDiscontinuity: imminentDiscontinuity, hasFinishedLoading: hasFinishedLoading, neededSegments: neededSegments, shouldRefreshManifest: shouldRefreshManifest };
122
+ return { imminentDiscontinuity: imminentDiscontinuity, hasFinishedLoading: hasFinishedLoading, neededSegments: prioritizedNeededSegments, isBufferFull: isBufferFull, shouldRefreshManifest: shouldRefreshManifest };
121
123
  }
122
124
  /**
123
125
  * From the given SegmentInventory, filters the "playable" (in a supported codec
@@ -128,6 +130,7 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
128
130
  * @returns {Array.<Object>}
129
131
  */
130
132
  function getPlayableBufferedSegments(neededRange, segmentInventory) {
133
+ var MINIMUM_SEGMENT_SIZE = config.getCurrent().MINIMUM_SEGMENT_SIZE;
131
134
  var segmentRoundingError = Math.max(1 / 60, MINIMUM_SEGMENT_SIZE);
132
135
  var minEnd = neededRange.start + segmentRoundingError;
133
136
  var maxStart = neededRange.end - segmentRoundingError;
@@ -14,17 +14,18 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import Manifest, { Adaptation, ISegment, Period, Representation } from "../../../manifest";
17
- import { IBufferedChunk } from "../../segment_buffers";
17
+ import { IBufferedChunk, IEndOfSegmentInfos } from "../../segment_buffers";
18
18
  import { IBufferedHistoryEntry, IChunkContext } from "../../segment_buffers/inventory";
19
+ interface IContentContext {
20
+ adaptation: Adaptation;
21
+ manifest: Manifest;
22
+ period: Period;
23
+ representation: Representation;
24
+ }
19
25
  /** Arguments for `getNeededSegments`. */
20
26
  export interface IGetNeededSegmentsArguments {
21
27
  /** The content we want to load segments for */
22
- content: {
23
- adaptation: Adaptation;
24
- manifest: Manifest;
25
- period: Period;
26
- representation: Representation;
27
- };
28
+ content: IContentContext;
28
29
  /**
29
30
  * The current playing position.
30
31
  * Important to avoid asking for segments on the same exact position, which
@@ -46,12 +47,7 @@ export interface IGetNeededSegmentsArguments {
46
47
  end: number;
47
48
  };
48
49
  /** The list of segments that are already in the process of being pushed. */
49
- segmentsBeingPushed: Array<{
50
- adaptation: Adaptation;
51
- period: Period;
52
- representation: Representation;
53
- segment: ISegment;
54
- }>;
50
+ segmentsBeingPushed: IEndOfSegmentInfos[];
55
51
  /**
56
52
  * Information on the segments already in the buffer, in chronological order.
57
53
  *
@@ -62,8 +58,16 @@ export interface IGetNeededSegmentsArguments {
62
58
  * re-requested.
63
59
  */
64
60
  bufferedSegments: IBufferedChunk[];
61
+ /**
62
+ * maxBufferSize is the maximum memory in kilobytes that the buffer should take
63
+ */
64
+ maxBufferSize: number;
65
65
  getBufferedHistory: (context: IChunkContext) => IBufferedHistoryEntry[];
66
66
  }
67
+ interface INeededSegments {
68
+ neededSegments: ISegment[];
69
+ isBufferFull: boolean;
70
+ }
67
71
  /**
68
72
  * Return the list of segments that can currently be downloaded to fill holes
69
73
  * in the buffer in the given range, including already-pushed segments currently
@@ -74,4 +78,5 @@ export interface IGetNeededSegmentsArguments {
74
78
  * @param {Object} args
75
79
  * @returns {Array.<Object>}
76
80
  */
77
- export default function getNeededSegments({ bufferedSegments, content, currentPlaybackTime, fastSwitchThreshold, getBufferedHistory, neededRange, segmentsBeingPushed, }: IGetNeededSegmentsArguments): ISegment[];
81
+ export default function getNeededSegments({ bufferedSegments, content, currentPlaybackTime, fastSwitchThreshold, getBufferedHistory, neededRange, segmentsBeingPushed, maxBufferSize, }: IGetNeededSegmentsArguments): INeededSegments;
82
+ export {};
@@ -18,12 +18,6 @@ import config from "../../../config";
18
18
  import log from "../../../log";
19
19
  import { areSameContent, } from "../../../manifest";
20
20
  import objectAssign from "../../../utils/object_assign";
21
- var CONTENT_REPLACEMENT_PADDING = config.CONTENT_REPLACEMENT_PADDING, BITRATE_REBUFFERING_RATIO = config.BITRATE_REBUFFERING_RATIO, MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT, MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
22
- /**
23
- * Epsilon compensating for rounding errors when comparing the start and end
24
- * time of multiple segments.
25
- */
26
- var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
27
21
  /**
28
22
  * Return the list of segments that can currently be downloaded to fill holes
29
23
  * in the buffer in the given range, including already-pushed segments currently
@@ -35,8 +29,11 @@ var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
35
29
  * @returns {Array.<Object>}
36
30
  */
37
31
  export default function getNeededSegments(_a) {
38
- var bufferedSegments = _a.bufferedSegments, content = _a.content, currentPlaybackTime = _a.currentPlaybackTime, fastSwitchThreshold = _a.fastSwitchThreshold, getBufferedHistory = _a.getBufferedHistory, neededRange = _a.neededRange, segmentsBeingPushed = _a.segmentsBeingPushed;
32
+ var bufferedSegments = _a.bufferedSegments, content = _a.content, currentPlaybackTime = _a.currentPlaybackTime, fastSwitchThreshold = _a.fastSwitchThreshold, getBufferedHistory = _a.getBufferedHistory, neededRange = _a.neededRange, segmentsBeingPushed = _a.segmentsBeingPushed, maxBufferSize = _a.maxBufferSize;
39
33
  var representation = content.representation;
34
+ var availableBufferSize = getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxBufferSize);
35
+ // Current buffer length in seconds
36
+ var bufferLength = getBufferLength(bufferedSegments, segmentsBeingPushed);
40
37
  var availableSegmentsForRange = representation.index
41
38
  .getSegments(neededRange.start, neededRange.end - neededRange.start);
42
39
  // Remove from `bufferedSegments` any segments we would prefer to replace:
@@ -57,7 +54,7 @@ export default function getNeededSegments(_a) {
57
54
  }
58
55
  log.debug("Stream: skipping segment gc-ed at the start", currentSeg);
59
56
  }
60
- if (doesEndSeemGarbageCollected(currentSeg, nextSeg, neededRange.start)) {
57
+ if (doesEndSeemGarbageCollected(currentSeg, nextSeg, neededRange.end)) {
61
58
  lazySegmentHistory = lazySegmentHistory !== null && lazySegmentHistory !== void 0 ? lazySegmentHistory : getBufferedHistory(currentSeg.infos);
62
59
  if (shouldReloadSegmentGCedAtTheEnd(lazySegmentHistory, currentSeg.bufferedEnd)) {
63
60
  return false;
@@ -66,7 +63,15 @@ export default function getNeededSegments(_a) {
66
63
  }
67
64
  return true;
68
65
  });
69
- var segmentsToDownload = availableSegmentsForRange.filter(function (segment) {
66
+ var _b = config.getCurrent(), MINIMUM_SEGMENT_SIZE = _b.MINIMUM_SEGMENT_SIZE, MIN_BUFFER_LENGTH = _b.MIN_BUFFER_LENGTH, MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP = _b.MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP;
67
+ var isMemorySaturated = false;
68
+ /**
69
+ * Epsilon compensating for rounding errors when comparing the start and end
70
+ * time of multiple segments.
71
+ */
72
+ var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
73
+ var isBufferFull = false;
74
+ var neededSegments = availableSegmentsForRange.filter(function (segment) {
70
75
  var contentObject = objectAssign({ segment: segment }, content);
71
76
  // First, check that the segment is not already being pushed
72
77
  if (segmentsBeingPushed.length > 0) {
@@ -80,6 +85,19 @@ export default function getNeededSegments(_a) {
80
85
  if (segment.isInit) {
81
86
  return true; // never skip initialization segments
82
87
  }
88
+ if (isMemorySaturated) {
89
+ // If we are so saturated in memory
90
+ // That we cannot download atleast till
91
+ // NeededRange.Start ( current position ) + a CONST
92
+ // Then the buffer is full
93
+ if (time < neededRange.start + MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP) {
94
+ isBufferFull = true;
95
+ }
96
+ }
97
+ if (isMemorySaturated &&
98
+ bufferLength > MIN_BUFFER_LENGTH) {
99
+ return false;
100
+ }
83
101
  if (segment.complete && duration < MINIMUM_SEGMENT_SIZE) {
84
102
  return false; // too small, don't download
85
103
  }
@@ -130,9 +148,57 @@ export default function getNeededSegments(_a) {
130
148
  getLastContiguousSegment(segmentsToKeep, i).end < end - ROUNDING_ERROR;
131
149
  }
132
150
  }
151
+ var estimatedSegmentSize = (duration * content.representation.bitrate) / 8000;
152
+ if (availableBufferSize - estimatedSegmentSize < 0 &&
153
+ bufferLength > MIN_BUFFER_LENGTH) {
154
+ isMemorySaturated = true;
155
+ return false;
156
+ }
157
+ availableBufferSize -= estimatedSegmentSize;
158
+ bufferLength += duration;
133
159
  return true;
134
160
  });
135
- return segmentsToDownload;
161
+ return { neededSegments: neededSegments, isBufferFull: isBufferFull };
162
+ }
163
+ /**
164
+ * Compute the estimated available buffer size in memory in kilobytes
165
+ * @param bufferedSegments
166
+ * @param segmentsBeingPushed
167
+ * @param maxVideoBufferSize
168
+ * @returns availableBufferSize in kilobytes
169
+ */
170
+ function getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxVideoBufferSize) {
171
+ var availableBufferSize = maxVideoBufferSize;
172
+ availableBufferSize -= segmentsBeingPushed.reduce(function (size, segment) {
173
+ var bitrate = segment.representation.bitrate;
174
+ // Not taking into account the fact that the segment
175
+ // can still be generated and the duration not fully exact
176
+ var duration = segment.segment.duration;
177
+ return size + ((bitrate / 8000) * duration);
178
+ }, 0);
179
+ return bufferedSegments.reduce(function (size, chunk) {
180
+ if (chunk.chunkSize !== undefined) {
181
+ return size - (chunk.chunkSize / 8000);
182
+ }
183
+ else {
184
+ return size;
185
+ }
186
+ }, availableBufferSize);
187
+ }
188
+ /**
189
+ * Compute the length of the buffer in seconds
190
+ * @param bufferedSegments
191
+ * @param segmentsBeingPushed
192
+ * @returns bufferLength in seconds
193
+ */
194
+ function getBufferLength(bufferedSegments, segmentsBeingPushed) {
195
+ var bufferLength = bufferedSegments.reduce(function (length, segment) {
196
+ return length + (segment.end - segment.start);
197
+ }, 0);
198
+ var bufferBeingPushed = segmentsBeingPushed.reduce(function (length, segment) {
199
+ return length + segment.segment.duration;
200
+ }, 0);
201
+ return bufferLength + bufferBeingPushed;
136
202
  }
137
203
  /**
138
204
  * From the given array of buffered chunks (`bufferedSegments`) returns the last
@@ -143,6 +209,12 @@ export default function getNeededSegments(_a) {
143
209
  */
144
210
  function getLastContiguousSegment(bufferedSegments, startIndex) {
145
211
  var j = startIndex + 1;
212
+ var MINIMUM_SEGMENT_SIZE = config.getCurrent().MINIMUM_SEGMENT_SIZE;
213
+ /**
214
+ * Epsilon compensating for rounding errors when comparing the start and end
215
+ * time of multiple segments.
216
+ */
217
+ var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
146
218
  // go through all contiguous segments and take the last one
147
219
  while (j < bufferedSegments.length - 1 &&
148
220
  (bufferedSegments[j - 1].end + ROUNDING_ERROR) >
@@ -162,6 +234,7 @@ function getLastContiguousSegment(bufferedSegments, startIndex) {
162
234
  * @returns {boolean}
163
235
  */
164
236
  function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime, fastSwitchThreshold) {
237
+ var CONTENT_REPLACEMENT_PADDING = config.getCurrent().CONTENT_REPLACEMENT_PADDING;
165
238
  if (oldContent.period.id !== currentContent.period.id) {
166
239
  return false; // keep segments from another Period by default.
167
240
  }
@@ -186,6 +259,7 @@ function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime
186
259
  */
187
260
  function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastSwitchThreshold) {
188
261
  var oldContentBitrate = oldSegmentRepresentation.bitrate;
262
+ var BITRATE_REBUFFERING_RATIO = config.getCurrent().BITRATE_REBUFFERING_RATIO;
189
263
  if (fastSwitchThreshold === undefined) {
190
264
  // only re-load comparatively-poor bitrates for the same Adaptation.
191
265
  var bitrateCeil = oldContentBitrate * BITRATE_REBUFFERING_RATIO;
@@ -207,6 +281,7 @@ function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastS
207
281
  * that time, we will return `false`.
208
282
  */
209
283
  function doesStartSeemGarbageCollected(currentSeg, prevSeg, maximumStartTime) {
284
+ var MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.getCurrent().MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT;
210
285
  if (currentSeg.bufferedStart === undefined) {
211
286
  log.warn("Stream: Start of a segment unknown. " +
212
287
  "Assuming it is garbage collected by default.", currentSeg);
@@ -237,6 +312,7 @@ function doesStartSeemGarbageCollected(currentSeg, prevSeg, maximumStartTime) {
237
312
  * that time, we will return `false`.
238
313
  */
239
314
  function doesEndSeemGarbageCollected(currentSeg, nextSeg, minimumEndTime) {
315
+ var MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.getCurrent().MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT;
240
316
  if (currentSeg.bufferedEnd === undefined) {
241
317
  log.warn("Stream: End of a segment unknown. " +
242
318
  "Assuming it is garbage collected by default.", currentSeg);
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import config from "../../../config";
17
- var SEGMENT_PRIORITIES_STEPS = config.SEGMENT_PRIORITIES_STEPS;
18
17
  /**
19
18
  * Calculate the priority number for a given segment start time, in function of
20
19
  * the distance with the wanted starting timestamp.
@@ -29,6 +28,7 @@ var SEGMENT_PRIORITIES_STEPS = config.SEGMENT_PRIORITIES_STEPS;
29
28
  */
30
29
  export default function getSegmentPriority(segmentTime, wantedStartTimestamp) {
31
30
  var distance = segmentTime - wantedStartTimestamp;
31
+ var SEGMENT_PRIORITIES_STEPS = config.getCurrent().SEGMENT_PRIORITIES_STEPS;
32
32
  for (var priority = 0; priority < SEGMENT_PRIORITIES_STEPS.length; priority++) {
33
33
  if (distance < SEGMENT_PRIORITIES_STEPS[priority]) {
34
34
  return priority;
@@ -18,7 +18,6 @@ import config from "../../../config";
18
18
  import objectAssign from "../../../utils/object_assign";
19
19
  import EVENTS from "../events_generators";
20
20
  import appendSegmentToBuffer from "./append_segment_to_buffer";
21
- var APPEND_WINDOW_SECURITIES = config.APPEND_WINDOW_SECURITIES;
22
21
  /**
23
22
  * Push a given media segment (non-init segment) to a SegmentBuffer.
24
23
  * The Observable returned:
@@ -34,8 +33,9 @@ export default function pushMediaSegment(_a) {
34
33
  if (parsedSegment.chunkData === null) {
35
34
  return EMPTY;
36
35
  }
37
- var chunkData = parsedSegment.chunkData, chunkInfos = parsedSegment.chunkInfos, chunkOffset = parsedSegment.chunkOffset, appendWindow = parsedSegment.appendWindow;
36
+ var chunkData = parsedSegment.chunkData, chunkInfos = parsedSegment.chunkInfos, chunkOffset = parsedSegment.chunkOffset, chunkSize = parsedSegment.chunkSize, appendWindow = parsedSegment.appendWindow;
38
37
  var codec = content.representation.getMimeTypeString();
38
+ var APPEND_WINDOW_SECURITIES = config.getCurrent().APPEND_WINDOW_SECURITIES;
39
39
  // Cutting exactly at the start or end of the appendWindow can lead to
40
40
  // cases of infinite rebuffering due to how browser handle such windows.
41
41
  // To work-around that, we add a small offset before and after those.
@@ -60,7 +60,7 @@ export default function pushMediaSegment(_a) {
60
60
  if (safeAppendWindow[1] !== undefined) {
61
61
  estimatedEnd = Math.min(estimatedEnd, safeAppendWindow[1]);
62
62
  }
63
- var inventoryInfos = objectAssign({ segment: segment, start: estimatedStart,
63
+ var inventoryInfos = objectAssign({ segment: segment, chunkSize: chunkSize, start: estimatedStart,
64
64
  end: estimatedEnd }, content);
65
65
  return appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: inventoryInfos }).pipe(map(function () {
66
66
  var buffered = segmentBuffer.getBufferedRanges();
@@ -79,6 +79,12 @@ export interface IRepresentationStreamOptions {
79
79
  * goes below that size again.
80
80
  */
81
81
  bufferGoal$: Observable<number>;
82
+ /**
83
+ * The buffer size limit in memory that we can reach.
84
+ * Once reached, no segments will be loaded until it
85
+ * goes below that size again
86
+ */
87
+ maxBufferSize$: Observable<number>;
82
88
  /**
83
89
  * Hex-encoded DRM "system ID" as found in:
84
90
  * https://dashif.org/identifiers/content_protection/