rx-player 4.0.0-dev.2023120600 → 4.0.0-dev.2023121900

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 (326) hide show
  1. package/CHANGELOG.md +178 -2
  2. package/README.md +2 -33
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/add_text_track.d.ts +3 -1
  5. package/dist/_esm5.processed/compat/add_text_track.js +7 -4
  6. package/dist/_esm5.processed/compat/browser_compatibility_types.d.ts +7 -0
  7. package/dist/_esm5.processed/compat/event_listeners.d.ts +15 -2
  8. package/dist/_esm5.processed/compat/event_listeners.js +37 -2
  9. package/dist/_esm5.processed/compat/fullscreen.d.ts +32 -0
  10. package/dist/_esm5.processed/compat/fullscreen.js +78 -0
  11. package/dist/_esm5.processed/compat/index.d.ts +3 -1
  12. package/dist/_esm5.processed/compat/index.js +3 -1
  13. package/dist/_esm5.processed/compat/is_offline.d.ts +39 -0
  14. package/dist/_esm5.processed/compat/is_offline.js +43 -0
  15. package/dist/_esm5.processed/config.d.ts +21 -9
  16. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.d.ts +58 -0
  17. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +54 -14
  18. package/dist/_esm5.processed/core/adaptive/utils/select_optimal_representation.d.ts +8 -2
  19. package/dist/_esm5.processed/core/adaptive/utils/select_optimal_representation.js +11 -2
  20. package/dist/_esm5.processed/core/api/debug/modules/general_info.js +46 -17
  21. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +3 -3
  22. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +1 -1
  23. package/dist/_esm5.processed/core/api/option_utils.d.ts +35 -14
  24. package/dist/_esm5.processed/core/api/option_utils.js +230 -47
  25. package/dist/_esm5.processed/core/api/public_api.d.ts +266 -92
  26. package/dist/_esm5.processed/core/api/public_api.js +802 -444
  27. package/dist/_esm5.processed/core/api/{track_management/media_element_tracks_store.d.ts → tracks_management/media_element_track_choice_manager.d.ts} +75 -15
  28. package/dist/_esm5.processed/core/api/{track_management/media_element_tracks_store.js → tracks_management/media_element_track_choice_manager.js} +193 -74
  29. package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.d.ts +258 -0
  30. package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.js +989 -0
  31. package/dist/_esm5.processed/core/api/utils.d.ts +0 -1
  32. package/dist/_esm5.processed/core/api/utils.js +11 -28
  33. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +3 -3
  34. package/dist/_esm5.processed/core/decrypt/find_key_system.js +71 -83
  35. package/dist/_esm5.processed/core/decrypt/get_media_keys.js +5 -6
  36. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +72 -10
  37. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.d.ts +4 -4
  38. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.js +4 -6
  39. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +3 -1
  40. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +26 -7
  41. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +9 -3
  42. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +9 -16
  43. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -1
  44. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +1 -1
  45. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.d.ts +6 -1
  46. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +41 -4
  47. package/dist/_esm5.processed/core/init/media_source_content_initializer.d.ts +8 -1
  48. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +5 -2
  49. package/dist/_esm5.processed/core/init/types.d.ts +15 -5
  50. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  51. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.d.ts +75 -0
  52. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +133 -0
  53. package/dist/_esm5.processed/core/{api/track_management → segment_buffers/implementations/image}/index.d.ts +2 -3
  54. package/dist/_esm5.processed/core/{api/track_management → segment_buffers/implementations/image}/index.js +2 -3
  55. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  56. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +2 -1
  57. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +4 -3
  58. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +2 -2
  59. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  60. package/dist/_esm5.processed/core/segment_buffers/index.js +1 -2
  61. package/dist/_esm5.processed/core/segment_buffers/inventory/index.d.ts +2 -3
  62. package/dist/_esm5.processed/core/segment_buffers/inventory/index.js +0 -1
  63. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  64. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +19 -10
  65. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.d.ts +1 -0
  66. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +16 -2
  67. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.d.ts +15 -0
  68. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +93 -183
  69. package/dist/_esm5.processed/core/stream/adaptation/types.d.ts +13 -27
  70. package/dist/_esm5.processed/core/stream/index.d.ts +3 -2
  71. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.d.ts +0 -2
  72. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +7 -5
  73. package/dist/_esm5.processed/core/stream/period/period_stream.js +12 -13
  74. package/dist/_esm5.processed/core/stream/period/types.d.ts +14 -5
  75. package/dist/_esm5.processed/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -2
  76. package/dist/_esm5.processed/core/stream/period/utils/get_adaptation_switch_strategy.js +46 -10
  77. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +23 -29
  78. package/dist/_esm5.processed/core/stream/representation/types.d.ts +1 -11
  79. package/dist/_esm5.processed/core/stream/representation/utils/get_buffer_status.js +1 -1
  80. package/dist/_esm5.processed/core/stream/representation/utils/get_needed_segments.js +1 -1
  81. package/dist/_esm5.processed/default_config.d.ts +98 -35
  82. package/dist/_esm5.processed/default_config.js +113 -36
  83. package/dist/_esm5.processed/errors/custom_loader_error.d.ts +3 -1
  84. package/dist/_esm5.processed/errors/custom_loader_error.js +3 -1
  85. package/dist/_esm5.processed/errors/media_error.js +2 -2
  86. package/dist/_esm5.processed/errors/network_error.d.ts +1 -0
  87. package/dist/_esm5.processed/errors/network_error.js +1 -0
  88. package/dist/_esm5.processed/errors/request_error.d.ts +3 -2
  89. package/dist/_esm5.processed/errors/request_error.js +5 -2
  90. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +3 -3
  91. package/dist/_esm5.processed/features/features_object.js +2 -0
  92. package/dist/_esm5.processed/{transports/smooth/is_mp4_embedded_track.js → features/list/bif_parser.d.ts} +6 -7
  93. package/dist/_esm5.processed/features/list/bif_parser.js +27 -0
  94. package/dist/_esm5.processed/features/list/directfile.js +5 -2
  95. package/dist/_esm5.processed/features/list/image_buffer.d.ts +23 -0
  96. package/dist/_esm5.processed/features/list/image_buffer.js +25 -0
  97. package/dist/_esm5.processed/features/list/index.d.ts +2 -0
  98. package/dist/_esm5.processed/features/list/index.js +2 -0
  99. package/dist/_esm5.processed/features/types.d.ts +27 -3
  100. package/dist/_esm5.processed/manifest/adaptation.d.ts +11 -9
  101. package/dist/_esm5.processed/manifest/adaptation.js +30 -41
  102. package/dist/_esm5.processed/manifest/index.d.ts +4 -3
  103. package/dist/_esm5.processed/manifest/manifest.d.ts +54 -5
  104. package/dist/_esm5.processed/manifest/manifest.js +110 -5
  105. package/dist/_esm5.processed/manifest/period.d.ts +5 -4
  106. package/dist/_esm5.processed/manifest/representation.d.ts +5 -10
  107. package/dist/_esm5.processed/manifest/representation.js +5 -15
  108. package/dist/_esm5.processed/manifest/representation_index/index.d.ts +2 -2
  109. package/dist/_esm5.processed/manifest/representation_index/static.d.ts +0 -2
  110. package/dist/_esm5.processed/manifest/representation_index/static.js +0 -6
  111. package/dist/_esm5.processed/manifest/representation_index/types.d.ts +21 -42
  112. package/dist/_esm5.processed/manifest/types.d.ts +2 -0
  113. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +31 -17
  114. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +19 -26
  115. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +0 -2
  116. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +1 -7
  117. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +6 -2
  118. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +8 -11
  119. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +0 -2
  120. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +0 -6
  121. package/dist/_esm5.processed/parsers/manifest/dash/common/infer_adaptation_type.d.ts +2 -2
  122. package/dist/_esm5.processed/parsers/manifest/dash/common/infer_adaptation_type.js +6 -1
  123. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +5 -3
  124. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.d.ts +2 -0
  125. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +1 -1
  126. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.js +2 -2
  127. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.d.ts +2 -0
  128. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +2 -2
  129. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.js +6 -10
  130. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/Representation.js +2 -4
  131. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/utils.d.ts +1 -10
  132. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/utils.js +2 -18
  133. package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +4 -4
  134. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.js +6 -3
  135. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Representation.js +2 -1
  136. package/dist/_esm5.processed/parsers/manifest/local/representation_index.d.ts +0 -2
  137. package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +0 -6
  138. package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.js +6 -6
  139. package/dist/_esm5.processed/parsers/manifest/metaplaylist/representation_index.d.ts +3 -12
  140. package/dist/_esm5.processed/parsers/manifest/metaplaylist/representation_index.js +2 -11
  141. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.d.ts +1 -0
  142. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +17 -11
  143. package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.d.ts +83 -21
  144. package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +125 -53
  145. package/dist/_esm5.processed/parsers/manifest/smooth/utils/add_segment_infos.d.ts +6 -3
  146. package/dist/_esm5.processed/parsers/manifest/smooth/utils/add_segment_infos.js +4 -4
  147. package/dist/_esm5.processed/parsers/manifest/types.d.ts +3 -3
  148. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  149. package/dist/_esm5.processed/public_types.d.ts +310 -396
  150. package/dist/_esm5.processed/tools/TextTrackRenderer/text_track_renderer.d.ts +4 -5
  151. package/dist/_esm5.processed/tools/TextTrackRenderer/text_track_renderer.js +4 -5
  152. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +4 -4
  153. package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +38 -0
  154. package/dist/_esm5.processed/transports/dash/image_pipelines.js +129 -0
  155. package/dist/_esm5.processed/transports/dash/manifest_parser.js +3 -2
  156. package/dist/_esm5.processed/transports/dash/pipelines.js +4 -1
  157. package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +2 -2
  158. package/dist/_esm5.processed/transports/dash/segment_loader.js +20 -26
  159. package/dist/_esm5.processed/transports/dash/segment_parser.js +24 -19
  160. package/dist/_esm5.processed/transports/dash/text_loader.js +5 -5
  161. package/dist/_esm5.processed/transports/dash/text_parser.js +33 -28
  162. package/dist/_esm5.processed/transports/local/pipelines.js +10 -1
  163. package/dist/_esm5.processed/transports/local/segment_loader.js +2 -2
  164. package/dist/_esm5.processed/transports/local/segment_parser.d.ts +1 -1
  165. package/dist/_esm5.processed/transports/local/segment_parser.js +10 -10
  166. package/dist/_esm5.processed/transports/local/text_parser.d.ts +2 -2
  167. package/dist/_esm5.processed/transports/local/text_parser.js +23 -23
  168. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +52 -34
  169. package/dist/_esm5.processed/transports/smooth/pipelines.js +190 -33
  170. package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +1 -1
  171. package/dist/_esm5.processed/transports/smooth/segment_loader.js +22 -28
  172. package/dist/_esm5.processed/transports/smooth/utils.d.ts +26 -1
  173. package/dist/_esm5.processed/transports/smooth/utils.js +55 -1
  174. package/dist/_esm5.processed/transports/types.d.ts +89 -94
  175. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
  176. package/dist/_esm5.processed/transports/utils/infer_segment_container.d.ts +3 -3
  177. package/dist/_esm5.processed/transports/utils/infer_segment_container.js +7 -5
  178. package/dist/_esm5.processed/transports/utils/parse_text_track.d.ts +12 -8
  179. package/dist/_esm5.processed/transports/utils/parse_text_track.js +21 -19
  180. package/dist/_esm5.processed/utils/array_includes.d.ts +1 -2
  181. package/dist/_esm5.processed/utils/array_includes.js +28 -30
  182. package/dist/_esm5.processed/{transports/smooth/is_mp4_embedded_track.d.ts → utils/list_to_map.d.ts} +5 -5
  183. package/dist/_esm5.processed/utils/list_to_map.js +28 -0
  184. package/dist/_esm5.processed/utils/request/xhr.js +5 -5
  185. package/dist/_esm5.processed/utils/simple_set.d.ts +51 -0
  186. package/dist/_esm5.processed/utils/simple_set.js +57 -0
  187. package/dist/_esm5.processed/utils/uniq.d.ts +36 -0
  188. package/dist/_esm5.processed/utils/uniq.js +43 -0
  189. package/dist/commonjs/config.d.ts +1 -1
  190. package/dist/commonjs/core/adaptive/adaptive_representation_selector.d.ts +2 -19
  191. package/dist/commonjs/core/adaptive/adaptive_representation_selector.js +2 -2
  192. package/dist/commonjs/core/adaptive/network_analyzer.js +3 -3
  193. package/dist/commonjs/core/api/index.d.ts +1 -1
  194. package/dist/commonjs/core/api/playback_observer.d.ts +128 -8
  195. package/dist/commonjs/core/api/playback_observer.js +217 -64
  196. package/dist/commonjs/core/api/public_api.js +9 -9
  197. package/dist/commonjs/core/api/utils.js +1 -1
  198. package/dist/commonjs/core/decrypt/get_media_keys.js +2 -6
  199. package/dist/commonjs/core/init/directfile_content_initializer.js +5 -1
  200. package/dist/commonjs/core/init/media_source_content_initializer.js +28 -14
  201. package/dist/commonjs/core/init/utils/content_time_boundaries_observer.js +1 -2
  202. package/dist/commonjs/core/init/utils/create_stream_playback_observer.d.ts +1 -5
  203. package/dist/commonjs/core/init/utils/create_stream_playback_observer.js +16 -14
  204. package/dist/commonjs/core/init/utils/initial_seek_and_play.d.ts +9 -11
  205. package/dist/commonjs/core/init/utils/initial_seek_and_play.js +121 -91
  206. package/dist/commonjs/core/init/utils/rebuffering_controller.js +27 -70
  207. package/dist/commonjs/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
  208. package/dist/commonjs/core/segment_buffers/garbage_collector.js +1 -2
  209. package/dist/commonjs/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  210. package/dist/commonjs/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  211. package/dist/commonjs/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  212. package/dist/commonjs/core/segment_buffers/index.d.ts +2 -2
  213. package/dist/commonjs/core/segment_buffers/inventory/index.d.ts +2 -2
  214. package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  215. package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.js +19 -10
  216. package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
  217. package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
  218. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +14 -18
  219. package/dist/commonjs/core/stream/period/period_stream.js +5 -8
  220. package/dist/commonjs/core/stream/period/types.d.ts +2 -3
  221. package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
  222. package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
  223. package/dist/commonjs/core/stream/representation/representation_stream.js +3 -4
  224. package/dist/commonjs/core/stream/representation/types.d.ts +2 -2
  225. package/dist/commonjs/core/stream/representation/utils/append_segment_to_buffer.js +11 -12
  226. package/dist/commonjs/core/stream/representation/utils/get_buffer_status.js +1 -1
  227. package/dist/commonjs/default_config.d.ts +7 -16
  228. package/dist/commonjs/default_config.js +16 -16
  229. package/dist/commonjs/manifest/adaptation.js +2 -1
  230. package/dist/commonjs/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  231. package/dist/commonjs/public_types.d.ts +29 -2
  232. package/dist/es2017/config.d.ts +1 -1
  233. package/dist/es2017/core/adaptive/adaptive_representation_selector.d.ts +2 -19
  234. package/dist/es2017/core/adaptive/adaptive_representation_selector.js +2 -2
  235. package/dist/es2017/core/adaptive/network_analyzer.js +3 -3
  236. package/dist/es2017/core/api/index.d.ts +1 -1
  237. package/dist/es2017/core/api/playback_observer.d.ts +128 -8
  238. package/dist/es2017/core/api/playback_observer.js +217 -66
  239. package/dist/es2017/core/api/public_api.js +9 -9
  240. package/dist/es2017/core/api/utils.js +1 -1
  241. package/dist/es2017/core/decrypt/get_media_keys.js +2 -6
  242. package/dist/es2017/core/init/directfile_content_initializer.js +7 -1
  243. package/dist/es2017/core/init/media_source_content_initializer.js +30 -16
  244. package/dist/es2017/core/init/utils/content_time_boundaries_observer.js +1 -2
  245. package/dist/es2017/core/init/utils/create_stream_playback_observer.d.ts +1 -5
  246. package/dist/es2017/core/init/utils/create_stream_playback_observer.js +16 -14
  247. package/dist/es2017/core/init/utils/initial_seek_and_play.d.ts +9 -11
  248. package/dist/es2017/core/init/utils/initial_seek_and_play.js +120 -91
  249. package/dist/es2017/core/init/utils/rebuffering_controller.js +27 -70
  250. package/dist/es2017/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
  251. package/dist/es2017/core/segment_buffers/garbage_collector.js +1 -2
  252. package/dist/es2017/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  253. package/dist/es2017/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  254. package/dist/es2017/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  255. package/dist/es2017/core/segment_buffers/index.d.ts +2 -2
  256. package/dist/es2017/core/segment_buffers/inventory/index.d.ts +2 -2
  257. package/dist/es2017/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  258. package/dist/es2017/core/segment_buffers/inventory/segment_inventory.js +19 -10
  259. package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
  260. package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
  261. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +16 -18
  262. package/dist/es2017/core/stream/period/period_stream.js +4 -7
  263. package/dist/es2017/core/stream/period/types.d.ts +2 -3
  264. package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
  265. package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
  266. package/dist/es2017/core/stream/representation/representation_stream.js +3 -4
  267. package/dist/es2017/core/stream/representation/types.d.ts +2 -2
  268. package/dist/es2017/core/stream/representation/utils/append_segment_to_buffer.js +1 -2
  269. package/dist/es2017/core/stream/representation/utils/get_buffer_status.js +1 -1
  270. package/dist/es2017/default_config.d.ts +7 -16
  271. package/dist/es2017/default_config.js +16 -16
  272. package/dist/es2017/manifest/adaptation.js +2 -1
  273. package/dist/es2017/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  274. package/dist/es2017/public_types.d.ts +29 -2
  275. package/dist/mpd-parser.wasm +0 -0
  276. package/dist/rx-player.js +614 -438
  277. package/dist/rx-player.min.js +1 -1
  278. package/package.json +5 -1
  279. package/scripts/canal-release.patch +78 -0
  280. package/scripts/make-dev-releases +65 -0
  281. package/scripts/update-version +5 -0
  282. package/sonar-project.properties +1 -1
  283. package/src/core/adaptive/adaptive_representation_selector.ts +4 -21
  284. package/src/core/adaptive/network_analyzer.ts +3 -3
  285. package/src/core/api/index.ts +1 -0
  286. package/src/core/api/playback_observer.ts +327 -107
  287. package/src/core/api/public_api.ts +9 -9
  288. package/src/core/api/utils.ts +3 -1
  289. package/src/core/decrypt/get_media_keys.ts +2 -8
  290. package/src/core/init/directfile_content_initializer.ts +8 -8
  291. package/src/core/init/media_source_content_initializer.ts +27 -20
  292. package/src/core/init/utils/content_time_boundaries_observer.ts +1 -1
  293. package/src/core/init/utils/create_stream_playback_observer.ts +19 -20
  294. package/src/core/init/utils/initial_seek_and_play.ts +140 -108
  295. package/src/core/init/utils/rebuffering_controller.ts +32 -77
  296. package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +5 -2
  297. package/src/core/segment_buffers/garbage_collector.ts +1 -1
  298. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +10 -2
  299. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +1 -1
  300. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +1 -1
  301. package/src/core/segment_buffers/index.ts +2 -0
  302. package/src/core/segment_buffers/inventory/index.ts +2 -0
  303. package/src/core/segment_buffers/inventory/segment_inventory.ts +49 -17
  304. package/src/core/stream/adaptation/get_representations_switch_strategy.ts +21 -12
  305. package/src/core/stream/orchestrator/stream_orchestrator.ts +14 -19
  306. package/src/core/stream/period/period_stream.ts +7 -8
  307. package/src/core/stream/period/types.ts +2 -3
  308. package/src/core/stream/period/utils/get_adaptation_switch_strategy.ts +21 -15
  309. package/src/core/stream/representation/representation_stream.ts +3 -5
  310. package/src/core/stream/representation/types.ts +2 -2
  311. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
  312. package/src/core/stream/representation/utils/get_buffer_status.ts +2 -1
  313. package/src/default_config.ts +17 -17
  314. package/src/manifest/adaptation.ts +2 -1
  315. package/src/parsers/texttracks/ttml/html/apply_line_height.ts +3 -1
  316. package/src/public_types.ts +29 -2
  317. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.d.ts +0 -84
  318. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.js +0 -158
  319. package/dist/_esm5.processed/core/api/track_management/tracks_store.d.ts +0 -406
  320. package/dist/_esm5.processed/core/api/track_management/tracks_store.js +0 -932
  321. package/dist/_esm5.processed/core/segment_buffers/inventory/utils.d.ts +0 -33
  322. package/dist/_esm5.processed/core/segment_buffers/inventory/utils.js +0 -49
  323. package/dist/_esm5.processed/core/stream/adaptation/get_representations_switch_strategy.d.ts +0 -39
  324. package/dist/_esm5.processed/core/stream/adaptation/get_representations_switch_strategy.js +0 -133
  325. package/dist/_esm5.processed/parsers/manifest/smooth/shared_smooth_segment_timeline.d.ts +0 -119
  326. package/dist/_esm5.processed/parsers/manifest/smooth/shared_smooth_segment_timeline.js +0 -159
