rx-player 4.3.0-dev.2025012900 → 4.3.0-dev.2025030400

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 (372) hide show
  1. package/CHANGELOG.md +10 -2
  2. package/VERSION +1 -1
  3. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  4. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  5. package/dist/commonjs/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  6. package/dist/commonjs/__GENERATED_CODE/embedded_worker.js +1 -1
  7. package/dist/commonjs/compat/browser_compatibility_types.d.ts +32 -13
  8. package/dist/commonjs/compat/browser_compatibility_types.d.ts.map +1 -1
  9. package/dist/commonjs/compat/browser_compatibility_types.js +12 -32
  10. package/dist/commonjs/compat/eme/close_session.d.ts +2 -2
  11. package/dist/commonjs/compat/eme/close_session.d.ts.map +1 -1
  12. package/dist/commonjs/compat/eme/custom_key_system_access.d.ts +4 -9
  13. package/dist/commonjs/compat/eme/custom_key_system_access.d.ts.map +1 -1
  14. package/dist/commonjs/compat/eme/custom_media_keys/ie11_media_keys.d.ts +5 -6
  15. package/dist/commonjs/compat/eme/custom_media_keys/ie11_media_keys.d.ts.map +1 -1
  16. package/dist/commonjs/compat/eme/custom_media_keys/ie11_media_keys.js +6 -4
  17. package/dist/commonjs/compat/eme/custom_media_keys/index.d.ts +0 -2
  18. package/dist/commonjs/compat/eme/custom_media_keys/index.d.ts.map +1 -1
  19. package/dist/commonjs/compat/eme/custom_media_keys/moz_media_keys_constructor.d.ts +4 -5
  20. package/dist/commonjs/compat/eme/custom_media_keys/moz_media_keys_constructor.d.ts.map +1 -1
  21. package/dist/commonjs/compat/eme/custom_media_keys/old_webkit_media_keys.d.ts +5 -6
  22. package/dist/commonjs/compat/eme/custom_media_keys/old_webkit_media_keys.d.ts.map +1 -1
  23. package/dist/commonjs/compat/eme/custom_media_keys/old_webkit_media_keys.js +1 -1
  24. package/dist/commonjs/compat/eme/custom_media_keys/webkit_media_keys.d.ts +5 -11
  25. package/dist/commonjs/compat/eme/custom_media_keys/webkit_media_keys.d.ts.map +1 -1
  26. package/dist/commonjs/compat/eme/custom_media_keys/webkit_media_keys.js +2 -2
  27. package/dist/commonjs/compat/eme/eme-api-implementation.d.ts +5 -6
  28. package/dist/commonjs/compat/eme/eme-api-implementation.d.ts.map +1 -1
  29. package/dist/commonjs/compat/eme/eme-api-implementation.js +1 -0
  30. package/dist/commonjs/compat/eme/generate_key_request.d.ts +2 -2
  31. package/dist/commonjs/compat/eme/generate_key_request.d.ts.map +1 -1
  32. package/dist/commonjs/compat/eme/get_init_data.d.ts +2 -2
  33. package/dist/commonjs/compat/eme/get_init_data.d.ts.map +1 -1
  34. package/dist/commonjs/compat/eme/index.d.ts +1 -3
  35. package/dist/commonjs/compat/eme/index.d.ts.map +1 -1
  36. package/dist/commonjs/compat/eme/load_session.d.ts +2 -2
  37. package/dist/commonjs/compat/eme/load_session.d.ts.map +1 -1
  38. package/dist/commonjs/compat/eme/set_media_keys.d.ts +2 -3
  39. package/dist/commonjs/compat/eme/set_media_keys.d.ts.map +1 -1
  40. package/dist/commonjs/compat/event_listeners.d.ts +2 -3
  41. package/dist/commonjs/compat/event_listeners.d.ts.map +1 -1
  42. package/dist/commonjs/compat/remove_cue.d.ts +2 -1
  43. package/dist/commonjs/compat/remove_cue.d.ts.map +1 -1
  44. package/dist/commonjs/core/main/common/FreezeResolver.d.ts +176 -0
  45. package/dist/commonjs/core/main/common/FreezeResolver.d.ts.map +1 -0
  46. package/dist/commonjs/core/main/common/FreezeResolver.js +431 -0
  47. package/dist/commonjs/core/main/common/synchronize_sinks_on_observation.d.ts +11 -0
  48. package/dist/commonjs/core/main/common/synchronize_sinks_on_observation.d.ts.map +1 -0
  49. package/dist/commonjs/core/main/common/synchronize_sinks_on_observation.js +20 -0
  50. package/dist/commonjs/core/main/worker/content_preparer.d.ts +82 -5
  51. package/dist/commonjs/core/main/worker/content_preparer.d.ts.map +1 -1
  52. package/dist/commonjs/core/main/worker/content_preparer.js +83 -18
  53. package/dist/commonjs/core/main/worker/worker_main.d.ts.map +1 -1
  54. package/dist/commonjs/core/main/worker/worker_main.js +69 -14
  55. package/dist/commonjs/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
  56. package/dist/commonjs/core/stream/adaptation/adaptation_stream.js +26 -4
  57. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
  58. package/dist/commonjs/default_config.d.ts +26 -0
  59. package/dist/commonjs/default_config.d.ts.map +1 -1
  60. package/dist/commonjs/default_config.js +26 -0
  61. package/dist/commonjs/main_thread/api/option_utils.d.ts +26 -0
  62. package/dist/commonjs/main_thread/api/option_utils.d.ts.map +1 -1
  63. package/dist/commonjs/main_thread/api/option_utils.js +5 -2
  64. package/dist/commonjs/main_thread/api/public_api.d.ts.map +1 -1
  65. package/dist/commonjs/main_thread/api/public_api.js +14 -12
  66. package/dist/commonjs/main_thread/api/utils.d.ts +1 -2
  67. package/dist/commonjs/main_thread/api/utils.d.ts.map +1 -1
  68. package/dist/commonjs/main_thread/api/utils.js +2 -3
  69. package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  70. package/dist/commonjs/main_thread/decrypt/create_or_load_session.d.ts +2 -2
  71. package/dist/commonjs/main_thread/decrypt/create_or_load_session.d.ts.map +1 -1
  72. package/dist/commonjs/main_thread/decrypt/create_session.d.ts +3 -3
  73. package/dist/commonjs/main_thread/decrypt/create_session.d.ts.map +1 -1
  74. package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts +3 -4
  75. package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  76. package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts +3 -4
  77. package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
  78. package/dist/commonjs/main_thread/decrypt/session_events_listener.d.ts +2 -2
  79. package/dist/commonjs/main_thread/decrypt/session_events_listener.d.ts.map +1 -1
  80. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts +3 -3
  81. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  82. package/dist/commonjs/main_thread/decrypt/utils/check_key_statuses.d.ts +2 -2
  83. package/dist/commonjs/main_thread/decrypt/utils/check_key_statuses.d.ts.map +1 -1
  84. package/dist/commonjs/main_thread/decrypt/utils/is_session_usable.d.ts +2 -2
  85. package/dist/commonjs/main_thread/decrypt/utils/is_session_usable.d.ts.map +1 -1
  86. package/dist/commonjs/main_thread/decrypt/utils/loaded_sessions_store.d.ts +10 -10
  87. package/dist/commonjs/main_thread/decrypt/utils/loaded_sessions_store.d.ts.map +1 -1
  88. package/dist/commonjs/main_thread/decrypt/utils/loaded_sessions_store.js +2 -2
  89. package/dist/commonjs/main_thread/decrypt/utils/media_keys_attacher.d.ts +4 -4
  90. package/dist/commonjs/main_thread/decrypt/utils/media_keys_attacher.d.ts.map +1 -1
  91. package/dist/commonjs/main_thread/decrypt/utils/persistent_sessions_store.d.ts +5 -7
  92. package/dist/commonjs/main_thread/decrypt/utils/persistent_sessions_store.d.ts.map +1 -1
  93. package/dist/commonjs/main_thread/decrypt/utils/persistent_sessions_store.js +3 -5
  94. package/dist/commonjs/main_thread/decrypt/utils/server_certificate_store.d.ts +5 -5
  95. package/dist/commonjs/main_thread/decrypt/utils/server_certificate_store.d.ts.map +1 -1
  96. package/dist/commonjs/main_thread/init/directfile_content_initializer.js +1 -1
  97. package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts +6 -0
  98. package/dist/commonjs/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
  99. package/dist/commonjs/main_thread/init/media_source_content_initializer.js +77 -25
  100. package/dist/commonjs/main_thread/init/multi_thread_content_initializer.d.ts +6 -0
  101. package/dist/commonjs/main_thread/init/multi_thread_content_initializer.d.ts.map +1 -1
  102. package/dist/commonjs/main_thread/init/multi_thread_content_initializer.js +8 -8
  103. package/dist/commonjs/main_thread/init/types.d.ts +3 -2
  104. package/dist/commonjs/main_thread/init/types.d.ts.map +1 -1
  105. package/dist/commonjs/main_thread/init/utils/create_core_playback_observer.d.ts +2 -0
  106. package/dist/commonjs/main_thread/init/utils/create_core_playback_observer.d.ts.map +1 -1
  107. package/dist/commonjs/main_thread/init/utils/create_core_playback_observer.js +1 -0
  108. package/dist/commonjs/main_thread/init/utils/get_loaded_reference.d.ts +1 -3
  109. package/dist/commonjs/main_thread/init/utils/get_loaded_reference.d.ts.map +1 -1
  110. package/dist/commonjs/main_thread/init/utils/get_loaded_reference.js +4 -5
  111. package/dist/commonjs/main_thread/init/utils/rebuffering_controller.d.ts.map +1 -1
  112. package/dist/commonjs/main_thread/init/utils/rebuffering_controller.js +1 -13
  113. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +1 -4
  114. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
  115. package/dist/commonjs/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +3 -5
  116. package/dist/commonjs/main_thread/tracks_store/tracks_store.d.ts +2 -2
  117. package/dist/commonjs/main_thread/tracks_store/tracks_store.d.ts.map +1 -1
  118. package/dist/commonjs/main_thread/tracks_store/tracks_store.js +16 -22
  119. package/dist/commonjs/manifest/classes/index.d.ts +2 -2
  120. package/dist/commonjs/manifest/classes/index.d.ts.map +1 -1
  121. package/dist/commonjs/manifest/classes/manifest.d.ts +17 -2
  122. package/dist/commonjs/manifest/classes/manifest.d.ts.map +1 -1
  123. package/dist/commonjs/manifest/classes/manifest.js +55 -12
  124. package/dist/commonjs/manifest/classes/representation.d.ts +9 -0
  125. package/dist/commonjs/manifest/classes/representation.d.ts.map +1 -1
  126. package/dist/commonjs/manifest/classes/representation.js +1 -0
  127. package/dist/commonjs/manifest/index.d.ts +2 -2
  128. package/dist/commonjs/manifest/index.d.ts.map +1 -1
  129. package/dist/commonjs/manifest/utils.js +1 -1
  130. package/dist/commonjs/multithread_types.d.ts +8 -0
  131. package/dist/commonjs/multithread_types.d.ts.map +1 -1
  132. package/dist/commonjs/parsers/containers/isobmff/extract_complete_chunks.d.ts +1 -1
  133. package/dist/commonjs/parsers/containers/isobmff/extract_complete_chunks.js +1 -1
  134. package/dist/commonjs/parsers/manifest/dash/common/parse_adaptation_sets.js +1 -1
  135. package/dist/commonjs/playback_observer/media_element_playback_observer.d.ts.map +1 -1
  136. package/dist/commonjs/playback_observer/media_element_playback_observer.js +6 -4
  137. package/dist/commonjs/playback_observer/types.d.ts +2 -0
  138. package/dist/commonjs/playback_observer/types.d.ts.map +1 -1
  139. package/dist/commonjs/playback_observer/worker_playback_observer.d.ts +2 -0
  140. package/dist/commonjs/playback_observer/worker_playback_observer.d.ts.map +1 -1
  141. package/dist/commonjs/public_types.d.ts +14 -0
  142. package/dist/commonjs/public_types.d.ts.map +1 -1
  143. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  144. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  145. package/dist/es2017/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  146. package/dist/es2017/__GENERATED_CODE/embedded_worker.js +1 -1
  147. package/dist/es2017/compat/browser_compatibility_types.d.ts +32 -13
  148. package/dist/es2017/compat/browser_compatibility_types.d.ts.map +1 -1
  149. package/dist/es2017/compat/browser_compatibility_types.js +12 -32
  150. package/dist/es2017/compat/eme/close_session.d.ts +2 -2
  151. package/dist/es2017/compat/eme/close_session.d.ts.map +1 -1
  152. package/dist/es2017/compat/eme/custom_key_system_access.d.ts +4 -9
  153. package/dist/es2017/compat/eme/custom_key_system_access.d.ts.map +1 -1
  154. package/dist/es2017/compat/eme/custom_media_keys/ie11_media_keys.d.ts +5 -6
  155. package/dist/es2017/compat/eme/custom_media_keys/ie11_media_keys.d.ts.map +1 -1
  156. package/dist/es2017/compat/eme/custom_media_keys/ie11_media_keys.js +4 -4
  157. package/dist/es2017/compat/eme/custom_media_keys/index.d.ts +0 -2
  158. package/dist/es2017/compat/eme/custom_media_keys/index.d.ts.map +1 -1
  159. package/dist/es2017/compat/eme/custom_media_keys/moz_media_keys_constructor.d.ts +4 -5
  160. package/dist/es2017/compat/eme/custom_media_keys/moz_media_keys_constructor.d.ts.map +1 -1
  161. package/dist/es2017/compat/eme/custom_media_keys/old_webkit_media_keys.d.ts +5 -6
  162. package/dist/es2017/compat/eme/custom_media_keys/old_webkit_media_keys.d.ts.map +1 -1
  163. package/dist/es2017/compat/eme/custom_media_keys/old_webkit_media_keys.js +1 -1
  164. package/dist/es2017/compat/eme/custom_media_keys/webkit_media_keys.d.ts +5 -11
  165. package/dist/es2017/compat/eme/custom_media_keys/webkit_media_keys.d.ts.map +1 -1
  166. package/dist/es2017/compat/eme/custom_media_keys/webkit_media_keys.js +2 -2
  167. package/dist/es2017/compat/eme/eme-api-implementation.d.ts +5 -6
  168. package/dist/es2017/compat/eme/eme-api-implementation.d.ts.map +1 -1
  169. package/dist/es2017/compat/eme/eme-api-implementation.js +1 -0
  170. package/dist/es2017/compat/eme/generate_key_request.d.ts +2 -2
  171. package/dist/es2017/compat/eme/generate_key_request.d.ts.map +1 -1
  172. package/dist/es2017/compat/eme/get_init_data.d.ts +2 -2
  173. package/dist/es2017/compat/eme/get_init_data.d.ts.map +1 -1
  174. package/dist/es2017/compat/eme/index.d.ts +1 -3
  175. package/dist/es2017/compat/eme/index.d.ts.map +1 -1
  176. package/dist/es2017/compat/eme/load_session.d.ts +2 -2
  177. package/dist/es2017/compat/eme/load_session.d.ts.map +1 -1
  178. package/dist/es2017/compat/eme/set_media_keys.d.ts +2 -3
  179. package/dist/es2017/compat/eme/set_media_keys.d.ts.map +1 -1
  180. package/dist/es2017/compat/event_listeners.d.ts +2 -3
  181. package/dist/es2017/compat/event_listeners.d.ts.map +1 -1
  182. package/dist/es2017/compat/remove_cue.d.ts +2 -1
  183. package/dist/es2017/compat/remove_cue.d.ts.map +1 -1
  184. package/dist/es2017/core/main/common/FreezeResolver.d.ts +176 -0
  185. package/dist/es2017/core/main/common/FreezeResolver.d.ts.map +1 -0
  186. package/dist/es2017/core/main/common/FreezeResolver.js +363 -0
  187. package/dist/es2017/core/main/common/synchronize_sinks_on_observation.d.ts +11 -0
  188. package/dist/es2017/core/main/common/synchronize_sinks_on_observation.d.ts.map +1 -0
  189. package/dist/es2017/core/main/common/synchronize_sinks_on_observation.js +17 -0
  190. package/dist/es2017/core/main/worker/content_preparer.d.ts +82 -5
  191. package/dist/es2017/core/main/worker/content_preparer.d.ts.map +1 -1
  192. package/dist/es2017/core/main/worker/content_preparer.js +82 -17
  193. package/dist/es2017/core/main/worker/worker_main.d.ts.map +1 -1
  194. package/dist/es2017/core/main/worker/worker_main.js +68 -14
  195. package/dist/es2017/core/stream/adaptation/adaptation_stream.d.ts.map +1 -1
  196. package/dist/es2017/core/stream/adaptation/adaptation_stream.js +24 -2
  197. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.d.ts.map +1 -1
  198. package/dist/es2017/default_config.d.ts +26 -0
  199. package/dist/es2017/default_config.d.ts.map +1 -1
  200. package/dist/es2017/default_config.js +26 -0
  201. package/dist/es2017/main_thread/api/option_utils.d.ts +26 -0
  202. package/dist/es2017/main_thread/api/option_utils.d.ts.map +1 -1
  203. package/dist/es2017/main_thread/api/option_utils.js +4 -1
  204. package/dist/es2017/main_thread/api/public_api.d.ts.map +1 -1
  205. package/dist/es2017/main_thread/api/public_api.js +14 -12
  206. package/dist/es2017/main_thread/api/utils.d.ts +1 -2
  207. package/dist/es2017/main_thread/api/utils.d.ts.map +1 -1
  208. package/dist/es2017/main_thread/api/utils.js +2 -3
  209. package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  210. package/dist/es2017/main_thread/decrypt/create_or_load_session.d.ts +2 -2
  211. package/dist/es2017/main_thread/decrypt/create_or_load_session.d.ts.map +1 -1
  212. package/dist/es2017/main_thread/decrypt/create_session.d.ts +3 -3
  213. package/dist/es2017/main_thread/decrypt/create_session.d.ts.map +1 -1
  214. package/dist/es2017/main_thread/decrypt/find_key_system.d.ts +3 -4
  215. package/dist/es2017/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  216. package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts +3 -4
  217. package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
  218. package/dist/es2017/main_thread/decrypt/session_events_listener.d.ts +2 -2
  219. package/dist/es2017/main_thread/decrypt/session_events_listener.d.ts.map +1 -1
  220. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts +3 -3
  221. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  222. package/dist/es2017/main_thread/decrypt/utils/check_key_statuses.d.ts +2 -2
  223. package/dist/es2017/main_thread/decrypt/utils/check_key_statuses.d.ts.map +1 -1
  224. package/dist/es2017/main_thread/decrypt/utils/is_session_usable.d.ts +2 -2
  225. package/dist/es2017/main_thread/decrypt/utils/is_session_usable.d.ts.map +1 -1
  226. package/dist/es2017/main_thread/decrypt/utils/loaded_sessions_store.d.ts +10 -10
  227. package/dist/es2017/main_thread/decrypt/utils/loaded_sessions_store.d.ts.map +1 -1
  228. package/dist/es2017/main_thread/decrypt/utils/loaded_sessions_store.js +2 -2
  229. package/dist/es2017/main_thread/decrypt/utils/media_keys_attacher.d.ts +4 -4
  230. package/dist/es2017/main_thread/decrypt/utils/media_keys_attacher.d.ts.map +1 -1
  231. package/dist/es2017/main_thread/decrypt/utils/persistent_sessions_store.d.ts +5 -7
  232. package/dist/es2017/main_thread/decrypt/utils/persistent_sessions_store.d.ts.map +1 -1
  233. package/dist/es2017/main_thread/decrypt/utils/persistent_sessions_store.js +3 -5
  234. package/dist/es2017/main_thread/decrypt/utils/server_certificate_store.d.ts +5 -5
  235. package/dist/es2017/main_thread/decrypt/utils/server_certificate_store.d.ts.map +1 -1
  236. package/dist/es2017/main_thread/init/directfile_content_initializer.js +1 -1
  237. package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts +6 -0
  238. package/dist/es2017/main_thread/init/media_source_content_initializer.d.ts.map +1 -1
  239. package/dist/es2017/main_thread/init/media_source_content_initializer.js +77 -26
  240. package/dist/es2017/main_thread/init/multi_thread_content_initializer.d.ts +6 -0
  241. package/dist/es2017/main_thread/init/multi_thread_content_initializer.d.ts.map +1 -1
  242. package/dist/es2017/main_thread/init/multi_thread_content_initializer.js +8 -8
  243. package/dist/es2017/main_thread/init/types.d.ts +3 -2
  244. package/dist/es2017/main_thread/init/types.d.ts.map +1 -1
  245. package/dist/es2017/main_thread/init/utils/create_core_playback_observer.d.ts +2 -0
  246. package/dist/es2017/main_thread/init/utils/create_core_playback_observer.d.ts.map +1 -1
  247. package/dist/es2017/main_thread/init/utils/create_core_playback_observer.js +1 -0
  248. package/dist/es2017/main_thread/init/utils/get_loaded_reference.d.ts +1 -3
  249. package/dist/es2017/main_thread/init/utils/get_loaded_reference.d.ts.map +1 -1
  250. package/dist/es2017/main_thread/init/utils/get_loaded_reference.js +4 -5
  251. package/dist/es2017/main_thread/init/utils/rebuffering_controller.d.ts.map +1 -1
  252. package/dist/es2017/main_thread/init/utils/rebuffering_controller.js +1 -13
  253. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts +1 -4
  254. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.d.ts.map +1 -1
  255. package/dist/es2017/main_thread/init/utils/stream_events_emitter/stream_events_emitter.js +3 -5
  256. package/dist/es2017/main_thread/tracks_store/tracks_store.d.ts +2 -2
  257. package/dist/es2017/main_thread/tracks_store/tracks_store.d.ts.map +1 -1
  258. package/dist/es2017/main_thread/tracks_store/tracks_store.js +16 -22
  259. package/dist/es2017/manifest/classes/index.d.ts +2 -2
  260. package/dist/es2017/manifest/classes/index.d.ts.map +1 -1
  261. package/dist/es2017/manifest/classes/manifest.d.ts +17 -2
  262. package/dist/es2017/manifest/classes/manifest.d.ts.map +1 -1
  263. package/dist/es2017/manifest/classes/manifest.js +32 -0
  264. package/dist/es2017/manifest/classes/representation.d.ts +9 -0
  265. package/dist/es2017/manifest/classes/representation.d.ts.map +1 -1
  266. package/dist/es2017/manifest/classes/representation.js +1 -0
  267. package/dist/es2017/manifest/index.d.ts +2 -2
  268. package/dist/es2017/manifest/index.d.ts.map +1 -1
  269. package/dist/es2017/manifest/utils.js +1 -1
  270. package/dist/es2017/multithread_types.d.ts +8 -0
  271. package/dist/es2017/multithread_types.d.ts.map +1 -1
  272. package/dist/es2017/parsers/containers/isobmff/extract_complete_chunks.d.ts +1 -1
  273. package/dist/es2017/parsers/containers/isobmff/extract_complete_chunks.js +1 -1
  274. package/dist/es2017/parsers/manifest/dash/common/parse_adaptation_sets.js +1 -1
  275. package/dist/es2017/playback_observer/media_element_playback_observer.d.ts.map +1 -1
  276. package/dist/es2017/playback_observer/media_element_playback_observer.js +6 -4
  277. package/dist/es2017/playback_observer/types.d.ts +2 -0
  278. package/dist/es2017/playback_observer/types.d.ts.map +1 -1
  279. package/dist/es2017/playback_observer/worker_playback_observer.d.ts +2 -0
  280. package/dist/es2017/playback_observer/worker_playback_observer.d.ts.map +1 -1
  281. package/dist/es2017/public_types.d.ts +14 -0
  282. package/dist/es2017/public_types.d.ts.map +1 -1
  283. package/dist/mpd-parser.wasm +0 -0
  284. package/dist/rx-player.js +489 -191
  285. package/dist/rx-player.min.js +18 -18
  286. package/dist/worker.js +6 -6
  287. package/package.json +18 -18
  288. package/src/__GENERATED_CODE/embedded_dash_wasm.ts +1 -1
  289. package/src/__GENERATED_CODE/embedded_worker.ts +1 -1
  290. package/src/compat/browser_compatibility_types.ts +45 -42
  291. package/src/compat/eme/close_session.ts +2 -4
  292. package/src/compat/eme/custom_key_system_access.ts +4 -11
  293. package/src/compat/eme/custom_media_keys/ie11_media_keys.ts +29 -23
  294. package/src/compat/eme/custom_media_keys/index.ts +0 -2
  295. package/src/compat/eme/custom_media_keys/moz_media_keys_constructor.ts +5 -9
  296. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +15 -20
  297. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +28 -36
  298. package/src/compat/eme/eme-api-implementation.ts +16 -14
  299. package/src/compat/eme/generate_key_request.ts +2 -2
  300. package/src/compat/eme/get_init_data.ts +2 -2
  301. package/src/compat/eme/index.ts +1 -10
  302. package/src/compat/eme/load_session.ts +4 -10
  303. package/src/compat/eme/set_media_keys.ts +2 -3
  304. package/src/compat/event_listeners.ts +2 -2
  305. package/src/compat/remove_cue.ts +11 -4
  306. package/src/core/main/common/FreezeResolver.ts +584 -0
  307. package/src/core/main/common/synchronize_sinks_on_observation.ts +22 -0
  308. package/src/core/main/worker/content_preparer.ts +112 -24
  309. package/src/core/main/worker/worker_main.ts +90 -13
  310. package/src/core/stream/adaptation/adaptation_stream.ts +38 -4
  311. package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -6
  312. package/src/default_config.ts +27 -0
  313. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/DRMInfos.test.ts +3 -3
  314. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/HDCPPolicy.test.ts +2 -2
  315. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/decodingInfos.test.ts +4 -4
  316. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/mediaContentType.test.ts +2 -2
  317. package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/mediaDisplayInfos.test.ts +1 -1
  318. package/src/main_thread/api/__tests__/option_utils.test.ts +3 -0
  319. package/src/main_thread/api/option_utils.ts +30 -0
  320. package/src/main_thread/api/public_api.ts +16 -12
  321. package/src/main_thread/api/utils.ts +1 -3
  322. package/src/main_thread/decrypt/__tests__/__global__/media_key_system_access.test.ts +2 -2
  323. package/src/main_thread/decrypt/content_decryptor.ts +9 -8
  324. package/src/main_thread/decrypt/create_or_load_session.ts +3 -3
  325. package/src/main_thread/decrypt/create_session.ts +3 -3
  326. package/src/main_thread/decrypt/find_key_system.ts +5 -3
  327. package/src/main_thread/decrypt/get_media_keys.ts +9 -6
  328. package/src/main_thread/decrypt/session_events_listener.ts +3 -3
  329. package/src/main_thread/decrypt/set_server_certificate.ts +4 -4
  330. package/src/main_thread/decrypt/utils/check_key_statuses.ts +2 -2
  331. package/src/main_thread/decrypt/utils/is_session_usable.ts +2 -4
  332. package/src/main_thread/decrypt/utils/loaded_sessions_store.ts +15 -16
  333. package/src/main_thread/decrypt/utils/media_keys_attacher.ts +7 -7
  334. package/src/main_thread/decrypt/utils/persistent_sessions_store.ts +5 -7
  335. package/src/main_thread/decrypt/utils/server_certificate_store.ts +6 -12
  336. package/src/main_thread/init/directfile_content_initializer.ts +1 -1
  337. package/src/main_thread/init/media_source_content_initializer.ts +98 -36
  338. package/src/main_thread/init/multi_thread_content_initializer.ts +14 -15
  339. package/src/main_thread/init/types.ts +3 -2
  340. package/src/main_thread/init/utils/create_core_playback_observer.ts +3 -0
  341. package/src/main_thread/init/utils/get_loaded_reference.ts +3 -6
  342. package/src/main_thread/init/utils/rebuffering_controller.ts +2 -24
  343. package/src/main_thread/init/utils/stream_events_emitter/stream_events_emitter.ts +3 -7
  344. package/src/main_thread/tracks_store/tracks_store.ts +16 -26
  345. package/src/manifest/classes/__tests__/representation.test.ts +16 -0
  346. package/src/manifest/classes/index.ts +2 -2
  347. package/src/manifest/classes/manifest.ts +48 -4
  348. package/src/manifest/classes/representation.ts +10 -0
  349. package/src/manifest/index.ts +2 -2
  350. package/src/manifest/utils.ts +1 -1
  351. package/src/multithread_types.ts +8 -0
  352. package/src/parsers/containers/isobmff/extract_complete_chunks.ts +1 -1
  353. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +1 -1
  354. package/src/playback_observer/media_element_playback_observer.ts +14 -24
  355. package/src/playback_observer/types.ts +2 -0
  356. package/src/playback_observer/worker_playback_observer.ts +2 -0
  357. package/src/public_types.ts +17 -0
  358. package/src/utils/__tests__/logger.test.ts +44 -60
  359. package/dist/commonjs/compat/eme/custom_media_keys/types.d.ts +0 -48
  360. package/dist/commonjs/compat/eme/custom_media_keys/types.d.ts.map +0 -1
  361. package/dist/commonjs/compat/eme/custom_media_keys/types.js +0 -17
  362. package/dist/commonjs/core/main/common/DecipherabilityFreezeDetector.d.ts +0 -80
  363. package/dist/commonjs/core/main/common/DecipherabilityFreezeDetector.d.ts.map +0 -1
  364. package/dist/commonjs/core/main/common/DecipherabilityFreezeDetector.js +0 -127
  365. package/dist/es2017/compat/eme/custom_media_keys/types.d.ts +0 -48
  366. package/dist/es2017/compat/eme/custom_media_keys/types.d.ts.map +0 -1
  367. package/dist/es2017/compat/eme/custom_media_keys/types.js +0 -16
  368. package/dist/es2017/core/main/common/DecipherabilityFreezeDetector.d.ts +0 -80
  369. package/dist/es2017/core/main/common/DecipherabilityFreezeDetector.d.ts.map +0 -1
  370. package/dist/es2017/core/main/common/DecipherabilityFreezeDetector.js +0 -91
  371. package/src/compat/eme/custom_media_keys/types.ts +0 -66
  372. package/src/core/main/common/DecipherabilityFreezeDetector.ts +0 -147
