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
@@ -39,6 +39,13 @@ export default class PlaybackObserver {
39
39
  * influence on some chosen interval values here.
40
40
  */
41
41
  private _lowLatencyMode;
42
+ /**
43
+ * If set, position which could not yet be seeked to as the HTMLMediaElement
44
+ * had a readyState of `0`.
45
+ * This position should be seeked to as soon as the HTMLMediaElement is able
46
+ * to handle it.
47
+ */
48
+ private _pendingSeek;
42
49
  /**
43
50
  * The RxPlayer usually wants to differientate when a seek was sourced from
44
51
  * the RxPlayer's internal logic vs when it was sourced from an outside
@@ -64,6 +71,21 @@ export default class PlaybackObserver {
64
71
  * observations.
65
72
  */
66
73
  private _canceller;
74
+ /**
75
+ * On some devices (right now only seen on Tizen), seeking through the
76
+ * `currentTime` property can lead to the browser re-seeking once the
77
+ * segments have been loaded to improve seeking performances (for
78
+ * example, by seeking right to an intra video frame).
79
+ * In that case, we risk being in a conflict with that behavior: if for
80
+ * example we encounter a small discontinuity at the position the browser
81
+ * seeks to, we will seek over it, the browser would seek back and so on.
82
+ *
83
+ * This variable allows to store the maximum known position we were seeking to
84
+ * so we can detect when the browser seeked back (to avoid performing another
85
+ * seek after that). When browsers seek back to a position behind a
86
+ * discontinuity, they are usually able to skip them without our help.
87
+ */
88
+ private _expectedSeekingPosition;
67
89
  /**
68
90
  * Create a new `PlaybackObserver`, which allows to produce new "playback
69
91
  * observations" on various media events and intervals.
@@ -164,18 +186,22 @@ export default class PlaybackObserver {
164
186
  * @returns {Object}
165
187
  */
166
188
  deriveReadOnlyObserver<TDest>(transform: (observationRef: IReadOnlySharedReference<IPlaybackObservation>, cancellationSignal: CancellationSignal) => IReadOnlySharedReference<TDest>): IReadOnlyPlaybackObserver<TDest>;
189
+ private _actuallySetCurrentTime;
167
190
  /**
168
191
  * Creates the `IReadOnlySharedReference` that will generate playback
169
192
  * observations.
170
193
  * @returns {Object}
171
194
  */
172
195
  private _createSharedReference;
173
- private _generateInitialObservation;
196
+ private _getCurrentObservation;
197
+ private _generateObservationForEvent;
174
198
  }
175
199
  /** "Event" that triggered the playback observation. */
176
200
  export type IPlaybackObserverEventType =
177
201
  /** First playback observation automatically emitted. */
178
- "init" | // set once on first emit
202
+ "init" |
203
+ /** Observation manually forced by the PlaybackObserver. */
204
+ "manual" |
179
205
  /** Regularly emitted playback observation when no event happened in a long time. */
180
206
  "timeupdate" |
181
207
  /** On the HTML5 event with the same name */
@@ -236,8 +262,18 @@ interface IMediaInfos {
236
262
  readyState: number;
237
263
  /** Current `seeking` value on the mediaElement. */
238
264
  seeking: boolean;
239
- /** Event that triggered this playback observation. */
240
- event: IPlaybackObserverEventType;
265
+ }
266
+ /** Categorize a pending seek operation. */
267
+ export declare const enum SeekingState {
268
+ /** We're not currently seeking. */
269
+ None = 0,
270
+ /**
271
+ * We're currently seeking due to an internal logic of the RxPlayer (e.g.
272
+ * discontinuity skipping).
273
+ */
274
+ Internal = 1,
275
+ /** We're currently seeking due to a regular seek wanted by the application. */
276
+ External = 2
241
277
  }
242
278
  /**
243
279
  * Describes when the player is "rebuffering" and what event started that
@@ -277,7 +313,16 @@ export interface IFreezingStatus {
277
313
  timestamp: number;
278
314
  }
279
315
  /** Information emitted on each playback observation. */
