rx-player 4.0.0-dev.2023111400 → 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 (336) hide show
  1. package/CHANGELOG.md +20 -60
  2. package/FILES.md +1 -1
  3. package/README.md +2 -33
  4. package/VERSION +1 -1
  5. package/dist/_esm5.processed/core/api/debug/buffer_graph.js +2 -6
  6. package/dist/_esm5.processed/core/api/debug/modules/general_info.js +20 -10
  7. package/dist/_esm5.processed/core/api/option_utils.d.ts +0 -2
  8. package/dist/_esm5.processed/core/api/option_utils.js +0 -6
  9. package/dist/_esm5.processed/core/api/public_api.d.ts +1 -2
  10. package/dist/_esm5.processed/core/api/public_api.js +9 -17
  11. package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
  12. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +3 -14
  13. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.d.ts +2 -36
  14. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +2 -82
  15. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  16. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +1 -1
  17. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  18. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  19. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  20. package/dist/_esm5.processed/core/segment_buffers/inventory/index.d.ts +2 -2
  21. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  22. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +19 -10
  23. package/dist/_esm5.processed/core/stream/representation/utils/get_buffer_status.js +1 -1
  24. package/dist/_esm5.processed/core/stream/representation/utils/get_needed_segments.js +1 -1
  25. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +1 -8
  26. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  27. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +1 -9
  28. package/dist/_esm5.processed/public_types.d.ts +2 -0
  29. package/dist/commonjs/compat/is_codec_supported.js +22 -1
  30. package/dist/commonjs/config.d.ts +2 -1
  31. package/dist/commonjs/core/adaptive/adaptive_representation_selector.d.ts +2 -19
  32. package/dist/commonjs/core/adaptive/adaptive_representation_selector.js +2 -2
  33. package/dist/commonjs/core/adaptive/network_analyzer.js +3 -3
  34. package/dist/commonjs/core/api/debug/buffer_graph.js +2 -6
  35. package/dist/commonjs/core/api/debug/modules/general_info.js +17 -10
  36. package/dist/commonjs/core/api/index.d.ts +1 -1
  37. package/dist/commonjs/core/api/option_utils.d.ts +2 -0
  38. package/dist/commonjs/core/api/option_utils.js +2 -3
  39. package/dist/commonjs/core/api/playback_observer.d.ts +128 -8
  40. package/dist/commonjs/core/api/playback_observer.js +217 -64
  41. package/dist/commonjs/core/api/public_api.d.ts +9 -0
  42. package/dist/commonjs/core/api/public_api.js +41 -16
  43. package/dist/commonjs/core/api/utils.js +1 -1
  44. package/dist/commonjs/core/decrypt/get_media_keys.js +2 -6
  45. package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.d.ts +6 -0
  46. package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.js +11 -3
  47. package/dist/commonjs/core/fetchers/segment/segment_fetcher.d.ts +8 -1
  48. package/dist/commonjs/core/fetchers/segment/segment_fetcher.js +8 -4
  49. package/dist/commonjs/core/fetchers/segment/segment_fetcher_creator.d.ts +1 -0
  50. package/dist/commonjs/core/fetchers/utils/schedule_request.js +1 -1
  51. package/dist/commonjs/core/init/directfile_content_initializer.js +29 -8
  52. package/dist/commonjs/core/init/media_source_content_initializer.d.ts +6 -0
  53. package/dist/commonjs/core/init/media_source_content_initializer.js +32 -20
  54. package/dist/commonjs/core/init/utils/content_time_boundaries_observer.d.ts +13 -12
  55. package/dist/commonjs/core/init/utils/content_time_boundaries_observer.js +17 -19
  56. package/dist/commonjs/core/init/utils/create_stream_playback_observer.d.ts +1 -5
  57. package/dist/commonjs/core/init/utils/create_stream_playback_observer.js +16 -14
  58. package/dist/commonjs/core/init/utils/get_initial_time.d.ts +17 -3
  59. package/dist/commonjs/core/init/utils/get_initial_time.js +9 -7
  60. package/dist/commonjs/core/init/utils/initial_seek_and_play.d.ts +9 -11
  61. package/dist/commonjs/core/init/utils/initial_seek_and_play.js +121 -91
  62. package/dist/commonjs/core/init/utils/rebuffering_controller.js +27 -70
  63. package/dist/commonjs/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
  64. package/dist/commonjs/core/segment_buffers/garbage_collector.js +1 -2
  65. package/dist/commonjs/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  66. package/dist/commonjs/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  67. package/dist/commonjs/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  68. package/dist/commonjs/core/segment_buffers/index.d.ts +2 -2
  69. package/dist/commonjs/core/segment_buffers/inventory/index.d.ts +2 -2
  70. package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  71. package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.js +19 -10
  72. package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
  73. package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
  74. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +14 -18
  75. package/dist/commonjs/core/stream/period/period_stream.js +5 -8
  76. package/dist/commonjs/core/stream/period/types.d.ts +2 -3
  77. package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
  78. package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
  79. package/dist/commonjs/core/stream/representation/representation_stream.js +3 -4
  80. package/dist/commonjs/core/stream/representation/types.d.ts +2 -2
  81. package/dist/commonjs/core/stream/representation/utils/append_segment_to_buffer.js +11 -12
  82. package/dist/commonjs/core/stream/representation/utils/get_buffer_status.js +4 -4
  83. package/dist/commonjs/core/stream/representation/utils/get_needed_segments.js +1 -1
  84. package/dist/commonjs/default_config.d.ts +12 -16
  85. package/dist/commonjs/default_config.js +21 -16
  86. package/dist/commonjs/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +3 -1
  87. package/dist/commonjs/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +2 -0
  88. package/dist/commonjs/manifest/adaptation.js +2 -1
  89. package/dist/commonjs/manifest/representation_index/static.d.ts +1 -1
  90. package/dist/commonjs/manifest/representation_index/static.js +2 -2
  91. package/dist/commonjs/manifest/representation_index/types.d.ts +4 -4
  92. package/dist/commonjs/parsers/manifest/dash/common/indexes/base.d.ts +6 -1
  93. package/dist/commonjs/parsers/manifest/dash/common/indexes/base.js +4 -3
  94. package/dist/commonjs/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +5 -2
  95. package/dist/commonjs/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +15 -4
  96. package/dist/commonjs/parsers/manifest/dash/common/indexes/index.d.ts +5 -5
  97. package/dist/commonjs/parsers/manifest/dash/common/indexes/list.d.ts +1 -1
  98. package/dist/commonjs/parsers/manifest/dash/common/indexes/list.js +2 -2
  99. package/dist/commonjs/parsers/manifest/dash/common/indexes/template.d.ts +12 -5
  100. package/dist/commonjs/parsers/manifest/dash/common/indexes/template.js +42 -29
  101. package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/index.d.ts +2 -1
  102. package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +99 -6
  103. package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +250 -51
  104. package/dist/commonjs/parsers/manifest/dash/common/manifest_bounds_calculator.d.ts +40 -17
  105. package/dist/commonjs/parsers/manifest/dash/common/manifest_bounds_calculator.js +38 -18
  106. package/dist/commonjs/parsers/manifest/dash/common/parse_adaptation_sets.js +13 -10
  107. package/dist/commonjs/parsers/manifest/dash/common/parse_mpd.js +27 -14
  108. package/dist/commonjs/parsers/manifest/dash/common/parse_periods.d.ts +1 -1
  109. package/dist/commonjs/parsers/manifest/dash/common/parse_periods.js +17 -18
  110. package/dist/commonjs/parsers/manifest/dash/common/parse_representation_index.d.ts +19 -6
  111. package/dist/commonjs/parsers/manifest/dash/common/parse_representation_index.js +21 -8
  112. package/dist/commonjs/parsers/manifest/dash/common/parse_representations.js +7 -3
  113. package/dist/commonjs/parsers/manifest/local/representation_index.d.ts +1 -1
  114. package/dist/commonjs/parsers/manifest/local/representation_index.js +3 -3
  115. package/dist/commonjs/parsers/manifest/metaplaylist/representation_index.d.ts +1 -1
  116. package/dist/commonjs/parsers/manifest/metaplaylist/representation_index.js +2 -2
  117. package/dist/commonjs/parsers/manifest/smooth/representation_index.d.ts +5 -5
  118. package/dist/commonjs/parsers/manifest/smooth/representation_index.js +25 -9
  119. package/dist/commonjs/parsers/manifest/utils/index_helpers.js +1 -1
  120. package/dist/commonjs/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  121. package/dist/commonjs/public_types.d.ts +107 -36
  122. package/dist/commonjs/transports/dash/init_segment_loader.js +10 -5
  123. package/dist/commonjs/transports/dash/manifest_parser.js +5 -2
  124. package/dist/commonjs/transports/dash/segment_loader.js +2 -1
  125. package/dist/commonjs/transports/dash/text_loader.js +2 -0
  126. package/dist/commonjs/transports/metaplaylist/manifest_loader.js +2 -1
  127. package/dist/commonjs/transports/metaplaylist/pipelines.js +4 -1
  128. package/dist/commonjs/transports/smooth/pipelines.js +4 -2
  129. package/dist/commonjs/transports/smooth/segment_loader.js +2 -1
  130. package/dist/commonjs/transports/types.d.ts +12 -0
  131. package/dist/commonjs/transports/utils/generate_manifest_loader.js +6 -3
  132. package/dist/commonjs/utils/request/fetch.d.ts +6 -0
  133. package/dist/commonjs/utils/request/fetch.js +29 -8
  134. package/dist/commonjs/utils/request/xhr.d.ts +11 -5
  135. package/dist/commonjs/utils/request/xhr.js +29 -8
  136. package/dist/es2017/compat/is_codec_supported.js +22 -1
  137. package/dist/es2017/config.d.ts +2 -1
  138. package/dist/es2017/core/adaptive/adaptive_representation_selector.d.ts +2 -19
  139. package/dist/es2017/core/adaptive/adaptive_representation_selector.js +2 -2
  140. package/dist/es2017/core/adaptive/network_analyzer.js +3 -3
  141. package/dist/es2017/core/api/debug/buffer_graph.js +2 -6
  142. package/dist/es2017/core/api/debug/modules/general_info.js +17 -10
  143. package/dist/es2017/core/api/index.d.ts +1 -1
  144. package/dist/es2017/core/api/option_utils.d.ts +2 -0
  145. package/dist/es2017/core/api/option_utils.js +2 -3
  146. package/dist/es2017/core/api/playback_observer.d.ts +128 -8
  147. package/dist/es2017/core/api/playback_observer.js +217 -66
  148. package/dist/es2017/core/api/public_api.d.ts +9 -0
  149. package/dist/es2017/core/api/public_api.js +40 -15
  150. package/dist/es2017/core/api/utils.js +1 -1
  151. package/dist/es2017/core/decrypt/get_media_keys.js +2 -6
  152. package/dist/es2017/core/fetchers/manifest/manifest_fetcher.d.ts +6 -0
  153. package/dist/es2017/core/fetchers/manifest/manifest_fetcher.js +11 -3
  154. package/dist/es2017/core/fetchers/segment/segment_fetcher.d.ts +8 -1
  155. package/dist/es2017/core/fetchers/segment/segment_fetcher.js +8 -4
  156. package/dist/es2017/core/fetchers/segment/segment_fetcher_creator.d.ts +1 -0
  157. package/dist/es2017/core/fetchers/utils/schedule_request.js +1 -1
  158. package/dist/es2017/core/init/directfile_content_initializer.js +31 -8
  159. package/dist/es2017/core/init/media_source_content_initializer.d.ts +6 -0
  160. package/dist/es2017/core/init/media_source_content_initializer.js +34 -22
  161. package/dist/es2017/core/init/utils/content_time_boundaries_observer.d.ts +13 -12
  162. package/dist/es2017/core/init/utils/content_time_boundaries_observer.js +17 -17
  163. package/dist/es2017/core/init/utils/create_stream_playback_observer.d.ts +1 -5
  164. package/dist/es2017/core/init/utils/create_stream_playback_observer.js +16 -14
  165. package/dist/es2017/core/init/utils/get_initial_time.d.ts +17 -3
  166. package/dist/es2017/core/init/utils/get_initial_time.js +9 -7
  167. package/dist/es2017/core/init/utils/initial_seek_and_play.d.ts +9 -11
  168. package/dist/es2017/core/init/utils/initial_seek_and_play.js +120 -91
  169. package/dist/es2017/core/init/utils/rebuffering_controller.js +27 -70
  170. package/dist/es2017/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
  171. package/dist/es2017/core/segment_buffers/garbage_collector.js +1 -2
  172. package/dist/es2017/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  173. package/dist/es2017/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  174. package/dist/es2017/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  175. package/dist/es2017/core/segment_buffers/index.d.ts +2 -2
  176. package/dist/es2017/core/segment_buffers/inventory/index.d.ts +2 -2
  177. package/dist/es2017/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
  178. package/dist/es2017/core/segment_buffers/inventory/segment_inventory.js +19 -10
  179. package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
  180. package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
  181. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +16 -18
  182. package/dist/es2017/core/stream/period/period_stream.js +4 -7
  183. package/dist/es2017/core/stream/period/types.d.ts +2 -3
  184. package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
  185. package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
  186. package/dist/es2017/core/stream/representation/representation_stream.js +3 -4
  187. package/dist/es2017/core/stream/representation/types.d.ts +2 -2
  188. package/dist/es2017/core/stream/representation/utils/append_segment_to_buffer.js +1 -2
  189. package/dist/es2017/core/stream/representation/utils/get_buffer_status.js +4 -4
  190. package/dist/es2017/core/stream/representation/utils/get_needed_segments.js +1 -1
  191. package/dist/es2017/default_config.d.ts +12 -16
  192. package/dist/es2017/default_config.js +21 -16
  193. package/dist/es2017/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +3 -1
  194. package/dist/es2017/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +2 -0
  195. package/dist/es2017/manifest/adaptation.js +2 -1
  196. package/dist/es2017/manifest/representation_index/static.d.ts +1 -1
  197. package/dist/es2017/manifest/representation_index/static.js +2 -2
  198. package/dist/es2017/manifest/representation_index/types.d.ts +4 -4
  199. package/dist/es2017/parsers/manifest/dash/common/indexes/base.d.ts +6 -1
  200. package/dist/es2017/parsers/manifest/dash/common/indexes/base.js +4 -3
  201. package/dist/es2017/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +5 -2
  202. package/dist/es2017/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +15 -4
  203. package/dist/es2017/parsers/manifest/dash/common/indexes/index.d.ts +5 -5
  204. package/dist/es2017/parsers/manifest/dash/common/indexes/list.d.ts +1 -1
  205. package/dist/es2017/parsers/manifest/dash/common/indexes/list.js +2 -2
  206. package/dist/es2017/parsers/manifest/dash/common/indexes/template.d.ts +12 -5
  207. package/dist/es2017/parsers/manifest/dash/common/indexes/template.js +40 -27
  208. package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/index.d.ts +2 -1
  209. package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +99 -6
  210. package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +246 -51
  211. package/dist/es2017/parsers/manifest/dash/common/manifest_bounds_calculator.d.ts +40 -17
  212. package/dist/es2017/parsers/manifest/dash/common/manifest_bounds_calculator.js +38 -18
  213. package/dist/es2017/parsers/manifest/dash/common/parse_adaptation_sets.js +11 -8
  214. package/dist/es2017/parsers/manifest/dash/common/parse_mpd.js +27 -13
  215. package/dist/es2017/parsers/manifest/dash/common/parse_periods.d.ts +1 -1
  216. package/dist/es2017/parsers/manifest/dash/common/parse_periods.js +13 -16
  217. package/dist/es2017/parsers/manifest/dash/common/parse_representation_index.d.ts +19 -6
  218. package/dist/es2017/parsers/manifest/dash/common/parse_representation_index.js +10 -8
  219. package/dist/es2017/parsers/manifest/dash/common/parse_representations.js +7 -3
  220. package/dist/es2017/parsers/manifest/local/representation_index.d.ts +1 -1
  221. package/dist/es2017/parsers/manifest/local/representation_index.js +3 -3
  222. package/dist/es2017/parsers/manifest/metaplaylist/representation_index.d.ts +1 -1
  223. package/dist/es2017/parsers/manifest/metaplaylist/representation_index.js +2 -2
  224. package/dist/es2017/parsers/manifest/smooth/representation_index.d.ts +5 -5
  225. package/dist/es2017/parsers/manifest/smooth/representation_index.js +25 -9
  226. package/dist/es2017/parsers/manifest/utils/index_helpers.js +1 -1
  227. package/dist/es2017/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
  228. package/dist/es2017/public_types.d.ts +107 -36
  229. package/dist/es2017/transports/dash/init_segment_loader.js +5 -0
  230. package/dist/es2017/transports/dash/manifest_parser.js +3 -0
  231. package/dist/es2017/transports/dash/segment_loader.js +1 -0
  232. package/dist/es2017/transports/dash/text_loader.js +2 -0
  233. package/dist/es2017/transports/metaplaylist/manifest_loader.js +1 -0
  234. package/dist/es2017/transports/metaplaylist/pipelines.js +4 -1
  235. package/dist/es2017/transports/smooth/pipelines.js +2 -0
  236. package/dist/es2017/transports/smooth/segment_loader.js +1 -0
  237. package/dist/es2017/transports/types.d.ts +12 -0
  238. package/dist/es2017/transports/utils/generate_manifest_loader.js +3 -0
  239. package/dist/es2017/utils/request/fetch.d.ts +6 -0
  240. package/dist/es2017/utils/request/fetch.js +29 -8
  241. package/dist/es2017/utils/request/xhr.d.ts +11 -5
  242. package/dist/es2017/utils/request/xhr.js +30 -9
  243. package/dist/mpd-parser.wasm +0 -0
  244. package/dist/rx-player.js +1335 -812
  245. package/dist/rx-player.min.js +1 -1
  246. package/package.json +7 -4
  247. package/scripts/canal-release.patch +78 -0
  248. package/scripts/make-dev-releases +65 -0
  249. package/scripts/update-version +7 -0
  250. package/sonar-project.properties +1 -1
  251. package/src/compat/is_codec_supported.ts +23 -1
  252. package/src/core/adaptive/adaptive_representation_selector.ts +4 -21
  253. package/src/core/adaptive/network_analyzer.ts +3 -3
  254. package/src/core/api/debug/buffer_graph.ts +2 -5
  255. package/src/core/api/debug/modules/general_info.ts +15 -10
  256. package/src/core/api/index.ts +1 -0
  257. package/src/core/api/option_utils.ts +3 -3
  258. package/src/core/api/playback_observer.ts +327 -107
  259. package/src/core/api/public_api.ts +42 -14
  260. package/src/core/api/utils.ts +3 -1
  261. package/src/core/decrypt/get_media_keys.ts +2 -8
  262. package/src/core/fetchers/manifest/manifest_fetcher.ts +21 -3
  263. package/src/core/fetchers/segment/segment_fetcher.ts +19 -5
  264. package/src/core/fetchers/segment/segment_fetcher_creator.ts +1 -0
  265. package/src/core/fetchers/utils/schedule_request.ts +1 -1
  266. package/src/core/init/directfile_content_initializer.ts +31 -15
  267. package/src/core/init/media_source_content_initializer.ts +40 -27
  268. package/src/core/init/utils/content_time_boundaries_observer.ts +24 -23
  269. package/src/core/init/utils/create_stream_playback_observer.ts +19 -20
  270. package/src/core/init/utils/get_initial_time.ts +25 -12
  271. package/src/core/init/utils/initial_seek_and_play.ts +140 -108
  272. package/src/core/init/utils/rebuffering_controller.ts +32 -77
  273. package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +5 -2
  274. package/src/core/segment_buffers/garbage_collector.ts +1 -1
  275. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +10 -2
  276. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +1 -1
  277. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +1 -1
  278. package/src/core/segment_buffers/index.ts +2 -0
  279. package/src/core/segment_buffers/inventory/index.ts +2 -0
  280. package/src/core/segment_buffers/inventory/segment_inventory.ts +49 -17
  281. package/src/core/stream/adaptation/get_representations_switch_strategy.ts +21 -12
  282. package/src/core/stream/orchestrator/stream_orchestrator.ts +14 -19
  283. package/src/core/stream/period/period_stream.ts +7 -8
  284. package/src/core/stream/period/types.ts +2 -3
  285. package/src/core/stream/period/utils/get_adaptation_switch_strategy.ts +21 -15
  286. package/src/core/stream/representation/representation_stream.ts +3 -5
  287. package/src/core/stream/representation/types.ts +2 -2
  288. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
  289. package/src/core/stream/representation/utils/get_buffer_status.ts +5 -4
  290. package/src/core/stream/representation/utils/get_needed_segments.ts +2 -2
  291. package/src/default_config.ts +22 -17
  292. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +3 -1
  293. package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +2 -0
  294. package/src/manifest/adaptation.ts +2 -1
  295. package/src/manifest/representation_index/static.ts +2 -2
  296. package/src/manifest/representation_index/types.ts +4 -4
  297. package/src/parsers/manifest/dash/common/__tests__/manifest_bounds_calculator.test.ts +182 -36
  298. package/src/parsers/manifest/dash/common/indexes/base.ts +12 -4
  299. package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +19 -5
  300. package/src/parsers/manifest/dash/common/indexes/index.ts +16 -4
  301. package/src/parsers/manifest/dash/common/indexes/list.ts +2 -2
  302. package/src/parsers/manifest/dash/common/indexes/template.ts +52 -31
  303. package/src/parsers/manifest/dash/common/indexes/timeline/index.ts +4 -1
  304. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +366 -60
  305. package/src/parsers/manifest/dash/common/manifest_bounds_calculator.ts +63 -25
  306. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +10 -4
  307. package/src/parsers/manifest/dash/common/parse_mpd.ts +28 -15
  308. package/src/parsers/manifest/dash/common/parse_periods.ts +12 -17
  309. package/src/parsers/manifest/dash/common/parse_representation_index.ts +50 -26
  310. package/src/parsers/manifest/dash/common/parse_representations.ts +9 -3
  311. package/src/parsers/manifest/local/representation_index.ts +3 -3
  312. package/src/parsers/manifest/metaplaylist/representation_index.ts +2 -2
  313. package/src/parsers/manifest/smooth/representation_index.ts +23 -9
  314. package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +1 -1
  315. package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +1 -1
  316. package/src/parsers/manifest/utils/index_helpers.ts +1 -1
  317. package/src/parsers/texttracks/ttml/html/apply_line_height.ts +3 -1
  318. package/src/public_types.ts +108 -36
  319. package/src/transports/dash/init_segment_loader.ts +5 -0
  320. package/src/transports/dash/manifest_parser.ts +6 -0
  321. package/src/transports/dash/segment_loader.ts +1 -0
  322. package/src/transports/dash/text_loader.ts +2 -0
  323. package/src/transports/metaplaylist/manifest_loader.ts +1 -0
  324. package/src/transports/metaplaylist/pipelines.ts +4 -1
  325. package/src/transports/smooth/pipelines.ts +2 -0
  326. package/src/transports/smooth/segment_loader.ts +1 -0
  327. package/src/transports/types.ts +12 -0
  328. package/src/transports/utils/generate_manifest_loader.ts +3 -0
  329. package/src/utils/request/fetch.ts +35 -8
  330. package/src/utils/request/xhr.ts +45 -14
  331. package/dist/commonjs/parsers/manifest/utils/is_segment_still_available.d.ts +0 -29
  332. package/dist/commonjs/parsers/manifest/utils/is_segment_still_available.js +0 -54
  333. package/dist/es2017/parsers/manifest/utils/is_segment_still_available.d.ts +0 -29
  334. package/dist/es2017/parsers/manifest/utils/is_segment_still_available.js +0 -51
  335. package/src/parsers/manifest/utils/is_segment_still_available.ts +0 -58
  336. package/src/typings/object-assign.d.ts +0 -48
