rx-player 4.0.0-beta.0 → 4.0.0-beta.2
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.
- package/.eslintrc.js +8 -0
- package/CHANGELOG.md +93 -0
- package/CONTRIBUTING.md +48 -168
- package/FILES.md +40 -92
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +25 -12
- package/dist/_esm5.processed/compat/browser_detection.js +85 -38
- package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
- package/dist/_esm5.processed/compat/eme/close_session.js +2 -2
- package/dist/_esm5.processed/compat/eme/load_session.js +1 -1
- package/dist/_esm5.processed/compat/event_listeners.js +1 -1
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
- package/dist/_esm5.processed/config.d.ts +4 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +9 -6
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +106 -25
- package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
- package/dist/_esm5.processed/core/adaptive/network_analyzer.js +8 -5
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
- package/dist/_esm5.processed/core/api/debug/buffer_graph.d.ts +28 -0
- package/dist/_esm5.processed/core/api/debug/buffer_graph.js +175 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.d.ts +10 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +104 -0
- package/dist/_esm5.processed/core/api/debug/constants.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/constants.js +2 -0
- package/dist/_esm5.processed/core/api/debug/index.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/index.js +2 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.js +180 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.d.ts +4 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +121 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +35 -0
- package/dist/_esm5.processed/core/api/debug/render.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/render.js +32 -0
- package/dist/_esm5.processed/core/api/debug/utils.d.ts +39 -0
- package/dist/_esm5.processed/core/api/debug/utils.js +57 -0
- package/dist/_esm5.processed/core/api/playback_observer.js +4 -2
- package/dist/_esm5.processed/core/api/public_api.d.ts +60 -3
- package/dist/_esm5.processed/core/api/public_api.js +280 -60
- package/dist/_esm5.processed/core/api/track_management/media_element_tracks_store.js +10 -1
- package/dist/_esm5.processed/core/api/track_management/track_dispatcher.d.ts +13 -1
- package/dist/_esm5.processed/core/api/track_management/track_dispatcher.js +30 -15
- package/dist/_esm5.processed/core/api/track_management/tracks_store.d.ts +3 -1
- package/dist/_esm5.processed/core/api/track_management/tracks_store.js +67 -152
- package/dist/_esm5.processed/core/api/utils.d.ts +10 -0
- package/dist/_esm5.processed/core/api/utils.js +23 -3
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +27 -8
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
- package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +1 -1
- package/dist/_esm5.processed/core/decrypt/content_decryptor.js +1 -1
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +29 -6
- package/dist/_esm5.processed/core/decrypt/session_events_listener.js +42 -32
- package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +4 -0
- package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +2 -0
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +5 -1
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +17 -8
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +10 -6
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +5 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +22 -5
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +37 -21
- package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +21 -23
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +17 -7
- package/dist/_esm5.processed/core/init/directfile_content_initializer.js +2 -2
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +74 -41
- package/dist/_esm5.processed/core/init/types.d.ts +9 -1
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.d.ts +28 -1
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +24 -11
- package/dist/_esm5.processed/core/init/utils/create_media_source.js +3 -12
- package/dist/_esm5.processed/core/init/utils/end_of_stream.js +6 -3
- package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +2 -1
- package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +9 -5
- package/dist/_esm5.processed/core/init/utils/initialize_content_decryption.js +2 -1
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +58 -0
- package/dist/_esm5.processed/core/init/utils/{media_duration_updater.js → media_source_duration_updater.js} +87 -86
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.d.ts +36 -2
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +83 -3
- package/dist/_esm5.processed/core/init/utils/stream_events_emitter/stream_events_emitter.js +6 -4
- package/dist/_esm5.processed/core/init/utils/throw_on_media_error.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -7
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +38 -50
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +8 -0
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +16 -2
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +8 -0
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +12 -0
- package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +11 -4
- package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +13 -9
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +30 -16
- package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.d.ts +47 -0
- package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +70 -0
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +41 -20
- package/dist/_esm5.processed/core/stream/period/period_stream.js +12 -11
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +37 -28
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +3 -3
- package/dist/_esm5.processed/core/stream/representation/utils/downloading_queue.js +16 -6
- package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.d.ts +3 -2
- package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +8 -8
- package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.js +2 -3
- package/dist/_esm5.processed/core/stream/utils/create_reload_request.js +1 -1
- package/dist/_esm5.processed/default_config.d.ts +41 -0
- package/dist/_esm5.processed/default_config.js +46 -2
- package/dist/_esm5.processed/errors/index.d.ts +2 -2
- package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
- package/dist/_esm5.processed/errors/media_error.js +18 -5
- package/dist/_esm5.processed/experimental/features/debug_element.d.ts +8 -0
- package/dist/_esm5.processed/experimental/features/debug_element.js +10 -0
- package/dist/_esm5.processed/experimental/features/index.d.ts +1 -0
- package/dist/_esm5.processed/experimental/features/index.js +1 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.d.ts +1 -1
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.js +8 -7
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +7 -4
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +24 -12
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/index.js +0 -2
- package/dist/_esm5.processed/features/features_object.js +1 -0
- package/dist/_esm5.processed/features/initialize_features.js +13 -10
- package/dist/_esm5.processed/features/types.d.ts +3 -0
- package/dist/_esm5.processed/manifest/adaptation.d.ts +21 -2
- package/dist/_esm5.processed/manifest/adaptation.js +80 -1
- package/dist/_esm5.processed/manifest/manifest.js +2 -0
- package/dist/_esm5.processed/manifest/period.js +2 -2
- package/dist/_esm5.processed/manifest/representation.d.ts +33 -2
- package/dist/_esm5.processed/manifest/representation.js +32 -4
- package/dist/_esm5.processed/manifest/utils.js +1 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +105 -137
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +25 -5
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
- package/dist/_esm5.processed/public_types.d.ts +13 -3
- package/dist/_esm5.processed/tools/TextTrackRenderer/text_track_renderer.js +1 -1
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +15 -11
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +2 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
- package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/local/segment_loader.js +13 -26
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
- package/dist/_esm5.processed/utils/cancellable_sleep.js +4 -10
- package/dist/_esm5.processed/utils/create_cancellable_promise.d.ts +26 -0
- package/dist/_esm5.processed/utils/create_cancellable_promise.js +52 -0
- package/dist/_esm5.processed/utils/is_null_or_undefined.d.ts +1 -1
- package/dist/_esm5.processed/utils/is_null_or_undefined.js +1 -1
- package/dist/_esm5.processed/utils/reference.js +6 -0
- package/dist/_esm5.processed/utils/request/xhr.js +1 -1
- package/dist/_esm5.processed/utils/task_canceller.d.ts +34 -15
- package/dist/_esm5.processed/utils/task_canceller.js +55 -22
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +5424 -4712
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +1 -5
- package/package.json +44 -40
- package/scripts/build/constants.d.ts +1 -0
- package/scripts/build/generate_build.js +1 -1
- package/scripts/fast_demo_build.js +40 -40
- package/scripts/generate_full_demo.js +1 -1
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +105 -52
- package/src/compat/can_reuse_media_keys.ts +5 -2
- package/src/compat/eme/close_session.ts +2 -2
- package/src/compat/eme/load_session.ts +1 -1
- package/src/compat/event_listeners.ts +1 -1
- package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
- package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
- package/src/core/adaptive/adaptive_representation_selector.ts +11 -6
- package/src/core/adaptive/buffer_based_chooser.ts +144 -26
- package/src/core/adaptive/guess_based_chooser.ts +9 -8
- package/src/core/adaptive/network_analyzer.ts +9 -4
- package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
- package/src/core/api/debug/buffer_graph.ts +247 -0
- package/src/core/api/debug/buffer_size_graph.ts +130 -0
- package/src/core/api/debug/constants.ts +2 -0
- package/src/core/api/debug/index.ts +3 -0
- package/src/core/api/debug/modules/general_info.ts +184 -0
- package/src/core/api/debug/modules/segment_buffer_content.ts +155 -0
- package/src/core/api/debug/modules/segment_buffer_size.ts +48 -0
- package/src/core/api/debug/render.ts +40 -0
- package/src/core/api/debug/utils.ts +103 -0
- package/src/core/api/playback_observer.ts +5 -2
- package/src/core/api/public_api.ts +334 -73
- package/src/core/api/track_management/media_element_tracks_store.ts +17 -8
- package/src/core/api/track_management/track_dispatcher.ts +37 -14
- package/src/core/api/track_management/tracks_store.ts +77 -167
- package/src/core/api/utils.ts +29 -3
- package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
- package/src/core/decrypt/attach_media_keys.ts +1 -1
- package/src/core/decrypt/content_decryptor.ts +1 -1
- package/src/core/decrypt/find_key_system.ts +25 -11
- package/src/core/decrypt/session_events_listener.ts +45 -39
- package/src/core/decrypt/utils/check_key_statuses.ts +6 -0
- package/src/core/decrypt/utils/clean_old_loaded_sessions.ts +2 -1
- package/src/core/decrypt/utils/loaded_sessions_store.ts +8 -1
- package/src/core/fetchers/cdn_prioritizer.ts +18 -9
- package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -4
- package/src/core/fetchers/segment/segment_fetcher.ts +36 -14
- package/src/core/fetchers/segment/task_prioritizer.ts +25 -30
- package/src/core/fetchers/utils/schedule_request.ts +18 -7
- package/src/core/init/directfile_content_initializer.ts +2 -1
- package/src/core/init/media_source_content_initializer.ts +89 -50
- package/src/core/init/types.ts +9 -1
- package/src/core/init/utils/content_time_boundaries_observer.ts +48 -12
- package/src/core/init/utils/create_media_source.ts +4 -16
- package/src/core/init/utils/end_of_stream.ts +6 -3
- package/src/core/init/utils/get_loaded_reference.ts +2 -1
- package/src/core/init/utils/initial_seek_and_play.ts +9 -5
- package/src/core/init/utils/initialize_content_decryption.ts +2 -1
- package/src/core/init/utils/{media_duration_updater.ts → media_source_duration_updater.ts} +103 -110
- package/src/core/init/utils/rebuffering_controller.ts +115 -4
- package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +6 -4
- package/src/core/init/utils/throw_on_media_error.ts +1 -1
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +63 -66
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +20 -2
- package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +16 -0
- package/src/core/segment_buffers/implementations/types.ts +16 -4
- package/src/core/segment_buffers/index.ts +2 -0
- package/src/core/segment_buffers/segment_buffers_store.ts +16 -13
- package/src/core/stream/adaptation/adaptation_stream.ts +33 -19
- package/src/core/stream/adaptation/utils/create_representation_estimator.ts +114 -0
- package/src/core/stream/orchestrator/stream_orchestrator.ts +42 -20
- package/src/core/stream/period/period_stream.ts +13 -11
- package/src/core/stream/representation/representation_stream.ts +49 -37
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +9 -4
- package/src/core/stream/representation/utils/downloading_queue.ts +16 -4
- package/src/core/stream/representation/utils/push_init_segment.ts +11 -6
- package/src/core/stream/representation/utils/push_media_segment.ts +3 -3
- package/src/core/stream/utils/create_reload_request.ts +1 -1
- package/src/default_config.ts +59 -11
- package/src/errors/__tests__/media_error.test.ts +6 -6
- package/src/errors/index.ts +4 -1
- package/src/errors/media_error.ts +67 -1
- package/src/experimental/features/__tests__/debug_element.test.ts +26 -0
- package/src/experimental/features/debug_element.ts +13 -0
- package/src/experimental/features/index.ts +1 -0
- package/src/experimental/tools/VideoThumbnailLoader/load_and_push_segment.ts +10 -7
- package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +7 -4
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +25 -10
- package/src/experimental/tools/mediaCapabilitiesProber/index.ts +0 -4
- package/src/features/__tests__/initialize_features.test.ts +11 -0
- package/src/features/features_object.ts +1 -0
- package/src/features/initialize_features.ts +15 -10
- package/src/features/types.ts +9 -0
- package/src/manifest/__tests__/manifest.test.ts +7 -7
- package/src/manifest/__tests__/period.test.ts +90 -45
- package/src/manifest/adaptation.ts +96 -1
- package/src/manifest/manifest.ts +4 -0
- package/src/manifest/period.ts +4 -2
- package/src/manifest/representation.ts +77 -5
- package/src/manifest/utils.ts +1 -3
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +116 -151
- package/src/parsers/manifest/dash/common/parse_representations.ts +21 -4
- package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
- package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
- package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
- package/src/public_types.ts +16 -1
- package/src/tools/TextTrackRenderer/text_track_renderer.ts +1 -1
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +31 -22
- package/src/transports/dash/low_latency_segment_loader.ts +2 -2
- package/src/transports/dash/manifest_parser.ts +1 -1
- package/src/transports/dash/segment_loader.ts +4 -4
- package/src/transports/local/segment_loader.ts +14 -30
- package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
- package/src/transports/smooth/segment_loader.ts +4 -4
- package/src/transports/utils/call_custom_manifest_loader.ts +3 -3
- package/src/typings/globals.d.ts +21 -19
- package/src/utils/cancellable_sleep.ts +5 -14
- package/src/utils/create_cancellable_promise.ts +69 -0
- package/src/utils/is_null_or_undefined.ts +1 -1
- package/src/utils/reference.ts +6 -0
- package/src/utils/request/xhr.ts +1 -1
- package/src/utils/task_canceller.ts +63 -34
- package/tsconfig.json +1 -1
- package/tsconfig.modules.json +1 -1
- package/dist/_esm5.processed/core/init/utils/media_duration_updater.d.ts +0 -56
- package/locked_reps.js +0 -46
- package/scripts/doc-generator/construct_table_of_contents.js +0 -76
- package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
- package/scripts/doc-generator/create_documentation.js +0 -331
- package/scripts/doc-generator/create_documentation_page.js +0 -209
- package/scripts/doc-generator/create_page.js +0 -210
- package/scripts/doc-generator/generate_header_html.js +0 -147
- package/scripts/doc-generator/generate_page_html.js +0 -115
- package/scripts/doc-generator/generate_page_list_html.js +0 -92
- package/scripts/doc-generator/generate_sidebar_html.js +0 -85
- package/scripts/doc-generator/get_search_data_for_content.js +0 -137
- package/scripts/doc-generator/index.js +0 -34
- package/scripts/doc-generator/parse_doc_configs.js +0 -327
- package/scripts/doc-generator/scripts/lunr.js +0 -10
- package/scripts/doc-generator/scripts/script.js +0 -451
- package/scripts/doc-generator/styles/code.css +0 -99
- package/scripts/doc-generator/styles/style.css +0 -835
- package/scripts/doc-generator/utils.js +0 -74
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import log from "../../../log";
|
|
2
2
|
import arrayFindIndex from "../../../utils/array_find_index";
|
|
3
|
+
import createCancellablePromise from "../../../utils/create_cancellable_promise";
|
|
3
4
|
import TaskCanceller, {
|
|
4
5
|
CancellationError,
|
|
5
6
|
CancellationSignal,
|
|
@@ -64,19 +65,34 @@ export default class TaskPrioritizer<T> {
|
|
|
64
65
|
cancelSignal: CancellationSignal
|
|
65
66
|
): Promise<T> {
|
|
66
67
|
let newTask: IPrioritizerTask<T>;
|
|
67
|
-
|
|
68
|
-
return new Promise<T>((resolve, reject) => {
|
|
68
|
+
return createCancellablePromise<T>(cancelSignal, (resolve, reject) => {
|
|
69
69
|
/** Function allowing to start the underlying Promise. */
|
|
70
70
|
const trigger = () => {
|
|
71
71
|
if (newTask.hasEnded) {
|
|
72
|
-
unregisterCancelSignal();
|
|
73
72
|
return;
|
|
74
73
|
}
|
|
75
|
-
const
|
|
74
|
+
const finishTask = () => {
|
|
75
|
+
unlinkInterrupter();
|
|
76
|
+
this._endTask(newTask);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const onResolve = (value: T) => {
|
|
80
|
+
callbacks.beforeEnded();
|
|
81
|
+
finishTask();
|
|
82
|
+
resolve(value);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const onReject = (err: unknown) => {
|
|
86
|
+
finishTask();
|
|
87
|
+
reject(err);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const interrupter = new TaskCanceller();
|
|
91
|
+
const unlinkInterrupter = interrupter.linkToSignal(cancelSignal);
|
|
76
92
|
newTask.interrupter = interrupter;
|
|
77
93
|
interrupter.signal.register(() => {
|
|
78
94
|
newTask.interrupter = null;
|
|
79
|
-
if (!cancelSignal.isCancelled) {
|
|
95
|
+
if (!cancelSignal.isCancelled()) {
|
|
80
96
|
callbacks.beforeInterrupted();
|
|
81
97
|
}
|
|
82
98
|
});
|
|
@@ -89,8 +105,8 @@ export default class TaskPrioritizer<T> {
|
|
|
89
105
|
newTask.taskFn(interrupter.signal)
|
|
90
106
|
.then(onResolve)
|
|
91
107
|
.catch((err) => {
|
|
92
|
-
if (!cancelSignal.isCancelled &&
|
|
93
|
-
interrupter.isUsed &&
|
|
108
|
+
if (!cancelSignal.isCancelled() &&
|
|
109
|
+
interrupter.isUsed() &&
|
|
94
110
|
err instanceof CancellationError)
|
|
95
111
|
{
|
|
96
112
|
return;
|
|
@@ -99,29 +115,6 @@ export default class TaskPrioritizer<T> {
|
|
|
99
115
|
});
|
|
100
116
|
};
|
|
101
117
|
|
|
102
|
-
const unregisterCancelSignal = cancelSignal.register(
|
|
103
|
-
(cancellationError: CancellationError) => {
|
|
104
|
-
this._endTask(newTask);
|
|
105
|
-
reject(cancellationError);
|
|
106
|
-
}
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const finishTask = () => {
|
|
110
|
-
unregisterCancelSignal();
|
|
111
|
-
this._endTask(newTask);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const onResolve = (value: T) => {
|
|
115
|
-
callbacks.beforeEnded();
|
|
116
|
-
finishTask();
|
|
117
|
-
resolve(value);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const onReject = (err: unknown) => {
|
|
121
|
-
finishTask();
|
|
122
|
-
reject(err);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
118
|
newTask = {
|
|
126
119
|
hasEnded: false,
|
|
127
120
|
priority,
|
|
@@ -146,6 +139,8 @@ export default class TaskPrioritizer<T> {
|
|
|
146
139
|
this._interruptCancellableTasks();
|
|
147
140
|
}
|
|
148
141
|
}
|
|
142
|
+
|
|
143
|
+
return () => this._endTask(newTask);
|
|
149
144
|
});
|
|
150
145
|
}
|
|
151
146
|
|
|
@@ -266,7 +266,7 @@ export async function scheduleRequestWithCdns<T>(
|
|
|
266
266
|
async function retryWithNextCdn(prevRequestError : unknown) : Promise<T> {
|
|
267
267
|
const nextCdn = getCdnToRequest();
|
|
268
268
|
|
|
269
|
-
if (cancellationSignal.isCancelled) {
|
|
269
|
+
if (cancellationSignal.isCancelled()) {
|
|
270
270
|
throw cancellationSignal.cancellationError;
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -275,7 +275,7 @@ export async function scheduleRequestWithCdns<T>(
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
onRetry(prevRequestError);
|
|
278
|
-
if (cancellationSignal.isCancelled) {
|
|
278
|
+
if (cancellationSignal.isCancelled()) {
|
|
279
279
|
throw cancellationSignal.cancellationError;
|
|
280
280
|
}
|
|
281
281
|
|
|
@@ -309,26 +309,37 @@ export async function scheduleRequestWithCdns<T>(
|
|
|
309
309
|
return requestCdn(nextWantedCdn);
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
const canceller = new TaskCanceller(
|
|
312
|
+
const canceller = new TaskCanceller();
|
|
313
|
+
const unlinkCanceller = canceller.linkToSignal(cancellationSignal);
|
|
313
314
|
return new Promise<T>((res, rej) => {
|
|
314
315
|
/* eslint-disable-next-line @typescript-eslint/no-misused-promises */
|
|
315
316
|
cdnPrioritizer?.addEventListener("priorityChange", () => {
|
|
316
317
|
const updatedPrioritaryCdn = getCdnToRequest();
|
|
317
|
-
if (cancellationSignal.isCancelled) {
|
|
318
|
+
if (cancellationSignal.isCancelled()) {
|
|
318
319
|
throw cancellationSignal.cancellationError;
|
|
319
320
|
}
|
|
320
321
|
if (updatedPrioritaryCdn === undefined) {
|
|
321
|
-
return
|
|
322
|
+
return cleanAndReject(prevRequestError);
|
|
322
323
|
}
|
|
323
324
|
if (updatedPrioritaryCdn !== nextWantedCdn) {
|
|
324
325
|
canceller.cancel();
|
|
325
326
|
waitPotentialBackoffAndRequest(updatedPrioritaryCdn, prevRequestError)
|
|
326
|
-
.then(
|
|
327
|
+
.then(cleanAndResolve, cleanAndReject);
|
|
327
328
|
}
|
|
328
329
|
}, canceller.signal);
|
|
329
330
|
|
|
330
331
|
cancellableSleep(blockedFor, canceller.signal)
|
|
331
|
-
.then(() => requestCdn(nextWantedCdn)
|
|
332
|
+
.then(() => requestCdn(nextWantedCdn)
|
|
333
|
+
.then(cleanAndResolve, cleanAndReject), noop);
|
|
334
|
+
|
|
335
|
+
function cleanAndResolve(response : T) {
|
|
336
|
+
unlinkCanceller();
|
|
337
|
+
res(response);
|
|
338
|
+
}
|
|
339
|
+
function cleanAndReject(err : unknown) {
|
|
340
|
+
unlinkCanceller();
|
|
341
|
+
rej(err);
|
|
342
|
+
}
|
|
332
343
|
});
|
|
333
344
|
}
|
|
334
345
|
|
|
@@ -84,6 +84,7 @@ export default class DirectFileContentInitializer extends ContentInitializer {
|
|
|
84
84
|
* events when it cannot, as well as "unstalled" events when it get out of one.
|
|
85
85
|
*/
|
|
86
86
|
const rebufferingController = new RebufferingController(playbackObserver,
|
|
87
|
+
null,
|
|
87
88
|
null,
|
|
88
89
|
speed);
|
|
89
90
|
rebufferingController.addEventListener("stalled", (evt) =>
|
|
@@ -167,7 +168,7 @@ export default class DirectFileContentInitializer extends ContentInitializer {
|
|
|
167
168
|
}
|
|
168
169
|
}, { emitCurrentValue: true, clearSignal: cancelSignal }))
|
|
169
170
|
.catch((err) => {
|
|
170
|
-
if (!cancelSignal.isCancelled) {
|
|
171
|
+
if (!cancelSignal.isCancelled()) {
|
|
171
172
|
this._onFatalError(err);
|
|
172
173
|
}
|
|
173
174
|
});
|
|
@@ -25,13 +25,13 @@ import {
|
|
|
25
25
|
} from "../../public_types";
|
|
26
26
|
import { ITransportPipelines } from "../../transports";
|
|
27
27
|
import assert from "../../utils/assert";
|
|
28
|
+
import createCancellablePromise from "../../utils/create_cancellable_promise";
|
|
28
29
|
import objectAssign from "../../utils/object_assign";
|
|
29
30
|
import createSharedReference, {
|
|
30
31
|
IReadOnlySharedReference,
|
|
31
32
|
ISharedReference,
|
|
32
33
|
} from "../../utils/reference";
|
|
33
34
|
import TaskCanceller, {
|
|
34
|
-
CancellationError,
|
|
35
35
|
CancellationSignal,
|
|
36
36
|
} from "../../utils/task_canceller";
|
|
37
37
|
import AdaptiveRepresentationSelector, {
|
|
@@ -67,7 +67,7 @@ import getInitialTime, {
|
|
|
67
67
|
import getLoadedReference from "./utils/get_loaded_reference";
|
|
68
68
|
import performInitialSeekAndPlay from "./utils/initial_seek_and_play";
|
|
69
69
|
import initializeContentDecryption from "./utils/initialize_content_decryption";
|
|
70
|
-
import
|
|
70
|
+
import MediaSourceDurationUpdater from "./utils/media_source_duration_updater";
|
|
71
71
|
import RebufferingController from "./utils/rebuffering_controller";
|
|
72
72
|
import streamEventsEmitter from "./utils/stream_events_emitter";
|
|
73
73
|
import listenToMediaError from "./utils/throw_on_media_error";
|
|
@@ -124,21 +124,22 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
124
124
|
if (this._initialManifestProm !== null) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
|
-
this._initialManifestProm =
|
|
128
|
-
this._initCanceller.signal
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
res(manifest);
|
|
127
|
+
this._initialManifestProm = createCancellablePromise(
|
|
128
|
+
this._initCanceller.signal,
|
|
129
|
+
(res, rej) => {
|
|
130
|
+
this._manifestFetcher.addEventListener("warning", (err : IPlayerError) =>
|
|
131
|
+
this.trigger("warning", err));
|
|
132
|
+
this._manifestFetcher.addEventListener("error", (err : unknown) => {
|
|
133
|
+
this.trigger("error", err);
|
|
134
|
+
rej(err);
|
|
135
|
+
});
|
|
136
|
+
this._manifestFetcher.addEventListener("manifestReady", (manifest) => {
|
|
137
|
+
res(manifest);
|
|
138
|
+
});
|
|
140
139
|
});
|
|
141
|
-
|
|
140
|
+
this._manifestFetcher.start();
|
|
141
|
+
this._initCanceller.signal.register(() => {
|
|
142
|
+
this._manifestFetcher.dispose();
|
|
142
143
|
});
|
|
143
144
|
}
|
|
144
145
|
|
|
@@ -191,7 +192,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
private _onFatalError(err : unknown) {
|
|
194
|
-
if (this._initCanceller.isUsed) {
|
|
195
|
+
if (this._initCanceller.isUsed()) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
198
|
this._initCanceller.cancel();
|
|
@@ -205,13 +206,9 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
205
206
|
drmSystemId : string | undefined;
|
|
206
207
|
unlinkMediaSource : TaskCanceller; }>
|
|
207
208
|
{
|
|
208
|
-
|
|
209
|
+
const initCanceller = this._initCanceller;
|
|
210
|
+
return createCancellablePromise(initCanceller.signal, (resolve) => {
|
|
209
211
|
const { keySystems } = this._settings;
|
|
210
|
-
const initCanceller = this._initCanceller;
|
|
211
|
-
|
|
212
|
-
const unregisterReject = initCanceller.signal.register((err) => {
|
|
213
|
-
reject(err);
|
|
214
|
-
});
|
|
215
212
|
|
|
216
213
|
/** Initialize decryption capabilities. */
|
|
217
214
|
const drmInitRef =
|
|
@@ -226,9 +223,8 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
226
223
|
}
|
|
227
224
|
stopListeningToDrmUpdates();
|
|
228
225
|
|
|
229
|
-
const mediaSourceCanceller = new TaskCanceller(
|
|
230
|
-
|
|
231
|
-
});
|
|
226
|
+
const mediaSourceCanceller = new TaskCanceller();
|
|
227
|
+
mediaSourceCanceller.linkToSignal(initCanceller.signal);
|
|
232
228
|
openMediaSource(mediaElement, mediaSourceCanceller.signal)
|
|
233
229
|
.then((mediaSource) => {
|
|
234
230
|
const lastDrmStatus = drmInitRef.getValue();
|
|
@@ -237,7 +233,6 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
237
233
|
drmInitRef.onUpdate((newDrmStatus, stopListeningToDrmUpdatesAgain) => {
|
|
238
234
|
if (newDrmStatus.initializationState.type === "initialized") {
|
|
239
235
|
stopListeningToDrmUpdatesAgain();
|
|
240
|
-
unregisterReject();
|
|
241
236
|
resolve({ mediaSource,
|
|
242
237
|
drmSystemId: newDrmStatus.drmSystemId,
|
|
243
238
|
unlinkMediaSource: mediaSourceCanceller });
|
|
@@ -245,7 +240,6 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
245
240
|
}
|
|
246
241
|
}, { emitCurrentValue: true, clearSignal: initCanceller.signal });
|
|
247
242
|
} else if (drmStatus.initializationState.type === "initialized") {
|
|
248
|
-
unregisterReject();
|
|
249
243
|
resolve({ mediaSource,
|
|
250
244
|
drmSystemId: drmStatus.drmSystemId,
|
|
251
245
|
unlinkMediaSource: mediaSourceCanceller });
|
|
@@ -253,7 +247,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
253
247
|
}
|
|
254
248
|
})
|
|
255
249
|
.catch((err) => {
|
|
256
|
-
if (mediaSourceCanceller.isUsed) {
|
|
250
|
+
if (mediaSourceCanceller.isUsed()) {
|
|
257
251
|
return;
|
|
258
252
|
}
|
|
259
253
|
this._onFatalError(err);
|
|
@@ -307,7 +301,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
307
301
|
initCanceller.signal);
|
|
308
302
|
|
|
309
303
|
this.trigger("manifestReady", manifest);
|
|
310
|
-
if (initCanceller.isUsed) {
|
|
304
|
+
if (initCanceller.isUsed()) {
|
|
311
305
|
return ;
|
|
312
306
|
}
|
|
313
307
|
|
|
@@ -355,15 +349,16 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
355
349
|
autoPlay : boolean; }
|
|
356
350
|
) : void {
|
|
357
351
|
currentCanceller.cancel();
|
|
358
|
-
if (initCanceller.isUsed) {
|
|
352
|
+
if (initCanceller.isUsed()) {
|
|
359
353
|
return;
|
|
360
354
|
}
|
|
361
|
-
triggerEvent("reloadingMediaSource",
|
|
362
|
-
if (initCanceller.isUsed) {
|
|
355
|
+
triggerEvent("reloadingMediaSource", reloadOrder);
|
|
356
|
+
if (initCanceller.isUsed()) {
|
|
363
357
|
return;
|
|
364
358
|
}
|
|
365
359
|
|
|
366
|
-
const newCanceller = new TaskCanceller(
|
|
360
|
+
const newCanceller = new TaskCanceller();
|
|
361
|
+
newCanceller.linkToSignal(initCanceller.signal);
|
|
367
362
|
openMediaSource(mediaElement, newCanceller.signal)
|
|
368
363
|
.then(newMediaSource => {
|
|
369
364
|
recursivelyLoadOnMediaSource(newMediaSource,
|
|
@@ -372,7 +367,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
372
367
|
newCanceller);
|
|
373
368
|
})
|
|
374
369
|
.catch((err) => {
|
|
375
|
-
if (newCanceller.isUsed) {
|
|
370
|
+
if (newCanceller.isUsed()) {
|
|
376
371
|
return;
|
|
377
372
|
}
|
|
378
373
|
onFatalError(err);
|
|
@@ -427,7 +422,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
427
422
|
(err) => this.trigger("warning", err),
|
|
428
423
|
cancelSignal);
|
|
429
424
|
|
|
430
|
-
if (cancelSignal.isCancelled) {
|
|
425
|
+
if (cancelSignal.isCancelled()) {
|
|
431
426
|
return;
|
|
432
427
|
}
|
|
433
428
|
|
|
@@ -453,9 +448,20 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
453
448
|
|
|
454
449
|
const rebufferingController = this._createRebufferingController(playbackObserver,
|
|
455
450
|
manifest,
|
|
451
|
+
segmentBuffersStore,
|
|
456
452
|
speed,
|
|
457
453
|
cancelSignal);
|
|
458
|
-
|
|
454
|
+
rebufferingController.addEventListener("needsReload", () => {
|
|
455
|
+
// NOTE couldn't both be always calculated at event destination?
|
|
456
|
+
// Maybe there are exceptions?
|
|
457
|
+
const position = initialSeekPerformed.getValue() ?
|
|
458
|
+
playbackObserver.getCurrentTime() :
|
|
459
|
+
initialTime;
|
|
460
|
+
const autoplay = initialPlayPerformed.getValue() ?
|
|
461
|
+
!playbackObserver.getIsPaused() :
|
|
462
|
+
autoPlay;
|
|
463
|
+
onReloadOrder({ position, autoPlay: autoplay });
|
|
464
|
+
}, cancelSignal);
|
|
459
465
|
const contentTimeBoundariesObserver = this
|
|
460
466
|
._createContentTimeBoundariesObserver(manifest,
|
|
461
467
|
mediaSource,
|
|
@@ -479,7 +485,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
479
485
|
}, { emitCurrentValue: true, clearSignal: cancelSignal });
|
|
480
486
|
})
|
|
481
487
|
.catch((err) => {
|
|
482
|
-
if (cancelSignal.isCancelled) {
|
|
488
|
+
if (cancelSignal.isCancelled()) {
|
|
483
489
|
return; // Current loading cancelled, no need to trigger the error
|
|
484
490
|
}
|
|
485
491
|
this._onFatalError(err);
|
|
@@ -503,8 +509,36 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
503
509
|
*/
|
|
504
510
|
function handleStreamOrchestratorCallbacks() : IStreamOrchestratorCallbacks {
|
|
505
511
|
return {
|
|
506
|
-
needsBufferFlush: () =>
|
|
507
|
-
|
|
512
|
+
needsBufferFlush: () => {
|
|
513
|
+
const seekedTime = mediaElement.currentTime + 0.001;
|
|
514
|
+
playbackObserver.setCurrentTime(seekedTime);
|
|
515
|
+
|
|
516
|
+
// Seek again once data begins to be buffered.
|
|
517
|
+
// This is sadly necessary on some browsers to avoid decoding
|
|
518
|
+
// issues after a flush.
|
|
519
|
+
//
|
|
520
|
+
// NOTE: there's in theory a potential race condition in the following
|
|
521
|
+
// logic as the callback could be called when media data is still
|
|
522
|
+
// being removed by the browser - which is an asynchronous process.
|
|
523
|
+
// The following condition checking for buffered data could thus lead
|
|
524
|
+
// to a false positive where we're actually checking previous data.
|
|
525
|
+
// For now, such scenario is avoided by setting the
|
|
526
|
+
// `includeLastObservation` option to `false` and calling
|
|
527
|
+
// `needsBufferFlush` once MSE media removal operations have been
|
|
528
|
+
// explicitely validated by the browser, but that's a complex and easy
|
|
529
|
+
// to break system.
|
|
530
|
+
playbackObserver.listen((obs, stopListening) => {
|
|
531
|
+
if (
|
|
532
|
+
// Data is buffered around the current position
|
|
533
|
+
obs.currentRange !== null ||
|
|
534
|
+
// Or, for whatever reason, playback is already advancing
|
|
535
|
+
obs.position > seekedTime + 0.1
|
|
536
|
+
) {
|
|
537
|
+
stopListening();
|
|
538
|
+
playbackObserver.setCurrentTime(obs.position + 0.001);
|
|
539
|
+
}
|
|
540
|
+
}, { includeLastObservation: false, clearSignal: cancelSignal });
|
|
541
|
+
},
|
|
508
542
|
|
|
509
543
|
streamStatusUpdate(value) {
|
|
510
544
|
// Announce discontinuities if found
|
|
@@ -515,7 +549,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
515
549
|
discontinuity: imminentDiscontinuity,
|
|
516
550
|
position,
|
|
517
551
|
});
|
|
518
|
-
if (cancelSignal.isCancelled) {
|
|
552
|
+
if (cancelSignal.isCancelled()) {
|
|
519
553
|
return; // Previous call has stopped streams due to a side-effect
|
|
520
554
|
}
|
|
521
555
|
|
|
@@ -556,7 +590,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
556
590
|
|
|
557
591
|
adaptationChange: (value) => {
|
|
558
592
|
self.trigger("adaptationChange", value);
|
|
559
|
-
if (cancelSignal.isCancelled) {
|
|
593
|
+
if (cancelSignal.isCancelled()) {
|
|
560
594
|
return; // Previous call has stopped streams due to a side-effect
|
|
561
595
|
}
|
|
562
596
|
contentTimeBoundariesObserver.onAdaptationChange(value.type,
|
|
@@ -566,7 +600,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
566
600
|
|
|
567
601
|
representationChange: (value) => {
|
|
568
602
|
self.trigger("representationChange", value);
|
|
569
|
-
if (cancelSignal.isCancelled) {
|
|
603
|
+
if (cancelSignal.isCancelled()) {
|
|
570
604
|
return; // Previous call has stopped streams due to a side-effect
|
|
571
605
|
}
|
|
572
606
|
contentTimeBoundariesObserver.onRepresentationChange(value.type, value.period);
|
|
@@ -580,7 +614,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
580
614
|
|
|
581
615
|
periodStreamCleared: (value) => {
|
|
582
616
|
contentTimeBoundariesObserver.onPeriodCleared(value.type, value.period);
|
|
583
|
-
if (cancelSignal.isCancelled) {
|
|
617
|
+
if (cancelSignal.isCancelled()) {
|
|
584
618
|
return; // Previous call has stopped streams due to a side-effect
|
|
585
619
|
}
|
|
586
620
|
self.trigger("periodStreamCleared", value);
|
|
@@ -611,7 +645,7 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
611
645
|
encryptionDataEncountered: (value) => {
|
|
612
646
|
for (const protectionData of value) {
|
|
613
647
|
protectionRef.setValue(protectionData);
|
|
614
|
-
if (cancelSignal.isCancelled) {
|
|
648
|
+
if (cancelSignal.isCancelled()) {
|
|
615
649
|
return; // Previous call has stopped streams due to a side-effect
|
|
616
650
|
}
|
|
617
651
|
}
|
|
@@ -645,9 +679,9 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
645
679
|
cancelSignal : CancellationSignal
|
|
646
680
|
) : ContentTimeBoundariesObserver {
|
|
647
681
|
/** Maintains the MediaSource's duration up-to-date with the Manifest */
|
|
648
|
-
const
|
|
682
|
+
const mediaSourceDurationUpdater = new MediaSourceDurationUpdater(mediaSource);
|
|
649
683
|
cancelSignal.register(() => {
|
|
650
|
-
|
|
684
|
+
mediaSourceDurationUpdater.stopUpdating();
|
|
651
685
|
});
|
|
652
686
|
/** Allows to cancel a pending `end-of-stream` operation. */
|
|
653
687
|
let endOfStreamCanceller : TaskCanceller | null = null;
|
|
@@ -665,12 +699,12 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
665
699
|
this.trigger("activePeriodChanged", { period });
|
|
666
700
|
});
|
|
667
701
|
contentTimeBoundariesObserver.addEventListener("durationUpdate", (newDuration) => {
|
|
668
|
-
|
|
669
|
-
mediaDurationUpdater.updateKnownDuration(newDuration);
|
|
702
|
+
mediaSourceDurationUpdater.updateDuration(newDuration.duration, newDuration.isEnd);
|
|
670
703
|
});
|
|
671
704
|
contentTimeBoundariesObserver.addEventListener("endOfStream", () => {
|
|
672
705
|
if (endOfStreamCanceller === null) {
|
|
673
|
-
endOfStreamCanceller = new TaskCanceller(
|
|
706
|
+
endOfStreamCanceller = new TaskCanceller();
|
|
707
|
+
endOfStreamCanceller.linkToSignal(cancelSignal);
|
|
674
708
|
log.debug("Init: end-of-stream order received.");
|
|
675
709
|
maintainEndOfStream(mediaSource, endOfStreamCanceller.signal);
|
|
676
710
|
}
|
|
@@ -682,6 +716,9 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
682
716
|
endOfStreamCanceller = null;
|
|
683
717
|
}
|
|
684
718
|
});
|
|
719
|
+
const currentDuration = contentTimeBoundariesObserver.getCurrentDuration();
|
|
720
|
+
mediaSourceDurationUpdater.updateDuration(currentDuration.duration,
|
|
721
|
+
currentDuration.isEnd);
|
|
685
722
|
return contentTimeBoundariesObserver;
|
|
686
723
|
}
|
|
687
724
|
|
|
@@ -706,11 +743,13 @@ export default class MediaSourceContentInitializer extends ContentInitializer {
|
|
|
706
743
|
private _createRebufferingController(
|
|
707
744
|
playbackObserver : PlaybackObserver,
|
|
708
745
|
manifest : Manifest,
|
|
746
|
+
segmentBuffersStore : SegmentBuffersStore,
|
|
709
747
|
speed : IReadOnlySharedReference<number>,
|
|
710
748
|
cancelSignal : CancellationSignal
|
|
711
749
|
) : RebufferingController {
|
|
712
750
|
const rebufferingController = new RebufferingController(playbackObserver,
|
|
713
751
|
manifest,
|
|
752
|
+
segmentBuffersStore,
|
|
714
753
|
speed);
|
|
715
754
|
// Bubble-up events
|
|
716
755
|
rebufferingController.addEventListener("stalled",
|
package/src/core/init/types.ts
CHANGED
|
@@ -120,7 +120,15 @@ export interface IContentInitializerEvents {
|
|
|
120
120
|
* Event sent when we're starting attach a new MediaSource to the media element
|
|
121
121
|
* (after removing the previous one).
|
|
122
122
|
*/
|
|
123
|
-
reloadingMediaSource:
|
|
123
|
+
reloadingMediaSource: {
|
|
124
|
+
/** The position we're reloading at, in seconds. */
|
|
125
|
+
position: number;
|
|
126
|
+
/**
|
|
127
|
+
* If `true`, we'll play directly after finishing the reloading operation.
|
|
128
|
+
* If `false`, we'll be paused after it.
|
|
129
|
+
*/
|
|
130
|
+
autoPlay: boolean;
|
|
131
|
+
};
|
|
124
132
|
/** Event sent after the player stalled. */
|
|
125
133
|
stalled : IStallingSituation;
|
|
126
134
|
/** Event sent when the player goes out of a stalling situation. */
|
|
@@ -111,18 +111,20 @@ export default class ContentTimeBoundariesObserver
|
|
|
111
111
|
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
112
112
|
|
|
113
113
|
manifest.addEventListener("manifestUpdate", () => {
|
|
114
|
-
this.trigger("durationUpdate",
|
|
115
|
-
if (cancelSignal.isCancelled) {
|
|
114
|
+
this.trigger("durationUpdate", this._getManifestDuration());
|
|
115
|
+
if (cancelSignal.isCancelled()) {
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
this._checkEndOfStream();
|
|
119
119
|
}, cancelSignal);
|
|
120
|
+
}
|
|
120
121
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Returns an estimate of the current duration of the content.
|
|
124
|
+
* @returns {Object}
|
|
125
|
+
*/
|
|
126
|
+
public getCurrentDuration() : IDurationItem {
|
|
127
|
+
return this._getManifestDuration();
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
/**
|
|
@@ -154,14 +156,17 @@ export default class ContentTimeBoundariesObserver
|
|
|
154
156
|
this._maximumPositionCalculator
|
|
155
157
|
.updateLastVideoAdaptation(adaptation);
|
|
156
158
|
}
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
const endingPosition = this._maximumPositionCalculator.getEndingPosition();
|
|
160
|
+
const newDuration = endingPosition !== undefined ?
|
|
161
|
+
{ isEnd: true,
|
|
162
|
+
duration: endingPosition } :
|
|
163
|
+
{ isEnd: false,
|
|
164
|
+
duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
|
|
160
165
|
this.trigger("durationUpdate", newDuration);
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
}
|
|
164
|
-
if (this._canceller.isUsed) {
|
|
169
|
+
if (this._canceller.isUsed()) {
|
|
165
170
|
return;
|
|
166
171
|
}
|
|
167
172
|
if (adaptation === null) {
|
|
@@ -306,6 +311,15 @@ export default class ContentTimeBoundariesObserver
|
|
|
306
311
|
}
|
|
307
312
|
}
|
|
308
313
|
|
|
314
|
+
private _getManifestDuration() : IDurationItem {
|
|
315
|
+
const endingPosition = this._maximumPositionCalculator.getEndingPosition();
|
|
316
|
+
return endingPosition !== undefined ?
|
|
317
|
+
{ isEnd: true,
|
|
318
|
+
duration: endingPosition } :
|
|
319
|
+
{ isEnd: false,
|
|
320
|
+
duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
|
|
321
|
+
}
|
|
322
|
+
|
|
309
323
|
private _lazilyCreateActiveStreamInfo(bufferType : IBufferType) : IActiveStreamsInfo {
|
|
310
324
|
let streamInfo = this._activeStreams.get(bufferType);
|
|
311
325
|
if (streamInfo === undefined) {
|
|
@@ -334,6 +348,28 @@ export default class ContentTimeBoundariesObserver
|
|
|
334
348
|
}
|
|
335
349
|
}
|
|
336
350
|
|
|
351
|
+
export interface IDurationItem {
|
|
352
|
+
/**
|
|
353
|
+
* The new maximum known position (note that this is the ending position
|
|
354
|
+
* currently known of the current content, it might be superior to the last
|
|
355
|
+
* position at which segments are available and it might also evolve over
|
|
356
|
+
* time), in seconds.
|
|
357
|
+
*/
|
|
358
|
+
duration : number;
|
|
359
|
+
/**
|
|
360
|
+
* If `true`, the communicated `duration` is the actual end of the content.
|
|
361
|
+
* It may still be updated due to a track change or to add precision, but it
|
|
362
|
+
* is still a (rough) estimate of the maximum position that content should
|
|
363
|
+
* have.
|
|
364
|
+
*
|
|
365
|
+
* If `false`, this is the currently known maximum position associated to
|
|
366
|
+
* the content, but the content is still evolving (typically, new media
|
|
367
|
+
* segments are still being generated) and as such it can still have a
|
|
368
|
+
* longer duration in the future.
|
|
369
|
+
*/
|
|
370
|
+
isEnd : boolean;
|
|
371
|
+
}
|
|
372
|
+
|
|
337
373
|
/**
|
|
338
374
|
* Events triggered by a `ContentTimeBoundariesObserver` where the keys are the
|
|
339
375
|
* event names and the value is the payload of those events.
|
|
@@ -347,7 +383,7 @@ export interface IContentTimeBoundariesObserverEvent {
|
|
|
347
383
|
* Triggered when the duration of the currently-playing content became known
|
|
348
384
|
* or changed.
|
|
349
385
|
*/
|
|
350
|
-
durationUpdate :
|
|
386
|
+
durationUpdate : IDurationItem;
|
|
351
387
|
/**
|
|
352
388
|
* Triggered when the last possible chronological segment for all types of
|
|
353
389
|
* buffers has either been pushed or is being pushed to the corresponding
|
|
@@ -21,10 +21,9 @@ import {
|
|
|
21
21
|
} from "../../../compat";
|
|
22
22
|
import { MediaError } from "../../../errors";
|
|
23
23
|
import log from "../../../log";
|
|
24
|
+
import createCancellablePromise from "../../../utils/create_cancellable_promise";
|
|
24
25
|
import isNonEmptyString from "../../../utils/is_non_empty_string";
|
|
25
|
-
import
|
|
26
|
-
CancellationSignal,
|
|
27
|
-
} from "../../../utils/task_canceller";
|
|
26
|
+
import { CancellationSignal } from "../../../utils/task_canceller";
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* Dispose of ressources taken by the MediaSource:
|
|
@@ -128,21 +127,10 @@ export default function openMediaSource(
|
|
|
128
127
|
mediaElement : HTMLMediaElement,
|
|
129
128
|
unlinkSignal : CancellationSignal
|
|
130
129
|
) : Promise<MediaSource> {
|
|
131
|
-
return
|
|
132
|
-
let hasResolved = false;
|
|
130
|
+
return createCancellablePromise(unlinkSignal, (resolve) => {
|
|
133
131
|
const mediaSource = createMediaSource(mediaElement, unlinkSignal);
|
|
134
|
-
const eventListenerCanceller = new TaskCanceller({ cancelOn: unlinkSignal });
|
|
135
|
-
|
|
136
132
|
events.onSourceOpen(mediaSource, () => {
|
|
137
|
-
eventListenerCanceller.cancel();
|
|
138
|
-
hasResolved = true;
|
|
139
133
|
resolve(mediaSource);
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
unlinkSignal.register((error) => {
|
|
143
|
-
if (!hasResolved) {
|
|
144
|
-
reject(error);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
134
|
+
}, unlinkSignal);
|
|
147
135
|
});
|
|
148
136
|
}
|