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
|
@@ -40,48 +40,68 @@ import {
|
|
|
40
40
|
import { CancellationSignal } from "../../../../utils/task_canceller";
|
|
41
41
|
|
|
42
42
|
/** Default MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
43
|
-
export const defaultKSConfig = [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}]
|
|
43
|
+
export const defaultKSConfig = [
|
|
44
|
+
{
|
|
45
|
+
audioCapabilities: [ { contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
46
|
+
{ contentType: "audio/webm;codecs=opus" } ],
|
|
47
|
+
distinctiveIdentifier: "optional" as const,
|
|
48
|
+
initDataTypes: ["cenc"] as const,
|
|
49
|
+
persistentState: "optional" as const,
|
|
50
|
+
sessionTypes: ["temporary"] as const,
|
|
51
|
+
videoCapabilities: [ { contentType: "video/mp4;codecs=\"avc1.4d401e\"" },
|
|
52
|
+
{ contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
53
|
+
{ contentType: "video/webm;codecs=\"vp8\"" } ],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
audioCapabilities: undefined,
|
|
57
|
+
distinctiveIdentifier: "optional" as const,
|
|
58
|
+
initDataTypes: ["cenc"] as const,
|
|
59
|
+
persistentState: "optional" as const,
|
|
60
|
+
sessionTypes: ["temporary"] as const,
|
|
61
|
+
videoCapabilities: undefined,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
54
64
|
|
|
55
65
|
/**
|
|
56
66
|
* Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
|
|
57
67
|
* configuration used by the RxPlayer.
|
|
58
68
|
*/
|
|
59
|
-
export const defaultPRRecommendationKSConfig = [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}]
|
|
69
|
+
export const defaultPRRecommendationKSConfig = [
|
|
70
|
+
{
|
|
71
|
+
audioCapabilities: [ { robustness: "3000",
|
|
72
|
+
contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
73
|
+
{ robustness: "3000",
|
|
74
|
+
contentType: "audio/webm;codecs=opus" },
|
|
75
|
+
{ robustness: "2000",
|
|
76
|
+
contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
77
|
+
{ robustness: "2000",
|
|
78
|
+
contentType: "audio/webm;codecs=opus" } ],
|
|
79
|
+
distinctiveIdentifier: "optional" as const,
|
|
80
|
+
initDataTypes: ["cenc"] as const,
|
|
81
|
+
persistentState: "optional" as const,
|
|
82
|
+
sessionTypes: ["temporary"] as const,
|
|
83
|
+
videoCapabilities: [ { robustness: "3000",
|
|
84
|
+
contentType: "video/mp4;codecs=\"avc1.4d401e\"" },
|
|
85
|
+
{ robustness: "3000",
|
|
86
|
+
contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
87
|
+
{ robustness: "3000",
|
|
88
|
+
contentType: "video/webm;codecs=\"vp8\"" },
|
|
89
|
+
{ robustness: "2000",
|
|
90
|
+
contentType: "video/mp4;codecs=\"avc1.4d401e\"" },
|
|
91
|
+
{ robustness: "2000",
|
|
92
|
+
contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
93
|
+
{ robustness: "2000",
|
|
94
|
+
contentType: "video/webm;codecs=\"vp8\"" } ],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
audioCapabilities: undefined,
|
|
98
|
+
distinctiveIdentifier: "optional" as const,
|
|
99
|
+
initDataTypes: ["cenc"] as const,
|
|
100
|
+
persistentState: "optional" as const,
|
|
101
|
+
sessionTypes: ["temporary"] as const,
|
|
102
|
+
videoCapabilities: undefined,
|
|
103
|
+
},
|
|
104
|
+
];
|
|
85
105
|
|
|
86
106
|
/** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
87
107
|
export const defaultWidevineConfig = (() => {
|
|
@@ -104,9 +124,10 @@ export const defaultWidevineConfig = (() => {
|
|
|
104
124
|
{ contentType: "audio/webm;codecs=opus",
|
|
105
125
|
robustness } ];
|
|
106
126
|
});
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
return [
|
|
128
|
+
{ ...defaultKSConfig[0], audioCapabilities, videoCapabilities },
|
|
129
|
+
defaultKSConfig[1],
|
|
130
|
+
];
|
|
110
131
|
})();
|
|
111
132
|
|
|
112
133
|
/**
|
|
@@ -62,7 +62,7 @@ export default async function attachMediaKeys(
|
|
|
62
62
|
|
|
63
63
|
// If this task has been cancelled while we were closing previous sessions,
|
|
64
64
|
// stop now (and thus avoid setting the new media keys);
|
|
65
|
-
if (cancelSignal.isCancelled) {
|
|
65
|
+
if (cancelSignal.isCancelled()) {
|
|
66
66
|
throw cancelSignal.cancellationError;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -727,7 +727,7 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
|
|
|
727
727
|
* formatted and sent in an "error" event.
|
|
728
728
|
*/
|
|
729
729
|
private _onFatalError(err : unknown) : void {
|
|
730
|
-
if (this._canceller.isUsed) {
|
|
730
|
+
if (this._canceller.isUsed()) {
|
|
731
731
|
return;
|
|
732
732
|
}
|
|
733
733
|
const formattedErr = err instanceof Error ?
|
|
@@ -156,7 +156,9 @@ function buildKeySystemConfigurations(
|
|
|
156
156
|
if (!isNullOrUndefined(keySystem.distinctiveIdentifier)) {
|
|
157
157
|
distinctiveIdentifier = keySystem.distinctiveIdentifier;
|
|
158
158
|
}
|
|
159
|
-
const {
|
|
159
|
+
const { EME_DEFAULT_AUDIO_CODECS,
|
|
160
|
+
EME_DEFAULT_VIDEO_CODECS,
|
|
161
|
+
EME_DEFAULT_WIDEVINE_ROBUSTNESSES,
|
|
160
162
|
EME_DEFAULT_PLAYREADY_RECOMMENDATION_ROBUSTNESSES } = config.getCurrent();
|
|
161
163
|
|
|
162
164
|
// From the W3 EME spec, we have to provide videoCapabilities and
|
|
@@ -195,7 +197,7 @@ function buildKeySystemConfigurations(
|
|
|
195
197
|
|
|
196
198
|
const audioCodecs = audioCapabilitiesConfig?.type === "contentType" ?
|
|
197
199
|
audioCapabilitiesConfig.value :
|
|
198
|
-
|
|
200
|
+
EME_DEFAULT_AUDIO_CODECS;
|
|
199
201
|
|
|
200
202
|
audioCapabilities = flatMap(audioRobustnesses, (robustness) =>
|
|
201
203
|
audioCodecs.map(contentType => {
|
|
@@ -223,9 +225,7 @@ function buildKeySystemConfigurations(
|
|
|
223
225
|
|
|
224
226
|
const videoCodecs = videoCapabilitiesConfig?.type === "contentType" ?
|
|
225
227
|
videoCapabilitiesConfig.value :
|
|
226
|
-
|
|
227
|
-
"video/mp4;codecs=\"avc1.42e01e\"",
|
|
228
|
-
"video/webm;codecs=\"vp8\""];
|
|
228
|
+
EME_DEFAULT_VIDEO_CODECS;
|
|
229
229
|
|
|
230
230
|
videoCapabilities = flatMap(videoRobustnesses, (robustness) =>
|
|
231
231
|
videoCodecs.map(contentType => {
|
|
@@ -234,12 +234,26 @@ function buildKeySystemConfigurations(
|
|
|
234
234
|
}));
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
237
|
+
const wantedMediaKeySystemConfiguration : MediaKeySystemConfiguration = {
|
|
238
|
+
initDataTypes: ["cenc"],
|
|
239
|
+
videoCapabilities,
|
|
240
|
+
audioCapabilities,
|
|
241
|
+
distinctiveIdentifier,
|
|
242
|
+
persistentState,
|
|
243
|
+
sessionTypes,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
return [
|
|
247
|
+
wantedMediaKeySystemConfiguration,
|
|
248
|
+
|
|
249
|
+
// Some legacy implementations have issues with `audioCapabilities` and
|
|
250
|
+
// `videoCapabilities`, so we're including a supplementary
|
|
251
|
+
// `MediaKeySystemConfiguration` without those properties.
|
|
252
|
+
{ ...wantedMediaKeySystemConfiguration,
|
|
253
|
+
audioCapabilities: undefined ,
|
|
254
|
+
videoCapabilities: undefined,
|
|
255
|
+
} as unknown as MediaKeySystemConfiguration,
|
|
256
|
+
];
|
|
243
257
|
}
|
|
244
258
|
|
|
245
259
|
/**
|
|
@@ -58,13 +58,14 @@ export default function SessionEventsListener(
|
|
|
58
58
|
const { getLicenseConfig = {} } = keySystemOptions;
|
|
59
59
|
|
|
60
60
|
/** Allows to manually cancel everything the `SessionEventsListener` is doing. */
|
|
61
|
-
const manualCanceller = new TaskCanceller(
|
|
61
|
+
const manualCanceller = new TaskCanceller();
|
|
62
|
+
manualCanceller.linkToSignal(cancelSignal);
|
|
62
63
|
|
|
63
64
|
if (!isNullOrUndefined(session.closed)) {
|
|
64
65
|
session.closed
|
|
65
66
|
.then(() => manualCanceller.cancel())
|
|
66
67
|
.catch((err) => { // Should never happen
|
|
67
|
-
if (cancelSignal.isCancelled) {
|
|
68
|
+
if (cancelSignal.isCancelled()) {
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
70
71
|
manualCanceller.cancel();
|
|
@@ -79,10 +80,10 @@ export default function SessionEventsListener(
|
|
|
79
80
|
|
|
80
81
|
onKeyStatusesChange(session, () => {
|
|
81
82
|
try {
|
|
82
|
-
|
|
83
|
+
checkAndHandleCurrentKeyStatuses();
|
|
83
84
|
} catch (error) {
|
|
84
|
-
if (cancelSignal.isCancelled ||
|
|
85
|
-
(manualCanceller.isUsed && error instanceof CancellationSignal))
|
|
85
|
+
if (cancelSignal.isCancelled() ||
|
|
86
|
+
(manualCanceller.isUsed() && error instanceof CancellationSignal))
|
|
86
87
|
{
|
|
87
88
|
return;
|
|
88
89
|
}
|
|
@@ -106,17 +107,22 @@ export default function SessionEventsListener(
|
|
|
106
107
|
backoffOptions,
|
|
107
108
|
manualCanceller.signal)
|
|
108
109
|
.then((licenseObject) => {
|
|
109
|
-
if (manualCanceller.isUsed) {
|
|
110
|
+
if (manualCanceller.isUsed()) {
|
|
110
111
|
return Promise.resolve();
|
|
111
112
|
}
|
|
112
113
|
if (isNullOrUndefined(licenseObject)) {
|
|
113
114
|
log.info("DRM: No license given, skipping session.update");
|
|
114
115
|
} else {
|
|
115
|
-
|
|
116
|
+
try {
|
|
117
|
+
return updateSessionWithMessage(session, licenseObject);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
manualCanceller.cancel();
|
|
120
|
+
callbacks.onError(err);
|
|
121
|
+
}
|
|
116
122
|
}
|
|
117
123
|
})
|
|
118
124
|
.catch((err : unknown) => {
|
|
119
|
-
if (manualCanceller.isUsed) {
|
|
125
|
+
if (manualCanceller.isUsed()) {
|
|
120
126
|
return;
|
|
121
127
|
}
|
|
122
128
|
manualCanceller.cancel();
|
|
@@ -135,23 +141,25 @@ export default function SessionEventsListener(
|
|
|
135
141
|
});
|
|
136
142
|
}, manualCanceller.signal);
|
|
137
143
|
|
|
144
|
+
checkAndHandleCurrentKeyStatuses();
|
|
145
|
+
return;
|
|
138
146
|
/**
|
|
139
147
|
* Check current MediaKeyStatus for each key in the given MediaKeySession and:
|
|
140
148
|
* - throw if at least one status is a non-recoverable error
|
|
141
149
|
* - call warning callback for recoverable errors
|
|
142
150
|
* - call onKeyUpdate callback when the MediaKeyStatus of any key is updated
|
|
143
151
|
*/
|
|
144
|
-
function
|
|
152
|
+
function checkAndHandleCurrentKeyStatuses() : void {
|
|
145
153
|
log.info("DRM: keystatuseschange event received", session.sessionId);
|
|
146
154
|
|
|
147
|
-
if (manualCanceller.isUsed || session.keyStatuses.size === 0) {
|
|
155
|
+
if (manualCanceller.isUsed() || session.keyStatuses.size === 0) {
|
|
148
156
|
return ;
|
|
149
157
|
}
|
|
150
158
|
const { warning, blacklistedKeyIds, whitelistedKeyIds } =
|
|
151
159
|
checkKeyStatuses(session, keySystemOptions, keySystem);
|
|
152
160
|
if (warning !== undefined) {
|
|
153
161
|
callbacks.onWarning(warning);
|
|
154
|
-
if (manualCanceller.isUsed) {
|
|
162
|
+
if (manualCanceller.isUsed()) {
|
|
155
163
|
return;
|
|
156
164
|
}
|
|
157
165
|
}
|
|
@@ -162,40 +170,38 @@ export default function SessionEventsListener(
|
|
|
162
170
|
message : Uint8Array,
|
|
163
171
|
messageType : MediaKeyMessageType
|
|
164
172
|
) : Promise<BufferSource | null> {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const getLicense = keySystemOptions.getLicense(message, messageType);
|
|
168
|
-
const getLicenseTimeout = isNullOrUndefined(getLicenseConfig.timeout) ?
|
|
169
|
-
10 * 1000 :
|
|
170
|
-
getLicenseConfig.timeout;
|
|
171
|
-
|
|
172
|
-
let timeoutId : number | undefined;
|
|
173
|
-
if (getLicenseTimeout >= 0) {
|
|
174
|
-
timeoutId = setTimeout(() => {
|
|
175
|
-
rej(new GetLicenseTimeoutError(
|
|
176
|
-
`"getLicense" timeout exceeded (${getLicenseTimeout} ms)`
|
|
177
|
-
));
|
|
178
|
-
}, getLicenseTimeout) as unknown as number;
|
|
179
|
-
}
|
|
180
|
-
|
|
173
|
+
let timeoutId : number | undefined;
|
|
174
|
+
return new Promise<BufferSource | null>((res, rej) => {
|
|
181
175
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
log.debug("DRM: Calling `getLicense`", messageType);
|
|
177
|
+
const getLicense = keySystemOptions.getLicense(message, messageType);
|
|
178
|
+
const getLicenseTimeout = isNullOrUndefined(getLicenseConfig.timeout) ?
|
|
179
|
+
10 * 1000 :
|
|
180
|
+
getLicenseConfig.timeout;
|
|
181
|
+
|
|
182
|
+
if (getLicenseTimeout >= 0) {
|
|
183
|
+
timeoutId = setTimeout(() => {
|
|
184
|
+
rej(new GetLicenseTimeoutError(
|
|
185
|
+
`"getLicense" timeout exceeded (${getLicenseTimeout} ms)`
|
|
186
|
+
));
|
|
187
|
+
}, getLicenseTimeout) as unknown as number;
|
|
188
|
+
}
|
|
189
|
+
Promise.resolve(getLicense)
|
|
190
|
+
.then(clearTimeoutAndResolve, clearTimeoutAndReject);
|
|
191
191
|
} catch (err) {
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
clearTimeoutAndReject(err);
|
|
193
|
+
}
|
|
194
|
+
function clearTimeoutAndResolve(data : BufferSource | null) {
|
|
195
|
+
if (timeoutId !== undefined) {
|
|
196
|
+
clearTimeout(timeoutId);
|
|
197
|
+
}
|
|
198
|
+
res(data);
|
|
194
199
|
}
|
|
195
|
-
function
|
|
200
|
+
function clearTimeoutAndReject(err : unknown) {
|
|
196
201
|
if (timeoutId !== undefined) {
|
|
197
202
|
clearTimeout(timeoutId);
|
|
198
203
|
}
|
|
204
|
+
rej(err);
|
|
199
205
|
}
|
|
200
206
|
});
|
|
201
207
|
}
|
|
@@ -18,6 +18,7 @@ import { ICustomMediaKeySession } from "../../../compat";
|
|
|
18
18
|
/* eslint-disable-next-line max-len */
|
|
19
19
|
import getUUIDKidFromKeyStatusKID from "../../../compat/eme/get_uuid_kid_from_keystatus_kid";
|
|
20
20
|
import { EncryptedMediaError } from "../../../errors";
|
|
21
|
+
import log from "../../../log";
|
|
21
22
|
import {
|
|
22
23
|
IEncryptedMediaErrorKeyStatusObject,
|
|
23
24
|
IKeySystemOption,
|
|
@@ -111,6 +112,11 @@ export default function checkKeyStatuses(
|
|
|
111
112
|
new Uint8Array(keyStatusKeyId));
|
|
112
113
|
|
|
113
114
|
const keyStatusObj = { keyId: keyId.buffer, keyStatus };
|
|
115
|
+
|
|
116
|
+
if (log.hasLevel("DEBUG")) {
|
|
117
|
+
log.debug(`DRM: key status update (${bytesToHex(keyId)}): ${keyStatus}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
114
120
|
switch (keyStatus) {
|
|
115
121
|
case KEY_STATUSES.EXPIRED: {
|
|
116
122
|
const error = new EncryptedMediaError(
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import log from "../../../log";
|
|
17
18
|
import LoadedSessionsStore from "./loaded_sessions_store";
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -32,7 +33,7 @@ export default async function cleanOldLoadedSessions(
|
|
|
32
33
|
if (limit < 0 || limit >= loadedSessionsStore.getLength()) {
|
|
33
34
|
return ;
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
log.info("DRM: LSS cache limit exceeded", limit, loadedSessionsStore.getLength());
|
|
36
37
|
const proms : Array<Promise<unknown>> = [];
|
|
37
38
|
const entries = loadedSessionsStore.getAll().slice(); // clone
|
|
38
39
|
const toDelete = entries.length - limit;
|
|
@@ -63,6 +63,7 @@ export default class LoadedSessionsStore {
|
|
|
63
63
|
sessionType : MediaKeySessionType
|
|
64
64
|
) : IStoredSessionEntry {
|
|
65
65
|
const keySessionRecord = new KeySessionRecord(initData);
|
|
66
|
+
log.debug("DRM-LSS: calling `createSession`", sessionType);
|
|
66
67
|
const mediaKeySession = this._mediaKeys.createSession(sessionType);
|
|
67
68
|
const entry = { mediaKeySession,
|
|
68
69
|
sessionType,
|
|
@@ -73,6 +74,8 @@ export default class LoadedSessionsStore {
|
|
|
73
74
|
if (!isNullOrUndefined(mediaKeySession.closed)) {
|
|
74
75
|
mediaKeySession.closed
|
|
75
76
|
.then(() => {
|
|
77
|
+
log.info("DRM-LSS: session was closed, removing it.",
|
|
78
|
+
mediaKeySession.sessionId);
|
|
76
79
|
const index = this.getIndex(keySessionRecord);
|
|
77
80
|
if (index >= 0 &&
|
|
78
81
|
this._storage[index].mediaKeySession === mediaKeySession)
|
|
@@ -86,8 +89,8 @@ export default class LoadedSessionsStore {
|
|
|
86
89
|
});
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
log.debug("DRM-LSS: Add MediaKeySession", entry.sessionType);
|
|
90
92
|
this._storage.push({ ...entry });
|
|
93
|
+
log.debug("DRM-LSS: MediaKeySession added", entry.sessionType, this._storage.length);
|
|
91
94
|
return entry;
|
|
92
95
|
}
|
|
93
96
|
|
|
@@ -111,6 +114,8 @@ export default class LoadedSessionsStore {
|
|
|
111
114
|
if (stored.keySessionRecord.isCompatibleWith(initializationData)) {
|
|
112
115
|
this._storage.splice(i, 1);
|
|
113
116
|
this._storage.push(stored);
|
|
117
|
+
log.debug("DRM-LSS: Reusing session:",
|
|
118
|
+
stored.mediaKeySession.sessionId, stored.sessionType);
|
|
114
119
|
return { ...stored };
|
|
115
120
|
}
|
|
116
121
|
}
|
|
@@ -332,6 +337,8 @@ export default class LoadedSessionsStore {
|
|
|
332
337
|
for (let i = this._storage.length - 1; i >= 0; i--) {
|
|
333
338
|
const stored = this._storage[i];
|
|
334
339
|
if (stored.mediaKeySession === mediaKeySession) {
|
|
340
|
+
log.debug("DRM-LSS: Removing session without closing it",
|
|
341
|
+
mediaKeySession.sessionId);
|
|
335
342
|
this._storage.splice(i, 1);
|
|
336
343
|
return true;
|
|
337
344
|
}
|
|
@@ -16,19 +16,22 @@
|
|
|
16
16
|
|
|
17
17
|
import config from "../../config";
|
|
18
18
|
import { ICdnMetadata } from "../../parsers/manifest";
|
|
19
|
-
import { IPlayerError } from "../../public_types";
|
|
20
19
|
import arrayFindIndex from "../../utils/array_find_index";
|
|
21
20
|
import EventEmitter from "../../utils/event_emitter";
|
|
22
21
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
|
-
* Class signaling the priority between multiple CDN available for
|
|
26
|
-
* resource.
|
|
24
|
+
* Class storing and signaling the priority between multiple CDN available for
|
|
25
|
+
* any given resource.
|
|
27
26
|
*
|
|
28
|
-
* This class
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* This class was first created to implement the complexities behind
|
|
28
|
+
* Content Steering features, though its handling hasn't been added yet as we
|
|
29
|
+
* wait for its specification to be both standardized and relied on in the wild.
|
|
30
|
+
* In the meantime, it acts as an abstraction for the simple concept of
|
|
31
|
+
* avoiding to request a CDN for any segment when an issue is encountered with
|
|
32
|
+
* one (e.g. HTTP 500 statuses) and several CDN exist for a given resource. It
|
|
33
|
+
* should be noted that this is also one of the planified features of the
|
|
34
|
+
* Content Steering specification.
|
|
32
35
|
*
|
|
33
36
|
* @class CdnPrioritizer
|
|
34
37
|
*/
|
|
@@ -41,7 +44,7 @@ export default class CdnPrioritizer extends EventEmitter<ICdnPrioritizerEvents>
|
|
|
41
44
|
private _downgradedCdnList : {
|
|
42
45
|
/**
|
|
43
46
|
* Metadata of downgraded CDN, sorted by the time at which they have
|
|
44
|
-
* been downgraded.
|
|
47
|
+
* been downgraded ascending.
|
|
45
48
|
*/
|
|
46
49
|
metadata : ICdnMetadata[];
|
|
47
50
|
/**
|
|
@@ -174,8 +177,14 @@ export default class CdnPrioritizer extends EventEmitter<ICdnPrioritizerEvents>
|
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
/** Events sent by a `CdnPrioritizer` */
|
|
177
181
|
export interface ICdnPrioritizerEvents {
|
|
178
|
-
|
|
182
|
+
/**
|
|
183
|
+
* The priority of one or several CDN changed.
|
|
184
|
+
*
|
|
185
|
+
* You might want to re-check if a CDN should still be used when this event
|
|
186
|
+
* is triggered.
|
|
187
|
+
*/
|
|
179
188
|
priorityChange : null;
|
|
180
189
|
}
|
|
181
190
|
|
|
@@ -154,7 +154,7 @@ export default class ManifestFetcher extends EventEmitter<IManifestFetcherEvent>
|
|
|
154
154
|
manifestProm
|
|
155
155
|
.then((val : IManifestFetcherParsedResult) => {
|
|
156
156
|
this.trigger("manifestReady", val.manifest);
|
|
157
|
-
if (!this._canceller.isUsed) {
|
|
157
|
+
if (!this._canceller.isUsed()) {
|
|
158
158
|
this._recursivelyRefreshManifest(val.manifest, val);
|
|
159
159
|
}
|
|
160
160
|
})
|
|
@@ -340,7 +340,7 @@ export default class ManifestFetcher extends EventEmitter<IManifestFetcherEvent>
|
|
|
340
340
|
*/
|
|
341
341
|
function onWarnings(warnings : Error[]) : void {
|
|
342
342
|
for (const warning of warnings) {
|
|
343
|
-
if (cancelSignal.isCancelled) {
|
|
343
|
+
if (cancelSignal.isCancelled()) {
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
346
|
const formattedError = formatError(warning, {
|
|
@@ -444,7 +444,8 @@ export default class ManifestFetcher extends EventEmitter<IManifestFetcherEvent>
|
|
|
444
444
|
* be effectively considered.
|
|
445
445
|
* `nextRefreshCanceller` will allow to cancel every other when one is triggered.
|
|
446
446
|
*/
|
|
447
|
-
const nextRefreshCanceller = new TaskCanceller(
|
|
447
|
+
const nextRefreshCanceller = new TaskCanceller();
|
|
448
|
+
nextRefreshCanceller.linkToSignal(this._canceller.signal);
|
|
448
449
|
|
|
449
450
|
/* Function to manually schedule a Manifest refresh */
|
|
450
451
|
this.scheduleManualRefresh = (settings : IManifestRefreshSettings) => {
|
|
@@ -643,7 +644,7 @@ export default class ManifestFetcher extends EventEmitter<IManifestFetcherEvent>
|
|
|
643
644
|
}
|
|
644
645
|
|
|
645
646
|
private _onFatalError(err : unknown) : void {
|
|
646
|
-
if (this._canceller.isUsed) {
|
|
647
|
+
if (this._canceller.isUsed()) {
|
|
647
648
|
return;
|
|
648
649
|
}
|
|
649
650
|
this.trigger("error", err);
|
|
@@ -64,10 +64,22 @@ const generateRequestID = idGenerator();
|
|
|
64
64
|
* An `ISegmentFetcher` also implements a retry mechanism, based on the given
|
|
65
65
|
* `options` argument, which may retry a segment request when it fails.
|
|
66
66
|
*
|
|
67
|
-
* @param {string} bufferType
|
|
68
|
-
*
|
|
69
|
-
* @param {Object}
|
|
70
|
-
*
|
|
67
|
+
* @param {string} bufferType - Type of buffer concerned (e.g. `"audio"`,
|
|
68
|
+
* `"video"`, `"text" etc.)
|
|
69
|
+
* @param {Object} pipeline - The transport-specific logic allowing to load
|
|
70
|
+
* segments of the given buffer type and transport protocol (e.g. DASH).
|
|
71
|
+
* @param {Object|null} cdnPrioritizer - Abstraction allowing to synchronize,
|
|
72
|
+
* update and keep track of the priorization of the CDN to use to load any given
|
|
73
|
+
* segment, in cases where multiple ones are available.
|
|
74
|
+
*
|
|
75
|
+
* Can be set to `null` in which case a minimal priorization logic will be used
|
|
76
|
+
* instead.
|
|
77
|
+
* @param {Object} lifecycleCallbacks - Callbacks that can be registered to be
|
|
78
|
+
* informed when new requests are made, ended, new metrics are available etc.
|
|
79
|
+
* This should be mainly useful to implement an adaptive logic relying on those
|
|
80
|
+
* metrics and events.
|
|
81
|
+
* @param {Object} options - Various tweaking options allowing to configure the
|
|
82
|
+
* behavior of the returned `ISegmentFetcher`.
|
|
71
83
|
* @returns {Function}
|
|
72
84
|
*/
|
|
73
85
|
export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(
|
|
@@ -197,14 +209,7 @@ export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(
|
|
|
197
209
|
id: requestId,
|
|
198
210
|
content });
|
|
199
211
|
|
|
200
|
-
cancellationSignal.register(
|
|
201
|
-
if (requestInfo !== undefined) {
|
|
202
|
-
return; // Request already terminated
|
|
203
|
-
}
|
|
204
|
-
log.debug("SF: Segment request cancelled", segmentIdString);
|
|
205
|
-
requestInfo = null;
|
|
206
|
-
lifecycleCallbacks.onRequestEnd?.({ id: requestId });
|
|
207
|
-
});
|
|
212
|
+
cancellationSignal.register(onCancellation);
|
|
208
213
|
|
|
209
214
|
try {
|
|
210
215
|
const res = await scheduleRequestWithCdns(content.representation.cdnMetadata,
|
|
@@ -233,22 +238,34 @@ export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(
|
|
|
233
238
|
requestInfo = null;
|
|
234
239
|
}
|
|
235
240
|
|
|
236
|
-
if (!cancellationSignal.isCancelled) {
|
|
241
|
+
if (!cancellationSignal.isCancelled()) {
|
|
237
242
|
// The current task could have been canceled as a result of one
|
|
238
243
|
// of the previous callbacks call. In that case, we don't want to send
|
|
239
244
|
// a "requestEnd" again as it has already been sent on cancellation.
|
|
240
245
|
lifecycleCallbacks.onRequestEnd?.({ id: requestId });
|
|
241
246
|
}
|
|
247
|
+
cancellationSignal.deregister(onCancellation);
|
|
242
248
|
} catch (err) {
|
|
249
|
+
cancellationSignal.deregister(onCancellation);
|
|
243
250
|
requestInfo = null;
|
|
244
251
|
if (err instanceof CancellationError) {
|
|
245
252
|
log.debug("SF: Segment request aborted", segmentIdString);
|
|
246
253
|
throw err;
|
|
247
254
|
}
|
|
248
255
|
log.debug("SF: Segment request failed", segmentIdString);
|
|
256
|
+
lifecycleCallbacks.onRequestEnd?.({ id: requestId });
|
|
249
257
|
throw errorSelector(err);
|
|
250
258
|
}
|
|
251
259
|
|
|
260
|
+
function onCancellation() {
|
|
261
|
+
if (requestInfo !== undefined) {
|
|
262
|
+
return; // Request already terminated
|
|
263
|
+
}
|
|
264
|
+
log.debug("SF: Segment request cancelled", segmentIdString);
|
|
265
|
+
requestInfo = null;
|
|
266
|
+
lifecycleCallbacks.onRequestEnd?.({ id: requestId });
|
|
267
|
+
}
|
|
268
|
+
|
|
252
269
|
/**
|
|
253
270
|
* Call a segment loader for the given URL with the right arguments.
|
|
254
271
|
* @param {Object|null} cdnMetadata
|
|
@@ -373,11 +390,16 @@ export interface ISegmentFetcherCallbacks<TSegmentDataType> {
|
|
|
373
390
|
/**
|
|
374
391
|
* Callback called when all decodable chunks of the loaded segment have been
|
|
375
392
|
* communicated through the `onChunk` callback.
|
|
393
|
+
*
|
|
394
|
+
* This callback is called before the corresponding `ISegmentFetcher`'s
|
|
395
|
+
* returned Promise is resolved.
|
|
376
396
|
*/
|
|
377
397
|
onAllChunksReceived() : void;
|
|
378
398
|
|
|
379
399
|
/**
|
|
380
|
-
* Callback called when the segment request has to restart from scratch.
|
|
400
|
+
* Callback called when the segment request has to restart from scratch, e.g.
|
|
401
|
+
* due to a request error.
|
|
402
|
+
*/
|
|
381
403
|
onRetry(error : IPlayerError) : void;
|
|
382
404
|
}
|
|
383
405
|
|