280
- export interface IPlaybackObservation extends IMediaInfos {
316
+ export interface IPlaybackObservation extends Omit<IMediaInfos, "position" | "seeking"> {
317
+ /** Event that triggered this playback observation. */
318
+ event: IPlaybackObserverEventType;
319
+ /** Current seeking state. */
320
+ seeking: SeekingState;
321
+ /**
322
+ * Information on the current position being played, the position for which
323
+ * media is wanted etc.
324
+ */
325
+ position: IObservationPosition;
281
326
  /**
282
327
  * Set if the player is short on audio and/or video media data and is a such,
283
328
  * rebuffering.
@@ -292,11 +337,86 @@ export interface IPlaybackObservation extends IMediaInfos {
292
337
  * `null` if the player is not frozen.
293
338
  */
294
339
  freezing: IFreezingStatus | null;
340
+ }
341
+ export type IObservationPosition = ObservationPosition;
342
+ declare class ObservationPosition {
343
+ /**
344
+ * Known position at the time the Observation was emitted, in seconds.
345
+ *
346
+ * Note that it might have changed since. If you want truly precize
347
+ * information, you should recuperate it from the HTMLMediaElement directly
348
+ * through another mean.
349
+ */
350
+ private _last;
351
+ /**
352
+ * Actually wanted position in seconds that is not yet reached.
353
+ *
354
+ * This might for example be set to the initial position when the content is
355
+ * loading (and thus potentially at a `0` position) but which will be seeked
356
+ * to a given position once possible. It may also be the position of a seek
357
+ * that has not been properly accounted for by the current device.
358
+ */
359
+ private _wanted;
360
+ constructor(last: number, wanted: number | null);
361
+ /**
362
+ * Returns the playback position actually observed on the media element at
363
+ * the time the playback observation was made.
364
+ *
365
+ * Note that it may be different than the position for which media data is
366
+ * wanted in rare scenarios where the goal position is not yet set on the
367
+ * media element.
368
+ *
369
+ * You should use this value when you want to obtain the actual position set
370
+ * on the media element for browser compatibility purposes. Note that this
371
+ * position was calculated at observation time, it might thus not be
372
+ * up-to-date if what you want is milliseconds-accuracy.
373
+ *
374
+ * If what you want is the actual position which the player is intended to
375
+ * play, you should rely on `getWanted` instead`.
376
+ * @returns {number}
377
+ */
378
+ getPolled(): number;
379
+ /**
380
+ * Returns the position which the player should consider to load media data
381
+ * at the time the observation was made.
382
+ *
383
+ * It can be different than the value returned by `getPolled` in rare
384
+ * scenarios:
385
+ *
386
+ * - When the initial position has not been set yet.
387
+ *
388
+ * - When the current device do not let the RxPlayer peform precize seeks,
389
+ * usually for perfomance reasons by seeking to a previous IDR frame
390
+ * instead (for now only Tizen may be like this), in which case we
391
+ * prefer to generally rely on the position wanted by the player (this
392
+ * e.g. prevents issues where the RxPlayer logic and the device are
393
+ * seeking back and forth in a loop).
394
+ *
395
+ * - When a wanted position has been "forced" (@see forceWantedPosition).
396
+ * @returns {number}
397
+ */
398
+ getWanted(): number;
399
+ /**
400
+ * Method to call if you want to overwrite the currently wanted position.
401
+ * @param {number} pos
402
+ */
403
+ forceWantedPosition(pos: number): void;
295
404
  /**
296
- * If `true`, an "internal seek" (a seeking operation triggered by the
297
- * RxPlayer code) is currently pending.
405
+ * Returns `true` when the position wanted returned by `getWanted` and the
406
+ * actual position returned by `getPolled` may be different, meaning that
407
+ * we're currently not at the position we want to reach.
408
+ *
409
+ * This is a relatively rare situation which only happens when either the
410
+ * initial seek has not yet been performed. on specific targets where the
411
+ * seeking behavior is a little broken (@see getWanted) or when the wanted
412
+ * position has been forced (@see forceWantedPosition).
413
+ *
414
+ * In those situations, you might temporarily refrain from acting upon the
415
+ * actual current media position, as it may change soon.
416
+ *
417
+ * @returns {boolean}
298
418
  */
299
- pendingInternalSeek: number | null;
419
+ isAwaitingFuturePosition(): boolean;
300
420
  }
301
421
  /**
302
422
  * Interface providing a generic and read-only version of a `PlaybackObserver`.
@@ -15,6 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ var is_seeking_approximate_1 = require("../../compat/is_seeking_approximate");
18
19
  var config_1 = require("../../config");
19
20
  var log_1 = require("../../log");
20
21
  var monotonic_timestamp_1 = require("../../utils/monotonic_timestamp");
@@ -61,12 +62,26 @@ var PlaybackObserver = /** @class */ (function () {
61
62
  * @param {Object} options
62
63
  */
63
64
  function PlaybackObserver(mediaElement, options) {
65
+ var _this = this;
64
66
  this._internalSeeksIncoming = [];
65
67
  this._mediaElement = mediaElement;
66
68
  this._withMediaSource = options.withMediaSource;
67
69
  this._lowLatencyMode = options.lowLatencyMode;
68
70
  this._canceller = new task_canceller_1.default();
69
71
  this._observationRef = this._createSharedReference();
72
+ this._expectedSeekingPosition = null;
73
+ this._pendingSeek = null;
74
+ var onLoadedMetadata = function () {
75
+ if (_this._pendingSeek !== null) {
76
+ var positionToSeekTo = _this._pendingSeek;
77
+ _this._pendingSeek = null;
78
+ _this._actuallySetCurrentTime(positionToSeekTo);
79
+ }
80
+ };
81
+ mediaElement.addEventListener("loadedmetadata", onLoadedMetadata);
82
+ this._canceller.signal.register(function () {
83
+ mediaElement.removeEventListener("loadedmetadata", onLoadedMetadata);
84
+ });
70
85
  }
71
86
  /**
72
87
  * Stop the `PlaybackObserver` from emitting playback observations and free all
@@ -116,9 +131,14 @@ var PlaybackObserver = /** @class */ (function () {
116
131
  * @param {number} time
117
132
  */
118
133
  PlaybackObserver.prototype.setCurrentTime = function (time) {
119
- this._internalSeeksIncoming.push(time);
120
- log_1.default.info("API: Seeking internally", time);
121
- this._mediaElement.currentTime = time;
134
+ if (this._mediaElement.readyState >= 1) {
135
+ this._actuallySetCurrentTime(time);
136
+ }
137
+ else {
138
+ this._internalSeeksIncoming = [];
139
+ this._pendingSeek = time;
140
+ this._generateObservationForEvent("manual");
141
+ }
122
142
  };
123
143
  /**
124
144
  * Update the playback rate of the `HTMLMediaElement`.
@@ -183,6 +203,11 @@ var PlaybackObserver = /** @class */ (function () {
183
203
  PlaybackObserver.prototype.deriveReadOnlyObserver = function (transform) {
184
204
  return generateReadOnlyObserver(this, transform, this._canceller.signal);
185
205
  };
206
+ PlaybackObserver.prototype._actuallySetCurrentTime = function (time) {
207
+ log_1.default.info("API: Seeking internally", time);
208
+ this._internalSeeksIncoming.push(time);
209
+ this._mediaElement.currentTime = time;
210
+ };
186
211
  /**
187
212
  * Creates the `IReadOnlySharedReference` that will generate playback
188
213
  * observations.
@@ -193,56 +218,21 @@ var PlaybackObserver = /** @class */ (function () {
193
218
  if (this._observationRef !== undefined) {
194
219
  return this._observationRef;
195
220
  }
196
- var lastObservation;
197
221
  var _a = config_1.default.getCurrent(), SAMPLING_INTERVAL_MEDIASOURCE = _a.SAMPLING_INTERVAL_MEDIASOURCE, SAMPLING_INTERVAL_LOW_LATENCY = _a.SAMPLING_INTERVAL_LOW_LATENCY, SAMPLING_INTERVAL_NO_MEDIASOURCE = _a.SAMPLING_INTERVAL_NO_MEDIASOURCE;
198
- var getCurrentObservation = function (event) {
199
- var tmpEvt = event;
200
- var startedInternalSeekTime;
201
- if (tmpEvt === "seeking" && _this._internalSeeksIncoming.length > 0) {
202
- tmpEvt = "internal-seeking";
203
- startedInternalSeekTime = _this._internalSeeksIncoming.shift();
204
- }
205
- var _lastObservation = lastObservation !== null && lastObservation !== void 0 ? lastObservation : _this._generateInitialObservation();
206
- var mediaTimings = getMediaInfos(_this._mediaElement, tmpEvt, _this._withMediaSource);
207
- var pendingInternalSeek = null;
208
- if (mediaTimings.seeking) {
209
- if (typeof startedInternalSeekTime === "number") {
210
- pendingInternalSeek = startedInternalSeekTime;
211
- }
212
- else if (_lastObservation.pendingInternalSeek !== null && event !== "seeking") {
213
- pendingInternalSeek = _lastObservation.pendingInternalSeek;
214
- }
215
- }
216
- var rebufferingStatus = getRebufferingStatus(_lastObservation, mediaTimings, { lowLatencyMode: _this._lowLatencyMode,
217
- withMediaSource: _this._withMediaSource });
218
- var freezingStatus = getFreezingStatus(_lastObservation, mediaTimings);
219
- var timings = (0, object_assign_1.default)({}, { rebuffering: rebufferingStatus,
220
- freezing: freezingStatus, pendingInternalSeek: pendingInternalSeek }, mediaTimings);
221
- if (log_1.default.hasLevel("DEBUG")) {
222
- log_1.default.debug("API: current media element state tick", "event", timings.event, "position", timings.position, "seeking", timings.seeking, "internalSeek", timings.pendingInternalSeek, "rebuffering", timings.rebuffering !== null, "freezing", timings.freezing !== null, "ended", timings.ended, "paused", timings.paused, "playbackRate", timings.playbackRate, "readyState", timings.readyState);
223
- }
224
- return timings;
225
- };
226
- var returnedSharedReference = new reference_1.default(getCurrentObservation("init"), this._canceller.signal);
227
- var generateObservationForEvent = function (event) {
228
- var newObservation = getCurrentObservation(event);
229
- if (log_1.default.hasLevel("DEBUG")) {
230
- log_1.default.debug("API: current playback timeline:\n" +
231
- prettyPrintBuffered(newObservation.buffered, newObservation.position), "\n".concat(event));
232
- }
233
- lastObservation = newObservation;
234
- returnedSharedReference.setValue(newObservation);
235
- };
222
+ var returnedSharedReference = new reference_1.default(this._getCurrentObservation("init"), this._canceller.signal);
236
223
  var interval = this._lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY :
237
224
  this._withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE :
238
225
  SAMPLING_INTERVAL_NO_MEDIASOURCE;
226
+ var onInterval = function () {
227
+ _this._generateObservationForEvent("timeupdate");
228
+ };
239
229
  var intervalId = setInterval(onInterval, interval);
240
230
  var removeEventListeners = SCANNED_MEDIA_ELEMENTS_EVENTS.map(function (eventName) {
241
- _this._mediaElement.addEventListener(eventName, onMediaEvent);
242
- function onMediaEvent() {
231
+ var onMediaEvent = function () {
243
232
  restartInterval();
244
- generateObservationForEvent(eventName);
245
- }
233
+ _this._generateObservationForEvent(eventName);
234
+ };
235
+ _this._mediaElement.addEventListener(eventName, onMediaEvent);
246
236
  return function () {
247
237
  _this._mediaElement.removeEventListener(eventName, onMediaEvent);
248
238
  };
@@ -253,22 +243,168 @@ var PlaybackObserver = /** @class */ (function () {
253
243
  returnedSharedReference.finish();
254
244
  });
255
245
  return returnedSharedReference;
256
- function onInterval() {
257
- generateObservationForEvent("timeupdate");
258
- }
259
246
  function restartInterval() {
260
247
  clearInterval(intervalId);
261
248
  intervalId = setInterval(onInterval, interval);
262
249
  }
263
250
  };
264
- PlaybackObserver.prototype._generateInitialObservation = function () {
265
- return (0, object_assign_1.default)(getMediaInfos(this._mediaElement, "init", this._withMediaSource), { rebuffering: null,
266
- freezing: null,
267
- pendingInternalSeek: null });
251
+ PlaybackObserver.prototype._getCurrentObservation = function (event) {
252
+ var _a;
253
+ /** Actual event emitted through an observation. */
254
+ var tmpEvt = event;
255
+ // NOTE: `this._observationRef` may be `undefined` because we might here be
256
+ // called in the constructor when that property is not yet set.
257
+ var previousObservation = this._observationRef === undefined ?
258
+ getInitialObservation(this._mediaElement, this._withMediaSource) :
259
+ this._observationRef.getValue();
260
+ /**
261
+ * If `true`, there is a seek operation ongoing but it was done from the
262
+ * `PlaybackObserver`'s `setCurrentTime` method, not from external code.
263
+ */
264
+ var isInternalSeeking = false;
265
+ /** If set, the position for which we plan to seek to as soon as possible. */
266
+ var pendingPosition = this._pendingSeek;
267
+ /** Initially-polled playback observation, before adjustments. */
268
+ var mediaTimings = getMediaInfos(this._mediaElement, this._withMediaSource);
269
+ if (tmpEvt === "seeking") {
270
+ // We just began seeking.
271
+ // Let's find out if the seek is internal or external and handle approximate
272
+ // seeking
273
+ if (this._internalSeeksIncoming.length > 0) {
274
+ isInternalSeeking = true;
275
+ tmpEvt = "internal-seeking";
276
+ var startedInternalSeekTime = this._internalSeeksIncoming.shift();
277
+ this._expectedSeekingPosition = is_seeking_approximate_1.default ?
278
+ Math.max(mediaTimings.position, startedInternalSeekTime !== null && startedInternalSeekTime !== void 0 ? startedInternalSeekTime : 0) :
279
+ mediaTimings.position;
280
+ }
281
+ else {
282
+ this._expectedSeekingPosition = mediaTimings.position;
283
+ }
284
+ }
285
+ else if (mediaTimings.seeking) {
286
+ // we're still seeking, this time without a "seeking" event so it's an
287
+ // already handled one, keep track of the last wanted position we wanted
288
+ // to seek to, to work-around devices re-seeking silently.
289
+ this._expectedSeekingPosition = Math.max(mediaTimings.position, (_a = this._expectedSeekingPosition) !== null && _a !== void 0 ? _a : 0);
290
+ }
291
+ else if (is_seeking_approximate_1.default &&
292
+ this._expectedSeekingPosition !== null &&
293
+ mediaTimings.position < this._expectedSeekingPosition) {
294
+ // We're on a target with aproximate seeking, we're not seeking anymore, but
295
+ // we're not yet at the expected seeking position.
296
+ // Signal to the rest of the application that the intented position is not
297
+ // the current position but the one contained in `this._expectedSeekingPosition`
298
+ pendingPosition = this._expectedSeekingPosition;
299
+ }
300
+ else {
301
+ this._expectedSeekingPosition = null;
302
+ }
303
+ if (mediaTimings.seeking &&
304
+ previousObservation.seeking === 1 /* SeekingState.Internal */ &&
305
+ event !== "seeking") {
306
+ isInternalSeeking = true;
307
+ }
308
+ var rebufferingStatus = getRebufferingStatus(previousObservation, mediaTimings, tmpEvt, { lowLatencyMode: this._lowLatencyMode,
309
+ withMediaSource: this._withMediaSource });
310
+ var freezingStatus = getFreezingStatus(previousObservation, mediaTimings, tmpEvt);
311
+ var seeking = isInternalSeeking ? 1 /* SeekingState.Internal */ :
312
+ mediaTimings.seeking ? 2 /* SeekingState.External */ :
313
+ 0 /* SeekingState.None */;
314
+ var timings = (0, object_assign_1.default)({}, mediaTimings, { position: new ObservationPosition(mediaTimings.position, pendingPosition),
315
+ event: tmpEvt, seeking: seeking, rebuffering: rebufferingStatus,
316
+ freezing: freezingStatus });
317
+ if (log_1.default.hasLevel("DEBUG")) {
318
+ log_1.default.debug("API: current media element state tick", "event", timings.event, "position", timings.position.getPolled(), "seeking", timings.seeking, "internalSeek", isInternalSeeking, "rebuffering", timings.rebuffering !== null, "freezing", timings.freezing !== null, "ended", timings.ended, "paused", timings.paused, "playbackRate", timings.playbackRate, "readyState", timings.readyState);
319
+ }
320
+ return timings;
321
+ };
322
+ PlaybackObserver.prototype._generateObservationForEvent = function (event) {
323
+ var newObservation = this._getCurrentObservation(event);
324
+ if (log_1.default.hasLevel("DEBUG")) {
325
+ log_1.default.debug("API: current playback timeline:\n" +
326
+ prettyPrintBuffered(newObservation.buffered, newObservation.position.getPolled()), "\n".concat(event));
327
+ }
328
+ this._observationRef.setValue(newObservation);
268
329
  };
269
330
  return PlaybackObserver;
270
331
  }());
271
332
  exports.default = PlaybackObserver;
333
+ var ObservationPosition = /** @class */ (function () {
334
+ function ObservationPosition(last, wanted) {
335
+ this._last = last;
336
+ this._wanted = wanted;
337
+ }
338
+ /**
339
+ * Returns the playback position actually observed on the media element at
340
+ * the time the playback observation was made.
341
+ *
342
+ * Note that it may be different than the position for which media data is
343
+ * wanted in rare scenarios where the goal position is not yet set on the
344
+ * media element.
345
+ *
346
+ * You should use this value when you want to obtain the actual position set
347
+ * on the media element for browser compatibility purposes. Note that this
348
+ * position was calculated at observation time, it might thus not be
349
+ * up-to-date if what you want is milliseconds-accuracy.
350
+ *
351
+ * If what you want is the actual position which the player is intended to
352
+ * play, you should rely on `getWanted` instead`.
353
+ * @returns {number}
354
+ */
355
+ ObservationPosition.prototype.getPolled = function () {
356
+ return this._last;
357
+ };
358
+ /**
359
+ * Returns the position which the player should consider to load media data
360
+ * at the time the observation was made.
361
+ *
362
+ * It can be different than the value returned by `getPolled` in rare
363
+ * scenarios:
364
+ *
365
+ * - When the initial position has not been set yet.
366
+ *
367
+ * - When the current device do not let the RxPlayer peform precize seeks,
368
+ * usually for perfomance reasons by seeking to a previous IDR frame
369
+ * instead (for now only Tizen may be like this), in which case we
370
+ * prefer to generally rely on the position wanted by the player (this
371
+ * e.g. prevents issues where the RxPlayer logic and the device are
372
+ * seeking back and forth in a loop).
373
+ *
374
+ * - When a wanted position has been "forced" (@see forceWantedPosition).
375
+ * @returns {number}
376
+ */
377
+ ObservationPosition.prototype.getWanted = function () {
378
+ var _a;
379
+ return (_a = this._wanted) !== null && _a !== void 0 ? _a : this._last;
380
+ };
381
+ /**
382
+ * Method to call if you want to overwrite the currently wanted position.
383
+ * @param {number} pos
384
+ */
385
+ ObservationPosition.prototype.forceWantedPosition = function (pos) {
386
+ this._wanted = pos;
387
+ };
388
+ /**
389
+ * Returns `true` when the position wanted returned by `getWanted` and the
390
+ * actual position returned by `getPolled` may be different, meaning that
391
+ * we're currently not at the position we want to reach.
392
+ *
393
+ * This is a relatively rare situation which only happens when either the
394
+ * initial seek has not yet been performed. on specific targets where the
395
+ * seeking behavior is a little broken (@see getWanted) or when the wanted
396
+ * position has been forced (@see forceWantedPosition).
397
+ *
398
+ * In those situations, you might temporarily refrain from acting upon the
399
+ * actual current media position, as it may change soon.
400
+ *
401
+ * @returns {boolean}
402
+ */
403
+ ObservationPosition.prototype.isAwaitingFuturePosition = function () {
404
+ return this._wanted !== null;
405
+ };
406
+ return ObservationPosition;
407
+ }());
272
408
  /**
273
409
  * Returns the amount of time in seconds the buffer should have ahead of the
274
410
  * current position before resuming playback. Based on the infos of the
@@ -315,10 +451,9 @@ function hasLoadedUntilTheEnd(currentTime, currentRange, ended, duration, lowLat
315
451
  /**
316
452
  * Get basic playback information.
317
453
  * @param {HTMLMediaElement} mediaElement
318
- * @param {string} event
319
454
  * @returns {Object}
320
455
  */
321
- function getMediaInfos(mediaElement, event, withMediaSource) {
456
+ function getMediaInfos(mediaElement, withMediaSource) {
322
457
  var buffered = mediaElement.buffered, currentTime = mediaElement.currentTime, duration = mediaElement.duration, ended = mediaElement.ended, paused = mediaElement.paused, playbackRate = mediaElement.playbackRate, readyState = mediaElement.readyState, seeking = mediaElement.seeking;
323
458
  var currentRange;
324
459
  var bufferGap;
@@ -337,7 +472,7 @@ function getMediaInfos(mediaElement, event, withMediaSource) {
337
472
  // more appropriate
338
473
  Infinity;
339
474
  }
340
- return { bufferGap: bufferGap, buffered: buffered, currentRange: currentRange, position: currentTime, duration: duration, ended: ended, paused: paused, playbackRate: playbackRate, readyState: readyState, seeking: seeking, event: event };
475
+ return { bufferGap: bufferGap, buffered: buffered, currentRange: currentRange, position: currentTime, duration: duration, ended: ended, paused: paused, playbackRate: playbackRate, readyState: readyState, seeking: seeking };
341
476
  }
342
477
  /**
343
478
  * Infer rebuffering status of the media based on:
@@ -348,13 +483,14 @@ function getMediaInfos(mediaElement, event, withMediaSource) {
348
483
  * @param {Object} currentInfo - Current set of basic information on the
349
484
  * `HTMLMediaElement`. This does not need every single property from a regular
350
485
  * playback observation.
486
+ * @param {string} currentEvt
351
487
  * @param {Object} options
352
488
  * @returns {Object|null}
353
489
  */
354
- function getRebufferingStatus(prevObservation, currentInfo, _a) {
490
+ function getRebufferingStatus(prevObservation, currentInfo, currentEvt, _a) {
355
491
  var withMediaSource = _a.withMediaSource, lowLatencyMode = _a.lowLatencyMode;
356
492
  var REBUFFERING_GAP = config_1.default.getCurrent().REBUFFERING_GAP;
357
- var currentEvt = currentInfo.event, currentTime = currentInfo.position, bufferGap = currentInfo.bufferGap, currentRange = currentInfo.currentRange, duration = currentInfo.duration, paused = currentInfo.paused, readyState = currentInfo.readyState, ended = currentInfo.ended;
493
+ var currentTime = currentInfo.position, bufferGap = currentInfo.bufferGap, currentRange = currentInfo.currentRange, duration = currentInfo.duration, paused = currentInfo.paused, readyState = currentInfo.readyState, ended = currentInfo.ended;
358
494
  var prevRebuffering = prevObservation.rebuffering, prevEvt = prevObservation.event, prevTime = prevObservation.position;
359
495
  var fullyLoaded = hasLoadedUntilTheEnd(currentTime, currentRange, ended, duration, lowLatencyMode);
360
496
  var canSwitchToRebuffering = (readyState >= 1 &&
@@ -409,12 +545,12 @@ function getRebufferingStatus(prevObservation, currentInfo, _a) {
409
545
  if (canSwitchToRebuffering &&
410
546
  ((!paused &&
411
547
  currentEvt === "timeupdate" && prevEvt === "timeupdate" &&
412
- currentTime === prevTime) ||
548
+ currentTime === prevTime.getPolled()) ||
413
549
  (currentEvt === "seeking" && (bufferGap === Infinity || (bufferGap === undefined && readyState < 3))))) {
414
550
  shouldRebuffer = true;
415
551
  }
416
552
  else if (prevRebuffering !== null &&
417
- ((currentEvt !== "seeking" && currentTime !== prevTime) ||
553
+ ((currentEvt !== "seeking" && currentTime !== prevTime.getPolled()) ||
418
554
  currentEvt === "canplay" ||
419
555
  (bufferGap === undefined && readyState >= 3) ||
420
556
  (bufferGap !== undefined && bufferGap < Infinity &&
@@ -459,28 +595,29 @@ function getRebufferingStatus(prevObservation, currentInfo, _a) {
459
595
  * `null` if not.
460
596
  * @param {Object} prevObservation
461
597
  * @param {Object} currentInfo
598
+ * @param {string} currentEvt
462
599
  * @returns {Object|null}
463
600
  */
464
- function getFreezingStatus(prevObservation, currentInfo) {
601
+ function getFreezingStatus(prevObservation, currentInfo, currentEvt) {
465
602
  var MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING = config_1.default.getCurrent().MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING;
466
603
  if (prevObservation.freezing) {
467
604
  if (currentInfo.ended ||
468
605
  currentInfo.paused ||
469
606
  currentInfo.readyState === 0 ||
470
607
  currentInfo.playbackRate === 0 ||
471
- prevObservation.position !== currentInfo.position) {
608
+ prevObservation.position.getPolled() !== currentInfo.position) {
472
609
  return null; // Quit freezing status
473
610
  }
474
611
  return prevObservation.freezing; // Stay in it
475
612
  }
476
- return currentInfo.event === "timeupdate" &&
613
+ return currentEvt === "timeupdate" &&
477
614
  currentInfo.bufferGap !== undefined &&
478
615
  currentInfo.bufferGap > MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING &&
479
616
  !currentInfo.ended &&
480
617
  !currentInfo.paused &&
481
618
  currentInfo.readyState >= 1 &&
482
619
  currentInfo.playbackRate !== 0 &&
483
- currentInfo.position === prevObservation.position ?
620
+ currentInfo.position === prevObservation.position.getPolled() ?
484
621
  { timestamp: (0, monotonic_timestamp_1.default)() } :
485
622
  null;
486
623
  }
@@ -583,3 +720,19 @@ function generateReadOnlyObserver(src, transform, cancellationSignal) {
583
720
  },
584
721
  };
585
722
  }
723
+ /**
724
+ * Generate the initial playback observation for when no event has yet been
725
+ * emitted to lead to one.
726
+ * @param {HTMLMediaElement} mediaElement
727
+ * @param {boolean} withMediaSource
728
+ * @returns {Object}
729
+ */
730
+ function getInitialObservation(mediaElement, withMediaSource) {
731
+ var mediaTimings = getMediaInfos(mediaElement, withMediaSource);
732
+ return (0, object_assign_1.default)(mediaTimings, { rebuffering: null,
733
+ event: "init",
734
+ seeking: 0 /* SeekingState.None */,
735
+ position: { last: mediaTimings.position,
736
+ pending: undefined },
737
+ freezing: null });
738
+ }
@@ -557,6 +557,15 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
557
557
  * @returns {number}
558
558
  */
559
559
  getMinimumPosition(): number | null;
560
+ /**
561
+ * Returns the current position for live contents.
562
+ *
563
+ * Returns `null` if no content is loaded or if the current loaded content is
564
+ * not considered as a live content.
565
+ * Returns `undefined` if that live position is currently unknown.
566
+ * @returns {number}
567
+ */
568
+ getLivePosition(): number | undefined | null;
560
569
  /**
561
570
  * Get maximum seek-able position.
562
571
  * @returns {number}