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
@@ -56,6 +56,8 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
56
56
  const requestOptions = {
57
57
  timeout: options.requestTimeout < 0 ? undefined :
58
58
  options.requestTimeout,
59
+ connectionTimeout: options.connectionTimeout === undefined ? undefined :
60
+ options.connectionTimeout < 0 ? undefined : options.connectionTimeout,
59
61
  };
60
62
  /**
61
63
  * Cache audio and video initialization segments.
@@ -283,13 +285,15 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
283
285
  * @param {Object}
284
286
  * @returns {Object}
285
287
  */
286
- export function getSegmentFetcherOptions({ maxRetry, lowLatencyMode, requestTimeout }) {
287
- const { DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, DEFAULT_REQUEST_TIMEOUT, INITIAL_BACKOFF_DELAY_BASE, MAX_BACKOFF_DELAY_BASE } = config.getCurrent();
288
+ export function getSegmentFetcherOptions({ maxRetry, lowLatencyMode, requestTimeout, connectionTimeout }) {
289
+ const { DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, DEFAULT_REQUEST_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT, INITIAL_BACKOFF_DELAY_BASE, MAX_BACKOFF_DELAY_BASE } = config.getCurrent();
288
290
  return { maxRetry: maxRetry !== null && maxRetry !== void 0 ? maxRetry : DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,
289
291
  baseDelay: lowLatencyMode ? INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY :
290
292
  INITIAL_BACKOFF_DELAY_BASE.REGULAR,
291
293
  maxDelay: lowLatencyMode ? MAX_BACKOFF_DELAY_BASE.LOW_LATENCY :
292
294
  MAX_BACKOFF_DELAY_BASE.REGULAR,
293
- requestTimeout: isNullOrUndefined(requestTimeout) ? DEFAULT_REQUEST_TIMEOUT :
294
- requestTimeout };
295
+ requestTimeout: (requestTimeout === undefined) ? DEFAULT_REQUEST_TIMEOUT :
296
+ requestTimeout,
297
+ connectionTimeout: (connectionTimeout === undefined) ?
298
+ DEFAULT_CONNECTION_TIMEOUT : connectionTimeout, };
295
299
  }
@@ -74,4 +74,5 @@ export interface ISegmentFetcherCreatorBackoffOptions {
74
74
  * `undefined` will lead to a default, large, timeout being used.
75
75
  */
76
76
  requestTimeout: number | undefined;
77
+ connectionTimeout: number | undefined;
77
78
  }
