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
|
@@ -141,9 +141,9 @@ export default function StreamOrchestrator(
|
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
// Create automatically the right `PeriodStream` for every possible types
|
|
144
|
-
segmentBuffersStore.getBufferTypes()
|
|
144
|
+
for (const bufferType of segmentBuffersStore.getBufferTypes()) {
|
|
145
145
|
manageEveryStreams(bufferType, initialPeriod);
|
|
146
|
-
}
|
|
146
|
+
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
149
|
* Manage creation and removal of Streams for every Periods for a given type.
|
|
@@ -168,7 +168,8 @@ export default function StreamOrchestrator(
|
|
|
168
168
|
let enableOutOfBoundsCheck = false;
|
|
169
169
|
|
|
170
170
|
/** Cancels currently created `PeriodStream`s. */
|
|
171
|
-
let currentCanceller = new TaskCanceller(
|
|
171
|
+
let currentCanceller = new TaskCanceller();
|
|
172
|
+
currentCanceller.linkToSignal(orchestratorCancelSignal);
|
|
172
173
|
|
|
173
174
|
// Restart the current Stream when the wanted time is in another period
|
|
174
175
|
// than the ones already considered
|
|
@@ -187,7 +188,8 @@ export default function StreamOrchestrator(
|
|
|
187
188
|
callbacks.periodStreamCleared({ type: bufferType, manifest, period });
|
|
188
189
|
}
|
|
189
190
|
currentCanceller.cancel();
|
|
190
|
-
currentCanceller = new TaskCanceller(
|
|
191
|
+
currentCanceller = new TaskCanceller();
|
|
192
|
+
currentCanceller.linkToSignal(orchestratorCancelSignal);
|
|
191
193
|
|
|
192
194
|
const nextPeriod = manifest.getPeriodForTime(time) ??
|
|
193
195
|
manifest.getNextPeriod(time);
|
|
@@ -199,7 +201,13 @@ export default function StreamOrchestrator(
|
|
|
199
201
|
}, { clearSignal: orchestratorCancelSignal, includeLastObservation: true });
|
|
200
202
|
|
|
201
203
|
manifest.addEventListener("decipherabilityUpdate", (evt) => {
|
|
204
|
+
if (orchestratorCancelSignal.isCancelled()) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
202
207
|
onDecipherabilityUpdates(evt).catch(err => {
|
|
208
|
+
if (orchestratorCancelSignal.isCancelled()) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
203
211
|
currentCanceller.cancel();
|
|
204
212
|
callbacks.error(err);
|
|
205
213
|
});
|
|
@@ -276,8 +284,16 @@ export default function StreamOrchestrator(
|
|
|
276
284
|
const segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
|
|
277
285
|
const ofCurrentType = updates
|
|
278
286
|
.filter(update => update.adaptation.type === bufferType);
|
|
279
|
-
if (
|
|
280
|
-
|
|
287
|
+
if (
|
|
288
|
+
// No update concerns the current type of data
|
|
289
|
+
ofCurrentType.length === 0 ||
|
|
290
|
+
segmentBufferStatus.type !== "initialized" ||
|
|
291
|
+
// The update only notifies of now-decipherable streams
|
|
292
|
+
ofCurrentType.every(x => x.representation.decipherable === true)
|
|
293
|
+
) {
|
|
294
|
+
// Data won't have to be removed from the buffers, no need to stop the
|
|
295
|
+
// current Streams.
|
|
296
|
+
return ;
|
|
281
297
|
}
|
|
282
298
|
|
|
283
299
|
const segmentBuffer = segmentBufferStatus.value;
|
|
@@ -317,7 +333,8 @@ export default function StreamOrchestrator(
|
|
|
317
333
|
}
|
|
318
334
|
|
|
319
335
|
currentCanceller.cancel();
|
|
320
|
-
currentCanceller = new TaskCanceller(
|
|
336
|
+
currentCanceller = new TaskCanceller();
|
|
337
|
+
currentCanceller.linkToSignal(orchestratorCancelSignal);
|
|
321
338
|
|
|
322
339
|
/** Remove from the `SegmentBuffer` all the concerned time ranges. */
|
|
323
340
|
for (const { start, end } of [...undecipherableRanges, ...rangesToRemove]) {
|
|
@@ -330,7 +347,7 @@ export default function StreamOrchestrator(
|
|
|
330
347
|
// to reduce the risk of race conditions where the next observation
|
|
331
348
|
// was going to be emitted synchronously.
|
|
332
349
|
nextTick(() => {
|
|
333
|
-
if (orchestratorCancelSignal.isCancelled) {
|
|
350
|
+
if (orchestratorCancelSignal.isCancelled()) {
|
|
334
351
|
return ;
|
|
335
352
|
}
|
|
336
353
|
const observation = playbackObserver.getReference().getValue();
|
|
@@ -340,12 +357,12 @@ export default function StreamOrchestrator(
|
|
|
340
357
|
callbacks.needsDecipherabilityFlush({ position: observation.position.last,
|
|
341
358
|
autoPlay: shouldAutoPlay,
|
|
342
359
|
duration: observation.duration });
|
|
343
|
-
if (orchestratorCancelSignal.isCancelled) {
|
|
360
|
+
if (orchestratorCancelSignal.isCancelled()) {
|
|
344
361
|
return ;
|
|
345
362
|
}
|
|
346
363
|
} else if (needsFlushingAfterClean(observation, rangesToRemove)) {
|
|
347
364
|
callbacks.needsBufferFlush();
|
|
348
|
-
if (orchestratorCancelSignal.isCancelled) {
|
|
365
|
+
if (orchestratorCancelSignal.isCancelled()) {
|
|
349
366
|
return ;
|
|
350
367
|
}
|
|
351
368
|
}
|
|
@@ -418,7 +435,8 @@ export default function StreamOrchestrator(
|
|
|
418
435
|
} | null = null;
|
|
419
436
|
|
|
420
437
|
/** Emits when the `PeriodStream` linked to `basePeriod` should be destroyed. */
|
|
421
|
-
const currentStreamCanceller = new TaskCanceller(
|
|
438
|
+
const currentStreamCanceller = new TaskCanceller();
|
|
439
|
+
currentStreamCanceller.linkToSignal(cancelSignal);
|
|
422
440
|
|
|
423
441
|
// Stop current PeriodStream when the current position goes over the end of
|
|
424
442
|
// that Period.
|
|
@@ -453,12 +471,10 @@ export default function StreamOrchestrator(
|
|
|
453
471
|
...consecutivePeriodStreamCb,
|
|
454
472
|
streamStatusUpdate(value : IStreamStatusPayload) : void {
|
|
455
473
|
if (value.hasFinishedLoading) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
createNextPeriodStream(nextPeriod);
|
|
461
|
-
}
|
|
474
|
+
const nextPeriod = manifest.getPeriodAfter(basePeriod);
|
|
475
|
+
if (nextPeriod !== null) {
|
|
476
|
+
// current Stream is full, create the next one if not
|
|
477
|
+
checkOrCreateNextPeriodStream(nextPeriod);
|
|
462
478
|
}
|
|
463
479
|
} else if (nextStreamInfo !== null) {
|
|
464
480
|
// current Stream is active, destroy next Stream if created
|
|
@@ -490,15 +506,21 @@ export default function StreamOrchestrator(
|
|
|
490
506
|
* Create `PeriodStream` for the next Period, specified under `nextPeriod`.
|
|
491
507
|
* @param {Object} nextPeriod
|
|
492
508
|
*/
|
|
493
|
-
function
|
|
509
|
+
function checkOrCreateNextPeriodStream(nextPeriod : Period) : void {
|
|
494
510
|
if (nextStreamInfo !== null) {
|
|
495
|
-
|
|
511
|
+
if (nextStreamInfo.period.id === nextPeriod.id) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
log.warn("Stream: Creating next `PeriodStream` while one was already created.",
|
|
515
|
+
bufferType, nextPeriod.id, nextStreamInfo.period.id);
|
|
496
516
|
consecutivePeriodStreamCb.periodStreamCleared({ type: bufferType,
|
|
497
517
|
manifest,
|
|
498
518
|
period: nextStreamInfo.period });
|
|
499
519
|
nextStreamInfo.canceller.cancel();
|
|
500
520
|
}
|
|
501
|
-
|
|
521
|
+
const nextStreamCanceller = new TaskCanceller();
|
|
522
|
+
nextStreamCanceller.linkToSignal(cancelSignal);
|
|
523
|
+
nextStreamInfo = { canceller: nextStreamCanceller,
|
|
502
524
|
period: nextPeriod };
|
|
503
525
|
manageConsecutivePeriodStreams(bufferType,
|
|
504
526
|
nextPeriod,
|
|
@@ -111,7 +111,7 @@ export default function PeriodStream(
|
|
|
111
111
|
);
|
|
112
112
|
|
|
113
113
|
callbacks.periodStreamReady({ type: bufferType, manifest, period, adaptationRef });
|
|
114
|
-
if (parentCancelSignal.isCancelled) {
|
|
114
|
+
if (parentCancelSignal.isCancelled()) {
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -124,7 +124,8 @@ export default function PeriodStream(
|
|
|
124
124
|
if (choice === undefined) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
|
-
const streamCanceller = new TaskCanceller(
|
|
127
|
+
const streamCanceller = new TaskCanceller();
|
|
128
|
+
streamCanceller.linkToSignal(parentCancelSignal);
|
|
128
129
|
currentStreamCanceller?.cancel(); // Cancel oreviously created stream if one
|
|
129
130
|
currentStreamCanceller = streamCanceller;
|
|
130
131
|
|
|
@@ -147,20 +148,20 @@ export default function PeriodStream(
|
|
|
147
148
|
await segmentBufferStatus.value.removeBuffer(period.start,
|
|
148
149
|
periodEnd,
|
|
149
150
|
streamCanceller.signal);
|
|
150
|
-
if (streamCanceller.isUsed) {
|
|
151
|
+
if (streamCanceller.isUsed()) {
|
|
151
152
|
return; // The stream has been cancelled
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
} else if (segmentBufferStatus.type === "uninitialized") {
|
|
156
157
|
segmentBuffersStore.disableSegmentBuffer(bufferType);
|
|
157
|
-
if (streamCanceller.isUsed) {
|
|
158
|
+
if (streamCanceller.isUsed()) {
|
|
158
159
|
return; // The stream has been cancelled
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
callbacks.adaptationChange({ type: bufferType, adaptation: null, period });
|
|
163
|
-
if (streamCanceller.isUsed) {
|
|
164
|
+
if (streamCanceller.isUsed()) {
|
|
164
165
|
return; // Previous call has provoken Stream cancellation by side-effect
|
|
165
166
|
}
|
|
166
167
|
|
|
@@ -220,7 +221,7 @@ export default function PeriodStream(
|
|
|
220
221
|
`P: ${period.start}`);
|
|
221
222
|
|
|
222
223
|
callbacks.adaptationChange({ type: bufferType, adaptation, period });
|
|
223
|
-
if (streamCanceller.isUsed) {
|
|
224
|
+
if (streamCanceller.isUsed()) {
|
|
224
225
|
return; // Previous call has provoken cancellation by side-effect
|
|
225
226
|
}
|
|
226
227
|
|
|
@@ -244,19 +245,19 @@ export default function PeriodStream(
|
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
await segmentBuffersStore.waitForUsableBuffers(streamCanceller.signal);
|
|
247
|
-
if (streamCanceller.isUsed) {
|
|
248
|
+
if (streamCanceller.isUsed()) {
|
|
248
249
|
return; // The Stream has since been cancelled
|
|
249
250
|
}
|
|
250
251
|
if (strategy.type === "flush-buffer" || strategy.type === "clean-buffer") {
|
|
251
252
|
for (const { start, end } of strategy.value) {
|
|
252
253
|
await segmentBuffer.removeBuffer(start, end, streamCanceller.signal);
|
|
253
|
-
if (streamCanceller.isUsed) {
|
|
254
|
+
if (streamCanceller.isUsed()) {
|
|
254
255
|
return; // The Stream has since been cancelled
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
if (strategy.type === "flush-buffer") {
|
|
258
259
|
callbacks.needsBufferFlush();
|
|
259
|
-
if (streamCanceller.isUsed) {
|
|
260
|
+
if (streamCanceller.isUsed()) {
|
|
260
261
|
return ; // Previous callback cancelled the Stream by side-effect
|
|
261
262
|
}
|
|
262
263
|
}
|
|
@@ -319,7 +320,7 @@ export default function PeriodStream(
|
|
|
319
320
|
defaultReason: "Unknown `AdaptationStream` error",
|
|
320
321
|
});
|
|
321
322
|
callbacks.warning(formattedError);
|
|
322
|
-
if (cancelSignal.isCancelled) {
|
|
323
|
+
if (cancelSignal.isCancelled()) {
|
|
323
324
|
return ; // Previous callback cancelled the Stream by side-effect
|
|
324
325
|
}
|
|
325
326
|
|
|
@@ -371,7 +372,8 @@ function getFirstDeclaredMimeType(adaptation : Adaptation) : string {
|
|
|
371
372
|
if (representations.length === 0) {
|
|
372
373
|
const noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION",
|
|
373
374
|
"No Representation in the chosen " +
|
|
374
|
-
adaptation.type + " Adaptation can be played"
|
|
375
|
+
adaptation.type + " Adaptation can be played",
|
|
376
|
+
{ adaptation });
|
|
375
377
|
throw noRepErr;
|
|
376
378
|
}
|
|
377
379
|
return representations[0].getMimeTypeString();
|
|
@@ -97,23 +97,29 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
97
97
|
const bufferType = adaptation.type;
|
|
98
98
|
|
|
99
99
|
/** `TaskCanceller` stopping ALL operations performed by the `RepresentationStream` */
|
|
100
|
-
const globalCanceller = new TaskCanceller(
|
|
100
|
+
const globalCanceller = new TaskCanceller();
|
|
101
|
+
globalCanceller.linkToSignal(parentCancelSignal);
|
|
101
102
|
|
|
102
103
|
/**
|
|
103
104
|
* `TaskCanceller` allowing to only stop segment loading and checking operations.
|
|
104
105
|
* This allows to stop only tasks linked to network resource usage, which is
|
|
105
106
|
* often a limited resource, while still letting buffer operations to finish.
|
|
106
107
|
*/
|
|
107
|
-
const segmentsLoadingCanceller = new TaskCanceller(
|
|
108
|
-
|
|
109
|
-
});
|
|
108
|
+
const segmentsLoadingCanceller = new TaskCanceller();
|
|
109
|
+
segmentsLoadingCanceller.linkToSignal(globalCanceller.signal);
|
|
110
110
|
|
|
111
111
|
/** Saved initialization segment state for this representation. */
|
|
112
|
-
const initSegmentState : IInitSegmentState
|
|
112
|
+
const initSegmentState : IInitSegmentState = {
|
|
113
113
|
segment: representation.index.getInitSegment(),
|
|
114
|
-
|
|
114
|
+
uniqueId: null,
|
|
115
115
|
isLoaded: false,
|
|
116
116
|
};
|
|
117
|
+
globalCanceller.signal.register(() => {
|
|
118
|
+
// Free initialization segment if one has been declared
|
|
119
|
+
if (initSegmentState.uniqueId !== null) {
|
|
120
|
+
segmentBuffer.freeInitSegment(initSegmentState.uniqueId);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
117
123
|
|
|
118
124
|
/** Emit the last scheduled downloading queue for segments. */
|
|
119
125
|
const lastSegmentQueue = createSharedReference<IDownloadQueueItem>({
|
|
@@ -125,7 +131,6 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
125
131
|
const hasInitSegment = initSegmentState.segment !== null;
|
|
126
132
|
|
|
127
133
|
if (!hasInitSegment) {
|
|
128
|
-
initSegmentState.segmentData = null;
|
|
129
134
|
initSegmentState.isLoaded = true;
|
|
130
135
|
}
|
|
131
136
|
|
|
@@ -149,7 +154,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
149
154
|
callbacks.encryptionDataEncountered(
|
|
150
155
|
encryptionData.map(d => objectAssign({ content }, d))
|
|
151
156
|
);
|
|
152
|
-
if (globalCanceller.isUsed) {
|
|
157
|
+
if (globalCanceller.isUsed()) {
|
|
153
158
|
return ; // previous callback has stopped everything by side-effect
|
|
154
159
|
}
|
|
155
160
|
}
|
|
@@ -161,7 +166,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
161
166
|
segmentFetcher,
|
|
162
167
|
hasInitSegment);
|
|
163
168
|
downloadingQueue.addEventListener("error", (err) => {
|
|
164
|
-
if (segmentsLoadingCanceller.signal.isCancelled) {
|
|
169
|
+
if (segmentsLoadingCanceller.signal.isCancelled()) {
|
|
165
170
|
return; // ignore post requests-cancellation loading-related errors,
|
|
166
171
|
}
|
|
167
172
|
globalCanceller.cancel(); // Stop every operations
|
|
@@ -172,7 +177,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
172
177
|
downloadingQueue.addEventListener("emptyQueue", checkStatus);
|
|
173
178
|
downloadingQueue.addEventListener("requestRetry", (payload) => {
|
|
174
179
|
callbacks.warning(payload.error);
|
|
175
|
-
if (segmentsLoadingCanceller.signal.isCancelled) {
|
|
180
|
+
if (segmentsLoadingCanceller.signal.isCancelled()) {
|
|
176
181
|
return; // If the previous callback led to loading operations being stopped, skip
|
|
177
182
|
}
|
|
178
183
|
const retriedSegment = payload.segment;
|
|
@@ -218,7 +223,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
218
223
|
* issues at the current time, calling the right callbacks if necessary.
|
|
219
224
|
*/
|
|
220
225
|
function checkStatus() : void {
|
|
221
|
-
if (segmentsLoadingCanceller.isUsed) {
|
|
226
|
+
if (segmentsLoadingCanceller.isUsed()) {
|
|
222
227
|
return ; // Stop all buffer status checking if load operations are stopped
|
|
223
228
|
}
|
|
224
229
|
const observation = playbackObserver.getReference().getValue();
|
|
@@ -305,7 +310,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
305
310
|
isEmptyStream: false,
|
|
306
311
|
hasFinishedLoading: status.hasFinishedLoading,
|
|
307
312
|
neededSegments: status.neededSegments });
|
|
308
|
-
if (segmentsLoadingCanceller.signal.isCancelled) {
|
|
313
|
+
if (segmentsLoadingCanceller.signal.isCancelled()) {
|
|
309
314
|
return ; // previous callback has stopped loading operations by side-effect
|
|
310
315
|
}
|
|
311
316
|
const { UPTO_CURRENT_POSITION_CLEANUP } = config.getCurrent();
|
|
@@ -314,7 +319,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
314
319
|
0,
|
|
315
320
|
initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
|
|
316
321
|
if (gcedPosition > 0) {
|
|
317
|
-
segmentBuffer.removeBuffer(0, gcedPosition,
|
|
322
|
+
segmentBuffer.removeBuffer(0, gcedPosition, globalCanceller.signal)
|
|
318
323
|
.catch(onFatalBufferError);
|
|
319
324
|
}
|
|
320
325
|
}
|
|
@@ -332,7 +337,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
332
337
|
evt : IParsedInitSegmentPayload<TSegmentDataType> |
|
|
333
338
|
IParsedSegmentPayload<TSegmentDataType>
|
|
334
339
|
) : void {
|
|
335
|
-
if (globalCanceller.isUsed) {
|
|
340
|
+
if (globalCanceller.isUsed()) {
|
|
336
341
|
// We should not do anything with segments if the `RepresentationStream`
|
|
337
342
|
// is not running anymore.
|
|
338
343
|
return ;
|
|
@@ -359,7 +364,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
359
364
|
hasSentEncryptionData = true;
|
|
360
365
|
|
|
361
366
|
// previous callback could have lead to cancellation
|
|
362
|
-
if (globalCanceller.isUsed) {
|
|
367
|
+
if (globalCanceller.isUsed()) {
|
|
363
368
|
return ;
|
|
364
369
|
}
|
|
365
370
|
}
|
|
@@ -371,21 +376,27 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
371
376
|
{
|
|
372
377
|
representation.index.initialize(evt.segmentList);
|
|
373
378
|
}
|
|
374
|
-
initSegmentState.segmentData = evt.initializationData;
|
|
375
379
|
initSegmentState.isLoaded = true;
|
|
376
380
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
381
|
+
if (evt.initializationData !== null) {
|
|
382
|
+
const initSegmentUniqueId = representation.uniqueId;
|
|
383
|
+
initSegmentState.uniqueId = initSegmentUniqueId;
|
|
384
|
+
segmentBuffer.declareInitSegment(initSegmentUniqueId,
|
|
385
|
+
evt.initializationData);
|
|
386
|
+
pushInitSegment({ playbackObserver,
|
|
387
|
+
content,
|
|
388
|
+
initSegmentUniqueId,
|
|
389
|
+
segment: evt.segment,
|
|
390
|
+
segmentData: evt.initializationData,
|
|
391
|
+
segmentBuffer },
|
|
392
|
+
globalCanceller.signal)
|
|
393
|
+
.then((result) => {
|
|
394
|
+
if (result !== null) {
|
|
395
|
+
callbacks.addedSegment(result);
|
|
396
|
+
}
|
|
397
|
+
})
|
|
398
|
+
.catch(onFatalBufferError);
|
|
399
|
+
}
|
|
389
400
|
|
|
390
401
|
// Sometimes the segment list is only known once the initialization segment
|
|
391
402
|
// is parsed. Thus we immediately re-check if there's new segments to load.
|
|
@@ -401,21 +412,21 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
401
412
|
|
|
402
413
|
if (needsManifestRefresh === true) {
|
|
403
414
|
callbacks.needsManifestRefresh();
|
|
404
|
-
if (globalCanceller.isUsed) {
|
|
415
|
+
if (globalCanceller.isUsed()) {
|
|
405
416
|
return ; // previous callback has stopped everything by side-effect
|
|
406
417
|
}
|
|
407
418
|
}
|
|
408
419
|
if (inbandEvents !== undefined && inbandEvents.length > 0) {
|
|
409
420
|
callbacks.inbandEvent(inbandEvents);
|
|
410
|
-
if (globalCanceller.isUsed) {
|
|
421
|
+
if (globalCanceller.isUsed()) {
|
|
411
422
|
return ; // previous callback has stopped everything by side-effect
|
|
412
423
|
}
|
|
413
424
|
}
|
|
414
425
|
|
|
415
|
-
const
|
|
426
|
+
const initSegmentUniqueId = initSegmentState.uniqueId;
|
|
416
427
|
pushMediaSegment({ playbackObserver,
|
|
417
428
|
content,
|
|
418
|
-
|
|
429
|
+
initSegmentUniqueId,
|
|
419
430
|
parsedSegment: evt,
|
|
420
431
|
segment: evt.segment,
|
|
421
432
|
segmentBuffer },
|
|
@@ -436,7 +447,7 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
436
447
|
* @param {*} err
|
|
437
448
|
*/
|
|
438
449
|
function onFatalBufferError(err : unknown) : void {
|
|
439
|
-
if (globalCanceller.isUsed && err instanceof CancellationError) {
|
|
450
|
+
if (globalCanceller.isUsed() && err instanceof CancellationError) {
|
|
440
451
|
// The error is linked to cancellation AND we explicitely cancelled buffer
|
|
441
452
|
// operations.
|
|
442
453
|
// We can thus ignore it, it is very unlikely to lead to true buffer issues.
|
|
@@ -451,17 +462,18 @@ export default function RepresentationStream<TSegmentDataType>(
|
|
|
451
462
|
* Information about the initialization segment linked to the Representation
|
|
452
463
|
* which the RepresentationStream try to download segments for.
|
|
453
464
|
*/
|
|
454
|
-
interface IInitSegmentState
|
|
465
|
+
interface IInitSegmentState {
|
|
455
466
|
/**
|
|
456
467
|
* Segment Object describing that initialization segment.
|
|
457
468
|
* `null` if there's no initialization segment for that Representation.
|
|
458
469
|
*/
|
|
459
470
|
segment : ISegment | null;
|
|
460
471
|
/**
|
|
461
|
-
*
|
|
462
|
-
* `
|
|
472
|
+
* Unique identifier used to identify the initialization segment data, used by
|
|
473
|
+
* the `SegmentBuffer`.
|
|
474
|
+
* `null` either when it doesn't exist or when it has not been declared yet.
|
|
463
475
|
*/
|
|
464
|
-
|
|
476
|
+
uniqueId : string | null;
|
|
465
477
|
/** `true` if the initialization segment has been loaded and parsed. */
|
|
466
478
|
isLoaded : boolean;
|
|
467
479
|
}
|
|
@@ -22,6 +22,7 @@ import { MediaError } from "../../../../errors";
|
|
|
22
22
|
import { CancellationError, CancellationSignal } from "../../../../utils/task_canceller";
|
|
23
23
|
import { IReadOnlyPlaybackObserver } from "../../../api";
|
|
24
24
|
import {
|
|
25
|
+
IInsertedChunkInfos,
|
|
25
26
|
IPushChunkInfos,
|
|
26
27
|
SegmentBuffer,
|
|
27
28
|
} from "../../../segment_buffers";
|
|
@@ -41,13 +42,13 @@ import forceGarbageCollection from "./force_garbage_collection";
|
|
|
41
42
|
export default async function appendSegmentToBuffer<T>(
|
|
42
43
|
playbackObserver : IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>,
|
|
43
44
|
segmentBuffer : SegmentBuffer,
|
|
44
|
-
dataInfos : IPushChunkInfos<T
|
|
45
|
+
dataInfos : IPushChunkInfos<T> & { inventoryInfos: IInsertedChunkInfos },
|
|
45
46
|
cancellationSignal : CancellationSignal
|
|
46
47
|
) : Promise<void> {
|
|
47
48
|
try {
|
|
48
49
|
await segmentBuffer.pushChunk(dataInfos, cancellationSignal);
|
|
49
50
|
} catch (appendError : unknown) {
|
|
50
|
-
if (cancellationSignal.isCancelled && appendError instanceof CancellationError) {
|
|
51
|
+
if (cancellationSignal.isCancelled() && appendError instanceof CancellationError) {
|
|
51
52
|
throw appendError;
|
|
52
53
|
} else if (!(appendError instanceof Error) ||
|
|
53
54
|
appendError.name !== "QuotaExceededError")
|
|
@@ -55,7 +56,9 @@ export default async function appendSegmentToBuffer<T>(
|
|
|
55
56
|
const reason = appendError instanceof Error ?
|
|
56
57
|
appendError.toString() :
|
|
57
58
|
"An unknown error happened when pushing content";
|
|
58
|
-
throw new MediaError("BUFFER_APPEND_ERROR",
|
|
59
|
+
throw new MediaError("BUFFER_APPEND_ERROR",
|
|
60
|
+
reason,
|
|
61
|
+
{ adaptation: dataInfos.inventoryInfos.adaptation });
|
|
59
62
|
}
|
|
60
63
|
const { position } = playbackObserver.getReference().getValue();
|
|
61
64
|
const currentPos = position.pending ?? position.last;
|
|
@@ -66,7 +69,9 @@ export default async function appendSegmentToBuffer<T>(
|
|
|
66
69
|
const reason = err2 instanceof Error ? err2.toString() :
|
|
67
70
|
"Could not clean the buffer";
|
|
68
71
|
|
|
69
|
-
throw new MediaError("BUFFER_FULL_ERROR",
|
|
72
|
+
throw new MediaError("BUFFER_FULL_ERROR",
|
|
73
|
+
reason,
|
|
74
|
+
{ adaptation: dataInfos.inventoryInfos.adaptation });
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
77
|
}
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from "../../../../transports";
|
|
29
29
|
import assert from "../../../../utils/assert";
|
|
30
30
|
import EventEmitter from "../../../../utils/event_emitter";
|
|
31
|
+
import noop from "../../../../utils/noop";
|
|
31
32
|
import objectAssign from "../../../../utils/object_assign";
|
|
32
33
|
import createSharedReference, {
|
|
33
34
|
IReadOnlySharedReference,
|
|
@@ -231,6 +232,7 @@ export default class DownloadingQueue<T>
|
|
|
231
232
|
|
|
232
233
|
public stop() {
|
|
233
234
|
this._currentCanceller?.cancel();
|
|
235
|
+
this._currentCanceller = null;
|
|
234
236
|
}
|
|
235
237
|
|
|
236
238
|
/**
|
|
@@ -245,7 +247,7 @@ export default class DownloadingQueue<T>
|
|
|
245
247
|
const recursivelyRequestSegments = (
|
|
246
248
|
startingSegment : IQueuedSegment | undefined
|
|
247
249
|
) : void => {
|
|
248
|
-
if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
|
|
250
|
+
if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
|
|
249
251
|
this._mediaSegmentRequest = null;
|
|
250
252
|
return;
|
|
251
253
|
}
|
|
@@ -254,7 +256,10 @@ export default class DownloadingQueue<T>
|
|
|
254
256
|
this.trigger("emptyQueue", null);
|
|
255
257
|
return;
|
|
256
258
|
}
|
|
257
|
-
const canceller = new TaskCanceller(
|
|
259
|
+
const canceller = new TaskCanceller();
|
|
260
|
+
const unlinkCanceller = this._currentCanceller === null ?
|
|
261
|
+
noop :
|
|
262
|
+
canceller.linkToSignal(this._currentCanceller.signal);
|
|
258
263
|
|
|
259
264
|
const { segment, priority } = startingSegment;
|
|
260
265
|
const context = objectAssign({ segment }, this._content);
|
|
@@ -368,6 +373,7 @@ export default class DownloadingQueue<T>
|
|
|
368
373
|
* requests are scheduled. It is used to schedule the next segment.
|
|
369
374
|
*/
|
|
370
375
|
beforeEnded: () : void => {
|
|
376
|
+
unlinkCanceller();
|
|
371
377
|
this._mediaSegmentRequest = null;
|
|
372
378
|
|
|
373
379
|
if (isWaitingOnInitSegment) {
|
|
@@ -381,6 +387,7 @@ export default class DownloadingQueue<T>
|
|
|
381
387
|
}, canceller.signal);
|
|
382
388
|
|
|
383
389
|
request.catch((error : unknown) => {
|
|
390
|
+
unlinkCanceller();
|
|
384
391
|
if (!isComplete) {
|
|
385
392
|
isComplete = true;
|
|
386
393
|
this.stop();
|
|
@@ -400,7 +407,7 @@ export default class DownloadingQueue<T>
|
|
|
400
407
|
private _restartInitSegmentDownloadingQueue(
|
|
401
408
|
queuedInitSegment : IQueuedSegment | null
|
|
402
409
|
) : void {
|
|
403
|
-
if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
|
|
410
|
+
if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
|
|
404
411
|
return;
|
|
405
412
|
}
|
|
406
413
|
if (this._initSegmentRequest !== null) {
|
|
@@ -410,7 +417,10 @@ export default class DownloadingQueue<T>
|
|
|
410
417
|
return ;
|
|
411
418
|
}
|
|
412
419
|
|
|
413
|
-
const canceller = new TaskCanceller(
|
|
420
|
+
const canceller = new TaskCanceller();
|
|
421
|
+
const unlinkCanceller = this._currentCanceller === null ?
|
|
422
|
+
noop :
|
|
423
|
+
canceller.linkToSignal(this._currentCanceller.signal);
|
|
414
424
|
const { segment, priority } = queuedInitSegment;
|
|
415
425
|
const context = objectAssign({ segment }, this._content);
|
|
416
426
|
|
|
@@ -428,6 +438,7 @@ export default class DownloadingQueue<T>
|
|
|
428
438
|
log.info("Stream: init segment request interrupted temporarly.", segment.id);
|
|
429
439
|
},
|
|
430
440
|
beforeEnded: () => {
|
|
441
|
+
unlinkCanceller();
|
|
431
442
|
this._initSegmentRequest = null;
|
|
432
443
|
isComplete = true;
|
|
433
444
|
},
|
|
@@ -446,6 +457,7 @@ export default class DownloadingQueue<T>
|
|
|
446
457
|
}, canceller.signal);
|
|
447
458
|
|
|
448
459
|
request.catch((error : unknown) => {
|
|
460
|
+
unlinkCanceller();
|
|
449
461
|
if (!isComplete) {
|
|
450
462
|
isComplete = true;
|
|
451
463
|
this.stop();
|
|
@@ -20,6 +20,7 @@ import Manifest, {
|
|
|
20
20
|
Period,
|
|
21
21
|
Representation,
|
|
22
22
|
} from "../../../../manifest";
|
|
23
|
+
import objectAssign from "../../../../utils/object_assign";
|
|
23
24
|
import { CancellationSignal } from "../../../../utils/task_canceller";
|
|
24
25
|
import { IReadOnlyPlaybackObserver } from "../../../api";
|
|
25
26
|
import {
|
|
@@ -42,6 +43,7 @@ export default async function pushInitSegment<T>(
|
|
|
42
43
|
{
|
|
43
44
|
playbackObserver,
|
|
44
45
|
content,
|
|
46
|
+
initSegmentUniqueId,
|
|
45
47
|
segment,
|
|
46
48
|
segmentData,
|
|
47
49
|
segmentBuffer,
|
|
@@ -53,27 +55,30 @@ export default async function pushInitSegment<T>(
|
|
|
53
55
|
manifest : Manifest;
|
|
54
56
|
period : Period;
|
|
55
57
|
representation : Representation; };
|
|
56
|
-
|
|
58
|
+
initSegmentUniqueId : string;
|
|
59
|
+
segmentData : T;
|
|
57
60
|
segment : ISegment;
|
|
58
61
|
segmentBuffer : SegmentBuffer;
|
|
59
62
|
},
|
|
60
63
|
cancelSignal : CancellationSignal
|
|
61
64
|
) : Promise< IStreamEventAddedSegmentPayload<T> | null > {
|
|
62
|
-
if (segmentData === null) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
65
|
if (cancelSignal.cancellationError !== null) {
|
|
66
66
|
throw cancelSignal.cancellationError;
|
|
67
67
|
}
|
|
68
68
|
const codec = content.representation.getMimeTypeString();
|
|
69
|
-
const data : IPushedChunkData<T> = {
|
|
69
|
+
const data : IPushedChunkData<T> = { initSegmentUniqueId,
|
|
70
70
|
chunk: null,
|
|
71
71
|
timestampOffset: 0,
|
|
72
72
|
appendWindow: [ undefined, undefined ],
|
|
73
73
|
codec };
|
|
74
|
+
const inventoryInfos = objectAssign({ segment,
|
|
75
|
+
chunkSize: undefined,
|
|
76
|
+
start: 0,
|
|
77
|
+
end: 0 },
|
|
78
|
+
content);
|
|
74
79
|
await appendSegmentToBuffer(playbackObserver,
|
|
75
80
|
segmentBuffer,
|
|
76
|
-
{ data, inventoryInfos
|
|
81
|
+
{ data, inventoryInfos },
|
|
77
82
|
cancelSignal);
|
|
78
83
|
const buffered = segmentBuffer.getBufferedRanges();
|
|
79
84
|
return { content, segment, buffered, segmentData };
|
|
@@ -41,7 +41,7 @@ import appendSegmentToBuffer from "./append_segment_to_buffer";
|
|
|
41
41
|
export default async function pushMediaSegment<T>(
|
|
42
42
|
{ playbackObserver,
|
|
43
43
|
content,
|
|
44
|
-
|
|
44
|
+
initSegmentUniqueId,
|
|
45
45
|
parsedSegment,
|
|
46
46
|
segment,
|
|
47
47
|
segmentBuffer } :
|
|
@@ -52,7 +52,7 @@ export default async function pushMediaSegment<T>(
|
|
|
52
52
|
manifest : Manifest;
|
|
53
53
|
period : Period;
|
|
54
54
|
representation : Representation; };
|
|
55
|
-
|
|
55
|
+
initSegmentUniqueId : string | null;
|
|
56
56
|
parsedSegment : ISegmentParserParsedMediaChunk<T>;
|
|
57
57
|
segment : ISegment;
|
|
58
58
|
segmentBuffer : SegmentBuffer; },
|
|
@@ -83,7 +83,7 @@ export default async function pushMediaSegment<T>(
|
|
|
83
83
|
undefined,
|
|
84
84
|
];
|
|
85
85
|
|
|
86
|
-
const data = {
|
|
86
|
+
const data = { initSegmentUniqueId,
|
|
87
87
|
chunk: chunkData,
|
|
88
88
|
timestampOffset: chunkOffset,
|
|
89
89
|
appendWindow: safeAppendWindow,
|