@@ -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,
@@ -43,11 +43,25 @@ export interface IInitialTimeOptions {
43
43
  */
44
44
  fromFirstPosition? : number | null | undefined;
45
45
  /**
46
- * If set, we should begin at this position relative to the content's end,
47
- * in seconds.
46
+ * If set, we should begin at this position relative to the content's maximum
47
+ * seekable position, in seconds.
48
+ *
49
+ * It should consequently in most cases be a negative value.
48
50
  */
49
51
  fromLastPosition? : number | null | undefined;
50
- /** If set, we should begin at this position relative to the whole duration of
52
+ /**
53
+ * If set, we should begin at this position relative to the content's live
54
+ * edge if it makes sense, in seconds.
55
+ *
56
+ * It should consequently in most cases be a negative value.
57
+ *
58
+ * If the live edge is unknown or if it does not make sense for the current
59
+ * content, that position is relative to the content's maximum position
60
+ * instead.
61
+ */
62
+ fromLivePosition? : number | null | undefined;
63
+ /**
64
+ * If set, we should begin at this position relative to the whole duration of
51
65
  * the content, in percentage.
52
66
  */
53
67
  percentage? : number | null | undefined;
@@ -73,13 +87,7 @@ export default function getInitialTime(
73
87
  ) : number {
74
88
  if (!isNullOrUndefined(startAt)) {
75
89
  const min = manifest.getMinimumSafePosition();
76
- let max;
77
- if (manifest.isLive) {
78
- max = manifest.getLivePosition();
79
- }
80
- if (max === undefined) {
81
- max = manifest.getMaximumSafePosition();
82
- }
90
+ const max = manifest.getMaximumSafePosition();
83
91
  if (!isNullOrUndefined(startAt.position)) {
84
92
  log.debug("Init: using startAt.minimumPosition");
85
93
  return Math.max(Math.min(startAt.position, max), min);
@@ -97,12 +105,17 @@ export default function getInitialTime(
97
105
  const { fromFirstPosition } = startAt;
98
106
  return fromFirstPosition <= 0 ? min :
99
107
  Math.min(max, min + fromFirstPosition);
100
- }
101
- else if (!isNullOrUndefined(startAt.fromLastPosition)) {
108
+ } else if (!isNullOrUndefined(startAt.fromLastPosition)) {
102
109
  log.debug("Init: using startAt.fromLastPosition");
103
110
  const { fromLastPosition } = startAt;
104
111
  return fromLastPosition >= 0 ? max :
105
112
  Math.max(min, max + fromLastPosition);
113
+ } else if (!isNullOrUndefined(startAt.fromLivePosition)) {
114
+ log.debug("Init: using startAt.fromLivePosition");
115
+ const livePosition = manifest.getLivePosition() ?? max;
116
+ const { fromLivePosition } = startAt;
117
+ return fromLivePosition >= 0 ? livePosition :
118
+ Math.max(min, livePosition + fromLivePosition);
106
119
  } else if (!isNullOrUndefined(startAt.percentage)) {
107
120
  log.debug("Init: using startAt.percentage");
108
121
  const { percentage } = startAt;
@@ -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
  }
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import isSeekingApproximate from "../../../compat/is_seeking_approximate";
18
17
  import config from "../../../config";
19
18
  import { MediaError } from "../../../errors";
20
19
  import log from "../../../log";
@@ -31,6 +30,7 @@ import {
31
30
  IPlaybackObservation,
32
31
  PlaybackObserver,
33
32
  } from "../../api";
33
+ import { SeekingState } from "../../api/playback_observer";
34
34
  import SegmentBuffersStore, { IBufferType } from "../../segment_buffers";
35
35
  import { IStallingSituation } from "../types";
36
36
 
@@ -107,33 +107,6 @@ export default class RebufferingController
107
107
  }
108
108
  this._isStarted = true;
109
109
 
110
- /**
111
- * On some devices (right now only seen on Tizen), seeking through the
112
- * `currentTime` property can lead to the browser re-seeking once the
113
- * segments have been loaded to improve seeking performances (for
114
- * example, by seeking right to an intra video frame).
115
- * In that case, we risk being in a conflict with that behavior: if for
116
- * example we encounter a small discontinuity at the position the browser
117
- * seeks to, we will seek over it, the browser would seek back and so on.
118
- *
119
- * This variable allows to store the last known position we were seeking to
120
- * so we can detect when the browser seeked back (to avoid performing another
121
- * seek after that). When browsers seek back to a position behind a
122
- * discontinuity, they are usually able to skip them without our help.
123
- */
124
- let lastSeekingPosition : number | null;
125
-
126
- /**
127
- * In some conditions (see `lastSeekingPosition`), we might want to not
128
- * automatically seek over discontinuities because the browser might do it
129
- * itself instead.
130
- * In that case, we still want to perform the seek ourselves if the browser
131
- * doesn't do it after sufficient time.
132
- * This variable allows to store the timestamp at which a discontinuity began
133
- * to be ignored.
134
- */
135
- let ignoredStallTimeStamp : number | null = null;
136
-
137
110
  const playbackRateUpdater = new PlaybackRateUpdater(this._playbackObserver,
138
111
  this._speed);
139
112
  this._canceller.signal.register(() => {
@@ -151,26 +124,10 @@ export default class RebufferingController
151
124
  freezing } = observation;
152
125
 
153
126
  const { BUFFER_DISCONTINUITY_THRESHOLD,
154
- FORCE_DISCONTINUITY_SEEK_DELAY,
155
127
  FREEZING_STALLED_DELAY,
156
128
  UNFREEZING_SEEK_DELAY,
157
129
  UNFREEZING_DELTA_POSITION } = config.getCurrent();
158
130
 
159
- if (
160
- !observation.seeking &&
161
- isSeekingApproximate &&
162
- ignoredStallTimeStamp === null &&
163
- lastSeekingPosition !== null && observation.position < lastSeekingPosition)
164
- {
165
- log.debug("Init: the device appeared to have seeked back by itself.");
166
- const now = getMonotonicTimeStamp();
167
- ignoredStallTimeStamp = now;
168
- }
169
-
170
- lastSeekingPosition = observation.seeking ?
171
- Math.max(observation.pendingInternalSeek ?? 0, observation.position) :
172
- null;
173
-
174
131
  if (this._checkDecipherabilityFreeze(observation)) {
175
132
  return ;
176
133
  }
@@ -182,7 +139,10 @@ export default class RebufferingController
182
139
  freezing.timestamp :
183
140
  prevFreezingState.attemptTimestamp;
184
141
 
185
- if (now - referenceTimestamp > UNFREEZING_SEEK_DELAY) {
142
+ if (
143
+ !position.isAwaitingFuturePosition() &&
144
+ now - referenceTimestamp > UNFREEZING_SEEK_DELAY
145
+ ) {
186
146
  log.warn("Init: trying to seek to un-freeze player");
187
147
  this._playbackObserver.setCurrentTime(
188
148
  this._playbackObserver.getCurrentTime() + UNFREEZING_DELTA_POSITION);
@@ -190,7 +150,7 @@ export default class RebufferingController
190
150
  }
191
151
 
192
152
  if (now - freezing.timestamp > FREEZING_STALLED_DELAY) {
193
- if (rebuffering === null || ignoredStallTimeStamp !== null) {
153
+ if (rebuffering === null) {
194
154
  playbackRateUpdater.stopRebuffering();
195
155
  } else {
196
156
  playbackRateUpdater.startRebuffering();
@@ -208,9 +168,10 @@ export default class RebufferingController
208
168
  // With a readyState set to 1, we should still not be able to play:
209
169
  // Return that we're stalled
210
170
  let reason : IStallingSituation;
211
- if (observation.seeking) {
212
- reason = observation.pendingInternalSeek !== null ? "internal-seek" :
213
- "seeking";
171
+ if (observation.seeking !== SeekingState.None) {
172
+ reason = observation.seeking === SeekingState.Internal ?
173
+ "internal-seek" :
174
+ "seeking";
214
175
  } else {
215
176
  reason = "not-ready";
216
177
  }
@@ -224,24 +185,17 @@ export default class RebufferingController
224
185
  // We want to separate a stall situation when a seek is due to a seek done
225
186
  // internally by the player to when its due to a regular user seek.
226
187
  const stalledReason = rebuffering.reason === "seeking" &&
227
- observation.pendingInternalSeek !== null ?
188
+ observation.seeking === SeekingState.Internal ?
228
189
  "internal-seek" as const :
229
190
  rebuffering.reason;
230
191
 
231
- if (ignoredStallTimeStamp !== null) {
232
- const now = getMonotonicTimeStamp();
233
- if (now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) {
234
- playbackRateUpdater.stopRebuffering();
235
- log.debug("Init: letting the device get out of a stall by itself");
236
- this.trigger("stalled", stalledReason);
237
- return ;
238
- } else {
239
- log.warn("Init: ignored stall for too long, considering it",
240
- now - ignoredStallTimeStamp);
241
- }
192
+ if (position.isAwaitingFuturePosition()) {
193
+ playbackRateUpdater.stopRebuffering();
194
+ log.debug("Init: let rebuffering happen as we're awaiting a future position");
195
+ this.trigger("stalled", stalledReason);
196
+ return ;
242
197
  }
243
198
 
244
- ignoredStallTimeStamp = null;
245
199
  playbackRateUpdater.startRebuffering();
246
200
 
247
201
  if (this._manifest === null) {
@@ -266,7 +220,7 @@ export default class RebufferingController
266
220
  this._playbackObserver.getCurrentTime(), realSeekTime);
267
221
  } else {
268
222
  log.warn("SA: skippable discontinuity found in the stream",
269
- position, realSeekTime);
223
+ position.getPolled(), realSeekTime);
270
224
  this._playbackObserver.setCurrentTime(realSeekTime);
271
225
  this.trigger("warning", generateDiscontinuityError(stalledPosition,
272
226
  realSeekTime));
@@ -275,7 +229,7 @@ export default class RebufferingController
275
229
  }
276
230
  }
277
231
 
278
- const freezePosition = stalledPosition ?? position;
232
+ const positionBlockedAt = stalledPosition ?? position.getPolled();
279
233
 
280
234
  // Is it a very short discontinuity in buffer ? -> Seek at the beginning of the
281
235
  // next range
@@ -284,17 +238,17 @@ export default class RebufferingController
284
238
  // calculate a stalled state. This is useful for some
285
239
  // implementation that might drop an injected segment, or in
286
240
  // case of small discontinuity in the content.
287
- const nextBufferRangeGap = getNextBufferedTimeRangeGap(buffered, freezePosition);
241
+ const nextBufferRangeGap = getNextBufferedTimeRangeGap(buffered, positionBlockedAt);
288
242
  if (
289
243
  this._speed.getValue() > 0 &&
290
244
  nextBufferRangeGap < BUFFER_DISCONTINUITY_THRESHOLD
291
245
  ) {
292
- const seekTo = (freezePosition + nextBufferRangeGap + EPSILON);
246
+ const seekTo = (positionBlockedAt + nextBufferRangeGap + EPSILON);
293
247
  if (this._playbackObserver.getCurrentTime() < seekTo) {
294
248
  log.warn("Init: discontinuity encountered inferior to the threshold",
295
- freezePosition, seekTo, BUFFER_DISCONTINUITY_THRESHOLD);
249
+ positionBlockedAt, seekTo, BUFFER_DISCONTINUITY_THRESHOLD);
296
250
  this._playbackObserver.setCurrentTime(seekTo);
297
- this.trigger("warning", generateDiscontinuityError(freezePosition, seekTo));
251
+ this.trigger("warning", generateDiscontinuityError(positionBlockedAt, seekTo));
298
252
  return;
299
253
  }
300
254
  }
@@ -303,14 +257,14 @@ export default class RebufferingController
303
257
  // next period
304
258
  for (let i = this._manifest.periods.length - 2; i >= 0; i--) {
305
259
  const period = this._manifest.periods[i];
306
- if (period.end !== undefined && period.end <= freezePosition) {
307
- if (this._manifest.periods[i + 1].start > freezePosition &&
260
+ if (period.end !== undefined && period.end <= positionBlockedAt) {
261
+ if (this._manifest.periods[i + 1].start > positionBlockedAt &&
308
262
  this._manifest.periods[i + 1].start >
309
263
  this._playbackObserver.getCurrentTime())
310
264
  {
311
265
  const nextPeriod = this._manifest.periods[i + 1];
312
266
  this._playbackObserver.setCurrentTime(nextPeriod.start);
313
- this.trigger("warning", generateDiscontinuityError(freezePosition,
267
+ this.trigger("warning", generateDiscontinuityError(positionBlockedAt,
314
268
  nextPeriod.start));
315
269
  return;
316
270
 
@@ -360,10 +314,10 @@ export default class RebufferingController
360
314
  ) {
361
315
  return;
362
316
  }
363
- const currPos = observation.position;
364
- const rebufferingPos = observation.rebuffering.position ?? currPos;
317
+ const loadedPos = observation.position.getWanted();
318
+ const rebufferingPos = observation.rebuffering.position ?? loadedPos;
365
319
  const lockedPeriodStart = period.start;
366
- if (currPos < lockedPeriodStart &&
320
+ if (loadedPos < lockedPeriodStart &&
367
321
  Math.abs(rebufferingPos - lockedPeriodStart) < 1)
368
322
  {
369
323
  log.warn("Init: rebuffering because of a future locked stream.\n" +
@@ -403,8 +357,6 @@ export default class RebufferingController
403
357
  private _checkDecipherabilityFreeze(
404
358
  observation : IPlaybackObservation
405
359
  ): boolean {
406
- // XXX TODO allow this in in-worker configuration
407
-
408
360
  const { readyState,
409
361
  rebuffering,
410
362
  freezing } = observation;
@@ -555,10 +507,13 @@ function updateDiscontinuitiesStore(
555
507
  evt : IDiscontinuityEvent,
556
508
  observation : IPlaybackObservation
557
509
  ) : void {
510
+ const gcTime = Math.min(observation.position.getPolled(),
511
+ observation.position.getWanted());
512
+
558
513
  // First, perform clean-up of old discontinuities
559
514
  while (discontinuitiesStore.length > 0 &&
560
515
  discontinuitiesStore[0].period.end !== undefined &&
561
- discontinuitiesStore[0].period.end + 10 < observation.position)
516
+ discontinuitiesStore[0].period.end + 10 < gcTime)
562
517
  {
563
518
  discontinuitiesStore.shift();
564
519
  }