@@ -287,7 +287,7 @@ export async function scheduleRequestWithCdns(cdns, cdnPrioritizer, performReque
287
287
  * attempts already done for that resource.
288
288
  *
289
289
  * Returns `undefined` if there's no Cdn left to request the resource.
290
- * @param {Array.<Object>}
290
+ * @param {Array.<Object>} sortedCdns
291
291
  * @returns {Object|undefined}
292
292
  */
293
293
  function getPrioritaryRequestableCdnFromSortedList(sortedCdns) {
@@ -20,6 +20,7 @@
20
20
  import { clearElementSrc } from "../../compat";
21
21
  import log from "../../log";
22
22
  import assert from "../../utils/assert";
23
+ import isNullOrUndefined from "../../utils/is_null_or_undefined";
23
24
  import SharedReference from "../../utils/reference";
24
25
  import TaskCanceller from "../../utils/task_canceller";
25
26
  import { ContentInitializer } from "./types";
@@ -152,7 +153,13 @@ export default class DirectFileContentInitializer extends ContentInitializer {
152
153
  log.debug("Init: Initial time calculated:", initTime);
153
154
  return initTime;
154
155
  };
155
- performInitialSeekAndPlay(mediaElement, playbackObserver, initialTime, autoPlay, (err) => this.trigger("warning", err), cancelSignal).autoPlayResult
156
+ performInitialSeekAndPlay({ mediaElement,
157
+ playbackObserver,
158
+ startTime: initialTime,
159
+ mustAutoPlay: autoPlay,
160
+ onWarning: (err) => this.trigger("warning", err),
161
+ isDirectfile: true }, cancelSignal)
162
+ .autoPlayResult
156
163
  .then(() => getLoadedReference(playbackObserver, mediaElement, true, cancelSignal)
157
164
  .onUpdate((isLoaded, stopListening) => {
158
165
  if (isLoaded) {
@@ -174,10 +181,10 @@ export default class DirectFileContentInitializer extends ContentInitializer {
174
181
  * @returns {number}
175
182
  */
176
183
  function getDirectFileInitialTime(mediaElement, startAt) {
177
- if (startAt == null) {
184
+ if (isNullOrUndefined(startAt)) {
178
185
  return 0;
179
186
  }
180
- if (startAt.position != null) {
187
+ if (!isNullOrUndefined(startAt.position)) {
181
188
  return startAt.position;
182
189
  }
183
190
  else if (startAt.wallClockTime != null) {
@@ -187,15 +194,31 @@ function getDirectFileInitialTime(mediaElement, startAt) {
187
194
  return startAt.fromFirstPosition;
188
195
  }
189
196
  const duration = mediaElement.duration;
190
- if (duration == null || !isFinite(duration)) {
191
- log.warn("startAt.fromLastPosition set but no known duration, " +
192
- "beginning at 0.");
193
- return 0;
194
- }
195
197
  if (typeof startAt.fromLastPosition === "number") {
198
+ if (isNullOrUndefined(duration) || !isFinite(duration)) {
199
+ log.warn("startAt.fromLastPosition set but no known duration, " +
200
+ "beginning at 0.");
201
+ return 0;
202
+ }
196
203
  return Math.max(0, duration + startAt.fromLastPosition);
197
204
  }
205
+ else if (typeof startAt.fromLivePosition === "number") {
206
+ const livePosition = mediaElement.seekable.length > 0 ?
207
+ mediaElement.seekable.end(0) :
208
+ duration;
209
+ if (isNullOrUndefined(livePosition)) {
210
+ log.warn("startAt.fromLivePosition set but no known live position, " +
211
+ "beginning at 0.");
212
+ return 0;
213
+ }
214
+ return Math.max(0, livePosition + startAt.fromLivePosition);
215
+ }
198
216
  else if (startAt.percentage != null) {
217
+ if (isNullOrUndefined(duration) || !isFinite(duration)) {
218
+ log.warn("startAt.percentage set but no known duration, " +
219
+ "beginning at 0.");
220
+ return 0;
221
+ }
199
222
  const { percentage } = startAt;
200
223
  if (percentage >= 100) {
201
224
  return duration;
@@ -160,6 +160,12 @@ export interface IInitializeArguments {
160
160
  * `-1` indicates no timeout.
161
161
  */
162
162
  requestTimeout: number | undefined;
163
+ /**
164
+ * Amount of time, in milliseconds, after which a request that hasn't receive
165
+ * the headers and status code should be aborted and optionnaly retried,
166
+ * depending on the maxRetry configuration.
167
+ */
168
+ connectionTimeout: number | undefined;
163
169
  /** Maximum number of time a request on error will be retried. */
164
170
  maxRetry: number | undefined;
165
171
  };
@@ -267,7 +267,12 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
267
267
  cancelSignal.register(() => {
268
268
  segmentBuffersStore.disposeAll();
269
269
  });
270
- const { autoPlayResult, initialPlayPerformed, initialSeekPerformed } = performInitialSeekAndPlay(mediaElement, playbackObserver, initialTime, autoPlay, (err) => this.trigger("warning", err), cancelSignal);
270
+ const { autoPlayResult, initialPlayPerformed } = performInitialSeekAndPlay({ mediaElement,
271
+ playbackObserver,
272
+ startTime: initialTime,
273
+ mustAutoPlay: autoPlay,
274
+ onWarning: (err) => { this.trigger("warning", err); },
275
+ isDirectfile: false }, cancelSignal);
271
276
  if (cancelSignal.isCancelled()) {
272
277
  return;
273
278
  }
@@ -290,16 +295,19 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
290
295
  const streamObserver = createStreamPlaybackObserver(playbackObserver, { autoPlay,
291
296
  manifest,
292
297
  initialPlayPerformed,
293
- initialSeekPerformed,
294
- speed,
295
- startTime: initialTime }, cancelSignal);
298
+ speed }, cancelSignal);
296
299
  const rebufferingController = this._createRebufferingController(playbackObserver, manifest, segmentBuffersStore, speed, cancelSignal);
297
300
  rebufferingController.addEventListener("needsReload", () => {
301
+ let position;
302
+ const lastObservation = playbackObserver.getReference().getValue();
303
+ if (lastObservation.position.isAwaitingFuturePosition()) {
304
+ position = lastObservation.position.getWanted();
305
+ }
306
+ else {
307
+ position = playbackObserver.getCurrentTime();
308
+ }
298
309
  // NOTE couldn't both be always calculated at event destination?
299
310
  // Maybe there are exceptions?
300
- const position = initialSeekPerformed.getValue() ?
301
- playbackObserver.getCurrentTime() :
302
- initialTime;
303
311
  const autoplay = initialPlayPerformed.getValue() ?
304
312
  !playbackObserver.getIsPaused() :
305
313
  autoPlay;
@@ -359,10 +367,10 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
359
367
  if (
360
368
  // Data is buffered around the current position
361
369
  obs.currentRange !== null ||
362
- // Or, for whatever reason, playback is already advancing
363
- obs.position > seekedTime + 0.1) {
370
+ // Or, for whatever reason, we have no buffer but we're already advancing
371
+ obs.position.getPolled() > seekedTime + 0.1) {
364
372
  stopListening();
365
- playbackObserver.setCurrentTime(obs.position + 0.001);
373
+ playbackObserver.setCurrentTime(obs.position.getWanted() + 0.001);
366
374
  }
367
375
  }, { includeLastObservation: false, clearSignal: cancelSignal });
368
376
  },
@@ -434,10 +442,12 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
434
442
  },
435
443
  bitrateEstimateChange: (value) => self.trigger("bitrateEstimateChange", value),
436
444
  needsMediaSourceReload: (payload) => {
437
- var _a, _b;
445
+ var _a;
438
446
  const lastObservation = streamObserver.getReference().getValue();
439
- const currentPosition = (_a = lastObservation.position.pending) !== null && _a !== void 0 ? _a : streamObserver.getCurrentTime();
440
- const isPaused = (_b = lastObservation.paused.pending) !== null && _b !== void 0 ? _b : streamObserver.getIsPaused();
447
+ const currentPosition = lastObservation.position.isAwaitingFuturePosition() ?
448
+ lastObservation.position.getWanted() :
449
+ streamObserver.getCurrentTime();
450
+ const isPaused = (_a = lastObservation.paused.pending) !== null && _a !== void 0 ? _a : streamObserver.getIsPaused();
441
451
  let position = currentPosition + payload.timeOffset;
442
452
  if (payload.minimumPosition !== undefined) {
443
453
  position = Math.max(payload.minimumPosition, position);
@@ -448,17 +458,21 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
448
458
  onReloadOrder({ position, autoPlay: !isPaused });
449
459
  },
450
460
  needsDecipherabilityFlush() {
451
- var _a, _b, _c;
461
+ var _a;
452
462
  const keySystem = getKeySystemConfiguration(mediaElement);
453
463
  if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem === null || keySystem === void 0 ? void 0 : keySystem[0])) {
454
464
  const lastObservation = streamObserver.getReference().getValue();
455
- const position = (_a = lastObservation.position.pending) !== null && _a !== void 0 ? _a : streamObserver.getCurrentTime();
456
- const isPaused = (_b = lastObservation.paused.pending) !== null && _b !== void 0 ? _b : streamObserver.getIsPaused();
465
+ const position = lastObservation.position.isAwaitingFuturePosition() ?
466
+ lastObservation.position.getWanted() :
467
+ streamObserver.getCurrentTime();
468
+ const isPaused = (_a = lastObservation.paused.pending) !== null && _a !== void 0 ? _a : streamObserver.getIsPaused();
457
469
  onReloadOrder({ position, autoPlay: !isPaused });
458
470
  }
459
471
  else {
460
472
  const lastObservation = streamObserver.getReference().getValue();
461
- const position = (_c = lastObservation.position.pending) !== null && _c !== void 0 ? _c : streamObserver.getCurrentTime();
473
+ const position = lastObservation.position.isAwaitingFuturePosition() ?
474
+ lastObservation.position.getWanted() :
475
+ streamObserver.getCurrentTime();
462
476
  // simple seek close to the current position
463
477
  // to flush the buffers
464
478
  if (position + 0.001 < lastObservation.duration) {
@@ -512,9 +526,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
512
526
  contentTimeBoundariesObserver.addEventListener("periodChange", (period) => {
513
527
  this.trigger("activePeriodChanged", { period });
514
528
  });
515
- contentTimeBoundariesObserver.addEventListener("durationUpdate", (newDuration) => {
516
- mediaSourceDurationUpdater.updateDuration(newDuration.duration, newDuration.isEnd);
517
- });
529
+ contentTimeBoundariesObserver.addEventListener("endingPositionChange", (x) => mediaSourceDurationUpdater.updateDuration(x.endingPosition, x.isEnd));
518
530
  contentTimeBoundariesObserver.addEventListener("endOfStream", () => {
519
531
  if (endOfStreamCanceller === null) {
520
532
  endOfStreamCanceller = new TaskCanceller();
@@ -530,8 +542,8 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
530
542
  endOfStreamCanceller = null;
531
543
  }
532
544
  });
533
- const currentDuration = contentTimeBoundariesObserver.getCurrentDuration();
534
- mediaSourceDurationUpdater.updateDuration(currentDuration.duration, currentDuration.isEnd);
545
+ const endInfo = contentTimeBoundariesObserver.getCurrentEndingTime();
546
+ mediaSourceDurationUpdater.updateDuration(endInfo.endingPosition, endInfo.isEnd);
535
547
  return contentTimeBoundariesObserver;
536
548
  }
537
549
  /**
@@ -22,8 +22,8 @@ import { IStreamOrchestratorPlaybackObservation } from "../../stream";
22
22
  /**
23
23
  * Observes what's being played and take care of media events relating to time
24
24
  * boundaries:
25
- * - Emits a `durationUpdate` when the duration of the current content is
26
- * known and every time it changes.
25
+ * - Emits a `endingPositionChange` when the known maximum playable position
26
+ * of the current content is known and every time it changes.
27
27
  * - Emits `endOfStream` API once segments have been pushed until the end and
28
28
  * `resumeStream` if downloads starts back.
29
29
  * - Emits a `periodChange` event when the currently-playing Period seemed to
@@ -56,10 +56,11 @@ export default class ContentTimeBoundariesObserver extends EventEmitter<IContent
56
56
  */
57
57
  constructor(manifest: Manifest, playbackObserver: IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation>, bufferTypes: IBufferType[]);
58
58
  /**
59
- * Returns an estimate of the current duration of the content.
59
+ * Returns an estimate of the current last position which may be played in
60
+ * the content at the moment.
60
61
  * @returns {Object}
61
62
  */
62
- getCurrentDuration(): IDurationItem;
63
+ getCurrentEndingTime(): IEndingPositionInformation;
63
64
  /**
64
65
  * Method to call any time an Adaptation has been selected.
65
66
  *
@@ -126,20 +127,20 @@ export default class ContentTimeBoundariesObserver extends EventEmitter<IContent
126
127
  private _addActivelyLoadedPeriod;
127
128
  private _removeActivelyLoadedPeriod;
128
129
  private _checkCurrentPeriod;
129
- private _getManifestDuration;
130
+ private _getManifestEndTime;
130
131
  private _lazilyCreateActiveStreamInfo;
131
132
  private _checkEndOfStream;
132
133
  }
133
- export interface IDurationItem {
134
+ export interface IEndingPositionInformation {
134
135
  /**
135
136
  * The new maximum known position (note that this is the ending position
136
137
  * currently known of the current content, it might be superior to the last
137
138
  * position at which segments are available and it might also evolve over
138
139
  * time), in seconds.
139
140
  */
140
- duration: number;
141
+ endingPosition: number;
141
142
  /**
142
- * If `true`, the communicated `duration` is the actual end of the content.
143
+ * If `true`, the communicated `endingPosition` is the actual end of the content.
143
144
  * It may still be updated due to a track change or to add precision, but it
144
145
  * is still a (rough) estimate of the maximum position that content should
145
146
  * have.
@@ -147,7 +148,7 @@ export interface IDurationItem {
147
148
  * If `false`, this is the currently known maximum position associated to
148
149
  * the content, but the content is still evolving (typically, new media
149
150
  * segments are still being generated) and as such it can still have a
150
- * longer duration in the future.
151
+ * longer `endingPosition` in the future.
151
152
  */
152
153
  isEnd: boolean;
153
154
  }
@@ -161,10 +162,10 @@ export interface IContentTimeBoundariesObserverEvent {
161
162
  /** Triggered when a new `Period` is currently playing. */
162
163
  periodChange: Period;
163
164
  /**
164
- * Triggered when the duration of the currently-playing content became known
165
- * or changed.
165
+ * Triggered when the ending position of the currently-playing content became
166
+ * known or changed.
166
167
  */
167
- durationUpdate: IDurationItem;
168
+ endingPositionChange: IEndingPositionInformation;
168
169
  /**
169
170
  * Triggered when the last possible chronological segment for all types of
170
171
  * buffers has either been pushed or is being pushed to the corresponding
@@ -21,8 +21,8 @@ import TaskCanceller from "../../../utils/task_canceller";
21
21
  /**
22
22
  * Observes what's being played and take care of media events relating to time
23
23
  * boundaries:
24
- * - Emits a `durationUpdate` when the duration of the current content is
25
- * known and every time it changes.
24
+ * - Emits a `endingPositionChange` when the known maximum playable position
25
+ * of the current content is known and every time it changes.
26
26
  * - Emits `endOfStream` API once segments have been pushed until the end and
27
27
  * `resumeStream` if downloads starts back.
28
28
  * - Emits a `periodChange` event when the currently-playing Period seemed to
@@ -51,8 +51,7 @@ export default class ContentTimeBoundariesObserver extends EventEmitter {
51
51
  this._maximumPositionCalculator = maximumPositionCalculator;
52
52
  const cancelSignal = this._canceller.signal;
53
53
  playbackObserver.listen(({ position }) => {
54
- var _a;
55
- const wantedPosition = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
54
+ const wantedPosition = position.getWanted();
56
55
  if (wantedPosition < manifest.getMinimumSafePosition()) {
57
56
  const warning = new MediaError("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " +
58
57
  "earliest time announced in the Manifest.");
@@ -65,7 +64,7 @@ export default class ContentTimeBoundariesObserver extends EventEmitter {
65
64
  }
66
65
  }, { includeLastObservation: true, clearSignal: cancelSignal });
67
66
  manifest.addEventListener("manifestUpdate", () => {
68
- this.trigger("durationUpdate", this._getManifestDuration());
67
+ this.trigger("endingPositionChange", this._getManifestEndTime());
69
68
  if (cancelSignal.isCancelled()) {
70
69
  return;
71
70
  }
@@ -73,11 +72,12 @@ export default class ContentTimeBoundariesObserver extends EventEmitter {
73
72
  }, cancelSignal);
74
73
  }
75
74
  /**
76
- * Returns an estimate of the current duration of the content.
75
+ * Returns an estimate of the current last position which may be played in
76
+ * the content at the moment.
77
77
  * @returns {Object}
78
78
  */
79
- getCurrentDuration() {
80
- return this._getManifestDuration();
79
+ getCurrentEndingTime() {
80
+ return this._getManifestEndTime();
81
81
  }
82
82
  /**
83
83
  * Method to call any time an Adaptation has been selected.
@@ -106,12 +106,13 @@ export default class ContentTimeBoundariesObserver extends EventEmitter {
106
106
  .updateLastVideoAdaptation(adaptation);
107
107
  }
108
108
  const endingPosition = this._maximumPositionCalculator.getEndingPosition();
109
- const newDuration = endingPosition !== undefined ?
109
+ const newEndingPosition = endingPosition !== undefined ?
110
110
  { isEnd: true,
111
- duration: endingPosition } :
111
+ endingPosition } :
112
112
  { isEnd: false,
113
- duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
114
- this.trigger("durationUpdate", newDuration);
113
+ endingPosition: this._maximumPositionCalculator
114
+ .getMaximumAvailablePosition() };
115
+ this.trigger("endingPositionChange", newEndingPosition);
115
116
  }
116
117
  }
117
118
  }
@@ -238,13 +239,13 @@ export default class ContentTimeBoundariesObserver extends EventEmitter {
238
239
  }
239
240
  }
240
241
  }
241
- _getManifestDuration() {
242
+ _getManifestEndTime() {
242
243
  const endingPosition = this._maximumPositionCalculator.getEndingPosition();
243
244
  return endingPosition !== undefined ?
244
245
  { isEnd: true,
245
- duration: endingPosition } :
246
+ endingPosition } :
246
247
  { isEnd: false,
247
- duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
248
+ endingPosition: this._maximumPositionCalculator.getMaximumAvailablePosition() };
248
249
  }
249
250
  _lazilyCreateActiveStreamInfo(bufferType) {
250
251
  let streamInfo = this._activeStreams.get(bufferType);
@@ -315,9 +316,8 @@ class MaximumPositionCalculator {
315
316
  * @returns {number}
316
317
  */
317
318
  getMaximumAvailablePosition() {
318
- var _a;
319
319
  if (this._manifest.isDynamic) {
320
- return (_a = this._manifest.getLivePosition()) !== null && _a !== void 0 ? _a : this._manifest.getMaximumSafePosition();
320
+ return this._manifest.getMaximumSafePosition();
321
321
  }
322
322
  if (this._lastVideoAdaptation === undefined ||
323
323
  this._lastAudioAdaptation === undefined) {
@@ -26,12 +26,8 @@ export interface IStreamPlaybackObserverArguments {
26
26
  manifest: Manifest;
27
27
  /** Becomes `true` after the initial play has been taken care of. */
28
28
  initialPlayPerformed: IReadOnlySharedReference<boolean>;
29
- /** Becomes `true` after the initial seek has been taken care of. */
30
- initialSeekPerformed: IReadOnlySharedReference<boolean>;
31
29
  /** The last speed requested by the user. */
32
30
  speed: IReadOnlySharedReference<number>;
33
- /** The time the player will seek when `initialSeekPerformed` becomes `true`. */
34
- startTime: number;
35
31
  }
36
32
  /**
37
33
  * Create PlaybackObserver for the `Stream` part of the code.
@@ -42,4 +38,4 @@ export interface IStreamPlaybackObserverArguments {
42
38
  * @param {Object} fnCancelSignal - Abort the created PlaybackObserver.
43
39
  * @returns {Object}
44
40
  */
45
- export default function createStreamPlaybackObserver(srcPlaybackObserver: PlaybackObserver, { autoPlay, initialPlayPerformed, initialSeekPerformed, manifest, speed, startTime }: IStreamPlaybackObserverArguments, fnCancelSignal: CancellationSignal): IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation>;
41
+ export default function createStreamPlaybackObserver(srcPlaybackObserver: PlaybackObserver, { autoPlay, initialPlayPerformed, manifest, speed }: IStreamPlaybackObserverArguments, fnCancelSignal: CancellationSignal): IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation>;
@@ -24,7 +24,7 @@ import TaskCanceller from "../../../utils/task_canceller";
24
24
  * @param {Object} fnCancelSignal - Abort the created PlaybackObserver.
25
25
  * @returns {Object}
26
26
  */
27
- export default function createStreamPlaybackObserver(srcPlaybackObserver, { autoPlay, initialPlayPerformed, initialSeekPerformed, manifest, speed, startTime }, fnCancelSignal) {
27
+ export default function createStreamPlaybackObserver(srcPlaybackObserver, { autoPlay, initialPlayPerformed, manifest, speed }, fnCancelSignal) {
28
28
  return srcPlaybackObserver.deriveReadOnlyObserver(function transform(observationRef, parentObserverCancelSignal) {
29
29
  const canceller = new TaskCanceller();
30
30
  canceller.linkToSignal(parentObserverCancelSignal);
@@ -42,11 +42,7 @@ export default function createStreamPlaybackObserver(srcPlaybackObserver, { auto
42
42
  function constructStreamPlaybackObservation() {
43
43
  const observation = observationRef.getValue();
44
44
  const lastSpeed = speed.getValue();
45
- let pendingPosition;
46
- if (!initialSeekPerformed.getValue()) {
47
- pendingPosition = startTime;
48
- }
49
- else if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
45
+ if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
50
46
  // HACK: When the position is actually further than the maximum
51
47
  // position for a finished content, we actually want to be loading
52
48
  // the last segment before ending.
@@ -54,19 +50,25 @@ export default function createStreamPlaybackObserver(srcPlaybackObserver, { auto
54
50
  // want to seek one second before the period's end (despite never
55
51
  // doing it).
56
52
  const lastPeriod = manifest.periods[manifest.periods.length - 1];
57
- if (lastPeriod !== undefined &&
58
- lastPeriod.end !== undefined &&
59
- observation.position > lastPeriod.end) {
60
- pendingPosition = lastPeriod.end - 1;
53
+ if (lastPeriod !== undefined && lastPeriod.end !== undefined) {
54
+ const wantedPosition = observation.position.getWanted();
55
+ if (wantedPosition >= lastPeriod.start &&
56
+ wantedPosition >= lastPeriod.end - 1) {
57
+ // We're after the end of the last Period, check if `buffered`
58
+ // indicates that the last segment is probably not loaded, in which
59
+ // case act as if we want to load one second before the end.
60
+ const buffered = observation.buffered;
61
+ if (buffered.length === 0 ||
62
+ buffered.end(buffered.length - 1) < observation.duration - 1) {
63
+ observation.position.forceWantedPosition(lastPeriod.end - 1);
64
+ }
65
+ }
61
66
  }
62
67
  }
63
68
  return {
64
69
  // TODO more exact according to the current Adaptation chosen?
65
70
  maximumPosition: manifest.getMaximumSafePosition(),
66
- position: {
67
- last: observation.position,
68
- pending: pendingPosition,
69
- },
71
+ position: observation.position,
70
72
  duration: observation.duration,
71
73
  paused: {
72
74
  last: observation.paused,
@@ -37,11 +37,25 @@ export interface IInitialTimeOptions {
37
37
  */
38
38
  fromFirstPosition?: number | null | undefined;
39
39
  /**
40
- * If set, we should begin at this position relative to the content's end,
41
- * in seconds.
40
+ * If set, we should begin at this position relative to the content's maximum
41
+ * seekable position, in seconds.
42
+ *
43
+ * It should consequently in most cases be a negative value.
42
44
  */
43
45
  fromLastPosition?: number | null | undefined;
44
- /** If set, we should begin at this position relative to the whole duration of
46
+ /**
47
+ * If set, we should begin at this position relative to the content's live
48
+ * edge if it makes sense, in seconds.
49
+ *
50
+ * It should consequently in most cases be a negative value.
51
+ *
52
+ * If the live edge is unknown or if it does not make sense for the current
53
+ * content, that position is relative to the content's maximum position
54
+ * instead.
55
+ */
56
+ fromLivePosition?: number | null | undefined;
57
+ /**
58
+ * If set, we should begin at this position relative to the whole duration of
45
59
  * the content, in percentage.
46
60
  */
47
61
  percentage?: number | null | undefined;
@@ -31,15 +31,10 @@ import getMonotonicTimeStamp from "../../../utils/monotonic_timestamp";
31
31
  * @returns {Number}
32
32
  */
33
33
  export default function getInitialTime(manifest, lowLatencyMode, startAt) {
34
+ var _a;
34
35
  if (!isNullOrUndefined(startAt)) {
35
36
  const min = manifest.getMinimumSafePosition();
36
- let max;
37
- if (manifest.isLive) {
38
- max = manifest.getLivePosition();
39
- }
40
- if (max === undefined) {
41
- max = manifest.getMaximumSafePosition();
42
- }
37
+ const max = manifest.getMaximumSafePosition();
43
38
  if (!isNullOrUndefined(startAt.position)) {
44
39
  log.debug("Init: using startAt.minimumPosition");
45
40
  return Math.max(Math.min(startAt.position, max), min);
@@ -64,6 +59,13 @@ export default function getInitialTime(manifest, lowLatencyMode, startAt) {
64
59
  return fromLastPosition >= 0 ? max :
65
60
  Math.max(min, max + fromLastPosition);
66
61
  }
62
+ else if (!isNullOrUndefined(startAt.fromLivePosition)) {
63
+ log.debug("Init: using startAt.fromLivePosition");
64
+ const livePosition = (_a = manifest.getLivePosition()) !== null && _a !== void 0 ? _a : max;
65
+ const { fromLivePosition } = startAt;
66
+ return fromLivePosition >= 0 ? livePosition :
67
+ Math.max(min, livePosition + fromLivePosition);
68
+ }
67
69
  else if (!isNullOrUndefined(startAt.percentage)) {
68
70
  log.debug("Init: using startAt.percentage");
69
71
  const { percentage } = startAt;
@@ -38,11 +38,6 @@ export type IInitialPlayEvent =
38
38
  export interface IInitialSeekAndPlayObject {
39
39
  /** Emit the result of the auto-play operation, once performed. */
40
40
  autoPlayResult: Promise<IInitialPlayEvent>;
41
- /**
42
- * Shared reference whose value becomes `true` once the initial seek has
43
- * been considered / has been done by `performInitialSeekAndPlay`.
44
- */
45
- initialSeekPerformed: IReadOnlySharedReference<boolean>;
46
41
  /**
47
42
  * Shared reference whose value becomes `true` once the initial play has
48
43
  * been considered / has been done by `performInitialSeekAndPlay`.
@@ -52,12 +47,15 @@ export interface IInitialSeekAndPlayObject {
52
47
  /**
53
48
  * Seek as soon as possible at the initially wanted position and play if
54
49
  * autoPlay is wanted.
55
- * @param {HTMLMediaElement} mediaElement
56
- * @param {Object} playbackObserver
57
- * @param {number|Function} startTime
58
- * @param {boolean} mustAutoPlay
59
- * @param {Function} onWarning
50
+ * @param {Object} args
60
51
  * @param {Object} cancelSignal
61
52
  * @returns {Object}
62
53
  */
63
- export default function performInitialSeekAndPlay(mediaElement: HTMLMediaElement, playbackObserver: PlaybackObserver, startTime: number | (() => number), mustAutoPlay: boolean, onWarning: (err: IPlayerError) => void, cancelSignal: CancellationSignal): IInitialSeekAndPlayObject;
54
+ export default function performInitialSeekAndPlay({ mediaElement, playbackObserver, startTime, mustAutoPlay, isDirectfile, onWarning }: {
55
+ mediaElement: HTMLMediaElement;
56
+ playbackObserver: PlaybackObserver;
57
+ startTime: number | (() => number);
58
+ mustAutoPlay: boolean;
59
+ isDirectfile: boolean;
60
+ onWarning: (err: IPlayerError) => void;
61
+ }, cancelSignal: CancellationSignal): IInitialSeekAndPlayObject;