@@ -28,6 +28,7 @@ import {
28
28
  import {
29
29
  IPlaybackObservation,
30
30
  IReadOnlyPlaybackObserver,
31
+ SeekingState,
31
32
  } from "./playback_observer";
32
33
 
33
34
  /**
@@ -52,7 +53,8 @@ export function emitSeekEvents(
52
53
  return ;
53
54
  }
54
55
 
55
- let wasSeeking = playbackObserver.getReference().getValue().seeking;
56
+ let wasSeeking =
57
+ playbackObserver.getReference().getValue().seeking === SeekingState.External;
56
58
  if (wasSeeking) {
57
59
  onSeeking();
58
60
  if (cancelSignal.isCancelled()) {
@@ -39,15 +39,9 @@ import ServerCertificateStore from "./utils/server_certificate_store";
39
39
  function createPersistentSessionsStorage(
40
40
  keySystemOptions : IKeySystemOption
41
41
  ) : PersistentSessionsStore|null {
42
- if (isNullOrUndefined(keySystemOptions.persistentLicenseConfig)) {
43
- return null;
44
- }
45
-
46
42
  const { persistentLicenseConfig } = keySystemOptions;
47
- if (persistentLicenseConfig == null) {
48
- throw new EncryptedMediaError("INVALID_KEY_SYSTEM",
49
- "No `persistentLicenseConfig` found for " +
50
- "persistent license.");
43
+ if (isNullOrUndefined(persistentLicenseConfig)) {
44
+ return null;
51
45
  }
52
46
 
53
47
  log.debug("DRM: Set the given license storage");
@@ -208,14 +208,14 @@ export default class DirectFileContentInitializer extends ContentInitializer {
208
208
  log.debug("Init: Initial time calculated:", initTime);
209
209
  return initTime;
210
210
  };
211
- performInitialSeekAndPlay(
212
- mediaElement,
213
- playbackObserver,
214
- initialTime,
215
- autoPlay,
216
- (err) => this.trigger("warning", err),
217
- cancelSignal
218
- ).autoPlayResult
211
+ performInitialSeekAndPlay({ mediaElement,
212
+ playbackObserver,
213
+ startTime: initialTime,
214
+ mustAutoPlay: autoPlay,
215
+ onWarning: (err) => this.trigger("warning", err),
216
+ isDirectfile: true },
217
+ cancelSignal)
218
+ .autoPlayResult
219
219
  .then(() =>
220
220
  getLoadedReference(playbackObserver, mediaElement, true, cancelSignal)
221
221
  .onUpdate((isLoaded, stopListening) => {
@@ -416,12 +416,13 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
416
416
  segmentBuffersStore.disposeAll();
417
417
  });
418
418
 
419
- const { autoPlayResult, initialPlayPerformed, initialSeekPerformed } =
420
- performInitialSeekAndPlay(mediaElement,
421
- playbackObserver,
422
- initialTime,
423
- autoPlay,
424
- (err) => this.trigger("warning", err),
419
+ const { autoPlayResult, initialPlayPerformed } =
420
+ performInitialSeekAndPlay({ mediaElement,
421
+ playbackObserver,
422
+ startTime: initialTime,
423
+ mustAutoPlay: autoPlay,
424
+ onWarning: (err) => { this.trigger("warning", err); },
425
+ isDirectfile: false },
425
426
  cancelSignal);
426
427
 
427
428
  if (cancelSignal.isCancelled()) {
@@ -451,9 +452,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
451
452
  { autoPlay,
452
453
  manifest,
453
454
  initialPlayPerformed,
454
- initialSeekPerformed,
455
- speed,
456
- startTime: initialTime },
455
+ speed },
457
456
  cancelSignal);
458
457
 
459
458
  const rebufferingController = this._createRebufferingController(playbackObserver,
@@ -462,11 +461,16 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
462
461
  speed,
463
462
  cancelSignal);
464
463
  rebufferingController.addEventListener("needsReload", () => {
464
+ let position: number;
465
+ const lastObservation = playbackObserver.getReference().getValue();
466
+ if (lastObservation.position.isAwaitingFuturePosition()) {
467
+ position = lastObservation.position.getWanted();
468
+ } else {
469
+ position = playbackObserver.getCurrentTime();
470
+ }
471
+
465
472
  // NOTE couldn't both be always calculated at event destination?
466
473
  // Maybe there are exceptions?
467
- const position = initialSeekPerformed.getValue() ?
468
- playbackObserver.getCurrentTime() :
469
- initialTime;
470
474
  const autoplay = initialPlayPerformed.getValue() ?
471
475
  !playbackObserver.getIsPaused() :
472
476
  autoPlay;
@@ -542,10 +546,10 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
542
546
  // Data is buffered around the current position
543
547
  obs.currentRange !== null ||
544
548
  // Or, for whatever reason, we have no buffer but we're already advancing
545
- obs.position > seekedTime + 0.1
549
+ obs.position.getPolled() > seekedTime + 0.1
546
550
  ) {
547
551
  stopListening();
548
- playbackObserver.setCurrentTime(obs.position + 0.001);
552
+ playbackObserver.setCurrentTime(obs.position.getWanted() + 0.001);
549
553
  }
550
554
  }, { includeLastObservation: false, clearSignal: cancelSignal });
551
555
  },
@@ -635,8 +639,9 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
635
639
 
636
640
  needsMediaSourceReload: (payload) => {
637
641
  const lastObservation = streamObserver.getReference().getValue();
638
- const currentPosition = lastObservation.position.pending ??
639
- streamObserver.getCurrentTime();
642
+ const currentPosition = lastObservation.position.isAwaitingFuturePosition() ?
643
+ lastObservation.position.getWanted() :
644
+ streamObserver.getCurrentTime();
640
645
  const isPaused = lastObservation.paused.pending ??
641
646
  streamObserver.getIsPaused();
642
647
  let position = currentPosition + payload.timeOffset;
@@ -653,15 +658,17 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
653
658
  const keySystem = getKeySystemConfiguration(mediaElement);
654
659
  if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem?.[0])) {
655
660
  const lastObservation = streamObserver.getReference().getValue();
656
- const position = lastObservation.position.pending ??
657
- streamObserver.getCurrentTime();
661
+ const position = lastObservation.position.isAwaitingFuturePosition() ?
662
+ lastObservation.position.getWanted() :
663
+ streamObserver.getCurrentTime();
658
664
  const isPaused = lastObservation.paused.pending ??
659
665
  streamObserver.getIsPaused();
660
666
  onReloadOrder({ position, autoPlay: !isPaused });
661
667
  } else {
662
668
  const lastObservation = streamObserver.getReference().getValue();
663
- const position = lastObservation.position.pending ??
664
- streamObserver.getCurrentTime();
669
+ const position = lastObservation.position.isAwaitingFuturePosition() ?
670
+ lastObservation.position.getWanted() :
671
+ streamObserver.getCurrentTime();
665
672
  // simple seek close to the current position
666
673
  // to flush the buffers
667
674
  if (position + 0.001 < lastObservation.duration) {
@@ -94,7 +94,7 @@ export default class ContentTimeBoundariesObserver
94
94
 
95
95
  const cancelSignal = this._canceller.signal;
96
96
  playbackObserver.listen(({ position }) => {
97
- const wantedPosition = position.pending ?? position.last;
97
+ const wantedPosition = position.getWanted();
98
98
  if (wantedPosition < manifest.getMinimumSafePosition()) {
99
99
  const warning = new MediaError("MEDIA_TIME_BEFORE_MANIFEST",
100
100
  "The current position is behind the " +
@@ -36,12 +36,8 @@ export interface IStreamPlaybackObserverArguments {
36
36
  manifest : Manifest;
37
37
  /** Becomes `true` after the initial play has been taken care of. */
38
38
  initialPlayPerformed : IReadOnlySharedReference<boolean>;
39
- /** Becomes `true` after the initial seek has been taken care of. */
40
- initialSeekPerformed : IReadOnlySharedReference<boolean>;
41
39
  /** The last speed requested by the user. */
42
40
  speed : IReadOnlySharedReference<number>;
43
- /** The time the player will seek when `initialSeekPerformed` becomes `true`. */
44
- startTime : number;
45
41
  }
