rx-player 3.26.3-dev.2022021400 → 3.27.0-dev.2022032100
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 +0 -4
- package/CHANGELOG.md +17 -2
- package/FILES.md +5 -4
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +4 -2
- package/dist/_esm5.processed/compat/browser_detection.js +4 -2
- package/dist/_esm5.processed/compat/eme/close_session.d.ts +11 -5
- package/dist/_esm5.processed/compat/eme/close_session.js +143 -36
- package/dist/_esm5.processed/compat/eme/custom_key_system_access.d.ts +15 -0
- package/dist/_esm5.processed/compat/eme/custom_key_system_access.js +1 -17
- package/dist/_esm5.processed/compat/eme/custom_media_keys/ie11_media_keys.js +6 -7
- package/dist/_esm5.processed/compat/eme/custom_media_keys/index.d.ts +3 -5
- package/dist/_esm5.processed/compat/eme/custom_media_keys/index.js +20 -22
- package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +58 -40
- package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +49 -48
- package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +2 -3
- package/dist/_esm5.processed/compat/eme/generate_key_request.js +22 -26
- package/dist/_esm5.processed/compat/eme/load_session.d.ts +1 -2
- package/dist/_esm5.processed/compat/eme/load_session.js +67 -17
- package/dist/_esm5.processed/compat/event_listeners.js +2 -1
- package/dist/_esm5.processed/compat/should_favour_custom_safari_EME.js +2 -2
- package/dist/_esm5.processed/config.d.ts +166 -1080
- package/dist/_esm5.processed/config.js +17 -1119
- package/dist/_esm5.processed/core/abr/bandwidth_estimator.js +4 -1
- package/dist/_esm5.processed/core/abr/network_analyzer.js +2 -1
- package/dist/_esm5.processed/core/api/get_player_state.js +1 -1
- package/dist/_esm5.processed/core/api/index.d.ts +2 -1
- package/dist/_esm5.processed/core/api/media_element_track_choice_manager.js +2 -1
- package/dist/_esm5.processed/core/api/option_utils.d.ts +6 -3
- package/dist/_esm5.processed/core/api/option_utils.js +21 -7
- package/dist/_esm5.processed/core/api/playback_observer.js +5 -1
- package/dist/_esm5.processed/core/api/public_api.d.ts +82 -71
- package/dist/_esm5.processed/core/api/public_api.js +73 -35
- package/dist/_esm5.processed/core/{eme → decrypt}/__tests__/__global__/utils.d.ts +7 -49
- package/dist/_esm5.processed/core/{eme → decrypt}/__tests__/__global__/utils.js +25 -65
- package/dist/_esm5.processed/core/{eme → decrypt}/attach_media_keys.d.ts +12 -12
- package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +103 -0
- package/dist/_esm5.processed/core/{eme/clear_eme_session.d.ts → decrypt/clear_on_stop.d.ts} +3 -4
- package/dist/_esm5.processed/core/decrypt/clear_on_stop.js +40 -0
- package/dist/_esm5.processed/core/decrypt/content_decryptor.d.ts +216 -0
- package/dist/_esm5.processed/core/decrypt/content_decryptor.js +865 -0
- package/dist/_esm5.processed/core/{eme/get_session.d.ts → decrypt/create_or_load_session.d.ts} +28 -26
- package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +124 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/create_session.d.ts +22 -19
- package/dist/_esm5.processed/core/decrypt/create_session.js +173 -0
- package/dist/_esm5.processed/core/{eme/dispose_media_keys.d.ts → decrypt/dispose_decryption_resources.d.ts} +4 -4
- package/dist/_esm5.processed/core/decrypt/dispose_decryption_resources.js +81 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/find_key_system.d.ts +11 -14
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +299 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/get_current_key_system.d.ts +0 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/get_current_key_system.js +1 -1
- package/dist/_esm5.processed/core/{eme → decrypt}/get_media_keys.d.ts +13 -5
- package/dist/_esm5.processed/core/decrypt/get_media_keys.js +153 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/index.d.ts +5 -6
- package/dist/_esm5.processed/core/{eme → decrypt}/index.js +5 -5
- package/dist/_esm5.processed/core/{eme → decrypt}/init_media_keys.d.ts +6 -4
- package/dist/_esm5.processed/core/decrypt/init_media_keys.js +82 -0
- package/dist/_esm5.processed/core/decrypt/session_events_listener.d.ts +77 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/session_events_listener.js +25 -24
- package/dist/_esm5.processed/core/{eme → decrypt}/set_server_certificate.d.ts +15 -6
- package/dist/_esm5.processed/core/decrypt/set_server_certificate.js +141 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/types.d.ts +119 -241
- package/dist/_esm5.processed/core/{eme → decrypt}/types.js +0 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/are_init_values_compatible.d.ts +3 -3
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/are_init_values_compatible.js +5 -5
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/check_key_statuses.d.ts +2 -2
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/check_key_statuses.js +4 -3
- package/dist/_esm5.processed/core/{eme/utils/close_session.d.ts → decrypt/utils/clean_old_loaded_sessions.d.ts} +8 -7
- package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +84 -0
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.d.ts +1 -1
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.js +2 -2
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/get_drm_system_id.d.ts +0 -0
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/get_drm_system_id.js +1 -1
- package/dist/_esm5.processed/core/decrypt/utils/init_data_values_container.d.ts +69 -0
- package/dist/_esm5.processed/core/decrypt/utils/init_data_values_container.js +99 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/is_session_usable.d.ts +0 -1
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/is_session_usable.js +4 -5
- package/dist/_esm5.processed/core/decrypt/utils/key_id_comparison.d.ts +44 -0
- package/dist/_esm5.processed/core/decrypt/utils/key_id_comparison.js +77 -0
- package/dist/_esm5.processed/core/decrypt/utils/key_session_record.d.ts +104 -0
- package/dist/_esm5.processed/core/decrypt/utils/key_session_record.js +155 -0
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +108 -0
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +302 -0
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/media_keys_infos_store.d.ts +4 -4
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/media_keys_infos_store.js +0 -0
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/persistent_sessions_store.d.ts +8 -18
- package/dist/_esm5.processed/core/{eme → decrypt}/utils/persistent_sessions_store.js +119 -97
- package/dist/_esm5.processed/core/{eme/utils/init_data_container.d.ts → decrypt/utils/serializable_bytes.d.ts} +8 -5
- package/dist/_esm5.processed/core/{eme/utils/init_data_container.js → decrypt/utils/serializable_bytes.js} +9 -9
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/server_certificate_store.d.ts +1 -1
- package/dist/_esm5.processed/core/{eme → decrypt/utils}/server_certificate_store.js +1 -1
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +3 -5
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +1 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +1 -1
- package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +2 -3
- package/dist/_esm5.processed/core/init/get_initial_time.js +1 -1
- package/dist/_esm5.processed/core/init/initialize_directfile.d.ts +1 -1
- package/dist/_esm5.processed/core/init/initialize_directfile.js +11 -17
- package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +6 -3
- package/dist/_esm5.processed/core/init/initialize_media_source.js +18 -69
- package/dist/_esm5.processed/core/init/link_drm_and_content.d.ts +61 -0
- package/dist/_esm5.processed/core/init/link_drm_and_content.js +94 -0
- package/dist/_esm5.processed/core/init/manifest_update_scheduler.js +2 -1
- package/dist/_esm5.processed/core/init/stall_avoider.js +1 -1
- package/dist/_esm5.processed/core/init/stream_events_emitter/stream_events_emitter.js +1 -1
- package/dist/_esm5.processed/core/init/types.d.ts +2 -4
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +3 -1
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +17 -1
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +22 -5
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.d.ts +2 -1
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +6 -3
- package/dist/_esm5.processed/core/stream/events_generators.d.ts +8 -3
- package/dist/_esm5.processed/core/stream/events_generators.js +3 -2
- package/dist/_esm5.processed/core/stream/index.d.ts +1 -0
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.d.ts +1 -0
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +3 -3
- package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.js +2 -1
- package/dist/_esm5.processed/core/stream/period/get_adaptation_switch_strategy.d.ts +15 -11
- package/dist/_esm5.processed/core/stream/period/get_adaptation_switch_strategy.js +6 -3
- package/dist/_esm5.processed/core/stream/period/index.d.ts +1 -0
- package/dist/_esm5.processed/core/stream/period/period_stream.d.ts +5 -12
- package/dist/_esm5.processed/core/stream/period/period_stream.js +3 -3
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +2 -2
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +6 -1
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +12 -9
- package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +19 -14
- package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +86 -10
- package/dist/_esm5.processed/core/stream/representation/get_segment_priority.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +3 -3
- package/dist/_esm5.processed/core/stream/representation/representation_stream.d.ts +6 -0
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +19 -8
- package/dist/_esm5.processed/core/stream/types.d.ts +1 -1
- package/dist/_esm5.processed/default_config.d.ts +1114 -0
- package/dist/_esm5.processed/default_config.js +1145 -0
- package/dist/_esm5.processed/experimental/index.d.ts +2 -0
- package/dist/_esm5.processed/experimental/index.js +2 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.d.ts +1 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +6 -7
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/api/index.js +2 -3
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.d.ts +15 -0
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.js +1 -2
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/DRMInfos.js +3 -5
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/HDCPPolicy.js +3 -5
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/decodingInfo.js +1 -2
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/mediaContentType.js +1 -2
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/mediaContentTypeWithFeatures/index.js +1 -2
- package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/mediaDisplayInfos.js +1 -2
- package/dist/_esm5.processed/features/features_object.js +1 -1
- package/dist/_esm5.processed/features/initialize_features.js +1 -1
- package/dist/_esm5.processed/features/list/eme.d.ts +3 -3
- package/dist/_esm5.processed/features/list/eme.js +5 -5
- package/dist/_esm5.processed/features/types.d.ts +3 -3
- package/dist/_esm5.processed/manifest/manifest.d.ts +1 -14
- package/dist/_esm5.processed/manifest/manifest.js +10 -74
- package/dist/_esm5.processed/manifest/representation.d.ts +35 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/is_period_fulfilled.js +1 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +1 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +87 -75
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +1 -2
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +4 -5
- package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +1 -0
- package/dist/_esm5.processed/public_types.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +1 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +4 -3
- package/dist/_esm5.processed/transports/dash/image_pipelines.js +60 -11
- package/dist/_esm5.processed/transports/dash/init_segment_loader.js +1 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +2 -3
- package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +1 -1
- package/dist/_esm5.processed/transports/dash/segment_loader.js +3 -4
- package/dist/_esm5.processed/transports/dash/segment_parser.js +6 -3
- package/dist/_esm5.processed/transports/dash/text_loader.js +1 -2
- package/dist/_esm5.processed/transports/dash/text_parser.js +8 -2
- package/dist/_esm5.processed/transports/local/segment_loader.js +2 -3
- package/dist/_esm5.processed/transports/local/segment_parser.js +4 -1
- package/dist/_esm5.processed/transports/local/text_parser.js +8 -2
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +2 -3
- package/dist/_esm5.processed/transports/smooth/pipelines.js +71 -14
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +3 -4
- package/dist/_esm5.processed/transports/types.d.ts +22 -0
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +1 -2
- package/dist/_esm5.processed/utils/cancellable_sleep.js +1 -2
- package/dist/_esm5.processed/utils/cast_to_observable.js +1 -3
- package/dist/_esm5.processed/utils/deep_merge.d.ts +12 -0
- package/dist/_esm5.processed/utils/deep_merge.js +53 -0
- package/dist/_esm5.processed/utils/reference.d.ts +29 -0
- package/dist/_esm5.processed/utils/reference.js +72 -24
- package/dist/_esm5.processed/utils/request/fetch.js +1 -2
- package/dist/_esm5.processed/utils/request/xhr.js +2 -3
- package/dist/_esm5.processed/utils/rx-from_cancellable_promise.js +7 -2
- package/dist/_esm5.processed/utils/task_canceller.d.ts +5 -3
- package/dist/_esm5.processed/utils/task_canceller.js +3 -3
- package/dist/rx-player.js +4936 -3340
- package/dist/rx-player.min.js +1 -1
- package/dummy +1 -0
- package/{dist/_esm5.processed/utils/promise.d.ts → experimental/index.d.ts} +1 -2
- package/{dist/_esm5.processed/utils/promise.js → experimental/index.js} +1 -3
- package/package.json +32 -35
- package/{src/typings/pinkie.d.ts → scripts/build/templates/experimental/index.d.ts} +1 -4
- package/scripts/build/templates/experimental/index.js +16 -0
- package/scripts/update-version +2 -2
- package/sonar-project.properties +1 -1
- package/src/README.md +6 -6
- package/src/compat/__tests__/play.test.ts +2 -4
- package/src/compat/__tests__/should_favour_custom_safari_EME.test.ts +45 -5
- package/src/compat/browser_detection.ts +4 -2
- package/src/compat/eme/close_session.ts +89 -56
- package/src/compat/eme/custom_key_system_access.ts +1 -2
- package/src/compat/eme/custom_media_keys/ie11_media_keys.ts +6 -7
- package/src/compat/eme/custom_media_keys/index.ts +20 -38
- package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +68 -52
- package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +57 -56
- package/src/compat/eme/generate_key_request.ts +25 -33
- package/src/compat/eme/load_session.ts +28 -31
- package/src/compat/event_listeners.ts +2 -1
- package/src/compat/should_favour_custom_safari_EME.ts +5 -2
- package/src/config.ts +17 -1210
- package/src/core/README.md +1 -1
- package/src/core/abr/bandwidth_estimator.ts +4 -4
- package/src/core/abr/network_analyzer.ts +5 -6
- package/src/core/api/__tests__/get_player_state.test.ts +3 -3
- package/src/core/api/__tests__/option_utils.test.ts +29 -17
- package/src/core/api/get_player_state.ts +1 -1
- package/src/core/api/index.ts +3 -0
- package/src/core/api/option_utils.ts +42 -23
- package/src/core/api/playback_observer.ts +12 -8
- package/src/core/api/public_api.ts +152 -113
- package/src/core/decrypt/README.md +22 -0
- package/src/core/decrypt/__tests__/__global__/get_license.test.ts +418 -0
- package/src/core/decrypt/__tests__/__global__/init_data.test.ts +675 -0
- package/src/core/{eme → decrypt}/__tests__/__global__/media_key_system_access.test.ts +99 -92
- package/src/core/decrypt/__tests__/__global__/media_keys.test.ts +156 -0
- package/src/core/decrypt/__tests__/__global__/server_certificate.test.ts +262 -0
- package/src/core/{eme → decrypt}/__tests__/__global__/utils.ts +31 -93
- package/src/core/{eme → decrypt}/attach_media_keys.ts +48 -56
- package/src/core/decrypt/clear_on_stop.ts +47 -0
- package/src/core/decrypt/content_decryptor.ts +1157 -0
- package/src/core/decrypt/create_or_load_session.ts +130 -0
- package/src/core/decrypt/create_session.ts +174 -0
- package/src/core/decrypt/dispose_decryption_resources.ts +39 -0
- package/src/core/{eme → decrypt}/find_key_system.ts +111 -122
- package/src/core/{eme → decrypt}/get_current_key_system.ts +1 -1
- package/src/core/decrypt/get_media_keys.ts +145 -0
- package/src/core/{eme → decrypt}/index.ts +11 -8
- package/src/core/decrypt/init_media_keys.ts +51 -0
- package/src/core/{eme → decrypt}/session_events_listener.ts +93 -55
- package/src/core/decrypt/set_server_certificate.ts +104 -0
- package/src/core/{eme → decrypt}/types.ts +128 -258
- package/src/core/{eme → decrypt}/utils/__tests__/are_init_values_compatible.test.ts +1 -1
- package/src/core/{eme → decrypt/utils}/__tests__/clean_old_loaded_sessions.test.ts +29 -71
- package/src/core/{eme → decrypt/utils}/__tests__/clean_old_stored_persistent_info.test.ts +6 -6
- package/src/core/{eme → decrypt}/utils/are_init_values_compatible.ts +9 -9
- package/src/core/{eme → decrypt/utils}/check_key_statuses.ts +6 -5
- package/{dist/_esm5.processed/core/eme/clean_old_loaded_sessions.js → src/core/decrypt/utils/clean_old_loaded_sessions.ts} +19 -20
- package/src/core/{eme → decrypt/utils}/clean_old_stored_persistent_info.ts +3 -3
- package/src/core/{eme → decrypt/utils}/get_drm_system_id.ts +1 -1
- package/src/core/decrypt/utils/init_data_values_container.ts +119 -0
- package/src/core/{eme → decrypt}/utils/is_session_usable.ts +4 -5
- package/src/core/decrypt/utils/key_id_comparison.ts +82 -0
- package/src/core/decrypt/utils/key_session_record.ts +175 -0
- package/src/core/decrypt/utils/loaded_sessions_store.ts +317 -0
- package/src/core/{eme → decrypt/utils}/media_keys_infos_store.ts +4 -4
- package/src/core/{eme → decrypt}/utils/persistent_sessions_store.ts +122 -104
- package/src/core/{eme/utils/init_data_container.ts → decrypt/utils/serializable_bytes.ts} +8 -5
- package/src/core/{eme → decrypt/utils}/server_certificate_store.ts +2 -2
- package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -7
- package/src/core/fetchers/segment/segment_fetcher.ts +4 -4
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +2 -2
- package/src/core/fetchers/utils/try_urls_with_backoff.ts +2 -3
- package/src/core/init/.initialize_media_source.ts.un~ +0 -0
- package/src/core/init/get_initial_time.ts +2 -1
- package/src/core/init/initialize_directfile.ts +17 -20
- package/src/core/init/initialize_media_source.ts +44 -106
- package/src/core/init/link_drm_and_content.ts +176 -0
- package/src/core/init/manifest_update_scheduler.ts +5 -3
- package/src/core/init/stall_avoider.ts +6 -5
- package/src/core/init/stream_events_emitter/stream_events_emitter.ts +2 -1
- package/src/core/init/types.ts +1 -39
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +2 -1
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +3 -4
- package/src/core/segment_buffers/inventory/segment_inventory.ts +42 -8
- package/src/core/stream/adaptation/adaptation_stream.ts +7 -1
- package/src/core/stream/events_generators.ts +9 -4
- package/src/core/stream/index.ts +1 -0
- package/src/core/stream/orchestrator/stream_orchestrator.ts +9 -4
- package/src/core/stream/period/create_empty_adaptation_stream.ts +2 -1
- package/src/core/stream/period/get_adaptation_switch_strategy.ts +25 -15
- package/src/core/stream/period/index.ts +1 -0
- package/src/core/stream/period/period_stream.ts +10 -16
- package/src/core/stream/representation/force_garbage_collection.ts +2 -2
- package/src/core/stream/representation/get_buffer_status.ts +28 -16
- package/src/core/stream/representation/get_needed_segments.ts +124 -28
- package/src/core/stream/representation/get_segment_priority.ts +1 -2
- package/src/core/stream/representation/push_media_segment.ts +3 -2
- package/src/core/stream/representation/representation_stream.ts +30 -7
- package/src/core/stream/types.ts +1 -1
- package/src/default_config.ts +1241 -0
- package/src/experimental/index.ts +5 -0
- package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +1 -0
- package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +7 -7
- package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/DRMInfos.test.ts +3 -10
- package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/HDCPPolicy.test.ts +9 -10
- package/src/experimental/tools/mediaCapabilitiesProber/__tests__/probers/decodingInfos.test.ts +2 -4
- package/src/experimental/tools/mediaCapabilitiesProber/api/index.ts +2 -3
- package/src/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.ts +1 -2
- package/src/experimental/tools/mediaCapabilitiesProber/probers/DRMInfos.ts +3 -5
- package/src/experimental/tools/mediaCapabilitiesProber/probers/HDCPPolicy.ts +3 -5
- package/src/experimental/tools/mediaCapabilitiesProber/probers/decodingInfo.ts +1 -2
- package/src/experimental/tools/mediaCapabilitiesProber/probers/mediaContentType.ts +1 -2
- package/src/experimental/tools/mediaCapabilitiesProber/probers/mediaContentTypeWithFeatures/index.ts +1 -2
- package/src/experimental/tools/mediaCapabilitiesProber/probers/mediaDisplayInfos.ts +1 -2
- package/src/features/__tests__/initialize_features.test.ts +2 -2
- package/src/features/features_object.ts +1 -1
- package/src/features/initialize_features.ts +1 -1
- package/src/features/list/__tests__/eme.test.ts +5 -5
- package/src/features/list/eme.ts +5 -5
- package/src/features/types.ts +3 -10
- package/src/manifest/manifest.ts +6 -76
- package/src/manifest/representation.ts +36 -3
- package/src/parsers/manifest/dash/common/indexes/is_period_fulfilled.ts +1 -2
- package/src/parsers/manifest/dash/common/indexes/template.ts +1 -2
- package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +1 -1
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +109 -64
- package/src/parsers/manifest/dash/common/parse_mpd.ts +1 -2
- package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +4 -5
- package/src/parsers/manifest/smooth/create_parser.ts +1 -0
- package/src/parsers/texttracks/webvtt/html/__tests__/create_styled_element.test.ts +1 -0
- package/src/public_types.ts +6 -1
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +1 -2
- package/src/transports/dash/image_pipelines.ts +15 -14
- package/src/transports/dash/init_segment_loader.ts +1 -2
- package/src/transports/dash/manifest_parser.ts +2 -3
- package/src/transports/dash/segment_loader.ts +4 -5
- package/src/transports/dash/segment_parser.ts +5 -0
- package/src/transports/dash/text_loader.ts +2 -3
- package/src/transports/dash/text_parser.ts +8 -0
- package/src/transports/local/segment_loader.ts +2 -3
- package/src/transports/local/segment_parser.ts +4 -0
- package/src/transports/local/text_parser.ts +8 -0
- package/src/transports/metaplaylist/pipelines.ts +2 -3
- package/src/transports/smooth/pipelines.ts +26 -14
- package/src/transports/smooth/segment_loader.ts +5 -6
- package/src/transports/types.ts +22 -0
- package/src/transports/utils/call_custom_manifest_loader.ts +1 -2
- package/src/utils/__tests__/deep_merge.test.ts +48 -0
- package/src/utils/cancellable_sleep.ts +1 -2
- package/src/utils/cast_to_observable.ts +0 -2
- package/src/utils/deep_merge.ts +46 -0
- package/src/utils/reference.ts +116 -23
- package/src/utils/request/fetch.ts +1 -2
- package/src/utils/request/xhr.ts +3 -3
- package/src/utils/rx-from_cancellable_promise.ts +7 -2
- package/src/utils/task_canceller.ts +6 -4
- package/tsconfig.json +0 -1
- package/tsconfig.modules.json +0 -1
- package/dist/_esm5.processed/core/eme/attach_media_keys.js +0 -57
- package/dist/_esm5.processed/core/eme/clean_old_loaded_sessions.d.ts +0 -59
- package/dist/_esm5.processed/core/eme/clear_eme_session.js +0 -50
- package/dist/_esm5.processed/core/eme/create_session.js +0 -126
- package/dist/_esm5.processed/core/eme/dispose_eme.d.ts +0 -19
- package/dist/_esm5.processed/core/eme/dispose_eme.js +0 -23
- package/dist/_esm5.processed/core/eme/dispose_media_keys.js +0 -36
- package/dist/_esm5.processed/core/eme/eme_manager.d.ts +0 -31
- package/dist/_esm5.processed/core/eme/eme_manager.js +0 -278
- package/dist/_esm5.processed/core/eme/find_key_system.js +0 -253
- package/dist/_esm5.processed/core/eme/get_media_keys.js +0 -85
- package/dist/_esm5.processed/core/eme/get_session.js +0 -68
- package/dist/_esm5.processed/core/eme/init_media_keys.js +0 -66
- package/dist/_esm5.processed/core/eme/session_events_listener.d.ts +0 -41
- package/dist/_esm5.processed/core/eme/set_server_certificate.js +0 -85
- package/dist/_esm5.processed/core/eme/utils/close_session.js +0 -81
- package/dist/_esm5.processed/core/eme/utils/init_data_store.d.ts +0 -115
- package/dist/_esm5.processed/core/eme/utils/init_data_store.js +0 -181
- package/dist/_esm5.processed/core/eme/utils/loaded_sessions_store.d.ts +0 -123
- package/dist/_esm5.processed/core/eme/utils/loaded_sessions_store.js +0 -173
- package/dist/_esm5.processed/core/init/create_eme_manager.d.ts +0 -34
- package/dist/_esm5.processed/core/init/create_eme_manager.js +0 -52
- package/src/core/eme/README.md +0 -26
- package/src/core/eme/__tests__/__global__/get_license.test.ts +0 -414
- package/src/core/eme/__tests__/__global__/init_data.test.ts +0 -908
- package/src/core/eme/__tests__/__global__/media_keys.test.ts +0 -266
- package/src/core/eme/__tests__/__global__/server_certificate.test.ts +0 -364
- package/src/core/eme/__tests__/init_media_keys.test.ts +0 -182
- package/src/core/eme/clean_old_loaded_sessions.ts +0 -96
- package/src/core/eme/clear_eme_session.ts +0 -62
- package/src/core/eme/create_session.ts +0 -187
- package/src/core/eme/dispose_eme.ts +0 -25
- package/src/core/eme/dispose_media_keys.ts +0 -46
- package/src/core/eme/eme_manager.ts +0 -387
- package/src/core/eme/get_media_keys.ts +0 -141
- package/src/core/eme/get_session.ts +0 -135
- package/src/core/eme/init_media_keys.ts +0 -106
- package/src/core/eme/set_server_certificate.ts +0 -115
- package/src/core/eme/utils/close_session.ts +0 -113
- package/src/core/eme/utils/init_data_store.ts +0 -234
- package/src/core/eme/utils/loaded_sessions_store.ts +0 -235
- package/src/core/init/create_eme_manager.ts +0 -95
- package/src/utils/__tests__/promise.test.ts +0 -23
- package/src/utils/promise.ts +0 -20
|
@@ -32,7 +32,6 @@ import EVENTS from "../events_generators";
|
|
|
32
32
|
import reloadAfterSwitch from "../reload_after_switch";
|
|
33
33
|
import RepresentationStream from "../representation";
|
|
34
34
|
import createRepresentationEstimator from "./create_representation_estimator";
|
|
35
|
-
var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
|
|
36
35
|
/**
|
|
37
36
|
* Create new AdaptationStream Observable, which task will be to download the
|
|
38
37
|
* media data for a given Adaptation (i.e. "track").
|
|
@@ -48,7 +47,7 @@ var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
|
|
|
48
47
|
* @returns {Observable}
|
|
49
48
|
*/
|
|
50
49
|
export default function AdaptationStream(_a) {
|
|
51
|
-
var abrManager = _a.abrManager, playbackObserver = _a.playbackObserver, content = _a.content, options = _a.options, segmentBuffer = _a.segmentBuffer, segmentFetcherCreator = _a.segmentFetcherCreator, wantedBufferAhead = _a.wantedBufferAhead;
|
|
50
|
+
var abrManager = _a.abrManager, playbackObserver = _a.playbackObserver, content = _a.content, options = _a.options, segmentBuffer = _a.segmentBuffer, segmentFetcherCreator = _a.segmentFetcherCreator, wantedBufferAhead = _a.wantedBufferAhead, maxVideoBufferSize = _a.maxVideoBufferSize;
|
|
52
51
|
var directManualBitrateSwitching = options.manualBitrateSwitchingMode === "direct";
|
|
53
52
|
var manifest = content.manifest, period = content.period, adaptation = content.adaptation;
|
|
54
53
|
/**
|
|
@@ -120,6 +119,7 @@ export default function AdaptationStream(_a) {
|
|
|
120
119
|
if (directManualBitrateSwitching &&
|
|
121
120
|
fromEstimate.manual &&
|
|
122
121
|
!isFirstEstimate) {
|
|
122
|
+
var DELTA_POSITION_AFTER_RELOAD = config.getCurrent().DELTA_POSITION_AFTER_RELOAD;
|
|
123
123
|
return reloadAfterSwitch(period, adaptation.type, playbackObserver, DELTA_POSITION_AFTER_RELOAD.bitrateSwitch);
|
|
124
124
|
}
|
|
125
125
|
/**
|
|
@@ -187,9 +187,12 @@ export default function AdaptationStream(_a) {
|
|
|
187
187
|
1;
|
|
188
188
|
bufferGoalRatioMap[representation.id] = bufferGoalRatio;
|
|
189
189
|
var bufferGoal$ = wantedBufferAhead.asObservable().pipe(map(function (wba) { return wba * bufferGoalRatio; }));
|
|
190
|
+
// eslint-disable-next-line max-len
|
|
191
|
+
var maxBufferSize$ = adaptation.type === "video" ? maxVideoBufferSize.asObservable() :
|
|
192
|
+
observableOf(Infinity);
|
|
190
193
|
log.info("Stream: changing representation", adaptation.type, representation.id, representation.bitrate);
|
|
191
194
|
return RepresentationStream({ playbackObserver: playbackObserver, content: { representation: representation, adaptation: adaptation, period: period, manifest: manifest }, segmentBuffer: segmentBuffer, segmentFetcher: segmentFetcher, terminate$: terminateCurrentStream$,
|
|
192
|
-
options: { bufferGoal$: bufferGoal$, drmSystemId: options.drmSystemId, fastSwitchThreshold$: fastSwitchThreshold$ } })
|
|
195
|
+
options: { bufferGoal$: bufferGoal$, maxBufferSize$: maxBufferSize$, drmSystemId: options.drmSystemId, fastSwitchThreshold$: fastSwitchThreshold$ } })
|
|
193
196
|
.pipe(catchError(function (err) {
|
|
194
197
|
var formattedError = formatError(err, {
|
|
195
198
|
defaultCode: "NONE",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { Subject } from "rxjs";
|
|
17
17
|
import { ICustomError } from "../../errors";
|
|
18
|
-
import { Adaptation, ISegment, Period, Representation } from "../../manifest";
|
|
19
|
-
import {
|
|
18
|
+
import Manifest, { Adaptation, ISegment, Period, Representation } from "../../manifest";
|
|
19
|
+
import { IRepresentationProtectionData } from "../../manifest/representation";
|
|
20
20
|
import { IBufferType } from "../segment_buffers";
|
|
21
21
|
import { IActivePeriodChangedEvent, IAdaptationChangeEvent, IBitrateEstimationChangeEvent, ICompletedStreamEvent, IEncryptionDataEncounteredEvent, IEndOfStreamEvent, ILockedStreamEvent, INeedsBufferFlushEvent, INeedsDecipherabilityFlush, INeedsMediaSourceReload, IPeriodStreamClearedEvent, IPeriodStreamReadyEvent, IRepresentationChangeEvent, IResumeStreamEvent, IStreamEventAddedSegment, IStreamManifestMightBeOutOfSync, IStreamNeedsManifestRefresh, IStreamTerminatingEvent, IStreamWarningEvent, IWaitingMediaSourceReloadInternalEvent } from "./types";
|
|
22
22
|
declare const EVENTS: {
|
|
@@ -52,7 +52,12 @@ declare const EVENTS: {
|
|
|
52
52
|
needsDecipherabilityFlush(position: number, autoPlay: boolean, duration: number): INeedsDecipherabilityFlush;
|
|
53
53
|
periodStreamReady(type: IBufferType, period: Period, adaptation$: Subject<Adaptation | null>): IPeriodStreamReadyEvent;
|
|
54
54
|
periodStreamCleared(type: IBufferType, period: Period): IPeriodStreamClearedEvent;
|
|
55
|
-
encryptionDataEncountered(
|
|
55
|
+
encryptionDataEncountered(reprProtData: IRepresentationProtectionData, content: {
|
|
56
|
+
manifest: Manifest;
|
|
57
|
+
period: Period;
|
|
58
|
+
adaptation: Adaptation;
|
|
59
|
+
representation: Representation;
|
|
60
|
+
}): IEncryptionDataEncounteredEvent;
|
|
56
61
|
representationChange(type: IBufferType, period: Period, representation: Representation): IRepresentationChangeEvent;
|
|
57
62
|
streamTerminating(): IStreamTerminatingEvent;
|
|
58
63
|
resumeStream(): IResumeStreamEvent;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import objectAssign from "../../utils/object_assign";
|
|
16
17
|
var EVENTS = {
|
|
17
18
|
activePeriodChanged: function (period) {
|
|
18
19
|
return { type: "activePeriodChanged",
|
|
@@ -84,9 +85,9 @@ var EVENTS = {
|
|
|
84
85
|
return { type: "periodStreamCleared",
|
|
85
86
|
value: { type: type, period: period } };
|
|
86
87
|
},
|
|
87
|
-
encryptionDataEncountered: function (
|
|
88
|
+
encryptionDataEncountered: function (reprProtData, content) {
|
|
88
89
|
return { type: "encryption-data-encountered",
|
|
89
|
-
value:
|
|
90
|
+
value: objectAssign({ content: content }, reprProtData) };
|
|
90
91
|
},
|
|
91
92
|
representationChange: function (type, period, representation) {
|
|
92
93
|
return { type: "representationChange",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import StreamOrchestrator, { IStreamOrchestratorOptions, IStreamOrchestratorPlaybackObservation } from "./orchestrator";
|
|
17
|
+
export { IAudioTrackSwitchingMode } from "./period";
|
|
17
18
|
export * from "./types";
|
|
18
19
|
export default StreamOrchestrator;
|
|
19
20
|
export { IStreamOrchestratorPlaybackObservation, IStreamOrchestratorOptions, };
|
|
@@ -26,6 +26,7 @@ export declare type IStreamOrchestratorPlaybackObservation = IPeriodStreamPlayba
|
|
|
26
26
|
/** Options tweaking the behavior of the StreamOrchestrator. */
|
|
27
27
|
export declare type IStreamOrchestratorOptions = IPeriodStreamOptions & {
|
|
28
28
|
wantedBufferAhead: IReadOnlySharedReference<number>;
|
|
29
|
+
maxVideoBufferSize: IReadOnlySharedReference<number>;
|
|
29
30
|
maxBufferAhead: IReadOnlySharedReference<number>;
|
|
30
31
|
maxBufferBehind: IReadOnlySharedReference<number>;
|
|
31
32
|
};
|
|
@@ -37,7 +37,6 @@ import PeriodStream from "../period";
|
|
|
37
37
|
import ActivePeriodEmitter from "./active_period_emitter";
|
|
38
38
|
import areStreamsComplete from "./are_streams_complete";
|
|
39
39
|
import getBlacklistedRanges from "./get_blacklisted_ranges";
|
|
40
|
-
var MAXIMUM_MAX_BUFFER_AHEAD = config.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = config.MAXIMUM_MAX_BUFFER_BEHIND;
|
|
41
40
|
/**
|
|
42
41
|
* Create and manage the various Stream Observables needed for the content to
|
|
43
42
|
* play:
|
|
@@ -65,7 +64,8 @@ var MAXIMUM_MAX_BUFFER_AHEAD = config.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFF
|
|
|
65
64
|
*/
|
|
66
65
|
export default function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffersStore, segmentFetcherCreator, options) {
|
|
67
66
|
var manifest = content.manifest, initialPeriod = content.initialPeriod;
|
|
68
|
-
var maxBufferAhead = options.maxBufferAhead, maxBufferBehind = options.maxBufferBehind, wantedBufferAhead = options.wantedBufferAhead;
|
|
67
|
+
var maxBufferAhead = options.maxBufferAhead, maxBufferBehind = options.maxBufferBehind, wantedBufferAhead = options.wantedBufferAhead, maxVideoBufferSize = options.maxVideoBufferSize;
|
|
68
|
+
var _a = config.getCurrent(), MAXIMUM_MAX_BUFFER_AHEAD = _a.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = _a.MAXIMUM_MAX_BUFFER_BEHIND;
|
|
69
69
|
// Keep track of a unique BufferGarbageCollector created per
|
|
70
70
|
// SegmentBuffer.
|
|
71
71
|
var garbageCollectors = new WeakMapMemory(function (segmentBuffer) {
|
|
@@ -315,7 +315,7 @@ export default function StreamOrchestrator(content, playbackObserver, abrManager
|
|
|
315
315
|
);
|
|
316
316
|
// Will emit when the current Stream should be destroyed.
|
|
317
317
|
var killCurrentStream$ = observableMerge(endOfCurrentStream$, destroyAll$);
|
|
318
|
-
var periodStream$ = PeriodStream({ abrManager: abrManager, bufferType: bufferType, content: { manifest: manifest, period: basePeriod }, garbageCollectors: garbageCollectors, segmentFetcherCreator: segmentFetcherCreator, segmentBuffersStore: segmentBuffersStore, options: options, playbackObserver: playbackObserver, wantedBufferAhead: wantedBufferAhead }).pipe(mergeMap(function (evt) {
|
|
318
|
+
var periodStream$ = PeriodStream({ abrManager: abrManager, bufferType: bufferType, content: { manifest: manifest, period: basePeriod }, garbageCollectors: garbageCollectors, segmentFetcherCreator: segmentFetcherCreator, segmentBuffersStore: segmentBuffersStore, options: options, playbackObserver: playbackObserver, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize }).pipe(mergeMap(function (evt) {
|
|
319
319
|
if (evt.type === "stream-status") {
|
|
320
320
|
if (evt.value.hasFinishedLoading) {
|
|
321
321
|
var nextPeriod = manifest.getPeriodAfter(basePeriod);
|
|
@@ -31,7 +31,8 @@ export default function createEmptyAdaptationStream(playbackObserver, wantedBuff
|
|
|
31
31
|
var hasFinishedLoading = false;
|
|
32
32
|
var wantedBufferAhead$ = wantedBufferAhead.asObservable();
|
|
33
33
|
var observation$ = playbackObserver.observe(true);
|
|
34
|
-
return observableCombineLatest([observation$,
|
|
34
|
+
return observableCombineLatest([observation$,
|
|
35
|
+
wantedBufferAhead$]).pipe(mergeMap(function (_a) {
|
|
35
36
|
var observation = _a[0], wba = _a[1];
|
|
36
37
|
var position = observation.position;
|
|
37
38
|
if (period.end !== undefined && position + wba >= period.end) {
|
|
@@ -35,20 +35,24 @@ export declare type IAdaptationSwitchStrategy = {
|
|
|
35
35
|
value: undefined;
|
|
36
36
|
};
|
|
37
37
|
export interface IAdaptationSwitchOptions {
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
* Can be either:
|
|
41
|
-
* - "seamless": transitions are smooth but could be not immediate.
|
|
42
|
-
* - "direct": strategy will be "smart", if the mimetype and the codec,
|
|
43
|
-
* change, we will perform a hard reload of the media source, however, if it
|
|
44
|
-
* doesn't change, we will just perform a small flush by removing buffered range
|
|
45
|
-
* and performing, a small seek on the media element.
|
|
46
|
-
* Transitions are faster, but, we could see appear a reloading or seeking state.
|
|
47
|
-
*/
|
|
48
|
-
audioTrackSwitchingMode: "seamless" | "direct";
|
|
38
|
+
/** RxPlayer's behavior when switching the audio track. */
|
|
39
|
+
audioTrackSwitchingMode: IAudioTrackSwitchingMode;
|
|
49
40
|
/** Behavior when a new video and/or audio codec is encountered. */
|
|
50
41
|
onCodecSwitch: "continue" | "reload";
|
|
51
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Strategy to adopt when manually switching of audio adaptation.
|
|
45
|
+
* Can be either:
|
|
46
|
+
* - "seamless": transitions are smooth but could be not immediate.
|
|
47
|
+
* - "direct": strategy will be "smart", if the mimetype and the codec,
|
|
48
|
+
* change, we will perform a hard reload of the media source, however, if it
|
|
49
|
+
* doesn't change, we will just perform a small flush by removing buffered range
|
|
50
|
+
* and performing, a small seek on the media element.
|
|
51
|
+
* Transitions are faster, but, we could see appear a BUFFERING state.
|
|
52
|
+
* - "reload": completely reload the content. This allows a direct switch
|
|
53
|
+
* compatible with most device but may necessitate a RELOADING phase.
|
|
54
|
+
*/
|
|
55
|
+
export declare type IAudioTrackSwitchingMode = "seamless" | "direct" | "reload";
|
|
52
56
|
/**
|
|
53
57
|
* Find out what to do when switching Adaptation, based on the current
|
|
54
58
|
* situation.
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
import config from "../../../config";
|
|
17
17
|
import areCodecsCompatible from "../../../utils/are_codecs_compatible";
|
|
18
18
|
import { convertToRanges, excludeFromRanges, isTimeInRange, isTimeInRanges, keepRangeIntersection, } from "../../../utils/ranges";
|
|
19
|
-
var ADAPTATION_SWITCH_BUFFER_PADDINGS = config.ADAPTATION_SWITCH_BUFFER_PADDINGS;
|
|
20
19
|
/**
|
|
21
20
|
* Find out what to do when switching Adaptation, based on the current
|
|
22
21
|
* situation.
|
|
@@ -63,7 +62,10 @@ export default function getAdaptationSwitchStrategy(segmentBuffer, period, adapt
|
|
|
63
62
|
return { type: "continue", value: undefined };
|
|
64
63
|
}
|
|
65
64
|
var currentTime = playbackInfo.currentTime;
|
|
66
|
-
|
|
65
|
+
var audioTrackSwitchingMode = options.audioTrackSwitchingMode;
|
|
66
|
+
var hasReloadSwitchingMode = adaptation.type === "video" ||
|
|
67
|
+
(adaptation.type === "audio" && audioTrackSwitchingMode === "reload");
|
|
68
|
+
if (hasReloadSwitchingMode &&
|
|
67
69
|
// We're playing the current Period
|
|
68
70
|
isTimeInRange({ start: start, end: end }, currentTime) &&
|
|
69
71
|
// There is data for the current position or the codecs are differents
|
|
@@ -75,7 +77,7 @@ export default function getAdaptationSwitchStrategy(segmentBuffer, period, adapt
|
|
|
75
77
|
}
|
|
76
78
|
// From here, clean-up data from the previous Adaptation, if one
|
|
77
79
|
var shouldFlush = adaptation.type === "audio" &&
|
|
78
|
-
|
|
80
|
+
audioTrackSwitchingMode === "direct";
|
|
79
81
|
var rangesToExclude = [];
|
|
80
82
|
// First, we don't want to accidentally remove some segments from the previous
|
|
81
83
|
// Period (which overlap a little with this one)
|
|
@@ -92,6 +94,7 @@ export default function getAdaptationSwitchStrategy(segmentBuffer, period, adapt
|
|
|
92
94
|
}
|
|
93
95
|
// Next, exclude data around current position to avoid decoding issues
|
|
94
96
|
var bufferType = adaptation.type;
|
|
97
|
+
var ADAPTATION_SWITCH_BUFFER_PADDINGS = config.getCurrent().ADAPTATION_SWITCH_BUFFER_PADDINGS;
|
|
95
98
|
/** Ranges that won't be cleaned from the current buffer. */
|
|
96
99
|
var paddingBefore = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].before;
|
|
97
100
|
if (paddingBefore == null) {
|
|
@@ -14,5 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import PeriodStream, { IPeriodStreamArguments, IPeriodStreamOptions, IPeriodStreamPlaybackObservation } from "./period_stream";
|
|
17
|
+
export { IAudioTrackSwitchingMode } from "./get_adaptation_switch_strategy";
|
|
17
18
|
export default PeriodStream;
|
|
18
19
|
export { IPeriodStreamArguments, IPeriodStreamOptions, IPeriodStreamPlaybackObservation, };
|
|
@@ -23,6 +23,7 @@ import { SegmentFetcherCreator } from "../../fetchers";
|
|
|
23
23
|
import SegmentBuffersStore, { IBufferType, ITextTrackSegmentBufferOptions, SegmentBuffer } from "../../segment_buffers";
|
|
24
24
|
import { IAdaptationStreamOptions } from "../adaptation";
|
|
25
25
|
import { IPeriodStreamEvent } from "../types";
|
|
26
|
+
import { IAudioTrackSwitchingMode } from "./get_adaptation_switch_strategy";
|
|
26
27
|
/** Playback observation required by the `PeriodStream`. */
|
|
27
28
|
export interface IPeriodStreamPlaybackObservation {
|
|
28
29
|
/** The position we are in the video in seconds at the time of the observation. */
|
|
@@ -60,20 +61,12 @@ export interface IPeriodStreamArguments {
|
|
|
60
61
|
playbackObserver: IReadOnlyPlaybackObserver<IPeriodStreamPlaybackObservation>;
|
|
61
62
|
options: IPeriodStreamOptions;
|
|
62
63
|
wantedBufferAhead: IReadOnlySharedReference<number>;
|
|
64
|
+
maxVideoBufferSize: IReadOnlySharedReference<number>;
|
|
63
65
|
}
|
|
64
66
|
/** Options tweaking the behavior of the PeriodStream. */
|
|
65
67
|
export declare type IPeriodStreamOptions = IAdaptationStreamOptions & {
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
* Can be either:
|
|
69
|
-
* - "seamless": transitions are smooth but could be not immediate.
|
|
70
|
-
* - "direct": strategy will be "smart", if the mimetype and the codec,
|
|
71
|
-
* change, we will perform a hard reload of the media source, however, if it
|
|
72
|
-
* doesn't change, we will just perform a small flush by removing buffered range
|
|
73
|
-
* and performing, a small seek on the media element.
|
|
74
|
-
* Transitions are faster, but, we could see appear a reloading or seeking state.
|
|
75
|
-
*/
|
|
76
|
-
audioTrackSwitchingMode: "seamless" | "direct";
|
|
68
|
+
/** RxPlayer's behavior when switching the audio track. */
|
|
69
|
+
audioTrackSwitchingMode: IAudioTrackSwitchingMode;
|
|
77
70
|
/** Behavior when a new video and/or audio codec is encountered. */
|
|
78
71
|
onCodecSwitch: "continue" | "reload";
|
|
79
72
|
/** Options specific to the text SegmentBuffer. */
|
|
@@ -89,4 +82,4 @@ export declare type IPeriodStreamOptions = IAdaptationStreamOptions & {
|
|
|
89
82
|
* @param {Object} args
|
|
90
83
|
* @returns {Observable}
|
|
91
84
|
*/
|
|
92
|
-
export default function PeriodStream({ abrManager, bufferType, content, garbageCollectors, playbackObserver, segmentFetcherCreator, segmentBuffersStore, options, wantedBufferAhead, }: IPeriodStreamArguments): Observable<IPeriodStreamEvent>;
|
|
85
|
+
export default function PeriodStream({ abrManager, bufferType, content, garbageCollectors, playbackObserver, segmentFetcherCreator, segmentBuffersStore, options, wantedBufferAhead, maxVideoBufferSize, }: IPeriodStreamArguments): Observable<IPeriodStreamEvent>;
|
|
@@ -25,7 +25,6 @@ import EVENTS from "../events_generators";
|
|
|
25
25
|
import reloadAfterSwitch from "../reload_after_switch";
|
|
26
26
|
import createEmptyStream from "./create_empty_adaptation_stream";
|
|
27
27
|
import getAdaptationSwitchStrategy from "./get_adaptation_switch_strategy";
|
|
28
|
-
var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
|
|
29
28
|
/**
|
|
30
29
|
* Create single PeriodStream Observable:
|
|
31
30
|
* - Lazily create (or reuse) a SegmentBuffer for the given type.
|
|
@@ -37,7 +36,7 @@ var DELTA_POSITION_AFTER_RELOAD = config.DELTA_POSITION_AFTER_RELOAD;
|
|
|
37
36
|
* @returns {Observable}
|
|
38
37
|
*/
|
|
39
38
|
export default function PeriodStream(_a) {
|
|
40
|
-
var abrManager = _a.abrManager, bufferType = _a.bufferType, content = _a.content, garbageCollectors = _a.garbageCollectors, playbackObserver = _a.playbackObserver, segmentFetcherCreator = _a.segmentFetcherCreator, segmentBuffersStore = _a.segmentBuffersStore, options = _a.options, wantedBufferAhead = _a.wantedBufferAhead;
|
|
39
|
+
var abrManager = _a.abrManager, bufferType = _a.bufferType, content = _a.content, garbageCollectors = _a.garbageCollectors, playbackObserver = _a.playbackObserver, segmentFetcherCreator = _a.segmentFetcherCreator, segmentBuffersStore = _a.segmentBuffersStore, options = _a.options, wantedBufferAhead = _a.wantedBufferAhead, maxVideoBufferSize = _a.maxVideoBufferSize;
|
|
41
40
|
var period = content.period;
|
|
42
41
|
// Emits the chosen Adaptation for the current type.
|
|
43
42
|
// `null` when no Adaptation is chosen (e.g. no subtitles)
|
|
@@ -50,6 +49,7 @@ export default function PeriodStream(_a) {
|
|
|
50
49
|
* This value contains this relative position, in seconds.
|
|
51
50
|
* @see reloadAfterSwitch
|
|
52
51
|
*/
|
|
52
|
+
var DELTA_POSITION_AFTER_RELOAD = config.getCurrent().DELTA_POSITION_AFTER_RELOAD;
|
|
53
53
|
var relativePosAfterSwitch = switchNb === 0 ? 0 :
|
|
54
54
|
bufferType === "audio" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio :
|
|
55
55
|
bufferType === "video" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.video :
|
|
@@ -118,7 +118,7 @@ export default function PeriodStream(_a) {
|
|
|
118
118
|
function createAdaptationStream(adaptation, segmentBuffer) {
|
|
119
119
|
var manifest = content.manifest;
|
|
120
120
|
var adaptationPlaybackObserver = createAdaptationStreamPlaybackObserver(playbackObserver, segmentBuffer);
|
|
121
|
-
return AdaptationStream({ abrManager: abrManager, content: { manifest: manifest, period: period, adaptation: adaptation }, options: options, playbackObserver: adaptationPlaybackObserver, segmentBuffer: segmentBuffer, segmentFetcherCreator: segmentFetcherCreator, wantedBufferAhead: wantedBufferAhead }).pipe(catchError(function (error) {
|
|
121
|
+
return AdaptationStream({ abrManager: abrManager, content: { manifest: manifest, period: period, adaptation: adaptation }, options: options, playbackObserver: adaptationPlaybackObserver, segmentBuffer: segmentBuffer, segmentFetcherCreator: segmentFetcherCreator, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize }).pipe(catchError(function (error) {
|
|
122
122
|
// Stream linked to a non-native media buffer should not impact the
|
|
123
123
|
// stability of the player. ie: if a text buffer sends an error, we want
|
|
124
124
|
// to continue playing without any subtitles
|
|
@@ -17,8 +17,6 @@ import { concatAll, defer as observableDefer, from as observableFrom, } from "rx
|
|
|
17
17
|
import config from "../../../config";
|
|
18
18
|
import log from "../../../log";
|
|
19
19
|
import { getInnerAndOuterTimeRanges } from "../../../utils/ranges";
|
|
20
|
-
var GC_GAP_CALM = config.BUFFER_GC_GAPS.CALM;
|
|
21
|
-
var GC_GAP_BEEFY = config.BUFFER_GC_GAPS.BEEFY;
|
|
22
20
|
/**
|
|
23
21
|
* Run the garbage collector.
|
|
24
22
|
*
|
|
@@ -31,6 +29,8 @@ var GC_GAP_BEEFY = config.BUFFER_GC_GAPS.BEEFY;
|
|
|
31
29
|
*/
|
|
32
30
|
export default function forceGarbageCollection(currentPosition, bufferingQueue) {
|
|
33
31
|
return observableDefer(function () {
|
|
32
|
+
var GC_GAP_CALM = config.getCurrent().BUFFER_GC_GAPS.CALM;
|
|
33
|
+
var GC_GAP_BEEFY = config.getCurrent().BUFFER_GC_GAPS.BEEFY;
|
|
34
34
|
log.warn("Stream: Running garbage collector");
|
|
35
35
|
var buffered = bufferingQueue.getBufferedRanges();
|
|
36
36
|
var cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_CALM);
|
|
@@ -42,6 +42,11 @@ export interface IBufferStatus {
|
|
|
42
42
|
* on which segments should be loaded.
|
|
43
43
|
*/
|
|
44
44
|
shouldRefreshManifest: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* If 'true', the buffer memory is saturated before being able to download
|
|
47
|
+
* at least MIN_REQUIRED_BUFFER_AHEAD ( default : 10sec )
|
|
48
|
+
*/
|
|
49
|
+
isBufferFull: boolean;
|
|
45
50
|
}
|
|
46
51
|
/**
|
|
47
52
|
* Checks on the current buffered data for the given type and Period
|
|
@@ -62,4 +67,4 @@ export default function getBufferStatus(content: {
|
|
|
62
67
|
manifest: Manifest;
|
|
63
68
|
period: Period;
|
|
64
69
|
representation: Representation;
|
|
65
|
-
}, wantedStartPosition: number, playbackObserver: IReadOnlyPlaybackObserver<unknown>, fastSwitchThreshold: number | undefined, bufferGoal: number, segmentBuffer: SegmentBuffer): IBufferStatus;
|
|
70
|
+
}, wantedStartPosition: number, playbackObserver: IReadOnlyPlaybackObserver<unknown>, fastSwitchThreshold: number | undefined, bufferGoal: number, maxBufferSize: number, segmentBuffer: SegmentBuffer): IBufferStatus;
|
|
@@ -18,7 +18,6 @@ import { SegmentBufferOperation, } from "../../segment_buffers";
|
|
|
18
18
|
import checkForDiscontinuity from "./check_for_discontinuity";
|
|
19
19
|
import getNeededSegments from "./get_needed_segments";
|
|
20
20
|
import getSegmentPriority from "./get_segment_priority";
|
|
21
|
-
var MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
|
|
22
21
|
/**
|
|
23
22
|
* Checks on the current buffered data for the given type and Period
|
|
24
23
|
* and returns what should be done to fill the buffer according to the buffer
|
|
@@ -33,7 +32,7 @@ var MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
|
|
|
33
32
|
* @param {Object} segmentBuffer
|
|
34
33
|
* @returns {Object}
|
|
35
34
|
*/
|
|
36
|
-
export default function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, segmentBuffer) {
|
|
35
|
+
export default function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer) {
|
|
37
36
|
var _a;
|
|
38
37
|
var period = content.period, representation = content.representation;
|
|
39
38
|
segmentBuffer.synchronizeInventory();
|
|
@@ -56,8 +55,11 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
|
|
|
56
55
|
/** Callback allowing to retrieve a segment's history in the buffer. */
|
|
57
56
|
var getBufferedHistory = segmentBuffer.getSegmentHistory.bind(segmentBuffer);
|
|
58
57
|
/** List of segments we will need to download. */
|
|
59
|
-
var
|
|
60
|
-
|
|
58
|
+
var _b = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed, maxBufferSize: maxBufferSize }), neededSegments = _b.neededSegments, isBufferFull = _b.isBufferFull;
|
|
59
|
+
var prioritizedNeededSegments = neededSegments.map(function (segment) { return ({
|
|
60
|
+
priority: getSegmentPriority(segment.time, wantedStartPosition),
|
|
61
|
+
segment: segment,
|
|
62
|
+
}); });
|
|
61
63
|
/**
|
|
62
64
|
* `true` if the current `RepresentationStream` has loaded all the
|
|
63
65
|
* needed segments for this Representation until the end of the Period.
|
|
@@ -66,7 +68,7 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
|
|
|
66
68
|
var lastPosition = representation.index.getLastPosition();
|
|
67
69
|
if (!representation.index.isInitialized() ||
|
|
68
70
|
period.end === undefined ||
|
|
69
|
-
|
|
71
|
+
prioritizedNeededSegments.length > 0) {
|
|
70
72
|
hasFinishedLoading = false;
|
|
71
73
|
}
|
|
72
74
|
else {
|
|
@@ -110,14 +112,14 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
|
|
|
110
112
|
if (segmentsBeingPushed.length > 0) {
|
|
111
113
|
nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { return info.segment.time; }));
|
|
112
114
|
}
|
|
113
|
-
if (
|
|
115
|
+
if (prioritizedNeededSegments.length > 0) {
|
|
114
116
|
nextSegmentStart = nextSegmentStart !== null ?
|
|
115
|
-
Math.min(nextSegmentStart,
|
|
116
|
-
|
|
117
|
+
Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) :
|
|
118
|
+
prioritizedNeededSegments[0].segment.time;
|
|
117
119
|
}
|
|
118
120
|
imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments);
|
|
119
121
|
}
|
|
120
|
-
return { imminentDiscontinuity: imminentDiscontinuity, hasFinishedLoading: hasFinishedLoading, neededSegments:
|
|
122
|
+
return { imminentDiscontinuity: imminentDiscontinuity, hasFinishedLoading: hasFinishedLoading, neededSegments: prioritizedNeededSegments, isBufferFull: isBufferFull, shouldRefreshManifest: shouldRefreshManifest };
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
125
|
* From the given SegmentInventory, filters the "playable" (in a supported codec
|
|
@@ -128,6 +130,7 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
|
|
|
128
130
|
* @returns {Array.<Object>}
|
|
129
131
|
*/
|
|
130
132
|
function getPlayableBufferedSegments(neededRange, segmentInventory) {
|
|
133
|
+
var MINIMUM_SEGMENT_SIZE = config.getCurrent().MINIMUM_SEGMENT_SIZE;
|
|
131
134
|
var segmentRoundingError = Math.max(1 / 60, MINIMUM_SEGMENT_SIZE);
|
|
132
135
|
var minEnd = neededRange.start + segmentRoundingError;
|
|
133
136
|
var maxStart = neededRange.end - segmentRoundingError;
|
|
@@ -14,17 +14,18 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import Manifest, { Adaptation, ISegment, Period, Representation } from "../../../manifest";
|
|
17
|
-
import { IBufferedChunk } from "../../segment_buffers";
|
|
17
|
+
import { IBufferedChunk, IEndOfSegmentInfos } from "../../segment_buffers";
|
|
18
18
|
import { IBufferedHistoryEntry, IChunkContext } from "../../segment_buffers/inventory";
|
|
19
|
+
interface IContentContext {
|
|
20
|
+
adaptation: Adaptation;
|
|
21
|
+
manifest: Manifest;
|
|
22
|
+
period: Period;
|
|
23
|
+
representation: Representation;
|
|
24
|
+
}
|
|
19
25
|
/** Arguments for `getNeededSegments`. */
|
|
20
26
|
export interface IGetNeededSegmentsArguments {
|
|
21
27
|
/** The content we want to load segments for */
|
|
22
|
-
content:
|
|
23
|
-
adaptation: Adaptation;
|
|
24
|
-
manifest: Manifest;
|
|
25
|
-
period: Period;
|
|
26
|
-
representation: Representation;
|
|
27
|
-
};
|
|
28
|
+
content: IContentContext;
|
|
28
29
|
/**
|
|
29
30
|
* The current playing position.
|
|
30
31
|
* Important to avoid asking for segments on the same exact position, which
|
|
@@ -46,12 +47,7 @@ export interface IGetNeededSegmentsArguments {
|
|
|
46
47
|
end: number;
|
|
47
48
|
};
|
|
48
49
|
/** The list of segments that are already in the process of being pushed. */
|
|
49
|
-
segmentsBeingPushed:
|
|
50
|
-
adaptation: Adaptation;
|
|
51
|
-
period: Period;
|
|
52
|
-
representation: Representation;
|
|
53
|
-
segment: ISegment;
|
|
54
|
-
}>;
|
|
50
|
+
segmentsBeingPushed: IEndOfSegmentInfos[];
|
|
55
51
|
/**
|
|
56
52
|
* Information on the segments already in the buffer, in chronological order.
|
|
57
53
|
*
|
|
@@ -62,8 +58,16 @@ export interface IGetNeededSegmentsArguments {
|
|
|
62
58
|
* re-requested.
|
|
63
59
|
*/
|
|
64
60
|
bufferedSegments: IBufferedChunk[];
|
|
61
|
+
/**
|
|
62
|
+
* maxBufferSize is the maximum memory in kilobytes that the buffer should take
|
|
63
|
+
*/
|
|
64
|
+
maxBufferSize: number;
|
|
65
65
|
getBufferedHistory: (context: IChunkContext) => IBufferedHistoryEntry[];
|
|
66
66
|
}
|
|
67
|
+
interface INeededSegments {
|
|
68
|
+
neededSegments: ISegment[];
|
|
69
|
+
isBufferFull: boolean;
|
|
70
|
+
}
|
|
67
71
|
/**
|
|
68
72
|
* Return the list of segments that can currently be downloaded to fill holes
|
|
69
73
|
* in the buffer in the given range, including already-pushed segments currently
|
|
@@ -74,4 +78,5 @@ export interface IGetNeededSegmentsArguments {
|
|
|
74
78
|
* @param {Object} args
|
|
75
79
|
* @returns {Array.<Object>}
|
|
76
80
|
*/
|
|
77
|
-
export default function getNeededSegments({ bufferedSegments, content, currentPlaybackTime, fastSwitchThreshold, getBufferedHistory, neededRange, segmentsBeingPushed, }: IGetNeededSegmentsArguments):
|
|
81
|
+
export default function getNeededSegments({ bufferedSegments, content, currentPlaybackTime, fastSwitchThreshold, getBufferedHistory, neededRange, segmentsBeingPushed, maxBufferSize, }: IGetNeededSegmentsArguments): INeededSegments;
|
|
82
|
+
export {};
|
|
@@ -18,12 +18,6 @@ import config from "../../../config";
|
|
|
18
18
|
import log from "../../../log";
|
|
19
19
|
import { areSameContent, } from "../../../manifest";
|
|
20
20
|
import objectAssign from "../../../utils/object_assign";
|
|
21
|
-
var CONTENT_REPLACEMENT_PADDING = config.CONTENT_REPLACEMENT_PADDING, BITRATE_REBUFFERING_RATIO = config.BITRATE_REBUFFERING_RATIO, MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT, MINIMUM_SEGMENT_SIZE = config.MINIMUM_SEGMENT_SIZE;
|
|
22
|
-
/**
|
|
23
|
-
* Epsilon compensating for rounding errors when comparing the start and end
|
|
24
|
-
* time of multiple segments.
|
|
25
|
-
*/
|
|
26
|
-
var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
|
|
27
21
|
/**
|
|
28
22
|
* Return the list of segments that can currently be downloaded to fill holes
|
|
29
23
|
* in the buffer in the given range, including already-pushed segments currently
|
|
@@ -35,8 +29,11 @@ var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
|
|
|
35
29
|
* @returns {Array.<Object>}
|
|
36
30
|
*/
|
|
37
31
|
export default function getNeededSegments(_a) {
|
|
38
|
-
var bufferedSegments = _a.bufferedSegments, content = _a.content, currentPlaybackTime = _a.currentPlaybackTime, fastSwitchThreshold = _a.fastSwitchThreshold, getBufferedHistory = _a.getBufferedHistory, neededRange = _a.neededRange, segmentsBeingPushed = _a.segmentsBeingPushed;
|
|
32
|
+
var bufferedSegments = _a.bufferedSegments, content = _a.content, currentPlaybackTime = _a.currentPlaybackTime, fastSwitchThreshold = _a.fastSwitchThreshold, getBufferedHistory = _a.getBufferedHistory, neededRange = _a.neededRange, segmentsBeingPushed = _a.segmentsBeingPushed, maxBufferSize = _a.maxBufferSize;
|
|
39
33
|
var representation = content.representation;
|
|
34
|
+
var availableBufferSize = getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxBufferSize);
|
|
35
|
+
// Current buffer length in seconds
|
|
36
|
+
var bufferLength = getBufferLength(bufferedSegments, segmentsBeingPushed);
|
|
40
37
|
var availableSegmentsForRange = representation.index
|
|
41
38
|
.getSegments(neededRange.start, neededRange.end - neededRange.start);
|
|
42
39
|
// Remove from `bufferedSegments` any segments we would prefer to replace:
|
|
@@ -57,7 +54,7 @@ export default function getNeededSegments(_a) {
|
|
|
57
54
|
}
|
|
58
55
|
log.debug("Stream: skipping segment gc-ed at the start", currentSeg);
|
|
59
56
|
}
|
|
60
|
-
if (doesEndSeemGarbageCollected(currentSeg, nextSeg, neededRange.
|
|
57
|
+
if (doesEndSeemGarbageCollected(currentSeg, nextSeg, neededRange.end)) {
|
|
61
58
|
lazySegmentHistory = lazySegmentHistory !== null && lazySegmentHistory !== void 0 ? lazySegmentHistory : getBufferedHistory(currentSeg.infos);
|
|
62
59
|
if (shouldReloadSegmentGCedAtTheEnd(lazySegmentHistory, currentSeg.bufferedEnd)) {
|
|
63
60
|
return false;
|
|
@@ -66,7 +63,15 @@ export default function getNeededSegments(_a) {
|
|
|
66
63
|
}
|
|
67
64
|
return true;
|
|
68
65
|
});
|
|
69
|
-
var
|
|
66
|
+
var _b = config.getCurrent(), MINIMUM_SEGMENT_SIZE = _b.MINIMUM_SEGMENT_SIZE, MIN_BUFFER_LENGTH = _b.MIN_BUFFER_LENGTH, MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP = _b.MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP;
|
|
67
|
+
var isMemorySaturated = false;
|
|
68
|
+
/**
|
|
69
|
+
* Epsilon compensating for rounding errors when comparing the start and end
|
|
70
|
+
* time of multiple segments.
|
|
71
|
+
*/
|
|
72
|
+
var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
|
|
73
|
+
var isBufferFull = false;
|
|
74
|
+
var neededSegments = availableSegmentsForRange.filter(function (segment) {
|
|
70
75
|
var contentObject = objectAssign({ segment: segment }, content);
|
|
71
76
|
// First, check that the segment is not already being pushed
|
|
72
77
|
if (segmentsBeingPushed.length > 0) {
|
|
@@ -80,6 +85,19 @@ export default function getNeededSegments(_a) {
|
|
|
80
85
|
if (segment.isInit) {
|
|
81
86
|
return true; // never skip initialization segments
|
|
82
87
|
}
|
|
88
|
+
if (isMemorySaturated) {
|
|
89
|
+
// If we are so saturated in memory
|
|
90
|
+
// That we cannot download atleast till
|
|
91
|
+
// NeededRange.Start ( current position ) + a CONST
|
|
92
|
+
// Then the buffer is full
|
|
93
|
+
if (time < neededRange.start + MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP) {
|
|
94
|
+
isBufferFull = true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (isMemorySaturated &&
|
|
98
|
+
bufferLength > MIN_BUFFER_LENGTH) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
83
101
|
if (segment.complete && duration < MINIMUM_SEGMENT_SIZE) {
|
|
84
102
|
return false; // too small, don't download
|
|
85
103
|
}
|
|
@@ -130,9 +148,57 @@ export default function getNeededSegments(_a) {
|
|
|
130
148
|
getLastContiguousSegment(segmentsToKeep, i).end < end - ROUNDING_ERROR;
|
|
131
149
|
}
|
|
132
150
|
}
|
|
151
|
+
var estimatedSegmentSize = (duration * content.representation.bitrate) / 8000;
|
|
152
|
+
if (availableBufferSize - estimatedSegmentSize < 0 &&
|
|
153
|
+
bufferLength > MIN_BUFFER_LENGTH) {
|
|
154
|
+
isMemorySaturated = true;
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
availableBufferSize -= estimatedSegmentSize;
|
|
158
|
+
bufferLength += duration;
|
|
133
159
|
return true;
|
|
134
160
|
});
|
|
135
|
-
return
|
|
161
|
+
return { neededSegments: neededSegments, isBufferFull: isBufferFull };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Compute the estimated available buffer size in memory in kilobytes
|
|
165
|
+
* @param bufferedSegments
|
|
166
|
+
* @param segmentsBeingPushed
|
|
167
|
+
* @param maxVideoBufferSize
|
|
168
|
+
* @returns availableBufferSize in kilobytes
|
|
169
|
+
*/
|
|
170
|
+
function getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxVideoBufferSize) {
|
|
171
|
+
var availableBufferSize = maxVideoBufferSize;
|
|
172
|
+
availableBufferSize -= segmentsBeingPushed.reduce(function (size, segment) {
|
|
173
|
+
var bitrate = segment.representation.bitrate;
|
|
174
|
+
// Not taking into account the fact that the segment
|
|
175
|
+
// can still be generated and the duration not fully exact
|
|
176
|
+
var duration = segment.segment.duration;
|
|
177
|
+
return size + ((bitrate / 8000) * duration);
|
|
178
|
+
}, 0);
|
|
179
|
+
return bufferedSegments.reduce(function (size, chunk) {
|
|
180
|
+
if (chunk.chunkSize !== undefined) {
|
|
181
|
+
return size - (chunk.chunkSize / 8000);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
return size;
|
|
185
|
+
}
|
|
186
|
+
}, availableBufferSize);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Compute the length of the buffer in seconds
|
|
190
|
+
* @param bufferedSegments
|
|
191
|
+
* @param segmentsBeingPushed
|
|
192
|
+
* @returns bufferLength in seconds
|
|
193
|
+
*/
|
|
194
|
+
function getBufferLength(bufferedSegments, segmentsBeingPushed) {
|
|
195
|
+
var bufferLength = bufferedSegments.reduce(function (length, segment) {
|
|
196
|
+
return length + (segment.end - segment.start);
|
|
197
|
+
}, 0);
|
|
198
|
+
var bufferBeingPushed = segmentsBeingPushed.reduce(function (length, segment) {
|
|
199
|
+
return length + segment.segment.duration;
|
|
200
|
+
}, 0);
|
|
201
|
+
return bufferLength + bufferBeingPushed;
|
|
136
202
|
}
|
|
137
203
|
/**
|
|
138
204
|
* From the given array of buffered chunks (`bufferedSegments`) returns the last
|
|
@@ -143,6 +209,12 @@ export default function getNeededSegments(_a) {
|
|
|
143
209
|
*/
|
|
144
210
|
function getLastContiguousSegment(bufferedSegments, startIndex) {
|
|
145
211
|
var j = startIndex + 1;
|
|
212
|
+
var MINIMUM_SEGMENT_SIZE = config.getCurrent().MINIMUM_SEGMENT_SIZE;
|
|
213
|
+
/**
|
|
214
|
+
* Epsilon compensating for rounding errors when comparing the start and end
|
|
215
|
+
* time of multiple segments.
|
|
216
|
+
*/
|
|
217
|
+
var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
|
|
146
218
|
// go through all contiguous segments and take the last one
|
|
147
219
|
while (j < bufferedSegments.length - 1 &&
|
|
148
220
|
(bufferedSegments[j - 1].end + ROUNDING_ERROR) >
|
|
@@ -162,6 +234,7 @@ function getLastContiguousSegment(bufferedSegments, startIndex) {
|
|
|
162
234
|
* @returns {boolean}
|
|
163
235
|
*/
|
|
164
236
|
function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime, fastSwitchThreshold) {
|
|
237
|
+
var CONTENT_REPLACEMENT_PADDING = config.getCurrent().CONTENT_REPLACEMENT_PADDING;
|
|
165
238
|
if (oldContent.period.id !== currentContent.period.id) {
|
|
166
239
|
return false; // keep segments from another Period by default.
|
|
167
240
|
}
|
|
@@ -186,6 +259,7 @@ function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime
|
|
|
186
259
|
*/
|
|
187
260
|
function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastSwitchThreshold) {
|
|
188
261
|
var oldContentBitrate = oldSegmentRepresentation.bitrate;
|
|
262
|
+
var BITRATE_REBUFFERING_RATIO = config.getCurrent().BITRATE_REBUFFERING_RATIO;
|
|
189
263
|
if (fastSwitchThreshold === undefined) {
|
|
190
264
|
// only re-load comparatively-poor bitrates for the same Adaptation.
|
|
191
265
|
var bitrateCeil = oldContentBitrate * BITRATE_REBUFFERING_RATIO;
|
|
@@ -207,6 +281,7 @@ function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastS
|
|
|
207
281
|
* that time, we will return `false`.
|
|
208
282
|
*/
|
|
209
283
|
function doesStartSeemGarbageCollected(currentSeg, prevSeg, maximumStartTime) {
|
|
284
|
+
var MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.getCurrent().MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT;
|
|
210
285
|
if (currentSeg.bufferedStart === undefined) {
|
|
211
286
|
log.warn("Stream: Start of a segment unknown. " +
|
|
212
287
|
"Assuming it is garbage collected by default.", currentSeg);
|
|
@@ -237,6 +312,7 @@ function doesStartSeemGarbageCollected(currentSeg, prevSeg, maximumStartTime) {
|
|
|
237
312
|
* that time, we will return `false`.
|
|
238
313
|
*/
|
|
239
314
|
function doesEndSeemGarbageCollected(currentSeg, nextSeg, minimumEndTime) {
|
|
315
|
+
var MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config.getCurrent().MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT;
|
|
240
316
|
if (currentSeg.bufferedEnd === undefined) {
|
|
241
317
|
log.warn("Stream: End of a segment unknown. " +
|
|
242
318
|
"Assuming it is garbage collected by default.", currentSeg);
|