@@ -26,18 +26,52 @@ import type { IManifestRefreshSettings } from "../../fetchers";
26
26
  import { ManifestFetcher, SegmentQueueCreator } from "../../fetchers";
27
27
  import SegmentSinksStore from "../../segment_sinks";
28
28
  import type { INeedsMediaSourceReloadPayload } from "../../stream";
29
- import DecipherabilityFreezeDetector from "../common/DecipherabilityFreezeDetector";
29
+ import FreezeResolver from "../common/FreezeResolver";
30
30
  import { limitVideoResolution, throttleVideoBitrate } from "./globals";
31
31
  import sendMessage, { formatErrorForSender } from "./send_message";
32
32
  import TrackChoiceSetter from "./track_choice_setter";
33
33
  import WorkerTextDisplayerInterface from "./worker_text_displayer_interface";
34
34
 
35
+ /** Function allowing to associate a unique identifier to all created `MediaSource` */
35
36
  const generateMediaSourceId = idGenerator();
36
37
 
38
+ /**
39
+ * Class facilitating the workflows behind loading a new content for the
40
+ * RxPlayer Core:
41
+ *
42
+ * - Handle Manifest fetching and Manifest updates.
43
+ *
44
+ * - Handle the `MediaSource`'s creation and indirectly of its `SourceBuffer`s
45
+ * as well as handling "MediaSource reloading".
46
+ *
47
+ * - initialize various modules (`segmentQueueCreator`, CmcdDataBuilder`,
48
+ * `RepresentationEstimator`) linked to the initialized content.
49
+ *
50
+ * You can start loading a content through the `initializeNewContent` method.
51
+ *
52
+ * When a content is linked to the `ContentPreparer` you can inspect the
53
+ * different initialized modules by calling its `getCurrentContent` method.
54
+ *
55
+ * @class ContentPreparer
56
+ */
37
57
  export default class ContentPreparer {
58
+ /**
59
+ * Information on the content linked to that `ContentPreparer` through its
60
+ * `initializeNewContent` method.
61
+ * `null` if no content is initialized.
62
+ */
38
63
  private _currentContent: IPreparedContentData | null;
39
- private _currentMediaSourceCanceller: TaskCanceller;
64
+ /**
65
+ * TaskCanceller which is triggered when the currently-initialized content is
66
+ * not needed anymore, because we stopped it since or switched to a new content.
67
+ */
40
68
  private _contentCanceller: TaskCanceller;
69
+ /**
70
+ * TaskCanceller which is triggered when the currently-created MediaSource is
71
+ * not needed anymore, either because the content has changed or because we
72
+ * had to reload.
73
+ */
74
+ private _currentMediaSourceCanceller: TaskCanceller;
41
75
 
42
76
  /** @see constructor */
43
77
  private _hasMseInWorker: boolean;
@@ -73,6 +107,18 @@ export default class ContentPreparer {
73
107
  this._contentCanceller = contentCanceller;
74
108
  }
75
109
 
110
+ /**
111
+ * Start fetching the wanted content's Manifest and initializing the various
112
+ * modules stored by the `ContentPreparer` linked to that content.
113
+ *
114
+ * The returned Promise resolves with the parsed Manifest when those modules
115
+ * are all ready and you can thus begin to load the content.
116
+ *
117
+ * Reject if it failed to do so.
118
+ * @param {Object} context - Information on the content that should be
119
+ * initialized.
120
+ * @returns {Promise.<Object>}
121
+ */
76
122
  public initializeNewContent(
77
123
  context: IContentInitializationData,
78
124
  ): Promise<IManifestMetadata> {
@@ -84,7 +130,8 @@ export default class ContentPreparer {
84
130
 
85
131
  currentMediaSourceCanceller.linkToSignal(contentCanceller.signal);
86
132
 
87
- const { contentId, url, hasText, transportOptions } = context;
133
+ const { contentId, url, hasText, transportOptions, enableRepresentationAvoidance } =
134
+ context;
88
135
  let manifest: IManifest | null = null;
89
136
 
90
137
  // TODO better way
@@ -139,7 +186,7 @@ export default class ContentPreparer {
139
186
  const trackChoiceSetter = new TrackChoiceSetter();
140
187
 
141
188
  const [mediaSource, segmentSinksStore, workerTextSender] =
142
- createMediaSourceAndBuffersStore(
189
+ createMediaSourceInterfaceAndSegmentSinksStore(
143
190
  contentId,
144
191
  {
145
192
  hasMseInWorker: this._hasMseInWorker,
@@ -148,13 +195,12 @@ export default class ContentPreparer {
148
195
  },
149
196
  currentMediaSourceCanceller.signal,
150
197
  );
151
- const decipherabilityFreezeDetector = new DecipherabilityFreezeDetector(
152
- segmentSinksStore,
153
- );
198
+ const freezeResolver = new FreezeResolver(segmentSinksStore);
154
199
  this._currentContent = {
155
200
  cmcdDataBuilder,
156
201
  contentId,
157
- decipherabilityFreezeDetector,
202
+ enableRepresentationAvoidance,
203
+ freezeResolver,
158
204
  mediaSource,
159
205
  manifest: null,
160
206
  manifestFetcher,
@@ -204,6 +250,11 @@ export default class ContentPreparer {
204
250
  manifestFetcher.addEventListener(
205
251
  "error",
206
252
  (err: unknown) => {
253
+ sendMessage({
254
+ type: WorkerMessageType.Error,
255
+ contentId,
256
+ value: formatErrorForSender(err),
257
+ });
207
258
  rej(err);
208
259
  },
209
260
  contentCanceller.signal,
@@ -247,14 +298,36 @@ export default class ContentPreparer {
247
298
  });
248
299
  }
249
300
 
301
+ /**
302
+ * Get information on the current content prepared through the
303
+ * `initializeNewContent` method, or `null` if no content is currently
304
+ * prepared.
305
+ * @returns {Object|null}
306
+ */
250
307
  public getCurrentContent(): IPreparedContentData | null {
251
308
  return this._currentContent;
252
309
  }
253
310
 
311
+ /**
312
+ * Schedule an update for the Manifest file,
313
+ *
314
+ * Do nothing if no content is currently prepared.
315
+ * @param {Object} settings - Various settings to configure the ways and
316
+ * moment at which the Manifest will be refreshed.
317
+ */
254
318
  public scheduleManifestRefresh(settings: IManifestRefreshSettings): void {
255
319
  this._currentContent?.manifestFetcher.scheduleManualRefresh(settings);
256
320
  }
257
321
 
322
+ /**
323
+ * If there is a prepared content right now, performs the destructive
324
+ * "reloading" strategy: dispose of its `MediaSource` (and of its
325
+ * `SourceBuffer`) and recreate one.
326
+ *
327
+ * The returned Promise resolves when it restarts being ready.
328
+ * @param {Object} reloadInfo
329
+ * @returns {Promise}
330
+ */
258
331
  public reloadMediaSource(reloadInfo: INeedsMediaSourceReloadPayload): Promise<void> {
259
332
  this._currentMediaSourceCanceller.cancel();
260
333
  if (this._currentContent === null) {
@@ -272,8 +345,8 @@ export default class ContentPreparer {
272
345
  [],
273
346
  );
274
347
 
275
- const [mediaSource, segmentSinksStore, workerTextSender] =
276
- createMediaSourceAndBuffersStore(
348
+ const [mediaSourceInterface, segmentSinksStore, workerTextSender] =
349
+ createMediaSourceInterfaceAndSegmentSinksStore(
277
350
  this._currentContent.contentId,
278
351
  {
279
352
  hasMseInWorker: this._hasMseInWorker,
@@ -282,18 +355,19 @@ export default class ContentPreparer {
282
355
  },
283
356
  this._currentMediaSourceCanceller.signal,
284
357
  );
285
- this._currentContent.mediaSource = mediaSource;
358
+ this._currentContent.mediaSource = mediaSourceInterface;
286
359
  this._currentContent.segmentSinksStore = segmentSinksStore;
360
+ this._currentContent.freezeResolver = new FreezeResolver(segmentSinksStore);
287
361
  this._currentContent.workerTextSender = workerTextSender;
288
362
  return new Promise((res, rej) => {
289
- mediaSource.addEventListener(
363
+ mediaSourceInterface.addEventListener(
290
364
  "mediaSourceOpen",
291
365
  function () {
292
366
  res();
293
367
  },
294
368
  this._currentMediaSourceCanceller.signal,
295
369
  );
296
- mediaSource.addEventListener(
370
+ mediaSourceInterface.addEventListener(
297
371
  "mediaSourceClose",
298
372
  function () {
299
373
  rej(new Error("MediaSource ReadyState changed to close during init."));
@@ -306,6 +380,10 @@ export default class ContentPreparer {
306
380
  });
307
381
  }
308
382
 
383
+ /**
384
+ * Dispose all resources linked to the currently preopared content if one and
385
+ * stop linking it to this `ContentPreparer`.
386
+ */
309
387
  public disposeCurrentContent() {
310
388
  this._contentCanceller.cancel();
311
389
  this._contentCanceller = new TaskCanceller();
@@ -328,6 +406,12 @@ export interface IPreparedContentData {
328
406
  * conditions with a CDN.
329
407
  */
330
408
  cmcdDataBuilder: CmcdDataBuilder | null;
409
+ /**
410
+ * If `true`, the RxPlayer can enable its "Representation avoidance"
411
+ * mechanism, where it avoid loading Representation that it suspect
412
+ * have issues being decoded on the current device.
413
+ */
414
+ enableRepresentationAvoidance: boolean;
331
415
  /**
332
416
  * Interface to the MediaSource implementation, allowing to buffer audio
333
417
  * and video media segments.
@@ -342,10 +426,10 @@ export interface IPreparedContentData {
342
426
  */
343
427
  manifest: IManifest | null;
344
428
  /**
345
- * Specific module detecting freezing issues due to lower-level
346
- * decipherability-related bugs.
429
+ * Specific module detecting freezing issues and trying to work-around
430
+ * them.
347
431
  */
348
- decipherabilityFreezeDetector: DecipherabilityFreezeDetector;
432
+ freezeResolver: FreezeResolver;
349
433
  /**
350
434
  * Perform the adaptive logic, allowing to choose the best Representation for
351
435
  * the different types of media to load.
@@ -379,7 +463,7 @@ export interface IPreparedContentData {
379
463
  * @param {Object} cancelSignal
380
464
  * @returns {Array.<Object>}
381
465
  */
382
- function createMediaSourceAndBuffersStore(
466
+ function createMediaSourceInterfaceAndSegmentSinksStore(
383
467
  contentId: string,
384
468
  capabilities: {
385
469
  hasMseInWorker: boolean;
@@ -388,10 +472,10 @@ function createMediaSourceAndBuffersStore(
388
472
  },
389
473
  cancelSignal: CancellationSignal,
390
474
  ): [IMediaSourceInterface, SegmentSinksStore, WorkerTextDisplayerInterface | null] {
391
- let mediaSource: IMediaSourceInterface;
475
+ let mediaSourceInterface: IMediaSourceInterface;
392
476
  if (capabilities.hasMseInWorker) {
393
477
  const mainMediaSource = new MainMediaSourceInterface(generateMediaSourceId());
394
- mediaSource = mainMediaSource;
478
+ mediaSourceInterface = mainMediaSource;
395
479
 
396
480
  let sentMediaSourceLink: IAttachMediaSourceWorkerMessagePayload;
397
481
  const handle = mainMediaSource.handle;
@@ -410,12 +494,12 @@ function createMediaSourceAndBuffersStore(
410
494
  type: WorkerMessageType.AttachMediaSource,
411
495
  contentId,
412
496
  value: sentMediaSourceLink,
413
- mediaSourceId: mediaSource.id,
497
+ mediaSourceId: mediaSourceInterface.id,
414
498
  },
415
499
  [handle.value as unknown as Transferable],
416
500
  );
417
501
  } else {
418
- mediaSource = new WorkerMediaSourceInterface(
502
+ mediaSourceInterface = new WorkerMediaSourceInterface(
419
503
  generateMediaSourceId(),
420
504
  contentId,
421
505
  sendMessage,
@@ -426,12 +510,16 @@ function createMediaSourceAndBuffersStore(
426
510
  ? new WorkerTextDisplayerInterface(contentId, sendMessage)
427
511
  : null;
428
512
  const { hasVideo } = capabilities;
429
- const segmentSinksStore = new SegmentSinksStore(mediaSource, hasVideo, textSender);
513
+ const segmentSinksStore = new SegmentSinksStore(
514
+ mediaSourceInterface,
515
+ hasVideo,
516
+ textSender,
517
+ );
430
518
  cancelSignal.register(() => {
431
519
  segmentSinksStore.disposeAll();
432
520
  textSender?.stop();
433
- mediaSource.dispose();
521
+ mediaSourceInterface.dispose();
434
522
  });
435
523
 
436
- return [mediaSource, segmentSinksStore, textSender];
524
+ return [mediaSourceInterface, segmentSinksStore, textSender];
437
525
  }
@@ -34,7 +34,9 @@ import type {
34
34
  } from "../../stream";
35
35
  import StreamOrchestrator from "../../stream";
36
36
  import createContentTimeBoundariesObserver from "../common/create_content_time_boundaries_observer";
37
+ import type { IFreezeResolution } from "../common/FreezeResolver";
37
38
  import getBufferedDataPerMediaBuffer from "../common/get_buffered_data_per_media_buffer";
39
+ import synchronizeSegmentSinksOnObservation from "../common/synchronize_sinks_on_observation";
38
40
  import ContentPreparer from "./content_preparer";
39
41
  import {
40
42
  limitVideoResolution,
@@ -150,6 +152,7 @@ export default function initializeWorkerMain() {
150
152
  currentLoadedContentTaskCanceller.signal.register(() => {
151
153
  currentContentObservationRef.finish();
152
154
  });
155
+ log.debug("WP: Loading new pepared content.");
153
156
  loadOrReloadPreparedContent(
154
157
  msg.value,
155
158
  contentPreparer,
@@ -487,6 +490,7 @@ function loadOrReloadPreparedContent(
487
490
  playbackObservationRef: IReadOnlySharedReference<IWorkerPlaybackObservation>,
488
491
  parentCancelSignal: CancellationSignal,
489
492
  ) {
493
+ log.debug("WP: Loading prepared content");
490
494
  const currentLoadCanceller = new TaskCanceller();
491
495
  currentLoadCanceller.linkToSignal(parentCancelSignal);
492
496
 
@@ -516,6 +520,7 @@ function loadOrReloadPreparedContent(
516
520
  const {
517
521
  contentId,
518
522
  cmcdDataBuilder,
523
+ enableRepresentationAvoidance,
519
524
  manifest,
520
525
  mediaSource,
521
526
  representationEstimator,
@@ -523,23 +528,20 @@ function loadOrReloadPreparedContent(
523
528
  segmentQueueCreator,
524
529
  } = preparedContent;
525
530
  const { drmSystemId, enableFastSwitching, initialTime, onCodecSwitch } = val;
531
+
526
532
  playbackObservationRef.onUpdate(
527
533
  (observation) => {
528
- if (preparedContent.decipherabilityFreezeDetector.needToReload(observation)) {
529
- handleMediaSourceReload({
530
- timeOffset: 0,
531
- minimumPosition: 0,
532
- maximumPosition: Infinity,
534
+ synchronizeSegmentSinksOnObservation(observation, segmentSinksStore);
535
+ const freezeResolution =
536
+ preparedContent.freezeResolver.onNewObservation(observation);
537
+ if (freezeResolution !== null) {
538
+ handleFreezeResolution(freezeResolution, {
539
+ contentId,
540
+ manifest,
541
+ handleMediaSourceReload,
542
+ enableRepresentationAvoidance,
533
543
  });
534
544
  }
535
-
536
- // Synchronize SegmentSinks with what has been buffered.
537
- ["video" as const, "audio" as const, "text" as const].forEach((tType) => {
538
- const segmentSinkStatus = segmentSinksStore.getStatus(tType);
539
- if (segmentSinkStatus.type === "initialized") {
540
- segmentSinkStatus.value.synchronizeInventory(observation.buffered[tType] ?? []);
541
- }
542
- });
543
545
  },
544
546
  { clearSignal: currentLoadCanceller.signal },
545
547
  );
@@ -881,8 +883,15 @@ function loadOrReloadPreparedContent(
881
883
  if (currentLoadCanceller !== null) {
882
884
  currentLoadCanceller.cancel();
883
885
  }
886
+ log.debug(
887
+ "WP: Reloading MediaSource",
888
+ payload.timeOffset,
889
+ payload.minimumPosition,
890
+ payload.maximumPosition,
891
+ );
884
892
  contentPreparer.reloadMediaSource(payload).then(
885
893
  () => {
894
+ log.info("WP: MediaSource Reloaded, loading content again");
886
895
  loadOrReloadPreparedContent(
887
896
  {
888
897
  initialTime: newInitialTime,
@@ -960,3 +969,71 @@ function sendSegmentSinksStoreInfos(
960
969
  value: { segmentSinkMetrics: segmentSinksMetrics, messageId },
961
970
  });
962
971
  }
972
+
973
+ /**
974
+ * Handle accordingly an `IFreezeResolution` object.
975
+ * @param {Object|null} freezeResolution - The `IFreezeResolution` suggested.
976
+ * @param {Object} param - Parameters that might be needed to implement the
977
+ * resolution.
978
+ * @param {string} param.contentId - `contentId` for the current content, used
979
+ * e.g. for message exchanges between threads.
980
+ * @param {Object} param.manifest - The current content's Manifest object.
981
+ * @param {Function} param.handleMediaSourceReload - Function to call if we need
982
+ * to ask for a "MediaSource reload".
983
+ * @param {Boolean} param.enableRepresentationAvoidance - If `true`, this
984
+ * function is authorized to mark `Representation` as "to avoid" if the
985
+ * `IFreezeResolution` object suggest it.
986
+ */
987
+ function handleFreezeResolution(
988
+ freezeResolution: IFreezeResolution,
989
+ {
990
+ contentId,
991
+ manifest,
992
+ handleMediaSourceReload,
993
+ enableRepresentationAvoidance,
994
+ }: {
995
+ contentId: string;
996
+ manifest: Manifest;
997
+ handleMediaSourceReload: (payload: INeedsMediaSourceReloadPayload) => void;
998
+ enableRepresentationAvoidance: boolean;
999
+ },
1000
+ ): void {
1001
+ switch (freezeResolution.type) {
1002
+ case "reload": {
1003
+ log.info("WP: Planning reload due to freeze");
1004
+ handleMediaSourceReload({
1005
+ timeOffset: 0,
1006
+ minimumPosition: 0,
1007
+ maximumPosition: Infinity,
1008
+ });
1009
+ break;
1010
+ }
1011
+ case "flush": {
1012
+ log.info("WP: Flushing buffer due to freeze");
1013
+ sendMessage({
1014
+ type: WorkerMessageType.NeedsBufferFlush,
1015
+ contentId,
1016
+ value: {
1017
+ relativeResumingPosition: freezeResolution.value.relativeSeek,
1018
+ relativePosHasBeenDefaulted: false,
1019
+ },
1020
+ });
1021
+ break;
1022
+ }
1023
+ case "avoid-representations": {
1024
+ log.info("WP: Planning Representation avoidance due to freeze");
1025
+ const content = freezeResolution.value;
1026
+ if (enableRepresentationAvoidance) {
1027
+ manifest.addRepresentationsToAvoid(content);
1028
+ }
1029
+ handleMediaSourceReload({
1030
+ timeOffset: 0,
1031
+ minimumPosition: 0,
1032
+ maximumPosition: Infinity,
1033
+ });
1034
+ break;
1035
+ }
1036
+ default:
1037
+ assertUnreachable(freezeResolution);
1038
+ }
1039
+ }
@@ -94,8 +94,9 @@ export default function AdaptationStream(
94
94
  let previouslyEmittedBitrate: number | undefined;
95
95
 
96
96
  const initialRepIds = content.representations.getValue().representationIds;
97
- const initialRepresentations = content.adaptation.representations.filter(
98
- (r) => arrayIncludes(initialRepIds, r.id) && r.isPlayable() !== false,
97
+ const initialRepresentations = getRepresentationList(
98
+ content.adaptation.representations,
99
+ initialRepIds,
99
100
  );
100
101
 
101
102
  /** Emit the list of Representation for the adaptive logic. */
@@ -174,8 +175,13 @@ export default function AdaptationStream(
174
175
  cancelCurrentStreams.cancel();
175
176
  }
176
177
  const newRepIds = content.representations.getValue().representationIds;
177
- const newRepresentations = content.adaptation.representations.filter((r) =>
178
- arrayIncludes(newRepIds, r.id),
178
+
179
+ // NOTE: We expect that the rest of the RxPlayer code is already handling
180
+ // cases where the list of playable `Representation` changes:
181
+ // decipherability updates, "`Representation` avoidance" etc.
182
+ const newRepresentations = getRepresentationList(
183
+ content.adaptation.representations,
184
+ newRepIds,
179
185
  );
180
186
  representationsList.setValueIfChanged(newRepresentations);
181
187
  cancelCurrentStreams = new TaskCanceller();
@@ -540,3 +546,31 @@ export default function AdaptationStream(
540
546
  return wba * bufferGoalRatio;
541
547
  }
542
548
  }
549
+
550
+ /**
551
+ * Construct the list of the `Representation` to play, based on what's supported
552
+ * and what the API seem to authorize.
553
+ * @param {Array.<Object>} availableRepresentations - All available
554
+ * Representation in the current `Adaptation`, including unsupported ones.
555
+ * @param {Array.<string>} authorizedRepIds - The subset of `Representation`
556
+ * that the API authorize us to play.
557
+ * @returns {Array.<Object>}
558
+ */
559
+ function getRepresentationList(
560
+ availableRepresentations: IRepresentation[],
561
+ authorizedRepIds: string[],
562
+ ): IRepresentation[] {
563
+ const filteredRepresentations = availableRepresentations.filter(
564
+ (r) =>
565
+ arrayIncludes(authorizedRepIds, r.id) &&
566
+ !r.shouldBeAvoided &&
567
+ r.isPlayable() !== false,
568
+ );
569
+ if (filteredRepresentations.length > 0) {
570
+ return filteredRepresentations;
571
+ }
572
+ // Retry without "`Representation` avoidance"
573
+ return availableRepresentations.filter(
574
+ (r) => arrayIncludes(authorizedRepIds, r.id) && r.isPlayable() !== false,
575
+ );
576
+ }
@@ -17,11 +17,7 @@
17
17
  import config from "../../../config";
18
18
  import { MediaError } from "../../../errors";
19
19
  import log from "../../../log";
20
- import type {
21
- IManifest,
22
- IDecipherabilityUpdateElement,
23
- IPeriod,
24
- } from "../../../manifest";
20
+ import type { IManifest, IUpdatedRepresentationInfo, IPeriod } from "../../../manifest";
25
21
  import type { IReadOnlyPlaybackObserver } from "../../../playback_observer";
26
22
  import isNullOrUndefined from "../../../utils/is_null_or_undefined";
27
23
  import queueMicrotask from "../../../utils/queue_microtask";
@@ -295,7 +291,7 @@ export default function StreamOrchestrator(
295
291
  * @returns {Promise}
296
292
  */
297
293
  async function onDecipherabilityUpdates(
298
- updates: IDecipherabilityUpdateElement[],
294
+ updates: IUpdatedRepresentationInfo[],
299
295
  ): Promise<void> {
300
296
  const segmentSinkStatus = segmentSinksStore.getStatus(bufferType);
301
297
  const ofCurrentType = updates.filter(
@@ -550,6 +550,33 @@ const DEFAULT_CONFIG = {
550
550
  */
551
551
  UNFREEZING_DELTA_POSITION: 0.001,
552
552
 
553
+ /**
554
+ * `FREEZING` is a situation where the playback does not seem to advance despite
555
+ * all web indicators telling us we can.
556
+ * Those may be linked to device issues, but sometimes are just linked to
557
+ * performance or it may be just decryption negotiations taking more time than
558
+ * expected.
559
+ *
560
+ * Anyway we might in the RxPlayer "flush" the buffer in that situation to
561
+ * un-stuck playback (this is usually done by seeking close to the current
562
+ * position),
563
+ *
564
+ * Yet that "flush" attempt may not in the end be succesful.
565
+ *
566
+ * If a flush was performed more than `FREEZING_FLUSH_FAILURE_DELAY.MINIMUM`
567
+ * milliseconds ago and less than `FREEZING_FLUSH_FAILURE_DELAY.MAXIMUM`
568
+ * milliseconds ago, yet a `FREEZING` situation at roughly the same playback
569
+ * position (deviating from less than
570
+ * `FREEZING_FLUSH_FAILURE_DELAY.POSITION_DELTA` seconds from it) is
571
+ * encountered again, we will consider that the flushing attempt was unsuccesful
572
+ * and try more agressive solutions (such as reloading the content).
573
+ */
574
+ FREEZING_FLUSH_FAILURE_DELAY: {
575
+ MAXIMUM: 20000,
576
+ MINIMUM: 4000,
577
+ POSITION_DELTA: 1,
578
+ },
579
+
553
580
  /**
554
581
  * The RxPlayer has a recurring logic which will synchronize the browser's
555
582
  * buffers' buffered time ranges with its internal representation in the
@@ -12,7 +12,7 @@ describe("MediaCapabilitiesProber probers - DRMInfos", () => {
12
12
  const probeDRMInfos = (await vi.importActual("../../probers/DRMInfos"))
13
13
  .default as typeof IProbeDRMInfos;
14
14
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
15
- expect(probeDRMInfos(configuration)).rejects.toEqual(
15
+ await expect(probeDRMInfos(configuration)).rejects.toEqual(
16
16
  "MediaCapabilitiesProber >>> API_CALL: " +
17
17
  "Missing a type argument to request a media key system access.",
18
18
  );
@@ -25,7 +25,7 @@ describe("MediaCapabilitiesProber probers - DRMInfos", () => {
25
25
  const probeDRMInfos = (await vi.importActual("../../probers/DRMInfos"))
26
26
  .default as typeof IProbeDRMInfos;
27
27
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
28
- expect(probeDRMInfos(configuration)).rejects.toEqual(
28
+ await expect(probeDRMInfos(configuration)).rejects.toEqual(
29
29
  "MediaCapabilitiesProber >>> API_CALL: " +
30
30
  "Missing a type argument to request a media key system access.",
31
31
  );
@@ -43,7 +43,7 @@ describe("MediaCapabilitiesProber probers - DRMInfos", () => {
43
43
  const probeDRMInfos = (await vi.importActual("../../probers/DRMInfos"))
44
44
  .default as typeof IProbeDRMInfos;
45
45
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
46
- expect(probeDRMInfos(configuration)).resolves.toEqual([
46
+ await expect(probeDRMInfos(configuration)).resolves.toEqual([
47
47
  ProberStatus.NotSupported,
48
48
  { configuration: {}, type: "clearkick" },
49
49
  ]);
@@ -14,7 +14,7 @@ describe("MediaCapabilitiesProber probers - HDCPPolicy", () => {
14
14
  const probeHDCPPolicy = (await vi.importActual("../../probers/HDCPPolicy"))
15
15
  .default as typeof IProbeHDCPPolicy;
16
16
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
17
- expect(probeHDCPPolicy({})).rejects.toEqual(
17
+ await expect(probeHDCPPolicy({})).rejects.toEqual(
18
18
  "MediaCapabilitiesProber >>> API_CALL: API not available",
19
19
  );
20
20
  });
@@ -33,7 +33,7 @@ describe("MediaCapabilitiesProber probers - HDCPPolicy", () => {
33
33
  const probeHDCPPolicy = (await vi.importActual("../../probers/HDCPPolicy"))
34
34
  .default as typeof IProbeHDCPPolicy;
35
35
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
36
- expect(probeHDCPPolicy({})).rejects.toEqual(
36
+ await expect(probeHDCPPolicy({})).rejects.toEqual(
37
37
  "MediaCapabilitiesProber >>> API_CALL: " +
38
38
  "Missing policy argument for calling getStatusForPolicy.",
39
39
  );
@@ -162,17 +162,17 @@ describe("MediaCapabilitiesProber probers - decodingInfo", () => {
162
162
  });
163
163
  });
164
164
 
165
- it("should throw if API mediaCapabilities not available", () => {
165
+ it("should throw if API mediaCapabilities not available", async () => {
166
166
  // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for
167
167
  // now, we're going through JSDom through so that's OK.
168
168
  delete navigator.mediaCapabilities;
169
169
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
170
- expect(probeDecodingInfos({})).rejects.toThrowError(
170
+ await expect(probeDecodingInfos({})).rejects.toThrowError(
171
171
  "MediaCapabilitiesProber >>> API_CALL: MediaCapabilities API not available",
172
172
  );
173
173
  });
174
174
 
175
- it("should throw if API decodingInfo not available", () => {
175
+ it("should throw if API decodingInfo not available", async () => {
176
176
  if (!isNullOrUndefined(navigator.mediaCapabilities)) {
177
177
  // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for
178
178
  // now, we're going through JSDom through so that's OK.
@@ -183,7 +183,7 @@ describe("MediaCapabilitiesProber probers - decodingInfo", () => {
183
183
  navigator.mediaCapabilities = {};
184
184
  }
185
185
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
186
- expect(probeDecodingInfos({})).rejects.toThrowError(
186
+ await expect(probeDecodingInfos({})).rejects.toThrowError(
187
187
  "MediaCapabilitiesProber >>> API_CALL: Decoding Info not available",
188
188
  );
189
189
  });
@@ -16,7 +16,7 @@ describe("MediaCapabilitiesProber - probers probeMediaContentType", () => {
16
16
  await vi.importActual("../../probers/mediaContentType")
17
17
  ).default as typeof IProbeMediaContentType;
18
18
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
19
- expect(probeMediaContentType({})).rejects.toThrowError(
19
+ await expect(probeMediaContentType({})).rejects.toThrowError(
20
20
  "MediaCapabilitiesProber >>> API_CALL: " + "MediaSource API not available",
21
21
  );
22
22
  });
@@ -31,7 +31,7 @@ describe("MediaCapabilitiesProber - probers probeMediaContentType", () => {
31
31
  await vi.importActual("../../probers/mediaContentType")
32
32
  ).default as typeof IProbeMediaContentType;
33
33
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
34
- expect(probeMediaContentType({})).rejects.toThrowError(
34
+ await expect(probeMediaContentType({})).rejects.toThrowError(
35
35
  "MediaCapabilitiesProber >>> API_CALL: " + "isTypeSupported not available",
36
36
  );
37
37
  });
@@ -15,7 +15,7 @@ describe("MediaCapabilitiesProber probers probeMediaDisplayInfos", () => {
15
15
  await vi.importActual("../../probers/mediaDisplayInfos")
16
16
  ).default as typeof IProbeMediaDisplayInfos;
17
17
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
18
- expect(probeMediaDisplayInfos({})).rejects.toThrowError(
18
+ await expect(probeMediaDisplayInfos({})).rejects.toThrowError(
19
19
  "MediaCapabilitiesProber >>> API_CALL: matchMedia not available",
20
20
  );
21
21
  (
@@ -301,6 +301,9 @@ describe("API - parseLoadVideoOptions", () => {
301
301
  textTrackElement: undefined,
302
302
  textTrackMode: "native",
303
303
  url: undefined,
304
+ experimentalOptions: {
305
+ enableRepresentationAvoidance: false,
306
+ },
304
307
  };
305
308
 
306
309
  it("should throw if no option is given", () => {