46
42
 
47
43
  /**
@@ -57,10 +53,8 @@ export default function createStreamPlaybackObserver(
57
53
  srcPlaybackObserver : PlaybackObserver,
58
54
  { autoPlay,
59
55
  initialPlayPerformed,
60
- initialSeekPerformed,
61
56
  manifest,
62
- speed,
63
- startTime } : IStreamPlaybackObserverArguments,
57
+ speed } : IStreamPlaybackObserverArguments,
64
58
  fnCancelSignal : CancellationSignal
65
59
  ) : IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation> {
66
60
  return srcPlaybackObserver.deriveReadOnlyObserver(function transform(
@@ -87,10 +81,8 @@ export default function createStreamPlaybackObserver(
87
81
  function constructStreamPlaybackObservation() {
88
82
  const observation = observationRef.getValue();
89
83
  const lastSpeed = speed.getValue();
90
- let pendingPosition : number | undefined;
91
- if (!initialSeekPerformed.getValue()) {
92
- pendingPosition = startTime;
93
- } else if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
84
+
85
+ if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
94
86
  // HACK: When the position is actually further than the maximum
95
87
  // position for a finished content, we actually want to be loading
96
88
  // the last segment before ending.
@@ -98,21 +90,28 @@ export default function createStreamPlaybackObserver(
98
90
  // want to seek one second before the period's end (despite never
99
91
  // doing it).
100
92
  const lastPeriod = manifest.periods[manifest.periods.length - 1];
101
- if (lastPeriod !== undefined &&
102
- lastPeriod.end !== undefined &&
103
- observation.position > lastPeriod.end)
104
- {
105
- pendingPosition = lastPeriod.end - 1;
93
+ if (lastPeriod !== undefined && lastPeriod.end !== undefined) {
94
+ const wantedPosition = observation.position.getWanted();
95
+ if (wantedPosition >= lastPeriod.start &&
96
+ wantedPosition >= lastPeriod.end - 1)
97
+ {
98
+ // We're after the end of the last Period, check if `buffered`
99
+ // indicates that the last segment is probably not loaded, in which
100
+ // case act as if we want to load one second before the end.
101
+ const buffered = observation.buffered;
102
+ if (buffered.length === 0 ||
103
+ buffered.end(buffered.length - 1) < observation.duration - 1)
104
+ {
105
+ observation.position.forceWantedPosition(lastPeriod.end - 1);
106
+ }
107
+ }
106
108
  }
107
109
  }
108
110
 
109
111
  return {
110
112
  // TODO more exact according to the current Adaptation chosen?
111
113
  maximumPosition: manifest.getMaximumSafePosition(),
112
- position: {
113
- last: observation.position,
114
- pending: pendingPosition,
115
- },
114
+ position: observation.position,
116
115
  duration: observation.duration,
117
116
  paused: {
118
117
  last: observation.paused,
@@ -15,7 +15,6 @@
15
15
  */
