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
@@ -26,6 +26,7 @@ var __assign = (this && this.__assign) || function () {
26
26
  return __assign.apply(this, arguments);
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.getLastRequestableSegmentInfo = exports.isSegmentStillAvailable = void 0;
29
30
  var config_1 = require("../../../../../../config");
30
31
  var errors_1 = require("../../../../../../errors");
31
32
  var log_1 = require("../../../../../../log");
@@ -33,7 +34,6 @@ var assert_1 = require("../../../../../../utils/assert");
33
34
  var monotonic_timestamp_1 = require("../../../../../../utils/monotonic_timestamp");
34
35
  var clear_timeline_from_position_1 = require("../../../../utils/clear_timeline_from_position");
35
36
  var index_helpers_1 = require("../../../../utils/index_helpers");
36
- var is_segment_still_available_1 = require("../../../../utils/is_segment_still_available");
37
37
  var update_segment_timeline_1 = require("../../../../utils/update_segment_timeline");
38
38
  var get_init_segment_1 = require("../get_init_segment");
39
39
  var get_segments_from_timeline_1 = require("../get_segments_from_timeline");
@@ -42,6 +42,11 @@ var utils_1 = require("../utils");
42
42
  var construct_timeline_from_elements_1 = require("./construct_timeline_from_elements");
43
43
  // eslint-disable-next-line max-len
44
44
  var construct_timeline_from_previous_timeline_1 = require("./construct_timeline_from_previous_timeline");
45
+ /**
46
+ * `IRepresentationIndex` implementation for a DASH `SegmentTimeline` segment
47
+ * indexing scheme.
48
+ * @class TimelineRepresentationIndex
49
+ */
45
50
  var TimelineRepresentationIndex = /** @class */ (function () {
46
51
  /**
47
52
  * @param {Object} index
@@ -53,7 +58,7 @@ var TimelineRepresentationIndex = /** @class */ (function () {
53
58
  throw new Error("The given index is not compatible with a " +
54
59
  "TimelineRepresentationIndex.");
55
60
  }
56
- var availabilityTimeComplete = context.availabilityTimeComplete, manifestBoundsCalculator = context.manifestBoundsCalculator, isDynamic = context.isDynamic, isLastPeriod = context.isLastPeriod, representationId = context.representationId, representationBitrate = context.representationBitrate, periodStart = context.periodStart, periodEnd = context.periodEnd, isEMSGWhitelisted = context.isEMSGWhitelisted;
61
+ var availabilityTimeComplete = context.availabilityTimeComplete, availabilityTimeOffset = context.availabilityTimeOffset, manifestBoundsCalculator = context.manifestBoundsCalculator, isDynamic = context.isDynamic, isLastPeriod = context.isLastPeriod, representationId = context.representationId, representationBitrate = context.representationBitrate, periodStart = context.periodStart, periodEnd = context.periodEnd, isEMSGWhitelisted = context.isEMSGWhitelisted;
57
62
  var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1;
58
63
  var presentationTimeOffset = index.presentationTimeOffset != null ?
59
64
  index.presentationTimeOffset :
@@ -84,7 +89,27 @@ var TimelineRepresentationIndex = /** @class */ (function () {
84
89
  var segmentUrlTemplate = index.media === undefined ?
85
90
  null :
86
91
  (0, tokens_1.constructRepresentationUrl)(index.media, representationId, representationBitrate);
87
- this._index = { availabilityTimeComplete: availabilityTimeComplete, indexRange: index.indexRange, indexTimeOffset: indexTimeOffset, initialization: index.initialization == null ?
92
+ var actualAvailabilityTimeOffset;
93
+ // Technically, it seems (although it is not clear) that an MPD may contain
94
+ // future segments and it's the job of a player to not request segments later
95
+ // than the time at which they should be available.
96
+ // In practice, we don't do that for various reasons: precision issues,
97
+ // various DASH spec interpretations by packagers and players...
98
+ //
99
+ // So as a compromise, if nothing in the MPD indicates that future segments
100
+ // may be announced (see code below), we will act as if ALL segments in this
101
+ // TimelineRepresentationIndex are requestable
102
+ if (availabilityTimeOffset === undefined &&
103
+ availabilityTimeComplete === undefined) {
104
+ actualAvailabilityTimeOffset = Infinity; // Meaning: we can request
105
+ // everything in the index
106
+ }
107
+ else {
108
+ actualAvailabilityTimeOffset = availabilityTimeOffset !== null && availabilityTimeOffset !== void 0 ? availabilityTimeOffset : 0;
109
+ }
110
+ this._index = { availabilityTimeComplete: availabilityTimeComplete !== null && availabilityTimeComplete !== void 0 ? availabilityTimeComplete : true,
111
+ availabilityTimeOffset: actualAvailabilityTimeOffset,
112
+ indexRange: index.indexRange, indexTimeOffset: indexTimeOffset, initialization: index.initialization == null ?
88
113
  undefined :
89
114
  {
90
115
  url: initializationUrl,
@@ -118,7 +143,7 @@ var TimelineRepresentationIndex = /** @class */ (function () {
118
143
  }
119
144
  // destructuring to please TypeScript
120
145
  var _a = this._index, segmentUrlTemplate = _a.segmentUrlTemplate, startNumber = _a.startNumber, endNumber = _a.endNumber, timeline = _a.timeline, timescale = _a.timescale, indexTimeOffset = _a.indexTimeOffset;
121
- return (0, get_segments_from_timeline_1.default)({ segmentUrlTemplate: segmentUrlTemplate, startNumber: startNumber, endNumber: endNumber, timeline: timeline, timescale: timescale, indexTimeOffset: indexTimeOffset }, from, duration, this._isEMSGWhitelisted, this._scaledPeriodEnd);
146
+ return (0, get_segments_from_timeline_1.default)({ segmentUrlTemplate: segmentUrlTemplate, startNumber: startNumber, endNumber: endNumber, timeline: timeline, timescale: timescale, indexTimeOffset: indexTimeOffset }, from, duration, this._manifestBoundsCalculator, this._scaledPeriodEnd, this._isEMSGWhitelisted);
122
147
  };
123
148
  /**
124
149
  * Returns true if the index should be refreshed.
@@ -151,13 +176,19 @@ var TimelineRepresentationIndex = /** @class */ (function () {
151
176
  * @returns {Number|null}
152
177
  */
153
178
  TimelineRepresentationIndex.prototype.getLastAvailablePosition = function () {
179
+ var _a;
154
180
  this._refreshTimeline();
155
181
  if (this._index.timeline === null) {
156
182
  this._index.timeline = this._getTimeline();
157
183
  }
158
- var lastTime = TimelineRepresentationIndex.getIndexEnd(this._index.timeline, this._scaledPeriodEnd);
159
- return lastTime === null ? null :
160
- (0, index_helpers_1.fromIndexTime)(lastTime, this._index);
184
+ var lastReqSegInfo = getLastRequestableSegmentInfo(
185
+ // Needed typecast for TypeScript
186
+ this._index, this._manifestBoundsCalculator, this._scaledPeriodEnd);
187
+ if (lastReqSegInfo === null) {
188
+ return null;
189
+ }
190
+ var lastScaledPosition = Math.min(lastReqSegInfo.end, (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
191
+ return (0, index_helpers_1.fromIndexTime)(lastScaledPosition, this._index);
161
192
  };
162
193
  /**
163
194
  * Returns the absolute end in seconds this RepresentationIndex can reach once
@@ -165,10 +196,20 @@ var TimelineRepresentationIndex = /** @class */ (function () {
165
196
  * @returns {number|null|undefined}
166
197
  */
167
198
  TimelineRepresentationIndex.prototype.getEnd = function () {
168
- if (!this._isDynamic || !this._isLastPeriod) { // @see isFinished
169
- return this.getLastAvailablePosition();
199
+ var _a;
200
+ if (this._isDynamic && !this._isLastPeriod) {
201
+ return undefined;
202
+ }
203
+ this._refreshTimeline();
204
+ if (this._index.timeline === null) {
205
+ this._index.timeline = this._getTimeline();
206
+ }
207
+ if (this._index.timeline.length <= 0) {
208
+ return null;
170
209
  }
171
- return undefined;
210
+ var lastSegment = this._index.timeline[this._index.timeline.length - 1];
211
+ var lastTime = Math.min((0, index_helpers_1.getIndexSegmentEnd)(lastSegment, null, this._scaledPeriodEnd), (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
212
+ return (0, index_helpers_1.fromIndexTime)(lastTime, this._index);
172
213
  };
173
214
  /**
174
215
  * Returns:
@@ -182,33 +223,54 @@ var TimelineRepresentationIndex = /** @class */ (function () {
182
223
  * @returns {boolean|undefined}
183
224
  */
184
225
  TimelineRepresentationIndex.prototype.awaitSegmentBetween = function (start, end) {
185
- var _a;
226
+ var _a, _b;
186
227
  (0, assert_1.default)(start <= end);
187
- if (!this._isDynamic || !this._isLastPeriod) {
188
- return false;
228
+ if (!this._isDynamic) {
229
+ return false; // No segment will be newly available in the future
189
230
  }
190
231
  this._refreshTimeline();
191
232
  if (this._index.timeline === null) {
192
233
  this._index.timeline = this._getTimeline();
193
234
  }
194
- var _b = this._index, timeline = _b.timeline, timescale = _b.timescale;
235
+ var _c = this._index, timescale = _c.timescale, timeline = _c.timeline;
195
236
  var segmentTimeRounding = (0, utils_1.getSegmentTimeRoundingError)(timescale);
196
- var scaledEnd = (0, index_helpers_1.toIndexTime)(end, this._index);
197
- if (timeline.length > 0) {
198
- var lastTimelineElement = timeline[timeline.length - 1];
199
- var lastSegmentEnd = (0, index_helpers_1.getIndexSegmentEnd)(lastTimelineElement, null, this._scaledPeriodEnd);
200
- var roundedEnd = lastSegmentEnd + segmentTimeRounding;
201
- if (roundedEnd >= Math.min(scaledEnd, (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity)) {
202
- return false; // already loaded
237
+ var scaledWantedEnd = (0, index_helpers_1.toIndexTime)(end, this._index);
238
+ var lastReqSegInfo = getLastRequestableSegmentInfo(
239
+ // Needed typecast for TypeScript
240
+ this._index, this._manifestBoundsCalculator, this._scaledPeriodEnd);
241
+ if (lastReqSegInfo !== null) {
242
+ var lastReqSegmentEnd = Math.min(lastReqSegInfo.end, (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
243
+ var roundedReqSegmentEnd = lastReqSegmentEnd + segmentTimeRounding;
244
+ if (roundedReqSegmentEnd >= Math.min(scaledWantedEnd, (_b = this._scaledPeriodEnd) !== null && _b !== void 0 ? _b : Infinity)) {
245
+ return false; // everything up to that point is already requestable
246
+ }
247
+ }
248
+ var scaledWantedStart = (0, index_helpers_1.toIndexTime)(start, this._index);
249
+ if (timeline.length > 0 &&
250
+ lastReqSegInfo !== null &&
251
+ !lastReqSegInfo.isLastOfTimeline) {
252
+ // There are some future segments already anounced in the MPD
253
+ var lastSegment = timeline[timeline.length - 1];
254
+ var lastSegmentEnd = (0, index_helpers_1.getIndexSegmentEnd)(lastSegment, null, this._scaledPeriodEnd);
255
+ var roundedLastSegEnd = lastSegmentEnd + segmentTimeRounding;
256
+ if (scaledWantedStart < roundedLastSegEnd + segmentTimeRounding) {
257
+ return true; // The MPD's timeline already contains one such element,
258
+ // It is just not requestable yet
203
259
  }
204
260
  }
261
+ if (!this._isLastPeriod) {
262
+ // Let's consider - perhaps wrongly, that Periods which aren't the last
263
+ // one have all of their segments announced.
264
+ return false;
265
+ }
205
266
  if (this._scaledPeriodEnd === undefined) {
206
- return (scaledEnd + segmentTimeRounding) > this._scaledPeriodStart ? undefined :
207
- false;
267
+ return (scaledWantedEnd + segmentTimeRounding) > this._scaledPeriodStart ?
268
+ undefined : // There may be future segments at this point
269
+ false; // Before the current Period
208
270
  }
209
- var scaledStart = (0, index_helpers_1.toIndexTime)(start, this._index);
210
- return (scaledStart - segmentTimeRounding) < this._scaledPeriodEnd &&
211
- (scaledEnd + segmentTimeRounding) > this._scaledPeriodStart;
271
+ // `true` if within the boundaries of this Period. `false` otherwise.
272
+ return (scaledWantedStart - segmentTimeRounding) < this._scaledPeriodEnd &&
273
+ (scaledWantedEnd + segmentTimeRounding) > this._scaledPeriodStart;
212
274
  };
213
275
  /**
214
276
  * Returns true if a Segment returned by this index is still considered
@@ -226,8 +288,9 @@ var TimelineRepresentationIndex = /** @class */ (function () {
226
288
  if (this._index.timeline === null) {
227
289
  this._index.timeline = this._getTimeline();
228
290
  }
229
- var _a = this._index, timeline = _a.timeline, timescale = _a.timescale, indexTimeOffset = _a.indexTimeOffset;
230
- return (0, is_segment_still_available_1.default)(segment, timeline, timescale, indexTimeOffset);
291
+ return isSegmentStillAvailable(segment,
292
+ // Needed typecast for TypeScript
293
+ this._index, this._manifestBoundsCalculator, this._scaledPeriodEnd);
231
294
  };
232
295
  /**
233
296
  * Checks if the time given is in a discontinuity. That is:
@@ -289,6 +352,8 @@ var TimelineRepresentationIndex = /** @class */ (function () {
289
352
  if (hasReplaced) {
290
353
  this._index.startNumber = newIndex._index.startNumber;
291
354
  }
355
+ this._index.availabilityTimeOffset = newIndex._index.availabilityTimeOffset;
356
+ this._index.availabilityTimeComplete = newIndex._index.availabilityTimeComplete;
292
357
  this._index.endNumber = newIndex._index.endNumber;
293
358
  this._isDynamic = newIndex._isDynamic;
294
359
  this._scaledPeriodStart = newIndex._scaledPeriodStart;
@@ -297,32 +362,67 @@ var TimelineRepresentationIndex = /** @class */ (function () {
297
362
  this._isLastPeriod = newIndex._isLastPeriod;
298
363
  };
299
364
  /**
300
- * Returns `true` if this RepresentationIndex currently contains its last
365
+ * Returns `false` if this RepresentationIndex currently contains its last
301
366
  * segment.
302
- * Returns `false` if it's still pending.
367
+ * Returns `true` if it's still pending.
303
368
  * @returns {Boolean}
304
369
  */
305
- TimelineRepresentationIndex.prototype.isFinished = function () {
306
- if (!this._isDynamic || !this._isLastPeriod) {
307
- // Either the content is not dynamic, in which case no new segment will
308
- // be generated, either it is but this index is not linked to the current
309
- // last Period in the MPD, in which case it is inferred that it has been
310
- // completely generated. Note that this second condition might break very
311
- // very rare use cases where old Periods are still being generated, yet it
312
- // should fix more cases than it breaks.
313
- return true;
370
+ TimelineRepresentationIndex.prototype.isStillAwaitingFutureSegments = function () {
371
+ var _a;
372
+ if (!this._isDynamic) {
373
+ return false;
314
374
  }
375
+ this._refreshTimeline();
315
376
  if (this._index.timeline === null) {
316
377
  this._index.timeline = this._getTimeline();
317
378
  }
318
379
  var timeline = this._index.timeline;
319
- if (this._scaledPeriodEnd === undefined || timeline.length === 0) {
320
- return false;
380
+ if (timeline.length === 0) {
381
+ // No segment announced in this Period
382
+ if (this._scaledPeriodEnd !== undefined) {
383
+ var liveEdge = this._manifestBoundsCalculator.getEstimatedLiveEdge();
384
+ if (liveEdge !== undefined &&
385
+ (0, index_helpers_1.toIndexTime)(liveEdge, this._index) > this._scaledPeriodEnd) {
386
+ // This Period is over, we're not awaiting anything
387
+ return false;
388
+ }
389
+ }
390
+ // Let's just consider that we're awaiting only for when this is the last Period.
391
+ return this._isLastPeriod;
321
392
  }
322
- var lastTimelineElement = timeline[timeline.length - 1];
323
- var lastTime = (0, index_helpers_1.getIndexSegmentEnd)(lastTimelineElement, null, this._scaledPeriodEnd);
324
393
  var segmentTimeRounding = (0, utils_1.getSegmentTimeRoundingError)(this._index.timescale);
325
- return (lastTime + segmentTimeRounding) >= this._scaledPeriodEnd;
394
+ var lastReqSegInfo = getLastRequestableSegmentInfo(
395
+ // Needed typecast for TypeScript
396
+ this._index, this._manifestBoundsCalculator, this._scaledPeriodEnd);
397
+ if (lastReqSegInfo !== null && !lastReqSegInfo.isLastOfTimeline) {
398
+ // There might be non-yet requestable segments in the manifest
399
+ var lastReqSegmentEnd = Math.min(lastReqSegInfo.end, (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
400
+ if (this._scaledPeriodEnd !== undefined &&
401
+ lastReqSegmentEnd + segmentTimeRounding >= this._scaledPeriodEnd) {
402
+ // The last requestable segment ends after the end of the Period anyway
403
+ return false;
404
+ }
405
+ return true; // There are not-yet requestable segments
406
+ }
407
+ if (!this._isLastPeriod) {
408
+ // This index is not linked to the current last Period in the MPD, in
409
+ // which case it is inferred that all segments have been announced.
410
+ //
411
+ // Note that this condition might break very very rare use cases where old
412
+ // Periods are still being generated, yet it should fix more cases than it
413
+ // breaks.
414
+ return false;
415
+ }
416
+ if (this._scaledPeriodEnd === undefined) {
417
+ // This is the last Period of a dynamic content whose end is unknown.
418
+ // Just return true.
419
+ return true;
420
+ }
421
+ var lastSegment = timeline[timeline.length - 1];
422
+ var lastSegmentEnd = (0, index_helpers_1.getIndexSegmentEnd)(lastSegment, null, this._scaledPeriodEnd);
423
+ // We're awaiting future segments only if the current end is before the end
424
+ // of the Period
425
+ return (lastSegmentEnd + segmentTimeRounding) < this._scaledPeriodEnd;
326
426
  };
327
427
  /**
328
428
  * @returns {Boolean}
@@ -357,7 +457,8 @@ var TimelineRepresentationIndex = /** @class */ (function () {
357
457
  if (!this._isDynamic) {
358
458
  return;
359
459
  }
360
- var firstPosition = this._manifestBoundsCalculator.estimateMinimumBound();
460
+ var firstPosition = this._manifestBoundsCalculator
461
+ .getEstimatedMinimumSegmentTime();
361
462
  if (firstPosition == null) {
362
463
  return; // we don't know yet
363
464
  }
@@ -370,12 +471,6 @@ var TimelineRepresentationIndex = /** @class */ (function () {
370
471
  this._index.startNumber = nbEltsRemoved + 1;
371
472
  }
372
473
  };
373
- TimelineRepresentationIndex.getIndexEnd = function (timeline, scaledPeriodEnd) {
374
- if (timeline.length <= 0) {
375
- return null;
376
- }
377
- return Math.min((0, index_helpers_1.getIndexSegmentEnd)(timeline[timeline.length - 1], null, scaledPeriodEnd), scaledPeriodEnd !== null && scaledPeriodEnd !== void 0 ? scaledPeriodEnd : Infinity);
378
- };
379
474
  /**
380
475
  * Allows to generate the "timeline" for this RepresentationIndex.
381
476
  * Call this function when the timeline is unknown.
@@ -465,3 +560,107 @@ function updateTimelineFromEndNumber(timeline, startNumber, endNumber) {
465
560
  }
466
561
  return timeline;
467
562
  }
563
+ /**
564
+ * Returns true if a Segment returned by the corresponding index is still
565
+ * considered available.
566
+ * Returns false if it is not available anymore.
567
+ * Returns undefined if we cannot know whether it is still available or not.
568
+ * /!\ We do not check the mediaURLs of the segment.
569
+ * @param {Object} segment
570
+ * @param {Object} index
571
+ * @param {Object} manifestBoundsCalculator
572
+ * @param {number|undefined} scaledPeriodEnd
573
+ * @returns {Boolean|undefined}
574
+ */
575
+ function isSegmentStillAvailable(segment, index, manifestBoundsCalculator, scaledPeriodEnd) {
576
+ var lastReqSegInfo = getLastRequestableSegmentInfo(index, manifestBoundsCalculator, scaledPeriodEnd);
577
+ if (lastReqSegInfo === null) {
578
+ return false;
579
+ }
580
+ for (var i = 0; i < index.timeline.length; i++) {
581
+ if (lastReqSegInfo.timelineIdx < i) {
582
+ return false;
583
+ }
584
+ var tSegment = index.timeline[i];
585
+ var tSegmentTime = (tSegment.start - index.indexTimeOffset) / index.timescale;
586
+ if (tSegmentTime > segment.time) {
587
+ return false; // We went over it without finding it
588
+ }
589
+ else if (tSegmentTime === segment.time) {
590
+ if (tSegment.range === undefined) {
591
+ return segment.range === undefined;
592
+ }
593
+ return segment.range != null &&
594
+ tSegment.range[0] === segment.range[0] &&
595
+ tSegment.range[1] === segment.range[1];
596
+ }
597
+ else { // tSegment.start < segment.time
598
+ if (tSegment.repeatCount >= 0 && tSegment.duration !== undefined) {
599
+ var timeDiff = tSegmentTime - tSegment.start;
600
+ var repeat = (timeDiff / tSegment.duration) - 1;
601
+ return repeat % 1 === 0 && repeat <= lastReqSegInfo.newRepeatCount;
602
+ }
603
+ }
604
+ }
605
+ return false;
606
+ }
607
+ exports.isSegmentStillAvailable = isSegmentStillAvailable;
608
+ /**
609
+ * Returns from the given RepresentationIndex information on the last segment
610
+ * that may be requested currently.
611
+ *
612
+ * Returns `null` if there's no such segment.
613
+ * @param {Object} index
614
+ * @param {Object} manifestBoundsCalculator
615
+ * @param {number|undefined} scaledPeriodEnd
616
+ * @returns {number|null}
617
+ */
618
+ function getLastRequestableSegmentInfo(index, manifestBoundsCalculator, scaledPeriodEnd) {
619
+ if (index.timeline.length <= 0) {
620
+ return null;
621
+ }
622
+ if (index.availabilityTimeOffset === Infinity) {
623
+ // availabilityTimeOffset to Infinity == Everything is requestable in the timeline.
624
+ var lastIndex = index.timeline.length - 1;
625
+ var lastElem = index.timeline[lastIndex];
626
+ return { isLastOfTimeline: true,
627
+ timelineIdx: lastIndex,
628
+ newRepeatCount: lastElem.repeatCount,
629
+ end: (0, index_helpers_1.getIndexSegmentEnd)(lastElem, null, scaledPeriodEnd) };
630
+ }
631
+ var adjustedMaxSeconds = manifestBoundsCalculator.getEstimatedMaximumPosition(index.availabilityTimeOffset);
632
+ if (adjustedMaxSeconds === undefined) {
633
+ var lastIndex = index.timeline.length - 1;
634
+ var lastElem = index.timeline[lastIndex];
635
+ return { isLastOfTimeline: true,
636
+ timelineIdx: lastIndex,
637
+ newRepeatCount: lastElem.repeatCount,
638
+ end: (0, index_helpers_1.getIndexSegmentEnd)(lastElem, null, scaledPeriodEnd) };
639
+ }
640
+ for (var i = index.timeline.length - 1; i >= index.timeline.length; i--) {
641
+ var element = index.timeline[i];
642
+ var endOfFirstOccurence = element.start + element.duration;
643
+ if ((0, index_helpers_1.fromIndexTime)(endOfFirstOccurence, index) <= adjustedMaxSeconds) {
644
+ var endTime = (0, index_helpers_1.getIndexSegmentEnd)(element, index.timeline[i + 1], scaledPeriodEnd);
645
+ if ((0, index_helpers_1.fromIndexTime)(endTime, index) <= adjustedMaxSeconds) {
646
+ return { isLastOfTimeline: i === index.timeline.length - 1,
647
+ timelineIdx: i,
648
+ newRepeatCount: element.repeatCount,
649
+ end: endOfFirstOccurence };
650
+ }
651
+ else {
652
+ // We have to find the right repeatCount
653
+ var maxIndexTime = (0, index_helpers_1.toIndexTime)(adjustedMaxSeconds, index);
654
+ var diffToSegStart = maxIndexTime - element.start;
655
+ var nbOfSegs = Math.floor(diffToSegStart / element.duration);
656
+ (0, assert_1.default)(nbOfSegs >= 1);
657
+ return { isLastOfTimeline: false,
658
+ timelineIdx: i,
659
+ newRepeatCount: nbOfSegs - 1,
660
+ end: element.start + nbOfSegs * element.duration };
661
+ }
662
+ }
663
+ }
664
+ return null;
665
+ }
666
+ exports.getLastRequestableSegmentInfo = getLastRequestableSegmentInfo;
@@ -17,16 +17,6 @@
17
17
  * This class allows to easily calculate the first and last available positions
18
18
  * in a content at any time.
19
19
  *
20
- * That task can be an hard for dynamic DASH contents: it depends on a
21
- * `timeShiftBufferDepth` defined in the MPD and on the maximum possible
22
- * position.
23
- *
24
- * The latter can come from either a clock synchronization mechanism or the
25
- * indexing schemes (e.g. SegmentTemplate, SegmentTimeline etc.) of the last
26
- * Periods.
27
- * As such, it might only be known once a large chunk of the MPD has already
28
- * been parsed.
29
- *
30
20
  * By centralizing the manifest bounds calculation in this class and by giving
31
21
  * an instance of it to each parsed elements which might depend on it, we
32
22
  * ensure that we can provide it once it is known to every one of those
@@ -34,8 +24,18 @@
34
24
  * @class ManifestBoundsCalculator
35
25
  */
36
26
  export default class ManifestBoundsCalculator {
37
- /** Value of MPD@timeShiftBufferDepth. */
27
+ /**
28
+ * Value of MPD@timeShiftBufferDepth.
29
+ * `null` if not defined.
30
+ */
38
31
  private _timeShiftBufferDepth;
32
+ /**
33
+ * Value of MPD@availabilityStartTime as an unix timestamp in seconds.
34
+ * `0` if it wasn't defined.
35
+ */
36
+ private _availabilityStartTime;
37
+ /** `true` if MPD@type is equal to "dynamic". */
38
+ private _isDynamic;
39
39
  /**
40
40
  * Monotonically-raising timestamp (the one used by the RxPlayer) when
41
41
  * `lastPosition` was calculated.
@@ -43,14 +43,21 @@ export default class ManifestBoundsCalculator {
43
43
  private _positionTime;
44
44
  /** Last position calculated at a given moment (itself indicated by `_positionTime`. */
45
45
  private _lastPosition;
46
- /** `true` if MPD@type is equal to "dynamic". */
47
- private _isDynamic;
46
+ /**
47
+ * Offset to add to `performance.now` to obtain a good estimation of the
48
+ * server-side unix timestamp.
49
+ *
50
+ * `undefined` if unknown.
51
+ */
52
+ private _serverTimestampOffset;
48
53
  /**
49
54
  * @param {Object} args
50
55
  */
51
56
  constructor(args: {
57
+ availabilityStartTime: number;
52
58
  timeShiftBufferDepth: number | undefined;
53
59
  isDynamic: boolean;
60
+ serverTimestampOffset: number | undefined;
54
61
  });
55
62
  /**
56
63
  * Set the last position and the position time (the value of the RxPlayer's
@@ -82,11 +89,27 @@ export default class ManifestBoundsCalculator {
82
89
  * Consider that it is only an estimation, not the real value.
83
90
  * @return {number|undefined}
84
91
  */
85
- estimateMinimumBound(): number | undefined;
92
+ getEstimatedMinimumSegmentTime(): number | undefined;
86
93
  /**
87
- * Estimate a maximum bound for the content from the last set segment time.
88
- * Consider that it is only an estimation, not the real value.
94
+ * Estimate the segment time in seconds that corresponds to what could be
95
+ * considered the live edge (or `undefined` for non-live contents).
96
+ *
97
+ * Note that for some contents which just anounce segments in advance, this
98
+ * value might be very different than the maximum position that is
99
+ * requestable.
89
100
  * @return {number|undefined}
90
101
  */
91
- estimateMaximumBound(): number | undefined;
102
+ getEstimatedLiveEdge(): number | undefined;
103
+ /**
104
+ * Produce a rough estimate of the ending time of the last requestable segment
105
+ * in that content.
106
+ *
107
+ * This value is only an estimate and may be far from reality.
108
+ *
109
+ * The `availabilityTimeOffset` in argument is the corresponding
110
+ * `availabilityTimeOffset` that applies to the current wanted segment, or `0`
111
+ * if none exist. It will be applied on live content to deduce the maximum
112
+ * segment time available.
113
+ */
114
+ getEstimatedMaximumPosition(availabilityTimeOffset: number): number | undefined;
92
115
  }
@@ -20,16 +20,6 @@ var monotonic_timestamp_1 = require("../../../../utils/monotonic_timestamp");
20
20
  * This class allows to easily calculate the first and last available positions
21
21
  * in a content at any time.
22
22
  *
23
- * That task can be an hard for dynamic DASH contents: it depends on a
24
- * `timeShiftBufferDepth` defined in the MPD and on the maximum possible
25
- * position.
26
- *
27
- * The latter can come from either a clock synchronization mechanism or the
28
- * indexing schemes (e.g. SegmentTemplate, SegmentTimeline etc.) of the last
29
- * Periods.
30
- * As such, it might only be known once a large chunk of the MPD has already
31
- * been parsed.
32
- *
33
23
  * By centralizing the manifest bounds calculation in this class and by giving
34
24
  * an instance of it to each parsed elements which might depend on it, we
35
25
  * ensure that we can provide it once it is known to every one of those
@@ -46,6 +36,8 @@ var ManifestBoundsCalculator = /** @class */ (function () {
46
36
  args.timeShiftBufferDepth === undefined ?
47
37
  null :
48
38
  args.timeShiftBufferDepth;
39
+ this._serverTimestampOffset = args.serverTimestampOffset;
40
+ this._availabilityStartTime = args.availabilityStartTime;
49
41
  }
50
42
  /**
51
43
  * Set the last position and the position time (the value of the RxPlayer's
@@ -85,11 +77,12 @@ var ManifestBoundsCalculator = /** @class */ (function () {
85
77
  * Consider that it is only an estimation, not the real value.
86
78
  * @return {number|undefined}
87
79
  */
88
- ManifestBoundsCalculator.prototype.estimateMinimumBound = function () {
80
+ ManifestBoundsCalculator.prototype.getEstimatedMinimumSegmentTime = function () {
81
+ var _a;
89
82
  if (!this._isDynamic || this._timeShiftBufferDepth === null) {
90
83
  return 0;
91
84
  }
92
- var maximumBound = this.estimateMaximumBound();
85
+ var maximumBound = (_a = this.getEstimatedLiveEdge()) !== null && _a !== void 0 ? _a : this.getEstimatedMaximumPosition(0);
93
86
  if (maximumBound === undefined) {
94
87
  return undefined;
95
88
  }
@@ -97,14 +90,41 @@ var ManifestBoundsCalculator = /** @class */ (function () {
97
90
  return minimumBound;
98
91
  };
99
92
  /**
100
- * Estimate a maximum bound for the content from the last set segment time.
101
- * Consider that it is only an estimation, not the real value.
93
+ * Estimate the segment time in seconds that corresponds to what could be
94
+ * considered the live edge (or `undefined` for non-live contents).
95
+ *
96
+ * Note that for some contents which just anounce segments in advance, this
97
+ * value might be very different than the maximum position that is
98
+ * requestable.
102
99
  * @return {number|undefined}
103
100
  */
104
- ManifestBoundsCalculator.prototype.estimateMaximumBound = function () {
105
- if (this._isDynamic &&
106
- this._positionTime != null &&
107
- this._lastPosition != null) {
101
+ ManifestBoundsCalculator.prototype.getEstimatedLiveEdge = function () {
102
+ if (!this._isDynamic || this._serverTimestampOffset === undefined) {
103
+ return undefined;
104
+ }
105
+ return ((0, monotonic_timestamp_1.default)() + this._serverTimestampOffset) / 1000 -
106
+ this._availabilityStartTime;
107
+ };
108
+ /**
109
+ * Produce a rough estimate of the ending time of the last requestable segment
110
+ * in that content.
111
+ *
112
+ * This value is only an estimate and may be far from reality.
113
+ *
114
+ * The `availabilityTimeOffset` in argument is the corresponding
115
+ * `availabilityTimeOffset` that applies to the current wanted segment, or `0`
116
+ * if none exist. It will be applied on live content to deduce the maximum
117
+ * segment time available.
118
+ */
119
+ ManifestBoundsCalculator.prototype.getEstimatedMaximumPosition = function (availabilityTimeOffset) {
120
+ if (!this._isDynamic) {
121
+ return this._lastPosition;
122
+ }
123
+ var liveEdge = this.getEstimatedLiveEdge();
124
+ if (liveEdge !== undefined && availabilityTimeOffset !== Infinity) {
125
+ return liveEdge + availabilityTimeOffset;
126
+ }
127
+ else if (this._positionTime !== undefined && this._lastPosition !== undefined) {
108
128
  return Math.max((this._lastPosition - this._positionTime) +
109
129
  ((0, monotonic_timestamp_1.default)() / 1000), 0);
110
130
  }