rx-player 3.26.1 → 3.26.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/.github/workflows/checks.yml +99 -0
- package/.github/workflows/sonarcloud_analysis.yml +20 -0
- package/CHANGELOG.md +99 -71
- package/README.md +19 -18
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/clear_element_src.js +8 -6
- package/dist/_esm5.processed/compat/eme/close_session.js +1 -2
- package/dist/_esm5.processed/compat/eme/custom_media_keys/ie11_media_keys.js +1 -2
- package/dist/_esm5.processed/compat/eme/custom_media_keys/index.d.ts +3 -1
- package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +6 -4
- package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +1 -2
- package/dist/_esm5.processed/compat/eme/generate_key_request.js +1 -2
- package/dist/_esm5.processed/compat/eme/load_session.js +2 -3
- package/dist/_esm5.processed/compat/event_listeners.d.ts +3 -2
- package/dist/_esm5.processed/compat/event_listeners.js +8 -14
- package/dist/_esm5.processed/compat/make_vtt_cue.js +1 -1
- package/dist/_esm5.processed/compat/on_height_width_change.js +1 -2
- package/dist/_esm5.processed/compat/set_element_src.js +1 -1
- package/dist/_esm5.processed/compat/when_loaded_metadata.js +1 -2
- package/dist/_esm5.processed/compat/when_media_source_open.js +1 -2
- package/dist/_esm5.processed/config.d.ts +3 -8
- package/dist/_esm5.processed/config.js +4 -9
- package/dist/_esm5.processed/core/abr/abr_manager.d.ts +11 -10
- package/dist/_esm5.processed/core/abr/abr_manager.js +47 -8
- package/dist/_esm5.processed/core/abr/bandwidth_estimator.js +1 -1
- package/dist/_esm5.processed/core/abr/buffer_based_chooser.d.ts +2 -2
- package/dist/_esm5.processed/core/abr/buffer_based_chooser.js +3 -3
- package/dist/_esm5.processed/core/abr/get_buffer_levels.js +3 -0
- package/dist/_esm5.processed/core/abr/get_estimate_from_buffer_levels.d.ts +3 -3
- package/dist/_esm5.processed/core/abr/get_estimate_from_buffer_levels.js +3 -3
- package/dist/_esm5.processed/core/abr/guess_based_chooser.d.ts +95 -0
- package/dist/_esm5.processed/core/abr/guess_based_chooser.js +242 -0
- package/dist/_esm5.processed/core/abr/index.d.ts +3 -3
- package/dist/_esm5.processed/core/abr/last_estimate_storage.d.ts +61 -0
- package/dist/_esm5.processed/core/abr/last_estimate_storage.js +37 -0
- package/dist/_esm5.processed/core/abr/network_analyzer.d.ts +25 -7
- package/dist/_esm5.processed/core/abr/network_analyzer.js +68 -31
- package/dist/_esm5.processed/core/abr/pending_requests_store.d.ts +56 -28
- package/dist/_esm5.processed/core/abr/pending_requests_store.js +9 -7
- package/dist/_esm5.processed/core/abr/representation_estimator.d.ts +34 -51
- package/dist/_esm5.processed/core/abr/representation_estimator.js +111 -52
- package/dist/_esm5.processed/core/abr/representation_score_calculator.d.ts +5 -8
- package/dist/_esm5.processed/core/abr/representation_score_calculator.js +20 -23
- package/dist/_esm5.processed/core/abr/{ewma.d.ts → utils/ewma.d.ts} +0 -0
- package/dist/_esm5.processed/core/abr/{ewma.js → utils/ewma.js} +0 -0
- package/dist/_esm5.processed/core/abr/{filter_by_bitrate.d.ts → utils/filter_by_bitrate.d.ts} +1 -1
- package/dist/_esm5.processed/core/abr/{filter_by_bitrate.js → utils/filter_by_bitrate.js} +1 -1
- package/dist/_esm5.processed/core/abr/{filter_by_width.d.ts → utils/filter_by_width.d.ts} +1 -1
- package/dist/_esm5.processed/core/abr/{filter_by_width.js → utils/filter_by_width.js} +2 -2
- package/dist/_esm5.processed/core/abr/{select_optimal_representation.d.ts → utils/select_optimal_representation.d.ts} +1 -1
- package/dist/_esm5.processed/core/abr/{select_optimal_representation.js → utils/select_optimal_representation.js} +1 -1
- package/dist/_esm5.processed/core/api/emit_seek_events.d.ts +4 -4
- package/dist/_esm5.processed/core/api/emit_seek_events.js +12 -10
- package/dist/_esm5.processed/core/api/index.d.ts +3 -1
- package/dist/_esm5.processed/core/api/index.js +2 -0
- package/dist/_esm5.processed/core/api/option_utils.js +4 -4
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +280 -0
- package/dist/_esm5.processed/core/api/playback_observer.js +461 -0
- package/dist/_esm5.processed/core/api/public_api.d.ts +8 -7
- package/dist/_esm5.processed/core/api/public_api.js +98 -94
- package/dist/_esm5.processed/core/api/track_choice_manager.js +3 -3
- package/dist/_esm5.processed/core/eme/__tests__/__global__/utils.js +1 -0
- package/dist/_esm5.processed/core/eme/attach_media_keys.js +1 -2
- package/dist/_esm5.processed/core/eme/check_key_statuses.js +4 -5
- package/dist/_esm5.processed/core/eme/clean_old_loaded_sessions.js +1 -2
- package/dist/_esm5.processed/core/eme/clear_eme_session.js +6 -2
- package/dist/_esm5.processed/core/eme/create_session.js +1 -2
- package/dist/_esm5.processed/core/eme/dispose_media_keys.js +2 -3
- package/dist/_esm5.processed/core/eme/eme_manager.js +4 -5
- package/dist/_esm5.processed/core/eme/find_key_system.js +4 -5
- package/dist/_esm5.processed/core/eme/get_media_keys.js +2 -3
- package/dist/_esm5.processed/core/eme/get_session.js +1 -2
- package/dist/_esm5.processed/core/eme/init_media_keys.js +5 -5
- package/dist/_esm5.processed/core/eme/session_events_listener.js +6 -7
- package/dist/_esm5.processed/core/eme/set_server_certificate.js +8 -3
- package/dist/_esm5.processed/core/eme/types.d.ts +12 -4
- package/dist/_esm5.processed/core/eme/utils/close_session.js +2 -3
- package/dist/_esm5.processed/core/eme/utils/is_session_usable.js +1 -1
- package/dist/_esm5.processed/core/eme/utils/loaded_sessions_store.js +3 -4
- package/dist/_esm5.processed/core/eme/utils/persistent_sessions_store.js +3 -3
- package/dist/_esm5.processed/core/fetchers/index.d.ts +2 -2
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +2 -2
- package/dist/_esm5.processed/core/fetchers/segment/index.d.ts +2 -2
- package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.d.ts +12 -29
- package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.js +3 -7
- package/dist/_esm5.processed/core/fetchers/segment/prioritizer.d.ts +53 -53
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +42 -11
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +118 -46
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +21 -20
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +9 -8
- package/dist/_esm5.processed/core/init/create_eme_manager.js +1 -2
- package/dist/_esm5.processed/core/init/create_media_source.js +3 -4
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.d.ts +39 -0
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.js +50 -0
- package/dist/_esm5.processed/core/init/duration_updater.js +16 -7
- package/dist/_esm5.processed/core/init/emit_loaded_event.d.ts +4 -3
- package/dist/_esm5.processed/core/init/emit_loaded_event.js +8 -8
- package/dist/_esm5.processed/core/init/end_of_stream.js +1 -2
- package/dist/_esm5.processed/core/init/get_initial_time.js +2 -3
- package/dist/_esm5.processed/core/init/initial_seek_and_play.d.ts +32 -31
- package/dist/_esm5.processed/core/init/initial_seek_and_play.js +25 -32
- package/dist/_esm5.processed/core/init/initialize_directfile.d.ts +6 -5
- package/dist/_esm5.processed/core/init/initialize_directfile.js +16 -12
- package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +10 -10
- package/dist/_esm5.processed/core/init/initialize_media_source.js +18 -12
- package/dist/_esm5.processed/core/init/load_on_media_source.d.ts +8 -11
- package/dist/_esm5.processed/core/init/load_on_media_source.js +16 -19
- package/dist/_esm5.processed/core/init/manifest_update_scheduler.js +8 -7
- package/dist/_esm5.processed/core/init/stall_avoider.d.ts +4 -6
- package/dist/_esm5.processed/core/init/stall_avoider.js +56 -42
- package/dist/_esm5.processed/core/init/stream_events_emitter/stream_events_emitter.d.ts +2 -2
- package/dist/_esm5.processed/core/init/stream_events_emitter/stream_events_emitter.js +20 -15
- package/dist/_esm5.processed/core/init/throw_on_media_error.js +1 -2
- package/dist/_esm5.processed/core/init/types.d.ts +0 -20
- package/dist/_esm5.processed/core/init/update_playback_rate.d.ts +5 -4
- package/dist/_esm5.processed/core/init/update_playback_rate.js +10 -11
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.d.ts +4 -4
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +12 -7
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +8 -7
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +9 -10
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/text_track_cues_store.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +4 -4
- package/dist/_esm5.processed/core/segment_buffers/implementations/utils/manual_time_ranges.js +2 -2
- package/dist/_esm5.processed/core/segment_buffers/inventory/buffered_history.js +2 -2
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +1 -12
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +10 -10
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +1 -1
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.d.ts +15 -13
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +36 -23
- package/dist/_esm5.processed/core/stream/adaptation/create_representation_estimator.d.ts +9 -17
- package/dist/_esm5.processed/core/stream/adaptation/create_representation_estimator.js +11 -20
- package/dist/_esm5.processed/core/stream/adaptation/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/orchestrator/active_period_emitter.js +5 -6
- package/dist/_esm5.processed/core/stream/orchestrator/are_streams_complete.js +1 -2
- package/dist/_esm5.processed/core/stream/orchestrator/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.d.ts +10 -8
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +22 -21
- package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.d.ts +6 -4
- package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.js +11 -10
- package/dist/_esm5.processed/core/stream/period/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/period/period_stream.d.ts +23 -7
- package/dist/_esm5.processed/core/stream/period/period_stream.js +38 -24
- package/dist/_esm5.processed/core/stream/reload_after_switch.d.ts +5 -4
- package/dist/_esm5.processed/core/stream/reload_after_switch.js +8 -7
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.d.ts +4 -2
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +10 -8
- package/dist/_esm5.processed/core/stream/representation/downloading_queue.d.ts +9 -9
- package/dist/_esm5.processed/core/stream/representation/downloading_queue.js +10 -12
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.d.ts +1 -3
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +6 -8
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +3 -7
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +7 -8
- package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/get_segment_priority.d.ts +6 -9
- package/dist/_esm5.processed/core/stream/representation/get_segment_priority.js +7 -8
- package/dist/_esm5.processed/core/stream/representation/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/representation/push_init_segment.d.ts +4 -2
- package/dist/_esm5.processed/core/stream/representation/push_init_segment.js +3 -5
- package/dist/_esm5.processed/core/stream/representation/push_media_segment.d.ts +6 -4
- package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +3 -5
- package/dist/_esm5.processed/core/stream/representation/representation_stream.d.ts +9 -12
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +30 -21
- package/dist/_esm5.processed/errors/error_message.js +1 -1
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.d.ts +5 -3
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.js +21 -8
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +2 -3
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.d.ts +2 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.js +4 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +1 -1
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.d.ts +2 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +17 -6
- package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +1 -2
- package/dist/_esm5.processed/experimental/tools/createMetaplaylist/index.js +1 -2
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/mediaDisplayInfos.js +1 -1
- package/dist/_esm5.processed/features/initialize_features.js +47 -44
- package/dist/_esm5.processed/index.js +2 -2
- package/dist/_esm5.processed/manifest/index.d.ts +2 -2
- package/dist/_esm5.processed/manifest/index.js +2 -2
- package/dist/_esm5.processed/manifest/representation.js +1 -1
- package/dist/_esm5.processed/manifest/representation_index/static.js +1 -0
- package/dist/_esm5.processed/manifest/representation_index/types.d.ts +24 -3
- package/dist/_esm5.processed/manifest/update_period_in_place.js +1 -1
- package/dist/_esm5.processed/manifest/{are_same_content.d.ts → utils.d.ts} +9 -7
- package/dist/_esm5.processed/manifest/{are_same_content.js → utils.js} +18 -1
- package/dist/_esm5.processed/minimal.js +2 -2
- package/dist/_esm5.processed/parsers/containers/isobmff/get_box.d.ts +18 -9
- package/dist/_esm5.processed/parsers/containers/isobmff/get_box.js +32 -9
- package/dist/_esm5.processed/parsers/containers/isobmff/read.d.ts +18 -5
- package/dist/_esm5.processed/parsers/containers/isobmff/read.js +28 -6
- package/dist/_esm5.processed/parsers/containers/isobmff/utils.js +52 -47
- package/dist/_esm5.processed/parsers/images/bif.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/flatten_overlapping_periods.js +2 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/get_http_utc-timing_url.js +2 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +2 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +3 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.js +2 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +1 -0
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +7 -9
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +2 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +4 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +2 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +11 -5
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/convert_element_to_index_segment.js +10 -9
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/parse_s_element.js +3 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +6 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +5 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.js +4 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.d.ts +3 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +19 -18
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.d.ts +2 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +14 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.d.ts +2 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.js +7 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.d.ts +3 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +5 -10
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.d.ts +3 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +17 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.d.ts +7 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.js +22 -21
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.js +10 -0
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.js +9 -9
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/Representation.js +24 -0
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/SegmentTemplate.js +7 -5
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/utils.js +12 -9
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +5 -2
- package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +8 -0
- package/dist/_esm5.processed/parsers/manifest/dash/parsers_types.d.ts +11 -2
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +7 -4
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.js +11 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.js +7 -1
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/EventStream.js +5 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/MPD.js +5 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Period.js +13 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Representation.js +23 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/SegmentList.js +5 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/XLink.js +6 -0
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/root.js +6 -0
- package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +4 -2
- package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/smooth/get_codecs.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +3 -1
- package/dist/_esm5.processed/parsers/manifest/utils/check_manifest_ids.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/utils/clear_timeline_from_position.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/utils/index_helpers.d.ts +11 -3
- package/dist/_esm5.processed/parsers/manifest/utils/index_helpers.js +5 -5
- package/dist/_esm5.processed/parsers/manifest/utils/is_segment_still_available.js +3 -6
- package/dist/_esm5.processed/parsers/texttracks/sami/html.js +2 -2
- package/dist/_esm5.processed/parsers/texttracks/sami/native.js +2 -2
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_font_size.js +13 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/generate_css_test_outline.js +4 -4
- package/dist/_esm5.processed/parsers/texttracks/webvtt/html/create_default_style_elements.js +2 -2
- package/dist/_esm5.processed/parsers/texttracks/webvtt/html/create_style_attribute.js +5 -5
- package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +2 -2
- package/dist/_esm5.processed/transports/dash/init_segment_loader.js +1 -1
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +89 -20
- package/dist/_esm5.processed/transports/dash/segment_loader.js +1 -1
- package/dist/_esm5.processed/transports/local/segment_loader.js +2 -2
- package/dist/_esm5.processed/transports/local/segment_parser.d.ts +2 -2
- package/dist/_esm5.processed/transports/local/text_parser.d.ts +2 -2
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +1 -1
- package/dist/_esm5.processed/transports/smooth/extract_timings_infos.js +1 -1
- package/dist/_esm5.processed/transports/smooth/pipelines.js +2 -2
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +3 -3
- package/dist/_esm5.processed/transports/types.d.ts +29 -15
- package/dist/_esm5.processed/transports/utils/byte_range.js +2 -2
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +1 -1
- package/dist/_esm5.processed/transports/utils/get_isobmff_timing_infos.js +6 -1
- package/dist/_esm5.processed/transports/utils/parse_text_track.js +6 -4
- package/dist/_esm5.processed/utils/assert.js +3 -3
- package/dist/_esm5.processed/utils/concat_map_latest.js +1 -2
- package/dist/_esm5.processed/utils/defer_subscriptions.js +1 -2
- package/dist/_esm5.processed/utils/filter_map.js +1 -2
- package/dist/_esm5.processed/utils/reference.d.ts +108 -0
- package/dist/_esm5.processed/utils/reference.js +137 -0
- package/dist/_esm5.processed/utils/request/fetch.d.ts +1 -1
- package/dist/_esm5.processed/utils/request/fetch.js +3 -3
- package/dist/_esm5.processed/utils/request/xhr.d.ts +1 -1
- package/dist/_esm5.processed/utils/request/xhr.js +1 -1
- package/dist/_esm5.processed/utils/rx-retry_with_backoff.js +1 -2
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.d.ts +1 -15
- package/dist/rx-player.js +3666 -2470
- package/dist/rx-player.min.d.ts +1 -15
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +28 -1
- package/package.json +43 -43
- package/scripts/build/constants.d.ts +50 -0
- package/scripts/build/generate_build.js +1 -189
- package/scripts/doc-generator/construct_table_of_contents.js +31 -24
- package/scripts/doc-generator/convert_MD_to_HMTL.js +4 -8
- package/scripts/doc-generator/create_documentation.js +331 -0
- package/scripts/doc-generator/create_documentation_page.js +209 -0
- package/scripts/doc-generator/create_page.js +117 -35
- package/scripts/doc-generator/generate_header_html.js +148 -0
- package/scripts/doc-generator/generate_page_html.js +116 -0
- package/scripts/doc-generator/generate_page_list_html.js +93 -0
- package/scripts/doc-generator/generate_sidebar_html.js +88 -0
- package/scripts/doc-generator/get_search_data_for_content.js +137 -0
- package/scripts/doc-generator/index.js +14 -15
- package/scripts/doc-generator/parse_doc_configs.js +327 -0
- package/scripts/doc-generator/scripts/lunr.js +10 -0
- package/scripts/doc-generator/scripts/script.js +451 -0
- package/scripts/doc-generator/styles/style.css +712 -144
- package/scripts/doc-generator/utils.js +85 -0
- package/scripts/fast_demo_build.js +143 -0
- package/scripts/generate_documentation_list.js +6 -2
- package/scripts/generate_full_demo.js +26 -49
- package/scripts/start_demo_web_server.js +14 -4
- package/scripts/update-version +1 -1
- package/sonar-project.properties +2 -1
- package/src/compat/__tests__/add_text_track.test.ts +1 -0
- package/src/compat/__tests__/clear_element_src.test.ts +55 -28
- package/src/compat/__tests__/set_element_src.test.ts +2 -2
- package/src/compat/__tests__/when_loaded_metadata.test.ts +4 -5
- package/src/compat/__tests__/when_media_source_open.test.ts +4 -5
- package/src/compat/clear_element_src.ts +8 -6
- package/src/compat/eme/close_session.ts +3 -5
- package/src/compat/eme/custom_media_keys/ie11_media_keys.ts +1 -1
- package/src/compat/eme/custom_media_keys/index.ts +6 -6
- package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +6 -3
- package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +1 -1
- package/src/compat/eme/generate_key_request.ts +1 -1
- package/src/compat/eme/load_session.ts +4 -6
- package/src/compat/event_listeners.ts +12 -21
- package/src/compat/on_height_width_change.ts +3 -5
- package/src/compat/set_element_src.ts +1 -1
- package/src/compat/when_loaded_metadata.ts +1 -1
- package/src/compat/when_media_source_open.ts +1 -1
- package/src/config.ts +4 -9
- package/src/core/abr/README.md +7 -7
- package/src/core/abr/abr_manager.ts +62 -21
- package/src/core/abr/bandwidth_estimator.ts +1 -1
- package/src/core/abr/buffer_based_chooser.ts +8 -6
- package/src/core/abr/get_buffer_levels.ts +3 -0
- package/src/core/abr/get_estimate_from_buffer_levels.ts +4 -4
- package/src/core/abr/guess_based_chooser.ts +308 -0
- package/src/core/abr/index.ts +7 -3
- package/src/core/abr/last_estimate_storage.ts +79 -0
- package/src/core/abr/network_analyzer.ts +74 -31
- package/src/core/abr/pending_requests_store.ts +76 -42
- package/src/core/abr/representation_estimator.ts +200 -125
- package/src/core/abr/representation_score_calculator.ts +33 -26
- package/src/core/abr/{__tests__ → utils/__tests__}/ewma.test.ts +0 -0
- package/src/core/abr/{__tests__ → utils/__tests__}/filter_by_bitrate.test.ts +1 -1
- package/src/core/abr/{__tests__ → utils/__tests__}/filter_by_width.test.ts +1 -1
- package/src/core/abr/{__tests__ → utils/__tests__}/select_optimal_representation.test.ts +1 -1
- package/src/core/abr/{ewma.ts → utils/ewma.ts} +0 -0
- package/src/core/abr/{filter_by_bitrate.ts → utils/filter_by_bitrate.ts} +2 -2
- package/src/core/abr/{filter_by_width.ts → utils/filter_by_width.ts} +3 -3
- package/src/core/abr/{select_optimal_representation.ts → utils/select_optimal_representation.ts} +2 -2
- package/src/core/api/README.md +4 -3
- package/src/core/api/__tests__/option_utils.test.ts +1 -0
- package/src/core/api/emit_seek_events.ts +21 -20
- package/src/core/api/index.ts +6 -2
- package/src/core/api/playback_observer.ts +768 -0
- package/src/core/api/public_api.ts +111 -111
- package/src/core/api/track_choice_manager.ts +6 -3
- package/src/core/eme/__tests__/__global__/get_license.test.ts +5 -3
- package/src/core/eme/__tests__/__global__/init_data.test.ts +11 -12
- package/src/core/eme/__tests__/__global__/media_key_system_access.test.ts +2 -1
- package/src/core/eme/__tests__/__global__/media_keys.test.ts +5 -8
- package/src/core/eme/__tests__/__global__/server_certificate.test.ts +8 -6
- package/src/core/eme/__tests__/__global__/utils.ts +1 -0
- package/src/core/eme/__tests__/init_media_keys.test.ts +6 -65
- package/src/core/eme/attach_media_keys.ts +2 -1
- package/src/core/eme/check_key_statuses.ts +10 -8
- package/src/core/eme/clean_old_loaded_sessions.ts +2 -4
- package/src/core/eme/clear_eme_session.ts +6 -1
- package/src/core/eme/create_session.ts +3 -5
- package/src/core/eme/dispose_media_keys.ts +2 -2
- package/src/core/eme/eme_manager.ts +10 -12
- package/src/core/eme/find_key_system.ts +3 -5
- package/src/core/eme/get_media_keys.ts +4 -6
- package/src/core/eme/get_session.ts +2 -4
- package/src/core/eme/init_media_keys.ts +9 -9
- package/src/core/eme/session_events_listener.ts +14 -15
- package/src/core/eme/set_server_certificate.ts +9 -5
- package/src/core/eme/types.ts +15 -4
- package/src/core/eme/utils/close_session.ts +7 -7
- package/src/core/eme/utils/is_session_usable.ts +1 -1
- package/src/core/eme/utils/loaded_sessions_store.ts +2 -2
- package/src/core/eme/utils/persistent_sessions_store.ts +2 -2
- package/src/core/fetchers/index.ts +2 -2
- package/src/core/fetchers/manifest/manifest_fetcher.ts +1 -1
- package/src/core/fetchers/segment/__tests__/prioritizer.test.ts +3 -4
- package/src/core/fetchers/segment/index.ts +2 -2
- package/src/core/fetchers/segment/prioritized_segment_fetcher.ts +37 -45
- package/src/core/fetchers/segment/prioritizer.ts +82 -82
- package/src/core/fetchers/segment/segment_fetcher.ts +178 -80
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +23 -31
- package/src/core/init/create_eme_manager.ts +1 -1
- package/src/core/init/create_media_source.ts +5 -7
- package/src/core/init/create_stream_playback_observer.ts +88 -0
- package/src/core/init/duration_updater.ts +20 -17
- package/src/core/init/emit_loaded_event.ts +11 -15
- package/src/core/init/end_of_stream.ts +2 -4
- package/src/core/init/get_initial_time.ts +0 -1
- package/src/core/init/initial_seek_and_play.ts +67 -51
- package/src/core/init/initialize_directfile.ts +26 -35
- package/src/core/init/initialize_media_source.ts +28 -28
- package/src/core/init/load_on_media_source.ts +51 -58
- package/src/core/init/manifest_update_scheduler.ts +11 -12
- package/src/core/init/stall_avoider.ts +64 -47
- package/src/core/init/stream_events_emitter/stream_events_emitter.ts +24 -21
- package/src/core/init/throw_on_media_error.ts +1 -1
- package/src/core/init/types.ts +0 -24
- package/src/core/init/update_playback_rate.ts +15 -16
- package/src/core/segment_buffers/README.md +3 -3
- package/src/core/segment_buffers/garbage_collector.ts +15 -11
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +10 -7
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +14 -16
- package/src/core/segment_buffers/implementations/text/html/text_track_cues_store.ts +1 -1
- package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +4 -4
- package/src/core/segment_buffers/implementations/utils/manual_time_ranges.ts +2 -2
- package/src/core/segment_buffers/inventory/buffered_history.ts +2 -2
- package/src/core/segment_buffers/inventory/segment_inventory.ts +1 -13
- package/src/core/stream/adaptation/adaptation_stream.ts +78 -56
- package/src/core/stream/adaptation/create_representation_estimator.ts +19 -45
- package/src/core/stream/adaptation/index.ts +2 -2
- package/src/core/stream/index.ts +2 -2
- package/src/core/stream/orchestrator/active_period_emitter.ts +6 -8
- package/src/core/stream/orchestrator/are_streams_complete.ts +2 -4
- package/src/core/stream/orchestrator/index.ts +2 -2
- package/src/core/stream/orchestrator/stream_orchestrator.ts +58 -49
- package/src/core/stream/period/create_empty_adaptation_stream.ts +14 -10
- package/src/core/stream/period/index.ts +2 -2
- package/src/core/stream/period/period_stream.ts +118 -75
- package/src/core/stream/reload_after_switch.ts +13 -10
- package/src/core/stream/representation/append_segment_to_buffer.ts +20 -16
- package/src/core/stream/representation/downloading_queue.ts +21 -24
- package/src/core/stream/representation/force_garbage_collection.ts +16 -23
- package/src/core/stream/representation/get_buffer_status.ts +9 -11
- package/src/core/stream/representation/get_needed_segments.ts +1 -1
- package/src/core/stream/representation/get_segment_priority.ts +8 -10
- package/src/core/stream/representation/index.ts +2 -2
- package/src/core/stream/representation/push_init_segment.ts +19 -16
- package/src/core/stream/representation/push_media_segment.ts +21 -17
- package/src/core/stream/representation/representation_stream.ts +50 -47
- package/src/experimental/features/__tests__/dash_wasm.test.ts +1 -0
- package/src/experimental/tools/VideoThumbnailLoader/create_request.ts +32 -17
- package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +6 -9
- package/src/experimental/tools/VideoThumbnailLoader/load_segments.ts +12 -6
- package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +4 -2
- package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +2 -2
- package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +21 -12
- package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +1 -1
- package/src/experimental/tools/createMetaplaylist/index.ts +1 -1
- package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/DRMInfos.test.ts +4 -2
- package/src/features/__tests__/initialize_features.test.ts +191 -101
- package/src/features/initialize_features.ts +40 -37
- package/src/features/list/__tests__/bif_parser.test.ts +1 -0
- package/src/features/list/__tests__/dash.test.ts +1 -0
- package/src/features/list/__tests__/directfile.test.ts +1 -0
- package/src/features/list/__tests__/eme.test.ts +1 -0
- package/src/features/list/__tests__/html_sami_parser.test.ts +1 -0
- package/src/features/list/__tests__/html_srt_parser.test.ts +1 -0
- package/src/features/list/__tests__/html_text_buffer.test.ts +1 -0
- package/src/features/list/__tests__/html_ttml_parser.test.ts +1 -0
- package/src/features/list/__tests__/html_vtt_parser.test.ts +1 -0
- package/src/features/list/__tests__/image_buffer.test.ts +1 -0
- package/src/features/list/__tests__/native_sami_parser.test.ts +1 -0
- package/src/features/list/__tests__/native_srt_parser.test.ts +1 -0
- package/src/features/list/__tests__/native_text_buffer.test.ts +1 -0
- package/src/features/list/__tests__/native_ttml_parser.test.ts +1 -0
- package/src/features/list/__tests__/native_vtt_parser.test.ts +1 -0
- package/src/features/list/__tests__/smooth.test.ts +1 -0
- package/src/index.ts +2 -2
- package/src/manifest/__tests__/manifest.test.ts +1 -0
- package/src/manifest/index.ts +7 -1
- package/src/manifest/representation_index/__tests__/static.test.ts +1 -0
- package/src/manifest/representation_index/static.ts +1 -0
- package/src/manifest/representation_index/types.ts +25 -3
- package/src/manifest/{are_same_content.ts → utils.ts} +26 -9
- package/src/minimal.ts +3 -2
- package/src/parsers/containers/isobmff/get_box.ts +35 -8
- package/src/parsers/containers/isobmff/read.ts +32 -5
- package/src/parsers/containers/isobmff/utils.ts +52 -47
- package/src/parsers/manifest/dash/common/__tests__/flatten_overlapping_period.test.ts +4 -4
- package/src/parsers/manifest/dash/common/flatten_overlapping_periods.ts +4 -2
- package/src/parsers/manifest/dash/common/get_clock_offset.ts +3 -3
- package/src/parsers/manifest/dash/common/get_http_utc-timing_url.ts +15 -6
- package/src/parsers/manifest/dash/common/indexes/base.ts +5 -3
- package/src/parsers/manifest/dash/common/indexes/get_init_segment.ts +1 -0
- package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +9 -9
- package/src/parsers/manifest/dash/common/indexes/list.ts +6 -3
- package/src/parsers/manifest/dash/common/indexes/template.ts +13 -6
- package/src/parsers/manifest/dash/common/indexes/timeline/convert_element_to_index_segment.ts +10 -9
- package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +13 -5
- package/src/parsers/manifest/dash/common/indexes/tokens.ts +4 -4
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +10 -4
- package/src/parsers/manifest/dash/common/parse_mpd.ts +21 -13
- package/src/parsers/manifest/dash/common/parse_periods.ts +7 -8
- package/src/parsers/manifest/dash/common/parse_representation_index.ts +12 -12
- package/src/parsers/manifest/dash/common/parse_representations.ts +23 -4
- package/src/parsers/manifest/dash/common/resolve_base_urls.ts +33 -24
- package/src/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.ts +12 -0
- package/src/parsers/manifest/dash/js-parser/node_parsers/BaseURL.ts +13 -9
- package/src/parsers/manifest/dash/js-parser/node_parsers/Representation.ts +28 -0
- package/src/parsers/manifest/dash/js-parser/node_parsers/SegmentTemplate.ts +8 -5
- package/src/parsers/manifest/dash/js-parser/node_parsers/utils.ts +3 -0
- package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +5 -2
- package/src/parsers/manifest/dash/node_parser_types.ts +8 -0
- package/src/parsers/manifest/dash/parsers_types.ts +8 -2
- package/src/parsers/manifest/dash/wasm-parser/rs/lib.rs +1 -8
- package/src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs +26 -5
- package/src/parsers/manifest/dash/wasm-parser/rs/processor/mod.rs +75 -521
- package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +7 -4
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.ts +13 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.ts +8 -1
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/EventStream.ts +6 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/MPD.ts +6 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/Period.ts +14 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/Representation.ts +26 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/SegmentList.ts +6 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/XLink.ts +7 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/root.ts +7 -0
- package/src/parsers/manifest/dash/wasm-parser/ts/types.ts +1 -1
- package/src/parsers/manifest/local/representation_index.ts +2 -0
- package/src/parsers/manifest/smooth/create_parser.ts +1 -1
- package/src/parsers/manifest/smooth/representation_index.ts +3 -1
- package/src/parsers/manifest/utils/clear_timeline_from_position.ts +1 -1
- package/src/parsers/manifest/utils/index_helpers.ts +21 -11
- package/src/parsers/manifest/utils/is_segment_still_available.ts +4 -6
- package/src/parsers/texttracks/sami/html.ts +1 -1
- package/src/parsers/texttracks/sami/native.ts +1 -1
- package/src/parsers/texttracks/ttml/html/apply_font_size.ts +11 -1
- package/src/transports/dash/image_pipelines.ts +4 -4
- package/src/transports/dash/init_segment_loader.ts +1 -1
- package/src/transports/dash/manifest_parser.ts +99 -25
- package/src/transports/dash/segment_loader.ts +1 -1
- package/src/transports/dash/segment_parser.ts +4 -4
- package/src/transports/dash/text_parser.ts +8 -8
- package/src/transports/local/segment_loader.ts +2 -2
- package/src/transports/local/segment_parser.ts +4 -4
- package/src/transports/local/text_parser.ts +8 -8
- package/src/transports/metaplaylist/pipelines.ts +11 -11
- package/src/transports/smooth/extract_timings_infos.ts +1 -1
- package/src/transports/smooth/pipelines.ts +8 -8
- package/src/transports/smooth/segment_loader.ts +3 -3
- package/src/transports/types.ts +31 -17
- package/src/transports/utils/call_custom_manifest_loader.ts +1 -1
- package/src/transports/utils/get_isobmff_timing_infos.ts +6 -1
- package/src/transports/utils/parse_text_track.ts +4 -2
- package/src/typings/globals.d.ts +57 -40
- package/src/utils/__tests__/concat_map_latest.test.ts +7 -9
- package/src/utils/__tests__/defer_subscriptions.test.ts +4 -4
- package/src/utils/__tests__/event_emitter.test.ts +1 -1
- package/src/utils/__tests__/initialization_segment_cache.test.ts +7 -0
- package/src/utils/assert.ts +1 -1
- package/src/utils/concat_map_latest.ts +2 -4
- package/src/utils/defer_subscriptions.ts +1 -1
- package/src/utils/filter_map.ts +2 -4
- package/src/utils/reference.ts +234 -0
- package/src/utils/request/fetch.ts +3 -3
- package/src/utils/request/xhr.ts +2 -2
- package/src/utils/rx-retry_with_backoff.ts +2 -4
- package/tsconfig.json +4 -1
- package/tsconfig.modules.json +8 -3
- package/dist/_esm5.processed/core/abr/create_filters.d.ts +0 -27
- package/dist/_esm5.processed/core/abr/create_filters.js +0 -56
- package/dist/_esm5.processed/core/api/clock.d.ts +0 -157
- package/dist/_esm5.processed/core/api/clock.js +0 -363
- package/dist/_esm5.processed/core/init/create_stream_clock.d.ts +0 -34
- package/dist/_esm5.processed/core/init/create_stream_clock.js +0 -55
- package/dist/_esm5.processed/parsers/manifest/dash/common/extract_minimum_availability_time_offset.d.ts +0 -31
- package/dist/_esm5.processed/parsers/manifest/dash/common/extract_minimum_availability_time_offset.js +0 -37
- package/scripts/doc-generator/construct_html.js +0 -135
- package/scripts/doc-generator/construct_page_list.js +0 -120
- package/scripts/doc-generator/create_for_dir.js +0 -151
- package/scripts/doc-generator/get_files_to_convert.js +0 -71
- package/scripts/doc-generator/mkdir_parent.js +0 -21
- package/scripts/doc-generator/read_title_from_md.js +0 -22
- package/scripts/doc-generator/remove_toc_from_md.js +0 -20
- package/src/core/abr/create_filters.ts +0 -59
- package/src/core/api/clock.ts +0 -573
- package/src/core/init/create_stream_clock.ts +0 -93
- package/src/parsers/manifest/dash/common/extract_minimum_availability_time_offset.ts +0 -41
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015 CANAL+ Group
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import log from "../../log";
|
|
18
|
+
import { Representation } from "../../manifest";
|
|
19
|
+
import arrayFindIndex from "../../utils/array_find_index";
|
|
20
|
+
import LastEstimateStorage, {
|
|
21
|
+
ABRAlgorithmType,
|
|
22
|
+
} from "./last_estimate_storage";
|
|
23
|
+
import { estimateRequestBandwidth } from "./network_analyzer";
|
|
24
|
+
import { IRequestInfo } from "./pending_requests_store";
|
|
25
|
+
import RepresentationScoreCalculator, {
|
|
26
|
+
ScoreConfidenceLevel,
|
|
27
|
+
} from "./representation_score_calculator";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Estimate which Representation should be played based on risky "guesses".
|
|
31
|
+
*
|
|
32
|
+
* Basically, this `GuessBasedChooser` will attempt switching to the superior
|
|
33
|
+
* quality when conditions allows this and then check if we're able to maintain
|
|
34
|
+
* this quality. If we're not, it will rollbacks to the previous, maintaninable,
|
|
35
|
+
* guess.
|
|
36
|
+
*
|
|
37
|
+
* The algorithm behind the `GuessBasedChooser` is very risky in terms of
|
|
38
|
+
* rebuffering chances. As such, it should only be used when other approach
|
|
39
|
+
* don't work (e.g. low-latency contents).
|
|
40
|
+
* @class GuessBasedChooser
|
|
41
|
+
*/
|
|
42
|
+
export default class GuessBasedChooser {
|
|
43
|
+
private _lastAbrEstimate : LastEstimateStorage;
|
|
44
|
+
private _scoreCalculator : RepresentationScoreCalculator;
|
|
45
|
+
private _consecutiveWrongGuesses : number;
|
|
46
|
+
private _blockGuessesUntil : number;
|
|
47
|
+
private _lastMaintanableBitrate : number | null;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create a new `GuessBasedChooser`.
|
|
51
|
+
* @param {Object} scoreCalculator
|
|
52
|
+
* @param {Object} prevEstimate
|
|
53
|
+
*/
|
|
54
|
+
constructor(
|
|
55
|
+
scoreCalculator : RepresentationScoreCalculator,
|
|
56
|
+
prevEstimate : LastEstimateStorage
|
|
57
|
+
) {
|
|
58
|
+
this._scoreCalculator = scoreCalculator;
|
|
59
|
+
this._lastAbrEstimate = prevEstimate;
|
|
60
|
+
this._consecutiveWrongGuesses = 0;
|
|
61
|
+
this._blockGuessesUntil = 0;
|
|
62
|
+
this._lastMaintanableBitrate = null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Perform a "guess", which basically indicates which Representation should be
|
|
67
|
+
* chosen according to the `GuessBasedChooser`.
|
|
68
|
+
*
|
|
69
|
+
* @param {Array.<Object>} representations - Array of all Representation the
|
|
70
|
+
* GuessBasedChooser can choose from, sorted by bitrate ascending.
|
|
71
|
+
* /!\ It is very important that Representation in that Array are sorted by
|
|
72
|
+
* bitrate ascending for this method to work as intented.
|
|
73
|
+
* @param {Object} observation - Last playback observation performed.
|
|
74
|
+
* @param {Object} currentRepresentation - The Representation currently
|
|
75
|
+
* loading.
|
|
76
|
+
* @param {number} incomingBestBitrate - The bitrate of the Representation
|
|
77
|
+
* chosen by the more optimistic of the other ABR algorithms currently.
|
|
78
|
+
* @param {Array.<Object>} requests - Information on all pending requests.
|
|
79
|
+
* @returns {Object|null} - If a guess is made, return that guess, else
|
|
80
|
+
* returns `null` (in which case you should fallback to another ABR
|
|
81
|
+
* algorithm).
|
|
82
|
+
*/
|
|
83
|
+
public getGuess(
|
|
84
|
+
representations : Representation[],
|
|
85
|
+
observation : {
|
|
86
|
+
/**
|
|
87
|
+
* For the concerned media buffer, difference in seconds between the next
|
|
88
|
+
* position where no segment data is available and the current position.
|
|
89
|
+
*/
|
|
90
|
+
bufferGap: number;
|
|
91
|
+
/**
|
|
92
|
+
* Last "playback rate" set by the user. This is the ideal "playback rate" at
|
|
93
|
+
* which the media should play.
|
|
94
|
+
*/
|
|
95
|
+
speed: number;
|
|
96
|
+
},
|
|
97
|
+
currentRepresentation : Representation,
|
|
98
|
+
incomingBestBitrate : number,
|
|
99
|
+
requests : IRequestInfo[]
|
|
100
|
+
) : Representation | null {
|
|
101
|
+
const { bufferGap, speed } = observation;
|
|
102
|
+
const lastChosenRep = this._lastAbrEstimate.representation;
|
|
103
|
+
if (lastChosenRep === null) {
|
|
104
|
+
return null; // There's nothing to base our guess on
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (incomingBestBitrate > lastChosenRep.bitrate) {
|
|
108
|
+
// ABR estimates are already superior or equal to the guess
|
|
109
|
+
// we'll be doing here, so no need to guess
|
|
110
|
+
if (this._lastAbrEstimate.algorithmType === ABRAlgorithmType.GuessBased) {
|
|
111
|
+
if (this._lastAbrEstimate.representation !== null) {
|
|
112
|
+
this._lastMaintanableBitrate = this._lastAbrEstimate.representation.bitrate;
|
|
113
|
+
}
|
|
114
|
+
this._consecutiveWrongGuesses = 0;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const scoreData = this._scoreCalculator.getEstimate(currentRepresentation);
|
|
120
|
+
if (this._lastAbrEstimate.algorithmType !== ABRAlgorithmType.GuessBased) {
|
|
121
|
+
if (scoreData === undefined) {
|
|
122
|
+
return null; // not enough information to start guessing
|
|
123
|
+
}
|
|
124
|
+
if (this._canGuessHigher(bufferGap, speed, scoreData)) {
|
|
125
|
+
const nextRepresentation = getNextRepresentation(representations,
|
|
126
|
+
currentRepresentation);
|
|
127
|
+
if (nextRepresentation !== null) {
|
|
128
|
+
return nextRepresentation;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// If we reached here, we're currently already in guessing mode
|
|
135
|
+
|
|
136
|
+
if (this._isLastGuessValidated(lastChosenRep, incomingBestBitrate, scoreData)) {
|
|
137
|
+
log.debug("ABR: Guessed Representation validated", lastChosenRep.bitrate);
|
|
138
|
+
this._lastMaintanableBitrate = lastChosenRep.bitrate;
|
|
139
|
+
this._consecutiveWrongGuesses = 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (currentRepresentation.id !== lastChosenRep.id) {
|
|
143
|
+
return lastChosenRep;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const shouldStopGuess = this._shouldStopGuess(currentRepresentation,
|
|
147
|
+
scoreData,
|
|
148
|
+
bufferGap,
|
|
149
|
+
requests);
|
|
150
|
+
if (shouldStopGuess) {
|
|
151
|
+
// Block guesses for a time
|
|
152
|
+
this._consecutiveWrongGuesses++;
|
|
153
|
+
this._blockGuessesUntil = performance.now() +
|
|
154
|
+
Math.min(this._consecutiveWrongGuesses * 15000, 120000);
|
|
155
|
+
return getPreviousRepresentation(representations, currentRepresentation);
|
|
156
|
+
} else if (scoreData === undefined) {
|
|
157
|
+
return currentRepresentation;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (this._canGuessHigher(bufferGap, speed, scoreData)) {
|
|
161
|
+
const nextRepresentation = getNextRepresentation(representations,
|
|
162
|
+
currentRepresentation);
|
|
163
|
+
if (nextRepresentation !== null) {
|
|
164
|
+
return nextRepresentation;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return currentRepresentation;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Returns `true` if we've enough confidence on the current situation to make
|
|
172
|
+
* a higher guess.
|
|
173
|
+
* @param {number} bufferGap
|
|
174
|
+
* @param {number} speed
|
|
175
|
+
* @param {Array} scoreData
|
|
176
|
+
* @returns {boolean}
|
|
177
|
+
*/
|
|
178
|
+
private _canGuessHigher(
|
|
179
|
+
bufferGap : number,
|
|
180
|
+
speed : number,
|
|
181
|
+
[score, scoreConfidenceLevel] : [number, ScoreConfidenceLevel]
|
|
182
|
+
) : boolean {
|
|
183
|
+
return isFinite(bufferGap) && bufferGap >= 2.5 &&
|
|
184
|
+
performance.now() > this._blockGuessesUntil &&
|
|
185
|
+
scoreConfidenceLevel === ScoreConfidenceLevel.HIGH &&
|
|
186
|
+
score / speed > 1.01;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Returns `true` if the pending guess of `lastGuess` seems to not
|
|
191
|
+
* be maintainable and as such should be stopped.
|
|
192
|
+
* @param {Object} lastGuess
|
|
193
|
+
* @param {Array} scoreData
|
|
194
|
+
* @param {number} bufferGap
|
|
195
|
+
* @param {Array.<Object>} requests
|
|
196
|
+
* @returns {boolean}
|
|
197
|
+
*/
|
|
198
|
+
private _shouldStopGuess(
|
|
199
|
+
lastGuess : Representation,
|
|
200
|
+
scoreData : [number, ScoreConfidenceLevel] | undefined,
|
|
201
|
+
bufferGap : number,
|
|
202
|
+
requests : IRequestInfo[]
|
|
203
|
+
) : boolean {
|
|
204
|
+
if (scoreData !== undefined && scoreData[0] < 1.01) {
|
|
205
|
+
return true;
|
|
206
|
+
} else if ((scoreData === undefined || scoreData[0] < 1.2) && bufferGap < 0.6) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const guessedRepresentationRequests = requests.filter(req => {
|
|
211
|
+
return req.content.representation.id === lastGuess.id;
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const now = performance.now();
|
|
215
|
+
for (const req of guessedRepresentationRequests) {
|
|
216
|
+
const requestElapsedTime = now - req.requestTimestamp;
|
|
217
|
+
if (req.content.segment.isInit) {
|
|
218
|
+
if (requestElapsedTime > 1000) {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
} else if (requestElapsedTime > req.content.segment.duration * 1000 + 200) {
|
|
222
|
+
return true;
|
|
223
|
+
} else {
|
|
224
|
+
const fastBw = estimateRequestBandwidth(req);
|
|
225
|
+
if (fastBw !== undefined && fastBw < lastGuess.bitrate * 0.8) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private _isLastGuessValidated(
|
|
234
|
+
lastGuess : Representation,
|
|
235
|
+
incomingBestBitrate : number,
|
|
236
|
+
scoreData : [number, ScoreConfidenceLevel] | undefined
|
|
237
|
+
) : boolean {
|
|
238
|
+
if (scoreData !== undefined &&
|
|
239
|
+
scoreData[1] === ScoreConfidenceLevel.HIGH &&
|
|
240
|
+
scoreData[0] > 1.5)
|
|
241
|
+
{
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
return incomingBestBitrate >= lastGuess.bitrate &&
|
|
245
|
+
(this._lastMaintanableBitrate === null ||
|
|
246
|
+
this._lastMaintanableBitrate < lastGuess.bitrate);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* From the array of Representations given, returns the Representation with a
|
|
252
|
+
* bitrate immediately superior to the current one.
|
|
253
|
+
* Returns `null` if that "next" Representation is not found.
|
|
254
|
+
*
|
|
255
|
+
* /!\ The representations have to be already sorted by bitrate, in ascending
|
|
256
|
+
* order.
|
|
257
|
+
* @param {Array.<Object>} representations - Available representations to choose
|
|
258
|
+
* from, sorted by bitrate in ascending order.
|
|
259
|
+
* @param {Object} currentRepresentation - The Representation currently
|
|
260
|
+
* considered.
|
|
261
|
+
* @returns {Object|null}
|
|
262
|
+
*/
|
|
263
|
+
function getNextRepresentation(
|
|
264
|
+
representations : Representation[],
|
|
265
|
+
currentRepresentation : Representation
|
|
266
|
+
) : Representation | null {
|
|
267
|
+
const len = representations.length;
|
|
268
|
+
let index = arrayFindIndex(representations,
|
|
269
|
+
({ id }) => id === currentRepresentation.id);
|
|
270
|
+
if (index < 0) {
|
|
271
|
+
log.error("ABR: Current Representation not found.");
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
while (++index < len) {
|
|
276
|
+
if (representations[index].bitrate > currentRepresentation.bitrate) {
|
|
277
|
+
return representations[index];
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* From the array of Representations given, returns the Representation with a
|
|
285
|
+
* bitrate immediately inferior.
|
|
286
|
+
* Returns `null` if that "previous" Representation is not found.
|
|
287
|
+
* @param {Array.<Object>} representations
|
|
288
|
+
* @param {Object} representation
|
|
289
|
+
* @returns {Object|null}
|
|
290
|
+
*/
|
|
291
|
+
function getPreviousRepresentation(
|
|
292
|
+
representations : Representation[],
|
|
293
|
+
currentRepresentation : Representation
|
|
294
|
+
) : Representation | null {
|
|
295
|
+
let index = arrayFindIndex(representations,
|
|
296
|
+
({ id }) => id === currentRepresentation.id);
|
|
297
|
+
if (index < 0) {
|
|
298
|
+
log.error("ABR: Current Representation not found.");
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
while (--index >= 0) {
|
|
303
|
+
if (representations[index].bitrate < currentRepresentation.bitrate) {
|
|
304
|
+
return representations[index];
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
}
|
package/src/core/abr/index.ts
CHANGED
|
@@ -16,21 +16,25 @@
|
|
|
16
16
|
|
|
17
17
|
import ABRManager, {
|
|
18
18
|
IABRManagerArguments,
|
|
19
|
-
|
|
19
|
+
IABRManagerPlaybackObservation,
|
|
20
20
|
} from "./abr_manager";
|
|
21
21
|
export {
|
|
22
22
|
IABRAddedSegmentEvent,
|
|
23
|
-
IABRStreamEvents,
|
|
24
23
|
IABREstimate,
|
|
25
24
|
IABRMetricsEvent,
|
|
25
|
+
IABRMetricsEventValue,
|
|
26
26
|
IABRRepresentationChangeEvent,
|
|
27
27
|
IABRRequestBeginEvent,
|
|
28
|
+
IABRRequestBeginEventValue,
|
|
28
29
|
IABRRequestEndEvent,
|
|
30
|
+
IABRRequestEndEventValue,
|
|
29
31
|
IABRRequestProgressEvent,
|
|
32
|
+
IABRRequestProgressEventValue,
|
|
33
|
+
IABRStreamEvents,
|
|
30
34
|
} from "./representation_estimator";
|
|
31
35
|
|
|
32
36
|
export default ABRManager;
|
|
33
37
|
export {
|
|
34
38
|
IABRManagerArguments,
|
|
35
|
-
|
|
39
|
+
IABRManagerPlaybackObservation,
|
|
36
40
|
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015 CANAL+ Group
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Representation } from "../../manifest";
|
|
18
|
+
|
|
19
|
+
/** Stores the last estimate made by the `RepresentationEstimator`. */
|
|
20
|
+
export default class LastEstimateStorage {
|
|
21
|
+
/**
|
|
22
|
+
* Estimated bandwitdh in the last estimate.
|
|
23
|
+
* `undefined` either if no estimate has been performed yet or if the
|
|
24
|
+
* bandwidth was unknown during the last estimate.
|
|
25
|
+
*/
|
|
26
|
+
public bandwidth : number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Estimated Representation in the last estimate.
|
|
29
|
+
* `null` if no estimate has been performed yet.
|
|
30
|
+
*/
|
|
31
|
+
public representation : Representation | null;
|
|
32
|
+
|
|
33
|
+
/** Algorithm type used to make the last Representation estimate. */
|
|
34
|
+
public algorithmType : ABRAlgorithmType;
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
this.bandwidth = undefined;
|
|
38
|
+
this.representation = null;
|
|
39
|
+
this.algorithmType = ABRAlgorithmType.None;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Update this `LastEstimateStorage` with new values.
|
|
44
|
+
* @param {Object} representation - Estimated Representation.
|
|
45
|
+
* @param {number|undefined} bandwidth - Estimated bandwidth.
|
|
46
|
+
* @param {boolean} wasGuessed - If `true`, this estimate was a guess made by
|
|
47
|
+
* the `GuessingEstimator`.
|
|
48
|
+
*/
|
|
49
|
+
public update(
|
|
50
|
+
representation : Representation,
|
|
51
|
+
bandwidth : number | undefined,
|
|
52
|
+
algorithmType : ABRAlgorithmType
|
|
53
|
+
) : void {
|
|
54
|
+
this.representation = representation;
|
|
55
|
+
this.bandwidth = bandwidth;
|
|
56
|
+
this.algorithmType = algorithmType;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Identify an algorithm used to perform a Representation estimate. */
|
|
61
|
+
export const enum ABRAlgorithmType {
|
|
62
|
+
/**
|
|
63
|
+
* Buffer-based algorithm using mostly the size of the buffer to determine the
|
|
64
|
+
* best Representation.
|
|
65
|
+
*/
|
|
66
|
+
BufferBased,
|
|
67
|
+
/**
|
|
68
|
+
* Bandwidth-based algorithm using mostly the speed at which segments are
|
|
69
|
+
* downloaded to determine the best Representation.
|
|
70
|
+
*/
|
|
71
|
+
BandwidthBased,
|
|
72
|
+
/**
|
|
73
|
+
* Guess-based algorithm, which iterates through Representation and
|
|
74
|
+
* try to find the best one empirically.
|
|
75
|
+
*/
|
|
76
|
+
GuessBased,
|
|
77
|
+
/** None of the other or no algorithm was used yet. */
|
|
78
|
+
None,
|
|
79
|
+
}
|
|
@@ -18,13 +18,12 @@ import config from "../../config";
|
|
|
18
18
|
import log from "../../log";
|
|
19
19
|
import { Representation } from "../../manifest";
|
|
20
20
|
import arrayFind from "../../utils/array_find";
|
|
21
|
-
import arrayFindIndex from "../../utils/array_find_index";
|
|
22
21
|
import BandwidthEstimator from "./bandwidth_estimator";
|
|
23
|
-
import EWMA from "./ewma";
|
|
24
22
|
import {
|
|
25
|
-
|
|
23
|
+
IPendingRequestStoreProgress,
|
|
26
24
|
IRequestInfo,
|
|
27
25
|
} from "./pending_requests_store";
|
|
26
|
+
import EWMA from "./utils/ewma";
|
|
28
27
|
|
|
29
28
|
const { ABR_REGULAR_FACTOR,
|
|
30
29
|
ABR_STARVATION_DURATION_DELTA,
|
|
@@ -52,7 +51,8 @@ interface IPlaybackConditionsInfo {
|
|
|
52
51
|
|
|
53
52
|
/**
|
|
54
53
|
* Get pending segment request(s) starting with the asked segment position.
|
|
55
|
-
* @param {Object} requests
|
|
54
|
+
* @param {Object} requests - Every requests pending, in a chronological
|
|
55
|
+
* order in terms of segment time.
|
|
56
56
|
* @param {number} position
|
|
57
57
|
* @returns {Array.<Object>}
|
|
58
58
|
*/
|
|
@@ -61,26 +61,36 @@ function getConcernedRequests(
|
|
|
61
61
|
neededPosition : number
|
|
62
62
|
) : IRequestInfo[] {
|
|
63
63
|
/** Index of the request for the next needed segment, in `requests`. */
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
let nextSegmentIndex = -1;
|
|
65
|
+
for (let i = 0; i < requests.length; i++) {
|
|
66
|
+
const { segment } = requests[i].content;
|
|
67
|
+
if (segment.duration <= 0) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const segmentEnd = segment.time + segment.duration;
|
|
71
|
+
if (!segment.complete) {
|
|
72
|
+
if (i === requests.length - 1 && neededPosition - segment.time > -1.2) {
|
|
73
|
+
nextSegmentIndex = i;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
67
76
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
if (segmentEnd > neededPosition && neededPosition - segment.time > -1.2) {
|
|
78
|
+
nextSegmentIndex = i;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
72
82
|
|
|
73
83
|
if (nextSegmentIndex < 0) { // Not found
|
|
74
84
|
return [];
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
const nextRequest = requests[nextSegmentIndex];
|
|
78
|
-
const segmentTime = nextRequest.time;
|
|
88
|
+
const segmentTime = nextRequest.content.segment.time;
|
|
79
89
|
const filteredRequests = [nextRequest];
|
|
80
90
|
|
|
81
91
|
// Get the possibly multiple requests for that segment's position
|
|
82
92
|
for (let i = nextSegmentIndex + 1; i < requests.length; i++) {
|
|
83
|
-
if (requests[i].time === segmentTime) {
|
|
93
|
+
if (requests[i].content.segment.time === segmentTime) {
|
|
84
94
|
filteredRequests.push(requests[i]);
|
|
85
95
|
} else {
|
|
86
96
|
break;
|
|
@@ -96,7 +106,7 @@ function getConcernedRequests(
|
|
|
96
106
|
* @param {Object} request
|
|
97
107
|
* @returns {number|undefined}
|
|
98
108
|
*/
|
|
99
|
-
function estimateRequestBandwidth(request : IRequestInfo) : number|undefined {
|
|
109
|
+
export function estimateRequestBandwidth(request : IRequestInfo) : number|undefined {
|
|
100
110
|
if (request.progress.length < 5) { // threshold from which we can consider
|
|
101
111
|
// progress events reliably
|
|
102
112
|
return undefined;
|
|
@@ -122,7 +132,7 @@ function estimateRequestBandwidth(request : IRequestInfo) : number|undefined {
|
|
|
122
132
|
* @returns {number}
|
|
123
133
|
*/
|
|
124
134
|
function estimateRemainingTime(
|
|
125
|
-
lastProgressEvent:
|
|
135
|
+
lastProgressEvent: IPendingRequestStoreProgress,
|
|
126
136
|
bandwidthEstimate : number
|
|
127
137
|
) : number {
|
|
128
138
|
const remainingData = (lastProgressEvent.totalSize - lastProgressEvent.size) * 8;
|
|
@@ -133,10 +143,14 @@ function estimateRemainingTime(
|
|
|
133
143
|
* Check if the request for the most needed segment is too slow.
|
|
134
144
|
* If that's the case, re-calculate the bandwidth urgently based on
|
|
135
145
|
* this single request.
|
|
136
|
-
* @param {Object} pendingRequests -
|
|
146
|
+
* @param {Object} pendingRequests - Every requests pending, in a chronological
|
|
147
|
+
* order in terms of segment time.
|
|
137
148
|
* @param {Object} playbackInfo - Information on the current playback.
|
|
138
149
|
* @param {Object|null} currentRepresentation - The Representation being
|
|
139
150
|
* presently being loaded.
|
|
151
|
+
* @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
|
|
152
|
+
* low latency content - where requests might be pending when the segment is
|
|
153
|
+
* still encoded.
|
|
140
154
|
* @param {Number} lastEstimatedBitrate - Last bitrate estimate emitted.
|
|
141
155
|
* @returns {Number|undefined}
|
|
142
156
|
*/
|
|
@@ -144,8 +158,13 @@ function estimateStarvationModeBitrate(
|
|
|
144
158
|
pendingRequests : IRequestInfo[],
|
|
145
159
|
playbackInfo : IPlaybackConditionsInfo,
|
|
146
160
|
currentRepresentation : Representation | null,
|
|
161
|
+
lowLatencyMode : boolean,
|
|
147
162
|
lastEstimatedBitrate : number|undefined
|
|
148
163
|
) : number|undefined {
|
|
164
|
+
if (lowLatencyMode) {
|
|
165
|
+
// TODO Skip only for newer segments?
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
149
168
|
const { bufferGap, speed, position } = playbackInfo;
|
|
150
169
|
const realBufferGap = isFinite(bufferGap) ? bufferGap :
|
|
151
170
|
0;
|
|
@@ -158,7 +177,6 @@ function estimateStarvationModeBitrate(
|
|
|
158
177
|
}
|
|
159
178
|
|
|
160
179
|
const concernedRequest = concernedRequests[0];
|
|
161
|
-
const chunkDuration = concernedRequest.duration;
|
|
162
180
|
const now = performance.now();
|
|
163
181
|
const lastProgressEvent = concernedRequest.progress.length > 0 ?
|
|
164
182
|
concernedRequest.progress[concernedRequest.progress.length - 1] :
|
|
@@ -182,6 +200,11 @@ function estimateStarvationModeBitrate(
|
|
|
182
200
|
}
|
|
183
201
|
}
|
|
184
202
|
|
|
203
|
+
if (!concernedRequest.content.segment.complete) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const chunkDuration = concernedRequest.content.segment.duration;
|
|
185
208
|
const requestElapsedTime = (now - concernedRequest.requestTimestamp) / 1000;
|
|
186
209
|
const reasonableElapsedTime = requestElapsedTime <=
|
|
187
210
|
((chunkDuration * 1.5 + 2) / speed);
|
|
@@ -204,22 +227,28 @@ function estimateStarvationModeBitrate(
|
|
|
204
227
|
* switch immediately if a lower bitrate is more adapted.
|
|
205
228
|
* Returns false if it estimates that you have time before switching to a lower
|
|
206
229
|
* bitrate.
|
|
207
|
-
* @param {Object} playbackInfo
|
|
230
|
+
* @param {Object} playbackInfo - Information on the current playback.
|
|
208
231
|
* @param {Object} requests - Every requests pending, in a chronological
|
|
209
232
|
* order in terms of segment time.
|
|
210
|
-
* @param {
|
|
211
|
-
*
|
|
233
|
+
* @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
|
|
234
|
+
* low latency content, as close to the live edge as possible.
|
|
212
235
|
* @returns {boolean}
|
|
213
236
|
*/
|
|
214
237
|
function shouldDirectlySwitchToLowBitrate(
|
|
215
238
|
playbackInfo : IPlaybackConditionsInfo,
|
|
216
|
-
requests : IRequestInfo[]
|
|
239
|
+
requests : IRequestInfo[],
|
|
240
|
+
lowLatencyMode : boolean
|
|
217
241
|
) : boolean {
|
|
242
|
+
if (lowLatencyMode) {
|
|
243
|
+
// TODO only when playing close to the live edge?
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
218
246
|
const realBufferGap = isFinite(playbackInfo.bufferGap) ? playbackInfo.bufferGap :
|
|
219
247
|
0;
|
|
220
248
|
const nextNeededPosition = playbackInfo.position + realBufferGap;
|
|
221
|
-
const nextRequest = arrayFind(requests, (
|
|
222
|
-
|
|
249
|
+
const nextRequest = arrayFind(requests, ({ content }) =>
|
|
250
|
+
content.segment.duration > 0 &&
|
|
251
|
+
(content.segment.time + content.segment.duration) > nextNeededPosition);
|
|
223
252
|
|
|
224
253
|
if (nextRequest === undefined) {
|
|
225
254
|
return true;
|
|
@@ -251,6 +280,7 @@ function shouldDirectlySwitchToLowBitrate(
|
|
|
251
280
|
* @class NetworkAnalyzer
|
|
252
281
|
*/
|
|
253
282
|
export default class NetworkAnalyzer {
|
|
283
|
+
private _lowLatencyMode : boolean;
|
|
254
284
|
private _inStarvationMode : boolean;
|
|
255
285
|
private _initialBitrate : number;
|
|
256
286
|
private _config : { starvationGap : number;
|
|
@@ -261,6 +291,7 @@ export default class NetworkAnalyzer {
|
|
|
261
291
|
constructor(initialBitrate: number, lowLatencyMode: boolean) {
|
|
262
292
|
this._initialBitrate = initialBitrate;
|
|
263
293
|
this._inStarvationMode = false;
|
|
294
|
+
this._lowLatencyMode = lowLatencyMode;
|
|
264
295
|
if (lowLatencyMode) {
|
|
265
296
|
this._config = { starvationGap: ABR_STARVATION_GAP.LOW_LATENCY,
|
|
266
297
|
outOfStarvationGap: OUT_OF_STARVATION_GAP.LOW_LATENCY,
|
|
@@ -278,11 +309,16 @@ export default class NetworkAnalyzer {
|
|
|
278
309
|
* Gives an estimate of the current bandwidth and of the bitrate that should
|
|
279
310
|
* be considered for chosing a `representation`.
|
|
280
311
|
* This estimate is only based on network metrics.
|
|
281
|
-
* @param {Object} playbackInfo - Gives current information about playback
|
|
282
|
-
* @param {Object} bandwidthEstimator
|
|
283
|
-
*
|
|
284
|
-
* @param {
|
|
285
|
-
*
|
|
312
|
+
* @param {Object} playbackInfo - Gives current information about playback.
|
|
313
|
+
* @param {Object} bandwidthEstimator - `BandwidthEstimator` allowing to
|
|
314
|
+
* produce network bandwidth estimates.
|
|
315
|
+
* @param {Object|null} currentRepresentation - The Representation currently
|
|
316
|
+
* chosen.
|
|
317
|
+
* `null` if no Representation has been chosen yet.
|
|
318
|
+
* @param {Array.<Object>} currentRequests - All segment requests by segment's
|
|
319
|
+
* start chronological order
|
|
320
|
+
* @param {number|undefined} lastEstimatedBitrate - Bitrate emitted during the
|
|
321
|
+
* last estimate.
|
|
286
322
|
* @returns {Object}
|
|
287
323
|
*/
|
|
288
324
|
public getBandwidthEstimate(
|
|
@@ -324,6 +360,7 @@ export default class NetworkAnalyzer {
|
|
|
324
360
|
bandwidthEstimate = estimateStarvationModeBitrate(currentRequests,
|
|
325
361
|
playbackInfo,
|
|
326
362
|
currentRepresentation,
|
|
363
|
+
this._lowLatencyMode,
|
|
327
364
|
lastEstimatedBitrate);
|
|
328
365
|
|
|
329
366
|
if (bandwidthEstimate != null) {
|
|
@@ -361,8 +398,12 @@ export default class NetworkAnalyzer {
|
|
|
361
398
|
|
|
362
399
|
/**
|
|
363
400
|
* For a given wanted bitrate, tells if should switch urgently.
|
|
364
|
-
* @param {number} bitrate
|
|
365
|
-
* @param {Object}
|
|
401
|
+
* @param {number} bitrate - The new estimated bitrate.
|
|
402
|
+
* @param {Object|null} currentRepresentation - The Representation being
|
|
403
|
+
* presently being loaded.
|
|
404
|
+
* @param {Array.<Object>} currentRequests - All segment requests by segment's
|
|
405
|
+
* start chronological order
|
|
406
|
+
* @param {Object} playbackInfo - Information on the current playback.
|
|
366
407
|
* @returns {boolean}
|
|
367
408
|
*/
|
|
368
409
|
public isUrgent(
|
|
@@ -378,6 +419,8 @@ export default class NetworkAnalyzer {
|
|
|
378
419
|
} else if (bitrate > currentRepresentation.bitrate) {
|
|
379
420
|
return !this._inStarvationMode;
|
|
380
421
|
}
|
|
381
|
-
return shouldDirectlySwitchToLowBitrate(playbackInfo,
|
|
422
|
+
return shouldDirectlySwitchToLowBitrate(playbackInfo,
|
|
423
|
+
currentRequests,
|
|
424
|
+
this._lowLatencyMode);
|
|
382
425
|
}
|
|
383
426
|
}
|