16
16
 
17
17
  import { shouldValidateMetadata } from "../../../compat";
18
- import { READY_STATES } from "../../../compat/browser_compatibility_types";
19
18
  import { MediaError } from "../../../errors";
20
19
  import log from "../../../log";
21
20
  import { IPlayerError } from "../../../public_types";
@@ -24,6 +23,7 @@ import SharedReference, {
24
23
  } from "../../../utils/reference";
25
24
  import { CancellationError, CancellationSignal } from "../../../utils/task_canceller";
26
25
  import { PlaybackObserver } from "../../api";
26
+ import { SeekingState } from "../../api/playback_observer";
27
27
 
28
28
  /** Event emitted when trying to perform the initial `play`. */
29
29
  export type IInitialPlayEvent =
@@ -42,12 +42,6 @@ export interface IInitialSeekAndPlayObject {
42
42
  /** Emit the result of the auto-play operation, once performed. */
43
43
  autoPlayResult : Promise<IInitialPlayEvent>;
44
44
 
45
- /**
46
- * Shared reference whose value becomes `true` once the initial seek has
47
- * been considered / has been done by `performInitialSeekAndPlay`.
48
- */
49
- initialSeekPerformed : IReadOnlySharedReference<boolean>;
50
-
51
45
  /**
52
46
  * Shared reference whose value becomes `true` once the initial play has
53
47
  * been considered / has been done by `performInitialSeekAndPlay`.
@@ -58,126 +52,164 @@ export interface IInitialSeekAndPlayObject {
58
52
  /**
59
53
  * Seek as soon as possible at the initially wanted position and play if
60
54
  * autoPlay is wanted.
61
- * @param {HTMLMediaElement} mediaElement
62
- * @param {Object} playbackObserver
63
- * @param {number|Function} startTime
64
- * @param {boolean} mustAutoPlay
65
- * @param {Function} onWarning
55
+ * @param {Object} args
66
56
  * @param {Object} cancelSignal
67
57
  * @returns {Object}
68
58
  */
69
59
  export default function performInitialSeekAndPlay(
70
- mediaElement : HTMLMediaElement,
71
- playbackObserver : PlaybackObserver,
72
- startTime : number|(() => number),
73
- mustAutoPlay : boolean,
74
- onWarning : (err : IPlayerError) => void,
60
+ { mediaElement,
61
+ playbackObserver,
62
+ startTime,
63
+ mustAutoPlay,
64
+ isDirectfile,
65
+ onWarning }: { mediaElement : HTMLMediaElement;
66
+ playbackObserver : PlaybackObserver;
67
+ startTime : number|(() => number);
68
+ mustAutoPlay : boolean;
69
+ isDirectfile: boolean;
70
+ onWarning : (err : IPlayerError) => void; },
75
71
  cancelSignal : CancellationSignal
76
72
  ) : IInitialSeekAndPlayObject {
77
- let resolveAutoPlay : (x : IInitialPlayEvent) => void;
78
- let rejectAutoPlay : (x : unknown) => void;
79
- const autoPlayResult = new Promise<IInitialPlayEvent>((res, rej) => {
80
- resolveAutoPlay = res;
81
- rejectAutoPlay = rej;
82
- });
83
-
84
- const initialSeekPerformed = new SharedReference(false, cancelSignal);
85
73
  const initialPlayPerformed = new SharedReference(false, cancelSignal);
86
-
87
- mediaElement.addEventListener("loadedmetadata", onLoadedMetadata);
88
-
89
- const deregisterCancellation = cancelSignal.register((err : CancellationError) => {
90
- mediaElement.removeEventListener("loadedmetadata", onLoadedMetadata);
91
- rejectAutoPlay(err);
92
- });
93
-
94
- if (mediaElement.readyState >= READY_STATES.HAVE_METADATA) {
95
- onLoadedMetadata();
96
- }
97
-
98
- return { autoPlayResult, initialPlayPerformed, initialSeekPerformed };
99
-
100
- function onLoadedMetadata() {
101
- mediaElement.removeEventListener("loadedmetadata", onLoadedMetadata);
102
- const initialTime = typeof startTime === "function" ? startTime() :
103
- startTime;
104
- log.info("Init: Set initial time", initialTime);
105
- playbackObserver.setCurrentTime(initialTime);
106
- initialSeekPerformed.setValue(true);
107
- initialSeekPerformed.finish();
108
-
109
- if (shouldValidateMetadata() && mediaElement.duration === 0) {
110
- const error = new MediaError("MEDIA_ERR_NOT_LOADED_METADATA",
111
- "Cannot load automatically: your browser " +
112
- "falsely announced having loaded the content.");
113
- onWarning(error);
114
- }
115
- if (cancelSignal.isCancelled()) {
116
- return ;
74
+ const autoPlayResult = new Promise<IInitialPlayEvent>((
75
+ resolveAutoPlay,
76
+ rejectAutoPlay
77
+ ) => {
78
+ // `startTime` defined as a function might depend on metadata to make its
79
+ // choice, such as the content duration, minimum and/or maximum position.
80
+ //
81
+ // The RxPlayer might already know those through the Manifest file for
82
+ // non-Directfile contents, yet only through the `HTMLMediaElement` once a
83
+ // a sufficient `readyState` has been reached for directfile contents.
84
+ // So let's divide the two possibilities here.
85
+ if (!isDirectfile || typeof startTime === "number") {
86
+ playbackObserver.setCurrentTime(
87
+ typeof startTime === "number" ? startTime : startTime()
88
+ );
89
+ waitForSeekable();
90
+ } else {
91
+ playbackObserver.listen((obs, stopListening) => {
92
+ if (obs.readyState >= 1) {
93
+ stopListening();
94
+ playbackObserver.setCurrentTime(
95
+ typeof startTime === "number" ? startTime : startTime()
96
+ );
97
+ waitForSeekable();
98
+ }
99
+ }, { includeLastObservation: true, clearSignal: cancelSignal });
117
100
  }
118
101
 
119
- playbackObserver.listen((observation, stopListening) => {
120
- if (!observation.seeking &&
121
- observation.rebuffering === null &&
122
- observation.readyState >= 1)
123
- {
102
+ const deregisterCancellation = cancelSignal.register((err : CancellationError) => {
103
+ rejectAutoPlay(err);
104
+ });
105
+
106
+ /**
107
+ * Logic that should be run once the initial seek has been asked to the
108
+ * PlaybackObserver.
109
+ *
110
+ * Actually wait until the seek has been performed, wait for the right moment
111
+ * to perform autoplay, resolve the promise once everything has been done and
112
+ * potentially send warning if a minor issue is detected.
113
+ */
114
+ function waitForSeekable() {
115
+ playbackObserver.listen((obs, stopListening) => {
116
+ if (obs.seeking === SeekingState.None || obs.readyState === 0) {
117
+ return;
118
+ }
124
119
  stopListening();
125
- onPlayable();
126
- }
127
- }, { includeLastObservation: true, clearSignal: cancelSignal });
128
- }
129
-
130
- function onPlayable() {
131
- log.info("Init: Can begin to play content");
132
- if (!mustAutoPlay) {
133
- if (mediaElement.autoplay) {
134
- log.warn("Init: autoplay is enabled on HTML media element. " +
135
- "Media will play as soon as possible.");
136
- }
137
- initialPlayPerformed.setValue(true);
138
- initialPlayPerformed.finish();
139
- deregisterCancellation();
140
- return resolveAutoPlay({ type: "skipped" as const });
120
+ if (shouldValidateMetadata() && mediaElement.duration === 0) {
121
+ const error = new MediaError("MEDIA_ERR_NOT_LOADED_METADATA",
122
+ "Cannot load automatically: your browser " +
123
+ "falsely announced having loaded the content.");
124
+ onWarning(error);
125
+ }
126
+ if (cancelSignal.isCancelled()) {
127
+ return ;
128
+ }
129
+ waitForPlayable();
130
+ }, { includeLastObservation: true, clearSignal: cancelSignal });
141
131
  }
142
132
 
143
- let playResult : Promise<unknown>;
144
- try {
145
- playResult = mediaElement.play() ?? Promise.resolve();
146
- } catch (playError) {
147
- deregisterCancellation();
148
- return rejectAutoPlay(playError);
133
+ /**
134
+ * Logic that should be run once the initial seek has been properly performed.
135
+ *
136
+ * Wait for the media being playable before performing the autoplay operation
137
+ * if asked. Potentially send warning if a minor issue has been detected while
138
+ * doing so.
139
+ */
140
+ function waitForPlayable() {
141
+ playbackObserver.listen((observation, stopListening) => {
142
+ if (observation.seeking === SeekingState.None &&
143
+ observation.rebuffering === null &&
144
+ observation.readyState >= 1)
145
+ {
146
+ stopListening();
147
+ onPlayable();
148
+ }
149
+ }, { includeLastObservation: true, clearSignal: cancelSignal });
149
150
  }
150
- playResult
151
- .then(() => {
152
- if (cancelSignal.isCancelled()) {
153
- return;
151
+
152
+ /**
153
+ * Callback called once the content is considered "playable".
154
+ *
155
+ * Perform the autoplay if needed, handling potential issues and resolve the
156
+ * Promise when done.
157
+ * Might also send warnings if minor issues arise.
158
+ */
159
+ function onPlayable() {
160
+ log.info("Init: Can begin to play content");
161
+ if (!mustAutoPlay) {
162
+ if (mediaElement.autoplay) {
163
+ log.warn("Init: autoplay is enabled on HTML media element. " +
164
+ "Media will play as soon as possible.");
154
165
  }
155
166
  initialPlayPerformed.setValue(true);
156
167
  initialPlayPerformed.finish();
157
168
  deregisterCancellation();
158
- return resolveAutoPlay({ type: "autoplay" as const });
159
- })
160
- .catch((playError : unknown) => {
161
- deregisterCancellation();
162
- if (cancelSignal.isCancelled()) {
163
- return;
164
- }
165
- if (playError instanceof Error && playError.name === "NotAllowedError") {
166
- // auto-play was probably prevented.
167
- log.warn("Init: Media element can't play." +
168
- " It may be due to browser auto-play policies.");
169
+ return resolveAutoPlay({ type: "skipped" as const });
170
+ }
169
171
 
170
- const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY",
171
- "Cannot trigger auto-play automatically: " +
172
- "your browser does not allow it.");
173
- onWarning(error);
172
+ let playResult : Promise<unknown>;
173
+ try {
174
+ playResult = mediaElement.play() ?? Promise.resolve();
175
+ } catch (playError) {
176
+ deregisterCancellation();
177
+ return rejectAutoPlay(playError);
178
+ }
179
+ playResult
180
+ .then(() => {
174
181
  if (cancelSignal.isCancelled()) {
175
182
  return;
176
183
  }
177
- return resolveAutoPlay({ type: "autoplay-blocked" as const });
178
- } else {
179
- rejectAutoPlay(playError);
180
- }
181
- });
182
- }
184
+ initialPlayPerformed.setValue(true);
185
+ initialPlayPerformed.finish();
186
+ deregisterCancellation();
187
+ return resolveAutoPlay({ type: "autoplay" as const });
188
+ })
189
+ .catch((playError : unknown) => {
190
+ deregisterCancellation();
191
+ if (cancelSignal.isCancelled()) {
192
+ return;
193
+ }
194
+ if (playError instanceof Error && playError.name === "NotAllowedError") {
195
+ // auto-play was probably prevented.
196
+ log.warn("Init: Media element can't play." +
197
+ " It may be due to browser auto-play policies.");
198
+
199
+ const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY",
200
+ "Cannot trigger auto-play automatically: " +
201
+ "your browser does not allow it.");
202
+ onWarning(error);
203
+ if (cancelSignal.isCancelled()) {
204
+ return;
205
+ }
206
+ return resolveAutoPlay({ type: "autoplay-blocked" as const });
207
+ } else {
208
+ rejectAutoPlay(playError);
209
+ }
210
+ });
211
+ }
212
+ });
213
+
214
+ return { autoPlayResult, initialPlayPerformed };
183
215
  }