rx-player 4.0.0-dev.2023111400 → 4.0.0-dev.2023121900
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/CHANGELOG.md +20 -60
- package/FILES.md +1 -1
- package/README.md +2 -33
- package/VERSION +1 -1
- package/dist/_esm5.processed/core/api/debug/buffer_graph.js +2 -6
- package/dist/_esm5.processed/core/api/debug/modules/general_info.js +20 -10
- package/dist/_esm5.processed/core/api/option_utils.d.ts +0 -2
- package/dist/_esm5.processed/core/api/option_utils.js +0 -6
- package/dist/_esm5.processed/core/api/public_api.d.ts +1 -2
- package/dist/_esm5.processed/core/api/public_api.js +9 -17
- package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +3 -14
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.d.ts +2 -36
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +2 -82
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
- package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
- package/dist/_esm5.processed/core/segment_buffers/inventory/index.d.ts +2 -2
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
- package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +19 -10
- package/dist/_esm5.processed/core/stream/representation/utils/get_buffer_status.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/utils/get_needed_segments.js +1 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +1 -8
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +1 -9
- package/dist/_esm5.processed/public_types.d.ts +2 -0
- package/dist/commonjs/compat/is_codec_supported.js +22 -1
- package/dist/commonjs/config.d.ts +2 -1
- package/dist/commonjs/core/adaptive/adaptive_representation_selector.d.ts +2 -19
- package/dist/commonjs/core/adaptive/adaptive_representation_selector.js +2 -2
- package/dist/commonjs/core/adaptive/network_analyzer.js +3 -3
- package/dist/commonjs/core/api/debug/buffer_graph.js +2 -6
- package/dist/commonjs/core/api/debug/modules/general_info.js +17 -10
- package/dist/commonjs/core/api/index.d.ts +1 -1
- package/dist/commonjs/core/api/option_utils.d.ts +2 -0
- package/dist/commonjs/core/api/option_utils.js +2 -3
- package/dist/commonjs/core/api/playback_observer.d.ts +128 -8
- package/dist/commonjs/core/api/playback_observer.js +217 -64
- package/dist/commonjs/core/api/public_api.d.ts +9 -0
- package/dist/commonjs/core/api/public_api.js +41 -16
- package/dist/commonjs/core/api/utils.js +1 -1
- package/dist/commonjs/core/decrypt/get_media_keys.js +2 -6
- package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.d.ts +6 -0
- package/dist/commonjs/core/fetchers/manifest/manifest_fetcher.js +11 -3
- package/dist/commonjs/core/fetchers/segment/segment_fetcher.d.ts +8 -1
- package/dist/commonjs/core/fetchers/segment/segment_fetcher.js +8 -4
- package/dist/commonjs/core/fetchers/segment/segment_fetcher_creator.d.ts +1 -0
- package/dist/commonjs/core/fetchers/utils/schedule_request.js +1 -1
- package/dist/commonjs/core/init/directfile_content_initializer.js +29 -8
- package/dist/commonjs/core/init/media_source_content_initializer.d.ts +6 -0
- package/dist/commonjs/core/init/media_source_content_initializer.js +32 -20
- package/dist/commonjs/core/init/utils/content_time_boundaries_observer.d.ts +13 -12
- package/dist/commonjs/core/init/utils/content_time_boundaries_observer.js +17 -19
- package/dist/commonjs/core/init/utils/create_stream_playback_observer.d.ts +1 -5
- package/dist/commonjs/core/init/utils/create_stream_playback_observer.js +16 -14
- package/dist/commonjs/core/init/utils/get_initial_time.d.ts +17 -3
- package/dist/commonjs/core/init/utils/get_initial_time.js +9 -7
- package/dist/commonjs/core/init/utils/initial_seek_and_play.d.ts +9 -11
- package/dist/commonjs/core/init/utils/initial_seek_and_play.js +121 -91
- package/dist/commonjs/core/init/utils/rebuffering_controller.js +27 -70
- package/dist/commonjs/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
- package/dist/commonjs/core/segment_buffers/garbage_collector.js +1 -2
- package/dist/commonjs/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
- package/dist/commonjs/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
- package/dist/commonjs/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
- package/dist/commonjs/core/segment_buffers/index.d.ts +2 -2
- package/dist/commonjs/core/segment_buffers/inventory/index.d.ts +2 -2
- package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
- package/dist/commonjs/core/segment_buffers/inventory/segment_inventory.js +19 -10
- package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
- package/dist/commonjs/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
- package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +14 -18
- package/dist/commonjs/core/stream/period/period_stream.js +5 -8
- package/dist/commonjs/core/stream/period/types.d.ts +2 -3
- package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
- package/dist/commonjs/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
- package/dist/commonjs/core/stream/representation/representation_stream.js +3 -4
- package/dist/commonjs/core/stream/representation/types.d.ts +2 -2
- package/dist/commonjs/core/stream/representation/utils/append_segment_to_buffer.js +11 -12
- package/dist/commonjs/core/stream/representation/utils/get_buffer_status.js +4 -4
- package/dist/commonjs/core/stream/representation/utils/get_needed_segments.js +1 -1
- package/dist/commonjs/default_config.d.ts +12 -16
- package/dist/commonjs/default_config.js +21 -16
- package/dist/commonjs/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +3 -1
- package/dist/commonjs/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +2 -0
- package/dist/commonjs/manifest/adaptation.js +2 -1
- package/dist/commonjs/manifest/representation_index/static.d.ts +1 -1
- package/dist/commonjs/manifest/representation_index/static.js +2 -2
- package/dist/commonjs/manifest/representation_index/types.d.ts +4 -4
- package/dist/commonjs/parsers/manifest/dash/common/indexes/base.d.ts +6 -1
- package/dist/commonjs/parsers/manifest/dash/common/indexes/base.js +4 -3
- package/dist/commonjs/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +5 -2
- package/dist/commonjs/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +15 -4
- package/dist/commonjs/parsers/manifest/dash/common/indexes/index.d.ts +5 -5
- package/dist/commonjs/parsers/manifest/dash/common/indexes/list.d.ts +1 -1
- package/dist/commonjs/parsers/manifest/dash/common/indexes/list.js +2 -2
- package/dist/commonjs/parsers/manifest/dash/common/indexes/template.d.ts +12 -5
- package/dist/commonjs/parsers/manifest/dash/common/indexes/template.js +42 -29
- package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/index.d.ts +2 -1
- package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +99 -6
- package/dist/commonjs/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +250 -51
- package/dist/commonjs/parsers/manifest/dash/common/manifest_bounds_calculator.d.ts +40 -17
- package/dist/commonjs/parsers/manifest/dash/common/manifest_bounds_calculator.js +38 -18
- package/dist/commonjs/parsers/manifest/dash/common/parse_adaptation_sets.js +13 -10
- package/dist/commonjs/parsers/manifest/dash/common/parse_mpd.js +27 -14
- package/dist/commonjs/parsers/manifest/dash/common/parse_periods.d.ts +1 -1
- package/dist/commonjs/parsers/manifest/dash/common/parse_periods.js +17 -18
- package/dist/commonjs/parsers/manifest/dash/common/parse_representation_index.d.ts +19 -6
- package/dist/commonjs/parsers/manifest/dash/common/parse_representation_index.js +21 -8
- package/dist/commonjs/parsers/manifest/dash/common/parse_representations.js +7 -3
- package/dist/commonjs/parsers/manifest/local/representation_index.d.ts +1 -1
- package/dist/commonjs/parsers/manifest/local/representation_index.js +3 -3
- package/dist/commonjs/parsers/manifest/metaplaylist/representation_index.d.ts +1 -1
- package/dist/commonjs/parsers/manifest/metaplaylist/representation_index.js +2 -2
- package/dist/commonjs/parsers/manifest/smooth/representation_index.d.ts +5 -5
- package/dist/commonjs/parsers/manifest/smooth/representation_index.js +25 -9
- package/dist/commonjs/parsers/manifest/utils/index_helpers.js +1 -1
- package/dist/commonjs/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
- package/dist/commonjs/public_types.d.ts +107 -36
- package/dist/commonjs/transports/dash/init_segment_loader.js +10 -5
- package/dist/commonjs/transports/dash/manifest_parser.js +5 -2
- package/dist/commonjs/transports/dash/segment_loader.js +2 -1
- package/dist/commonjs/transports/dash/text_loader.js +2 -0
- package/dist/commonjs/transports/metaplaylist/manifest_loader.js +2 -1
- package/dist/commonjs/transports/metaplaylist/pipelines.js +4 -1
- package/dist/commonjs/transports/smooth/pipelines.js +4 -2
- package/dist/commonjs/transports/smooth/segment_loader.js +2 -1
- package/dist/commonjs/transports/types.d.ts +12 -0
- package/dist/commonjs/transports/utils/generate_manifest_loader.js +6 -3
- package/dist/commonjs/utils/request/fetch.d.ts +6 -0
- package/dist/commonjs/utils/request/fetch.js +29 -8
- package/dist/commonjs/utils/request/xhr.d.ts +11 -5
- package/dist/commonjs/utils/request/xhr.js +29 -8
- package/dist/es2017/compat/is_codec_supported.js +22 -1
- package/dist/es2017/config.d.ts +2 -1
- package/dist/es2017/core/adaptive/adaptive_representation_selector.d.ts +2 -19
- package/dist/es2017/core/adaptive/adaptive_representation_selector.js +2 -2
- package/dist/es2017/core/adaptive/network_analyzer.js +3 -3
- package/dist/es2017/core/api/debug/buffer_graph.js +2 -6
- package/dist/es2017/core/api/debug/modules/general_info.js +17 -10
- package/dist/es2017/core/api/index.d.ts +1 -1
- package/dist/es2017/core/api/option_utils.d.ts +2 -0
- package/dist/es2017/core/api/option_utils.js +2 -3
- package/dist/es2017/core/api/playback_observer.d.ts +128 -8
- package/dist/es2017/core/api/playback_observer.js +217 -66
- package/dist/es2017/core/api/public_api.d.ts +9 -0
- package/dist/es2017/core/api/public_api.js +40 -15
- package/dist/es2017/core/api/utils.js +1 -1
- package/dist/es2017/core/decrypt/get_media_keys.js +2 -6
- package/dist/es2017/core/fetchers/manifest/manifest_fetcher.d.ts +6 -0
- package/dist/es2017/core/fetchers/manifest/manifest_fetcher.js +11 -3
- package/dist/es2017/core/fetchers/segment/segment_fetcher.d.ts +8 -1
- package/dist/es2017/core/fetchers/segment/segment_fetcher.js +8 -4
- package/dist/es2017/core/fetchers/segment/segment_fetcher_creator.d.ts +1 -0
- package/dist/es2017/core/fetchers/utils/schedule_request.js +1 -1
- package/dist/es2017/core/init/directfile_content_initializer.js +31 -8
- package/dist/es2017/core/init/media_source_content_initializer.d.ts +6 -0
- package/dist/es2017/core/init/media_source_content_initializer.js +34 -22
- package/dist/es2017/core/init/utils/content_time_boundaries_observer.d.ts +13 -12
- package/dist/es2017/core/init/utils/content_time_boundaries_observer.js +17 -17
- package/dist/es2017/core/init/utils/create_stream_playback_observer.d.ts +1 -5
- package/dist/es2017/core/init/utils/create_stream_playback_observer.js +16 -14
- package/dist/es2017/core/init/utils/get_initial_time.d.ts +17 -3
- package/dist/es2017/core/init/utils/get_initial_time.js +9 -7
- package/dist/es2017/core/init/utils/initial_seek_and_play.d.ts +9 -11
- package/dist/es2017/core/init/utils/initial_seek_and_play.js +120 -91
- package/dist/es2017/core/init/utils/rebuffering_controller.js +27 -70
- package/dist/es2017/core/init/utils/stream_events_emitter/stream_events_emitter.js +4 -2
- package/dist/es2017/core/segment_buffers/garbage_collector.js +1 -2
- package/dist/es2017/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
- package/dist/es2017/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
- package/dist/es2017/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
- package/dist/es2017/core/segment_buffers/index.d.ts +2 -2
- package/dist/es2017/core/segment_buffers/inventory/index.d.ts +2 -2
- package/dist/es2017/core/segment_buffers/inventory/segment_inventory.d.ts +25 -8
- package/dist/es2017/core/segment_buffers/inventory/segment_inventory.js +19 -10
- package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.d.ts +2 -2
- package/dist/es2017/core/stream/adaptation/get_representations_switch_strategy.js +16 -9
- package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +16 -18
- package/dist/es2017/core/stream/period/period_stream.js +4 -7
- package/dist/es2017/core/stream/period/types.d.ts +2 -3
- package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.d.ts +4 -5
- package/dist/es2017/core/stream/period/utils/get_adaptation_switch_strategy.js +17 -13
- package/dist/es2017/core/stream/representation/representation_stream.js +3 -4
- package/dist/es2017/core/stream/representation/types.d.ts +2 -2
- package/dist/es2017/core/stream/representation/utils/append_segment_to_buffer.js +1 -2
- package/dist/es2017/core/stream/representation/utils/get_buffer_status.js +4 -4
- package/dist/es2017/core/stream/representation/utils/get_needed_segments.js +1 -1
- package/dist/es2017/default_config.d.ts +12 -16
- package/dist/es2017/default_config.js +21 -16
- package/dist/es2017/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +3 -1
- package/dist/es2017/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +2 -0
- package/dist/es2017/manifest/adaptation.js +2 -1
- package/dist/es2017/manifest/representation_index/static.d.ts +1 -1
- package/dist/es2017/manifest/representation_index/static.js +2 -2
- package/dist/es2017/manifest/representation_index/types.d.ts +4 -4
- package/dist/es2017/parsers/manifest/dash/common/indexes/base.d.ts +6 -1
- package/dist/es2017/parsers/manifest/dash/common/indexes/base.js +4 -3
- package/dist/es2017/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +5 -2
- package/dist/es2017/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +15 -4
- package/dist/es2017/parsers/manifest/dash/common/indexes/index.d.ts +5 -5
- package/dist/es2017/parsers/manifest/dash/common/indexes/list.d.ts +1 -1
- package/dist/es2017/parsers/manifest/dash/common/indexes/list.js +2 -2
- package/dist/es2017/parsers/manifest/dash/common/indexes/template.d.ts +12 -5
- package/dist/es2017/parsers/manifest/dash/common/indexes/template.js +40 -27
- package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/index.d.ts +2 -1
- package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +99 -6
- package/dist/es2017/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +246 -51
- package/dist/es2017/parsers/manifest/dash/common/manifest_bounds_calculator.d.ts +40 -17
- package/dist/es2017/parsers/manifest/dash/common/manifest_bounds_calculator.js +38 -18
- package/dist/es2017/parsers/manifest/dash/common/parse_adaptation_sets.js +11 -8
- package/dist/es2017/parsers/manifest/dash/common/parse_mpd.js +27 -13
- package/dist/es2017/parsers/manifest/dash/common/parse_periods.d.ts +1 -1
- package/dist/es2017/parsers/manifest/dash/common/parse_periods.js +13 -16
- package/dist/es2017/parsers/manifest/dash/common/parse_representation_index.d.ts +19 -6
- package/dist/es2017/parsers/manifest/dash/common/parse_representation_index.js +10 -8
- package/dist/es2017/parsers/manifest/dash/common/parse_representations.js +7 -3
- package/dist/es2017/parsers/manifest/local/representation_index.d.ts +1 -1
- package/dist/es2017/parsers/manifest/local/representation_index.js +3 -3
- package/dist/es2017/parsers/manifest/metaplaylist/representation_index.d.ts +1 -1
- package/dist/es2017/parsers/manifest/metaplaylist/representation_index.js +2 -2
- package/dist/es2017/parsers/manifest/smooth/representation_index.d.ts +5 -5
- package/dist/es2017/parsers/manifest/smooth/representation_index.js +25 -9
- package/dist/es2017/parsers/manifest/utils/index_helpers.js +1 -1
- package/dist/es2017/parsers/texttracks/ttml/html/apply_line_height.js +2 -1
- package/dist/es2017/public_types.d.ts +107 -36
- package/dist/es2017/transports/dash/init_segment_loader.js +5 -0
- package/dist/es2017/transports/dash/manifest_parser.js +3 -0
- package/dist/es2017/transports/dash/segment_loader.js +1 -0
- package/dist/es2017/transports/dash/text_loader.js +2 -0
- package/dist/es2017/transports/metaplaylist/manifest_loader.js +1 -0
- package/dist/es2017/transports/metaplaylist/pipelines.js +4 -1
- package/dist/es2017/transports/smooth/pipelines.js +2 -0
- package/dist/es2017/transports/smooth/segment_loader.js +1 -0
- package/dist/es2017/transports/types.d.ts +12 -0
- package/dist/es2017/transports/utils/generate_manifest_loader.js +3 -0
- package/dist/es2017/utils/request/fetch.d.ts +6 -0
- package/dist/es2017/utils/request/fetch.js +29 -8
- package/dist/es2017/utils/request/xhr.d.ts +11 -5
- package/dist/es2017/utils/request/xhr.js +30 -9
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +1335 -812
- package/dist/rx-player.min.js +1 -1
- package/package.json +7 -4
- package/scripts/canal-release.patch +78 -0
- package/scripts/make-dev-releases +65 -0
- package/scripts/update-version +7 -0
- package/sonar-project.properties +1 -1
- package/src/compat/is_codec_supported.ts +23 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +4 -21
- package/src/core/adaptive/network_analyzer.ts +3 -3
- package/src/core/api/debug/buffer_graph.ts +2 -5
- package/src/core/api/debug/modules/general_info.ts +15 -10
- package/src/core/api/index.ts +1 -0
- package/src/core/api/option_utils.ts +3 -3
- package/src/core/api/playback_observer.ts +327 -107
- package/src/core/api/public_api.ts +42 -14
- package/src/core/api/utils.ts +3 -1
- package/src/core/decrypt/get_media_keys.ts +2 -8
- package/src/core/fetchers/manifest/manifest_fetcher.ts +21 -3
- package/src/core/fetchers/segment/segment_fetcher.ts +19 -5
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +1 -0
- package/src/core/fetchers/utils/schedule_request.ts +1 -1
- package/src/core/init/directfile_content_initializer.ts +31 -15
- package/src/core/init/media_source_content_initializer.ts +40 -27
- package/src/core/init/utils/content_time_boundaries_observer.ts +24 -23
- package/src/core/init/utils/create_stream_playback_observer.ts +19 -20
- package/src/core/init/utils/get_initial_time.ts +25 -12
- package/src/core/init/utils/initial_seek_and_play.ts +140 -108
- package/src/core/init/utils/rebuffering_controller.ts +32 -77
- package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +5 -2
- package/src/core/segment_buffers/garbage_collector.ts +1 -1
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +10 -2
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +1 -1
- package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +1 -1
- package/src/core/segment_buffers/index.ts +2 -0
- package/src/core/segment_buffers/inventory/index.ts +2 -0
- package/src/core/segment_buffers/inventory/segment_inventory.ts +49 -17
- package/src/core/stream/adaptation/get_representations_switch_strategy.ts +21 -12
- package/src/core/stream/orchestrator/stream_orchestrator.ts +14 -19
- package/src/core/stream/period/period_stream.ts +7 -8
- package/src/core/stream/period/types.ts +2 -3
- package/src/core/stream/period/utils/get_adaptation_switch_strategy.ts +21 -15
- package/src/core/stream/representation/representation_stream.ts +3 -5
- package/src/core/stream/representation/types.ts +2 -2
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
- package/src/core/stream/representation/utils/get_buffer_status.ts +5 -4
- package/src/core/stream/representation/utils/get_needed_segments.ts +2 -2
- package/src/default_config.ts +22 -17
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +3 -1
- package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +2 -0
- package/src/manifest/adaptation.ts +2 -1
- package/src/manifest/representation_index/static.ts +2 -2
- package/src/manifest/representation_index/types.ts +4 -4
- package/src/parsers/manifest/dash/common/__tests__/manifest_bounds_calculator.test.ts +182 -36
- package/src/parsers/manifest/dash/common/indexes/base.ts +12 -4
- package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +19 -5
- package/src/parsers/manifest/dash/common/indexes/index.ts +16 -4
- package/src/parsers/manifest/dash/common/indexes/list.ts +2 -2
- package/src/parsers/manifest/dash/common/indexes/template.ts +52 -31
- package/src/parsers/manifest/dash/common/indexes/timeline/index.ts +4 -1
- package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +366 -60
- package/src/parsers/manifest/dash/common/manifest_bounds_calculator.ts +63 -25
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +10 -4
- package/src/parsers/manifest/dash/common/parse_mpd.ts +28 -15
- package/src/parsers/manifest/dash/common/parse_periods.ts +12 -17
- package/src/parsers/manifest/dash/common/parse_representation_index.ts +50 -26
- package/src/parsers/manifest/dash/common/parse_representations.ts +9 -3
- package/src/parsers/manifest/local/representation_index.ts +3 -3
- package/src/parsers/manifest/metaplaylist/representation_index.ts +2 -2
- package/src/parsers/manifest/smooth/representation_index.ts +23 -9
- package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +1 -1
- package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +1 -1
- package/src/parsers/manifest/utils/index_helpers.ts +1 -1
- package/src/parsers/texttracks/ttml/html/apply_line_height.ts +3 -1
- package/src/public_types.ts +108 -36
- package/src/transports/dash/init_segment_loader.ts +5 -0
- package/src/transports/dash/manifest_parser.ts +6 -0
- package/src/transports/dash/segment_loader.ts +1 -0
- package/src/transports/dash/text_loader.ts +2 -0
- package/src/transports/metaplaylist/manifest_loader.ts +1 -0
- package/src/transports/metaplaylist/pipelines.ts +4 -1
- package/src/transports/smooth/pipelines.ts +2 -0
- package/src/transports/smooth/segment_loader.ts +1 -0
- package/src/transports/types.ts +12 -0
- package/src/transports/utils/generate_manifest_loader.ts +3 -0
- package/src/utils/request/fetch.ts +35 -8
- package/src/utils/request/xhr.ts +45 -14
- package/dist/commonjs/parsers/manifest/utils/is_segment_still_available.d.ts +0 -29
- package/dist/commonjs/parsers/manifest/utils/is_segment_still_available.js +0 -54
- package/dist/es2017/parsers/manifest/utils/is_segment_still_available.d.ts +0 -29
- package/dist/es2017/parsers/manifest/utils/is_segment_still_available.js +0 -51
- package/src/parsers/manifest/utils/is_segment_still_available.ts +0 -58
- package/src/typings/object-assign.d.ts +0 -48
|
@@ -36,12 +36,8 @@ export interface IStreamPlaybackObserverArguments {
|
|
|
36
36
|
manifest : Manifest;
|
|
37
37
|
/** Becomes `true` after the initial play has been taken care of. */
|
|
38
38
|
initialPlayPerformed : IReadOnlySharedReference<boolean>;
|
|
39
|
-
/** Becomes `true` after the initial seek has been taken care of. */
|
|
40
|
-
initialSeekPerformed : IReadOnlySharedReference<boolean>;
|
|
41
39
|
/** The last speed requested by the user. */
|
|
42
40
|
speed : IReadOnlySharedReference<number>;
|
|
43
|
-
/** The time the player will seek when `initialSeekPerformed` becomes `true`. */
|
|
44
|
-
startTime : number;
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
/**
|
|
@@ -57,10 +53,8 @@ export default function createStreamPlaybackObserver(
|
|
|
57
53
|
srcPlaybackObserver : PlaybackObserver,
|
|
58
54
|
{ autoPlay,
|
|
59
55
|
initialPlayPerformed,
|
|
60
|
-
initialSeekPerformed,
|
|
61
56
|
manifest,
|
|
62
|
-
speed,
|
|
63
|
-
startTime } : IStreamPlaybackObserverArguments,
|
|
57
|
+
speed } : IStreamPlaybackObserverArguments,
|
|
64
58
|
fnCancelSignal : CancellationSignal
|
|
65
59
|
) : IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation> {
|
|
66
60
|
return srcPlaybackObserver.deriveReadOnlyObserver(function transform(
|
|
@@ -87,10 +81,8 @@ export default function createStreamPlaybackObserver(
|
|
|
87
81
|
function constructStreamPlaybackObservation() {
|
|
88
82
|
const observation = observationRef.getValue();
|
|
89
83
|
const lastSpeed = speed.getValue();
|
|
90
|
-
|
|
91
|
-
if (!
|
|
92
|
-
pendingPosition = startTime;
|
|
93
|
-
} else if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
|
|
84
|
+
|
|
85
|
+
if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
|
|
94
86
|
// HACK: When the position is actually further than the maximum
|
|
95
87
|
// position for a finished content, we actually want to be loading
|
|
96
88
|
// the last segment before ending.
|
|
@@ -98,21 +90,28 @@ export default function createStreamPlaybackObserver(
|
|
|
98
90
|
// want to seek one second before the period's end (despite never
|
|
99
91
|
// doing it).
|
|
100
92
|
const lastPeriod = manifest.periods[manifest.periods.length - 1];
|
|
101
|
-
if (lastPeriod !== undefined &&
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
93
|
+
if (lastPeriod !== undefined && lastPeriod.end !== undefined) {
|
|
94
|
+
const wantedPosition = observation.position.getWanted();
|
|
95
|
+
if (wantedPosition >= lastPeriod.start &&
|
|
96
|
+
wantedPosition >= lastPeriod.end - 1)
|
|
97
|
+
{
|
|
98
|
+
// We're after the end of the last Period, check if `buffered`
|
|
99
|
+
// indicates that the last segment is probably not loaded, in which
|
|
100
|
+
// case act as if we want to load one second before the end.
|
|
101
|
+
const buffered = observation.buffered;
|
|
102
|
+
if (buffered.length === 0 ||
|
|
103
|
+
buffered.end(buffered.length - 1) < observation.duration - 1)
|
|
104
|
+
{
|
|
105
|
+
observation.position.forceWantedPosition(lastPeriod.end - 1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
return {
|
|
110
112
|
// TODO more exact according to the current Adaptation chosen?
|
|
111
113
|
maximumPosition: manifest.getMaximumSafePosition(),
|
|
112
|
-
position:
|
|
113
|
-
last: observation.position,
|
|
114
|
-
pending: pendingPosition,
|
|
115
|
-
},
|
|
114
|
+
position: observation.position,
|
|
116
115
|
duration: observation.duration,
|
|
117
116
|
paused: {
|
|
118
117
|
last: observation.paused,
|
|
@@ -43,11 +43,25 @@ export interface IInitialTimeOptions {
|
|
|
43
43
|
*/
|
|
44
44
|
fromFirstPosition? : number | null | undefined;
|
|
45
45
|
/**
|
|
46
|
-
* If set, we should begin at this position relative to the content's
|
|
47
|
-
* in seconds.
|
|
46
|
+
* If set, we should begin at this position relative to the content's maximum
|
|
47
|
+
* seekable position, in seconds.
|
|
48
|
+
*
|
|
49
|
+
* It should consequently in most cases be a negative value.
|
|
48
50
|
*/
|
|
49
51
|
fromLastPosition? : number | null | undefined;
|
|
50
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* If set, we should begin at this position relative to the content's live
|
|
54
|
+
* edge if it makes sense, in seconds.
|
|
55
|
+
*
|
|
56
|
+
* It should consequently in most cases be a negative value.
|
|
57
|
+
*
|
|
58
|
+
* If the live edge is unknown or if it does not make sense for the current
|
|
59
|
+
* content, that position is relative to the content's maximum position
|
|
60
|
+
* instead.
|
|
61
|
+
*/
|
|
62
|
+
fromLivePosition? : number | null | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* If set, we should begin at this position relative to the whole duration of
|
|
51
65
|
* the content, in percentage.
|
|
52
66
|
*/
|
|
53
67
|
percentage? : number | null | undefined;
|
|
@@ -73,13 +87,7 @@ export default function getInitialTime(
|
|
|
73
87
|
) : number {
|
|
74
88
|
if (!isNullOrUndefined(startAt)) {
|
|
75
89
|
const min = manifest.getMinimumSafePosition();
|
|
76
|
-
|
|
77
|
-
if (manifest.isLive) {
|
|
78
|
-
max = manifest.getLivePosition();
|
|
79
|
-
}
|
|
80
|
-
if (max === undefined) {
|
|
81
|
-
max = manifest.getMaximumSafePosition();
|
|
82
|
-
}
|
|
90
|
+
const max = manifest.getMaximumSafePosition();
|
|
83
91
|
if (!isNullOrUndefined(startAt.position)) {
|
|
84
92
|
log.debug("Init: using startAt.minimumPosition");
|
|
85
93
|
return Math.max(Math.min(startAt.position, max), min);
|
|
@@ -97,12 +105,17 @@ export default function getInitialTime(
|
|
|
97
105
|
const { fromFirstPosition } = startAt;
|
|
98
106
|
return fromFirstPosition <= 0 ? min :
|
|
99
107
|
Math.min(max, min + fromFirstPosition);
|
|
100
|
-
}
|
|
101
|
-
else if (!isNullOrUndefined(startAt.fromLastPosition)) {
|
|
108
|
+
} else if (!isNullOrUndefined(startAt.fromLastPosition)) {
|
|
102
109
|
log.debug("Init: using startAt.fromLastPosition");
|
|
103
110
|
const { fromLastPosition } = startAt;
|
|
104
111
|
return fromLastPosition >= 0 ? max :
|
|
105
112
|
Math.max(min, max + fromLastPosition);
|
|
113
|
+
} else if (!isNullOrUndefined(startAt.fromLivePosition)) {
|
|
114
|
+
log.debug("Init: using startAt.fromLivePosition");
|
|
115
|
+
const livePosition = manifest.getLivePosition() ?? max;
|
|
116
|
+
const { fromLivePosition } = startAt;
|
|
117
|
+
return fromLivePosition >= 0 ? livePosition :
|
|
118
|
+
Math.max(min, livePosition + fromLivePosition);
|
|
106
119
|
} else if (!isNullOrUndefined(startAt.percentage)) {
|
|
107
120
|
log.debug("Init: using startAt.percentage");
|
|
108
121
|
const { percentage } = startAt;
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { shouldValidateMetadata } from "../../../compat";
|
|
18
|
-
import { READY_STATES } from "../../../compat/browser_compatibility_types";
|
|
19
18
|
import { MediaError } from "../../../errors";
|
|
20
19
|
import log from "../../../log";
|
|
21
20
|
import { IPlayerError } from "../../../public_types";
|
|
@@ -24,6 +23,7 @@ import SharedReference, {
|
|
|
24
23
|
} from "../../../utils/reference";
|
|
25
24
|
import { CancellationError, CancellationSignal } from "../../../utils/task_canceller";
|
|
26
25
|
import { PlaybackObserver } from "../../api";
|
|
26
|
+
import { SeekingState } from "../../api/playback_observer";
|
|
27
27
|
|
|
28
28
|
/** Event emitted when trying to perform the initial `play`. */
|
|
29
29
|
export type IInitialPlayEvent =
|
|
@@ -42,12 +42,6 @@ export interface IInitialSeekAndPlayObject {
|
|
|
42
42
|
/** Emit the result of the auto-play operation, once performed. */
|
|
43
43
|
autoPlayResult : Promise<IInitialPlayEvent>;
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
* Shared reference whose value becomes `true` once the initial seek has
|
|
47
|
-
* been considered / has been done by `performInitialSeekAndPlay`.
|
|
48
|
-
*/
|
|
49
|
-
initialSeekPerformed : IReadOnlySharedReference<boolean>;
|
|
50
|
-
|
|
51
45
|
/**
|
|
52
46
|
* Shared reference whose value becomes `true` once the initial play has
|
|
53
47
|
* been considered / has been done by `performInitialSeekAndPlay`.
|
|
@@ -58,126 +52,164 @@ export interface IInitialSeekAndPlayObject {
|
|
|
58
52
|
/**
|
|
59
53
|
* Seek as soon as possible at the initially wanted position and play if
|
|
60
54
|
* autoPlay is wanted.
|
|
61
|
-
* @param {
|
|
62
|
-
* @param {Object} playbackObserver
|
|
63
|
-
* @param {number|Function} startTime
|
|
64
|
-
* @param {boolean} mustAutoPlay
|
|
65
|
-
* @param {Function} onWarning
|
|
55
|
+
* @param {Object} args
|
|
66
56
|
* @param {Object} cancelSignal
|
|
67
57
|
* @returns {Object}
|
|
68
58
|
*/
|
|
69
59
|
export default function performInitialSeekAndPlay(
|
|
70
|
-
mediaElement
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
{ mediaElement,
|
|
61
|
+
playbackObserver,
|
|
62
|
+
startTime,
|
|
63
|
+
mustAutoPlay,
|
|
64
|
+
isDirectfile,
|
|
65
|
+
onWarning }: { mediaElement : HTMLMediaElement;
|
|
66
|
+
playbackObserver : PlaybackObserver;
|
|
67
|
+
startTime : number|(() => number);
|
|
68
|
+
mustAutoPlay : boolean;
|
|
69
|
+
isDirectfile: boolean;
|
|
70
|
+
onWarning : (err : IPlayerError) => void; },
|
|
75
71
|
cancelSignal : CancellationSignal
|
|
76
72
|
) : IInitialSeekAndPlayObject {
|
|
77
|
-
let resolveAutoPlay : (x : IInitialPlayEvent) => void;
|
|
78
|
-
let rejectAutoPlay : (x : unknown) => void;
|
|
79
|
-
const autoPlayResult = new Promise<IInitialPlayEvent>((res, rej) => {
|
|
80
|
-
resolveAutoPlay = res;
|
|
81
|
-
rejectAutoPlay = rej;
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const initialSeekPerformed = new SharedReference(false, cancelSignal);
|
|
85
73
|
const initialPlayPerformed = new SharedReference(false, cancelSignal);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"falsely announced having loaded the content.");
|
|
113
|
-
onWarning(error);
|
|
114
|
-
}
|
|
115
|
-
if (cancelSignal.isCancelled()) {
|
|
116
|
-
return ;
|
|
74
|
+
const autoPlayResult = new Promise<IInitialPlayEvent>((
|
|
75
|
+
resolveAutoPlay,
|
|
76
|
+
rejectAutoPlay
|
|
77
|
+
) => {
|
|
78
|
+
// `startTime` defined as a function might depend on metadata to make its
|
|
79
|
+
// choice, such as the content duration, minimum and/or maximum position.
|
|
80
|
+
//
|
|
81
|
+
// The RxPlayer might already know those through the Manifest file for
|
|
82
|
+
// non-Directfile contents, yet only through the `HTMLMediaElement` once a
|
|
83
|
+
// a sufficient `readyState` has been reached for directfile contents.
|
|
84
|
+
// So let's divide the two possibilities here.
|
|
85
|
+
if (!isDirectfile || typeof startTime === "number") {
|
|
86
|
+
playbackObserver.setCurrentTime(
|
|
87
|
+
typeof startTime === "number" ? startTime : startTime()
|
|
88
|
+
);
|
|
89
|
+
waitForSeekable();
|
|
90
|
+
} else {
|
|
91
|
+
playbackObserver.listen((obs, stopListening) => {
|
|
92
|
+
if (obs.readyState >= 1) {
|
|
93
|
+
stopListening();
|
|
94
|
+
playbackObserver.setCurrentTime(
|
|
95
|
+
typeof startTime === "number" ? startTime : startTime()
|
|
96
|
+
);
|
|
97
|
+
waitForSeekable();
|
|
98
|
+
}
|
|
99
|
+
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
117
100
|
}
|
|
118
101
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
102
|
+
const deregisterCancellation = cancelSignal.register((err : CancellationError) => {
|
|
103
|
+
rejectAutoPlay(err);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Logic that should be run once the initial seek has been asked to the
|
|
108
|
+
* PlaybackObserver.
|
|
109
|
+
*
|
|
110
|
+
* Actually wait until the seek has been performed, wait for the right moment
|
|
111
|
+
* to perform autoplay, resolve the promise once everything has been done and
|
|
112
|
+
* potentially send warning if a minor issue is detected.
|
|
113
|
+
*/
|
|
114
|
+
function waitForSeekable() {
|
|
115
|
+
playbackObserver.listen((obs, stopListening) => {
|
|
116
|
+
if (obs.seeking === SeekingState.None || obs.readyState === 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
124
119
|
stopListening();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
initialPlayPerformed.setValue(true);
|
|
138
|
-
initialPlayPerformed.finish();
|
|
139
|
-
deregisterCancellation();
|
|
140
|
-
return resolveAutoPlay({ type: "skipped" as const });
|
|
120
|
+
if (shouldValidateMetadata() && mediaElement.duration === 0) {
|
|
121
|
+
const error = new MediaError("MEDIA_ERR_NOT_LOADED_METADATA",
|
|
122
|
+
"Cannot load automatically: your browser " +
|
|
123
|
+
"falsely announced having loaded the content.");
|
|
124
|
+
onWarning(error);
|
|
125
|
+
}
|
|
126
|
+
if (cancelSignal.isCancelled()) {
|
|
127
|
+
return ;
|
|
128
|
+
}
|
|
129
|
+
waitForPlayable();
|
|
130
|
+
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
141
131
|
}
|
|
142
132
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Logic that should be run once the initial seek has been properly performed.
|
|
135
|
+
*
|
|
136
|
+
* Wait for the media being playable before performing the autoplay operation
|
|
137
|
+
* if asked. Potentially send warning if a minor issue has been detected while
|
|
138
|
+
* doing so.
|
|
139
|
+
*/
|
|
140
|
+
function waitForPlayable() {
|
|
141
|
+
playbackObserver.listen((observation, stopListening) => {
|
|
142
|
+
if (observation.seeking === SeekingState.None &&
|
|
143
|
+
observation.rebuffering === null &&
|
|
144
|
+
observation.readyState >= 1)
|
|
145
|
+
{
|
|
146
|
+
stopListening();
|
|
147
|
+
onPlayable();
|
|
148
|
+
}
|
|
149
|
+
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
149
150
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Callback called once the content is considered "playable".
|
|
154
|
+
*
|
|
155
|
+
* Perform the autoplay if needed, handling potential issues and resolve the
|
|
156
|
+
* Promise when done.
|
|
157
|
+
* Might also send warnings if minor issues arise.
|
|
158
|
+
*/
|
|
159
|
+
function onPlayable() {
|
|
160
|
+
log.info("Init: Can begin to play content");
|
|
161
|
+
if (!mustAutoPlay) {
|
|
162
|
+
if (mediaElement.autoplay) {
|
|
163
|
+
log.warn("Init: autoplay is enabled on HTML media element. " +
|
|
164
|
+
"Media will play as soon as possible.");
|
|
154
165
|
}
|
|
155
166
|
initialPlayPerformed.setValue(true);
|
|
156
167
|
initialPlayPerformed.finish();
|
|
157
168
|
deregisterCancellation();
|
|
158
|
-
return resolveAutoPlay({ type: "
|
|
159
|
-
}
|
|
160
|
-
.catch((playError : unknown) => {
|
|
161
|
-
deregisterCancellation();
|
|
162
|
-
if (cancelSignal.isCancelled()) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (playError instanceof Error && playError.name === "NotAllowedError") {
|
|
166
|
-
// auto-play was probably prevented.
|
|
167
|
-
log.warn("Init: Media element can't play." +
|
|
168
|
-
" It may be due to browser auto-play policies.");
|
|
169
|
+
return resolveAutoPlay({ type: "skipped" as const });
|
|
170
|
+
}
|
|
169
171
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
let playResult : Promise<unknown>;
|
|
173
|
+
try {
|
|
174
|
+
playResult = mediaElement.play() ?? Promise.resolve();
|
|
175
|
+
} catch (playError) {
|
|
176
|
+
deregisterCancellation();
|
|
177
|
+
return rejectAutoPlay(playError);
|
|
178
|
+
}
|
|
179
|
+
playResult
|
|
180
|
+
.then(() => {
|
|
174
181
|
if (cancelSignal.isCancelled()) {
|
|
175
182
|
return;
|
|
176
183
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
initialPlayPerformed.setValue(true);
|
|
185
|
+
initialPlayPerformed.finish();
|
|
186
|
+
deregisterCancellation();
|
|
187
|
+
return resolveAutoPlay({ type: "autoplay" as const });
|
|
188
|
+
})
|
|
189
|
+
.catch((playError : unknown) => {
|
|
190
|
+
deregisterCancellation();
|
|
191
|
+
if (cancelSignal.isCancelled()) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (playError instanceof Error && playError.name === "NotAllowedError") {
|
|
195
|
+
// auto-play was probably prevented.
|
|
196
|
+
log.warn("Init: Media element can't play." +
|
|
197
|
+
" It may be due to browser auto-play policies.");
|
|
198
|
+
|
|
199
|
+
const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY",
|
|
200
|
+
"Cannot trigger auto-play automatically: " +
|
|
201
|
+
"your browser does not allow it.");
|
|
202
|
+
onWarning(error);
|
|
203
|
+
if (cancelSignal.isCancelled()) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
return resolveAutoPlay({ type: "autoplay-blocked" as const });
|
|
207
|
+
} else {
|
|
208
|
+
rejectAutoPlay(playError);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
return { autoPlayResult, initialPlayPerformed };
|
|
183
215
|
}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import isSeekingApproximate from "../../../compat/is_seeking_approximate";
|
|
18
17
|
import config from "../../../config";
|
|
19
18
|
import { MediaError } from "../../../errors";
|
|
20
19
|
import log from "../../../log";
|
|
@@ -31,6 +30,7 @@ import {
|
|
|
31
30
|
IPlaybackObservation,
|
|
32
31
|
PlaybackObserver,
|
|
33
32
|
} from "../../api";
|
|
33
|
+
import { SeekingState } from "../../api/playback_observer";
|
|
34
34
|
import SegmentBuffersStore, { IBufferType } from "../../segment_buffers";
|
|
35
35
|
import { IStallingSituation } from "../types";
|
|
36
36
|
|
|
@@ -107,33 +107,6 @@ export default class RebufferingController
|
|
|
107
107
|
}
|
|
108
108
|
this._isStarted = true;
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
* On some devices (right now only seen on Tizen), seeking through the
|
|
112
|
-
* `currentTime` property can lead to the browser re-seeking once the
|
|
113
|
-
* segments have been loaded to improve seeking performances (for
|
|
114
|
-
* example, by seeking right to an intra video frame).
|
|
115
|
-
* In that case, we risk being in a conflict with that behavior: if for
|
|
116
|
-
* example we encounter a small discontinuity at the position the browser
|
|
117
|
-
* seeks to, we will seek over it, the browser would seek back and so on.
|
|
118
|
-
*
|
|
119
|
-
* This variable allows to store the last known position we were seeking to
|
|
120
|
-
* so we can detect when the browser seeked back (to avoid performing another
|
|
121
|
-
* seek after that). When browsers seek back to a position behind a
|
|
122
|
-
* discontinuity, they are usually able to skip them without our help.
|
|
123
|
-
*/
|
|
124
|
-
let lastSeekingPosition : number | null;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* In some conditions (see `lastSeekingPosition`), we might want to not
|
|
128
|
-
* automatically seek over discontinuities because the browser might do it
|
|
129
|
-
* itself instead.
|
|
130
|
-
* In that case, we still want to perform the seek ourselves if the browser
|
|
131
|
-
* doesn't do it after sufficient time.
|
|
132
|
-
* This variable allows to store the timestamp at which a discontinuity began
|
|
133
|
-
* to be ignored.
|
|
134
|
-
*/
|
|
135
|
-
let ignoredStallTimeStamp : number | null = null;
|
|
136
|
-
|
|
137
110
|
const playbackRateUpdater = new PlaybackRateUpdater(this._playbackObserver,
|
|
138
111
|
this._speed);
|
|
139
112
|
this._canceller.signal.register(() => {
|
|
@@ -151,26 +124,10 @@ export default class RebufferingController
|
|
|
151
124
|
freezing } = observation;
|
|
152
125
|
|
|
153
126
|
const { BUFFER_DISCONTINUITY_THRESHOLD,
|
|
154
|
-
FORCE_DISCONTINUITY_SEEK_DELAY,
|
|
155
127
|
FREEZING_STALLED_DELAY,
|
|
156
128
|
UNFREEZING_SEEK_DELAY,
|
|
157
129
|
UNFREEZING_DELTA_POSITION } = config.getCurrent();
|
|
158
130
|
|
|
159
|
-
if (
|
|
160
|
-
!observation.seeking &&
|
|
161
|
-
isSeekingApproximate &&
|
|
162
|
-
ignoredStallTimeStamp === null &&
|
|
163
|
-
lastSeekingPosition !== null && observation.position < lastSeekingPosition)
|
|
164
|
-
{
|
|
165
|
-
log.debug("Init: the device appeared to have seeked back by itself.");
|
|
166
|
-
const now = getMonotonicTimeStamp();
|
|
167
|
-
ignoredStallTimeStamp = now;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
lastSeekingPosition = observation.seeking ?
|
|
171
|
-
Math.max(observation.pendingInternalSeek ?? 0, observation.position) :
|
|
172
|
-
null;
|
|
173
|
-
|
|
174
131
|
if (this._checkDecipherabilityFreeze(observation)) {
|
|
175
132
|
return ;
|
|
176
133
|
}
|
|
@@ -182,7 +139,10 @@ export default class RebufferingController
|
|
|
182
139
|
freezing.timestamp :
|
|
183
140
|
prevFreezingState.attemptTimestamp;
|
|
184
141
|
|
|
185
|
-
if (
|
|
142
|
+
if (
|
|
143
|
+
!position.isAwaitingFuturePosition() &&
|
|
144
|
+
now - referenceTimestamp > UNFREEZING_SEEK_DELAY
|
|
145
|
+
) {
|
|
186
146
|
log.warn("Init: trying to seek to un-freeze player");
|
|
187
147
|
this._playbackObserver.setCurrentTime(
|
|
188
148
|
this._playbackObserver.getCurrentTime() + UNFREEZING_DELTA_POSITION);
|
|
@@ -190,7 +150,7 @@ export default class RebufferingController
|
|
|
190
150
|
}
|
|
191
151
|
|
|
192
152
|
if (now - freezing.timestamp > FREEZING_STALLED_DELAY) {
|
|
193
|
-
if (rebuffering === null
|
|
153
|
+
if (rebuffering === null) {
|
|
194
154
|
playbackRateUpdater.stopRebuffering();
|
|
195
155
|
} else {
|
|
196
156
|
playbackRateUpdater.startRebuffering();
|
|
@@ -208,9 +168,10 @@ export default class RebufferingController
|
|
|
208
168
|
// With a readyState set to 1, we should still not be able to play:
|
|
209
169
|
// Return that we're stalled
|
|
210
170
|
let reason : IStallingSituation;
|
|
211
|
-
if (observation.seeking) {
|
|
212
|
-
reason = observation.
|
|
213
|
-
|
|
171
|
+
if (observation.seeking !== SeekingState.None) {
|
|
172
|
+
reason = observation.seeking === SeekingState.Internal ?
|
|
173
|
+
"internal-seek" :
|
|
174
|
+
"seeking";
|
|
214
175
|
} else {
|
|
215
176
|
reason = "not-ready";
|
|
216
177
|
}
|
|
@@ -224,24 +185,17 @@ export default class RebufferingController
|
|
|
224
185
|
// We want to separate a stall situation when a seek is due to a seek done
|
|
225
186
|
// internally by the player to when its due to a regular user seek.
|
|
226
187
|
const stalledReason = rebuffering.reason === "seeking" &&
|
|
227
|
-
observation.
|
|
188
|
+
observation.seeking === SeekingState.Internal ?
|
|
228
189
|
"internal-seek" as const :
|
|
229
190
|
rebuffering.reason;
|
|
230
191
|
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.trigger("stalled", stalledReason);
|
|
237
|
-
return ;
|
|
238
|
-
} else {
|
|
239
|
-
log.warn("Init: ignored stall for too long, considering it",
|
|
240
|
-
now - ignoredStallTimeStamp);
|
|
241
|
-
}
|
|
192
|
+
if (position.isAwaitingFuturePosition()) {
|
|
193
|
+
playbackRateUpdater.stopRebuffering();
|
|
194
|
+
log.debug("Init: let rebuffering happen as we're awaiting a future position");
|
|
195
|
+
this.trigger("stalled", stalledReason);
|
|
196
|
+
return ;
|
|
242
197
|
}
|
|
243
198
|
|
|
244
|
-
ignoredStallTimeStamp = null;
|
|
245
199
|
playbackRateUpdater.startRebuffering();
|
|
246
200
|
|
|
247
201
|
if (this._manifest === null) {
|
|
@@ -266,7 +220,7 @@ export default class RebufferingController
|
|
|
266
220
|
this._playbackObserver.getCurrentTime(), realSeekTime);
|
|
267
221
|
} else {
|
|
268
222
|
log.warn("SA: skippable discontinuity found in the stream",
|
|
269
|
-
position, realSeekTime);
|
|
223
|
+
position.getPolled(), realSeekTime);
|
|
270
224
|
this._playbackObserver.setCurrentTime(realSeekTime);
|
|
271
225
|
this.trigger("warning", generateDiscontinuityError(stalledPosition,
|
|
272
226
|
realSeekTime));
|
|
@@ -275,7 +229,7 @@ export default class RebufferingController
|
|
|
275
229
|
}
|
|
276
230
|
}
|
|
277
231
|
|
|
278
|
-
const
|
|
232
|
+
const positionBlockedAt = stalledPosition ?? position.getPolled();
|
|
279
233
|
|
|
280
234
|
// Is it a very short discontinuity in buffer ? -> Seek at the beginning of the
|
|
281
235
|
// next range
|
|
@@ -284,17 +238,17 @@ export default class RebufferingController
|
|
|
284
238
|
// calculate a stalled state. This is useful for some
|
|
285
239
|
// implementation that might drop an injected segment, or in
|
|
286
240
|
// case of small discontinuity in the content.
|
|
287
|
-
const nextBufferRangeGap = getNextBufferedTimeRangeGap(buffered,
|
|
241
|
+
const nextBufferRangeGap = getNextBufferedTimeRangeGap(buffered, positionBlockedAt);
|
|
288
242
|
if (
|
|
289
243
|
this._speed.getValue() > 0 &&
|
|
290
244
|
nextBufferRangeGap < BUFFER_DISCONTINUITY_THRESHOLD
|
|
291
245
|
) {
|
|
292
|
-
const seekTo = (
|
|
246
|
+
const seekTo = (positionBlockedAt + nextBufferRangeGap + EPSILON);
|
|
293
247
|
if (this._playbackObserver.getCurrentTime() < seekTo) {
|
|
294
248
|
log.warn("Init: discontinuity encountered inferior to the threshold",
|
|
295
|
-
|
|
249
|
+
positionBlockedAt, seekTo, BUFFER_DISCONTINUITY_THRESHOLD);
|
|
296
250
|
this._playbackObserver.setCurrentTime(seekTo);
|
|
297
|
-
this.trigger("warning", generateDiscontinuityError(
|
|
251
|
+
this.trigger("warning", generateDiscontinuityError(positionBlockedAt, seekTo));
|
|
298
252
|
return;
|
|
299
253
|
}
|
|
300
254
|
}
|
|
@@ -303,14 +257,14 @@ export default class RebufferingController
|
|
|
303
257
|
// next period
|
|
304
258
|
for (let i = this._manifest.periods.length - 2; i >= 0; i--) {
|
|
305
259
|
const period = this._manifest.periods[i];
|
|
306
|
-
if (period.end !== undefined && period.end <=
|
|
307
|
-
if (this._manifest.periods[i + 1].start >
|
|
260
|
+
if (period.end !== undefined && period.end <= positionBlockedAt) {
|
|
261
|
+
if (this._manifest.periods[i + 1].start > positionBlockedAt &&
|
|
308
262
|
this._manifest.periods[i + 1].start >
|
|
309
263
|
this._playbackObserver.getCurrentTime())
|
|
310
264
|
{
|
|
311
265
|
const nextPeriod = this._manifest.periods[i + 1];
|
|
312
266
|
this._playbackObserver.setCurrentTime(nextPeriod.start);
|
|
313
|
-
this.trigger("warning", generateDiscontinuityError(
|
|
267
|
+
this.trigger("warning", generateDiscontinuityError(positionBlockedAt,
|
|
314
268
|
nextPeriod.start));
|
|
315
269
|
return;
|
|
316
270
|
|
|
@@ -360,10 +314,10 @@ export default class RebufferingController
|
|
|
360
314
|
) {
|
|
361
315
|
return;
|
|
362
316
|
}
|
|
363
|
-
const
|
|
364
|
-
const rebufferingPos = observation.rebuffering.position ??
|
|
317
|
+
const loadedPos = observation.position.getWanted();
|
|
318
|
+
const rebufferingPos = observation.rebuffering.position ?? loadedPos;
|
|
365
319
|
const lockedPeriodStart = period.start;
|
|
366
|
-
if (
|
|
320
|
+
if (loadedPos < lockedPeriodStart &&
|
|
367
321
|
Math.abs(rebufferingPos - lockedPeriodStart) < 1)
|
|
368
322
|
{
|
|
369
323
|
log.warn("Init: rebuffering because of a future locked stream.\n" +
|
|
@@ -403,8 +357,6 @@ export default class RebufferingController
|
|
|
403
357
|
private _checkDecipherabilityFreeze(
|
|
404
358
|
observation : IPlaybackObservation
|
|
405
359
|
): boolean {
|
|
406
|
-
// XXX TODO allow this in in-worker configuration
|
|
407
|
-
|
|
408
360
|
const { readyState,
|
|
409
361
|
rebuffering,
|
|
410
362
|
freezing } = observation;
|
|
@@ -555,10 +507,13 @@ function updateDiscontinuitiesStore(
|
|
|
555
507
|
evt : IDiscontinuityEvent,
|
|
556
508
|
observation : IPlaybackObservation
|
|
557
509
|
) : void {
|
|
510
|
+
const gcTime = Math.min(observation.position.getPolled(),
|
|
511
|
+
observation.position.getWanted());
|
|
512
|
+
|
|
558
513
|
// First, perform clean-up of old discontinuities
|
|
559
514
|
while (discontinuitiesStore.length > 0 &&
|
|
560
515
|
discontinuitiesStore[0].period.end !== undefined &&
|
|
561
|
-
discontinuitiesStore[0].period.end + 10 <
|
|
516
|
+
discontinuitiesStore[0].period.end + 10 < gcTime)
|
|
562
517
|
{
|
|
563
518
|
discontinuitiesStore.shift();
|
|
564
519
|
}
|