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
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import isSeekingApproximate from "../../compat/is_seeking_approximate";
|
|
17
18
|
import config from "../../config";
|
|
18
19
|
import log from "../../log";
|
|
19
20
|
import getMonotonicTimeStamp from "../../utils/monotonic_timestamp";
|
|
@@ -68,6 +69,14 @@ export default class PlaybackObserver {
|
|
|
68
69
|
*/
|
|
69
70
|
private _lowLatencyMode : boolean;
|
|
70
71
|
|
|
72
|
+
/**
|
|
73
|
+
* If set, position which could not yet be seeked to as the HTMLMediaElement
|
|
74
|
+
* had a readyState of `0`.
|
|
75
|
+
* This position should be seeked to as soon as the HTMLMediaElement is able
|
|
76
|
+
* to handle it.
|
|
77
|
+
*/
|
|
78
|
+
private _pendingSeek : number | null;
|
|
79
|
+
|
|
71
80
|
/**
|
|
72
81
|
* The RxPlayer usually wants to differientate when a seek was sourced from
|
|
73
82
|
* the RxPlayer's internal logic vs when it was sourced from an outside
|
|
@@ -88,7 +97,7 @@ export default class PlaybackObserver {
|
|
|
88
97
|
/**
|
|
89
98
|
* Stores the last playback observation produced by the `PlaybackObserver`.:
|
|
90
99
|
*/
|
|
91
|
-
private _observationRef :
|
|
100
|
+
private _observationRef : SharedReference<IPlaybackObservation>;
|
|
92
101
|
|
|
93
102
|
/**
|
|
94
103
|
* `TaskCanceller` allowing to free all resources and stop producing playback
|
|
@@ -96,6 +105,22 @@ export default class PlaybackObserver {
|
|
|
96
105
|
*/
|
|
97
106
|
private _canceller : TaskCanceller;
|
|
98
107
|
|
|
108
|
+
/**
|
|
109
|
+
* On some devices (right now only seen on Tizen), seeking through the
|
|
110
|
+
* `currentTime` property can lead to the browser re-seeking once the
|
|
111
|
+
* segments have been loaded to improve seeking performances (for
|
|
112
|
+
* example, by seeking right to an intra video frame).
|
|
113
|
+
* In that case, we risk being in a conflict with that behavior: if for
|
|
114
|
+
* example we encounter a small discontinuity at the position the browser
|
|
115
|
+
* seeks to, we will seek over it, the browser would seek back and so on.
|
|
116
|
+
*
|
|
117
|
+
* This variable allows to store the maximum known position we were seeking to
|
|
118
|
+
* so we can detect when the browser seeked back (to avoid performing another
|
|
119
|
+
* seek after that). When browsers seek back to a position behind a
|
|
120
|
+
* discontinuity, they are usually able to skip them without our help.
|
|
121
|
+
*/
|
|
122
|
+
private _expectedSeekingPosition : number | null;
|
|
123
|
+
|
|
99
124
|
/**
|
|
100
125
|
* Create a new `PlaybackObserver`, which allows to produce new "playback
|
|
101
126
|
* observations" on various media events and intervals.
|
|
@@ -113,6 +138,20 @@ export default class PlaybackObserver {
|
|
|
113
138
|
this._lowLatencyMode = options.lowLatencyMode;
|
|
114
139
|
this._canceller = new TaskCanceller();
|
|
115
140
|
this._observationRef = this._createSharedReference();
|
|
141
|
+
this._expectedSeekingPosition = null;
|
|
142
|
+
this._pendingSeek = null;
|
|
143
|
+
|
|
144
|
+
const onLoadedMetadata = () => {
|
|
145
|
+
if (this._pendingSeek !== null) {
|
|
146
|
+
const positionToSeekTo = this._pendingSeek;
|
|
147
|
+
this._pendingSeek = null;
|
|
148
|
+
this._actuallySetCurrentTime(positionToSeekTo);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
mediaElement.addEventListener("loadedmetadata", onLoadedMetadata);
|
|
152
|
+
this._canceller.signal.register(() => {
|
|
153
|
+
mediaElement.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
154
|
+
});
|
|
116
155
|
}
|
|
117
156
|
|
|
118
157
|
/**
|
|
@@ -167,9 +206,13 @@ export default class PlaybackObserver {
|
|
|
167
206
|
* @param {number} time
|
|
168
207
|
*/
|
|
169
208
|
public setCurrentTime(time: number) : void {
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
209
|
+
if (this._mediaElement.readyState >= 1) {
|
|
210
|
+
this._actuallySetCurrentTime(time);
|
|
211
|
+
} else {
|
|
212
|
+
this._internalSeeksIncoming = [];
|
|
213
|
+
this._pendingSeek = time;
|
|
214
|
+
this._generateObservationForEvent("manual");
|
|
215
|
+
}
|
|
173
216
|
}
|
|
174
217
|
|
|
175
218
|
/**
|
|
@@ -251,112 +294,53 @@ export default class PlaybackObserver {
|
|
|
251
294
|
return generateReadOnlyObserver(this, transform, this._canceller.signal);
|
|
252
295
|
}
|
|
253
296
|
|
|
297
|
+
private _actuallySetCurrentTime(time: number) : void {
|
|
298
|
+
log.info("API: Seeking internally", time);
|
|
299
|
+
this._internalSeeksIncoming.push(time);
|
|
300
|
+
this._mediaElement.currentTime = time;
|
|
301
|
+
}
|
|
302
|
+
|
|
254
303
|
/**
|
|
255
304
|
* Creates the `IReadOnlySharedReference` that will generate playback
|
|
256
305
|
* observations.
|
|
257
306
|
* @returns {Object}
|
|
258
307
|
*/
|
|
259
|
-
private _createSharedReference() :
|
|
308
|
+
private _createSharedReference() : SharedReference<IPlaybackObservation> {
|
|
260
309
|
if (this._observationRef !== undefined) {
|
|
261
310
|
return this._observationRef;
|
|
262
311
|
}
|
|
263
312
|
|
|
264
|
-
let lastObservation : IPlaybackObservation | null;
|
|
265
313
|
const { SAMPLING_INTERVAL_MEDIASOURCE,
|
|
266
314
|
SAMPLING_INTERVAL_LOW_LATENCY,
|
|
267
315
|
SAMPLING_INTERVAL_NO_MEDIASOURCE } = config.getCurrent();
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
)
|
|
272
|
-
let tmpEvt: IPlaybackObserverEventType = event;
|
|
273
|
-
let startedInternalSeekTime : number | undefined;
|
|
274
|
-
if (tmpEvt === "seeking" && this._internalSeeksIncoming.length > 0) {
|
|
275
|
-
tmpEvt = "internal-seeking";
|
|
276
|
-
startedInternalSeekTime = this._internalSeeksIncoming.shift();
|
|
277
|
-
}
|
|
278
|
-
const _lastObservation = lastObservation ?? this._generateInitialObservation();
|
|
279
|
-
const mediaTimings = getMediaInfos(this._mediaElement,
|
|
280
|
-
tmpEvt,
|
|
281
|
-
this._withMediaSource);
|
|
282
|
-
let pendingInternalSeek : number | null = null;
|
|
283
|
-
if (mediaTimings.seeking) {
|
|
284
|
-
if (typeof startedInternalSeekTime === "number") {
|
|
285
|
-
pendingInternalSeek = startedInternalSeekTime;
|
|
286
|
-
} else if (_lastObservation.pendingInternalSeek !== null && event !== "seeking") {
|
|
287
|
-
pendingInternalSeek = _lastObservation.pendingInternalSeek;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
const rebufferingStatus = getRebufferingStatus(
|
|
291
|
-
_lastObservation,
|
|
292
|
-
mediaTimings,
|
|
293
|
-
{ lowLatencyMode: this._lowLatencyMode,
|
|
294
|
-
withMediaSource: this._withMediaSource });
|
|
295
|
-
|
|
296
|
-
const freezingStatus = getFreezingStatus(_lastObservation, mediaTimings);
|
|
297
|
-
const timings = objectAssign(
|
|
298
|
-
{},
|
|
299
|
-
{ rebuffering: rebufferingStatus,
|
|
300
|
-
freezing: freezingStatus,
|
|
301
|
-
pendingInternalSeek },
|
|
302
|
-
mediaTimings);
|
|
303
|
-
if (log.hasLevel("DEBUG")) {
|
|
304
|
-
log.debug("API: current media element state tick",
|
|
305
|
-
"event", timings.event,
|
|
306
|
-
"position", timings.position,
|
|
307
|
-
"seeking", timings.seeking,
|
|
308
|
-
"internalSeek", timings.pendingInternalSeek,
|
|
309
|
-
"rebuffering", timings.rebuffering !== null,
|
|
310
|
-
"freezing", timings.freezing !== null,
|
|
311
|
-
"ended", timings.ended,
|
|
312
|
-
"paused", timings.paused,
|
|
313
|
-
"playbackRate", timings.playbackRate,
|
|
314
|
-
"readyState", timings.readyState);
|
|
315
|
-
}
|
|
316
|
-
return timings;
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
const returnedSharedReference = new SharedReference(getCurrentObservation("init"),
|
|
320
|
-
this._canceller.signal);
|
|
321
|
-
|
|
322
|
-
const generateObservationForEvent = (event : IPlaybackObserverEventType) => {
|
|
323
|
-
const newObservation = getCurrentObservation(event);
|
|
324
|
-
if (log.hasLevel("DEBUG")) {
|
|
325
|
-
log.debug("API: current playback timeline:\n" +
|
|
326
|
-
prettyPrintBuffered(newObservation.buffered,
|
|
327
|
-
newObservation.position),
|
|
328
|
-
`\n${event}`);
|
|
329
|
-
}
|
|
330
|
-
lastObservation = newObservation;
|
|
331
|
-
returnedSharedReference.setValue(newObservation);
|
|
332
|
-
};
|
|
333
|
-
|
|
316
|
+
const returnedSharedReference = new SharedReference(
|
|
317
|
+
this._getCurrentObservation("init"),
|
|
318
|
+
this._canceller.signal
|
|
319
|
+
);
|
|
334
320
|
const interval = this._lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY :
|
|
335
321
|
this._withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE :
|
|
336
322
|
SAMPLING_INTERVAL_NO_MEDIASOURCE;
|
|
323
|
+
const onInterval = () => {
|
|
324
|
+
this._generateObservationForEvent("timeupdate");
|
|
325
|
+
};
|
|
337
326
|
let intervalId = setInterval(onInterval, interval);
|
|
338
327
|
const removeEventListeners = SCANNED_MEDIA_ELEMENTS_EVENTS.map((eventName) => {
|
|
339
|
-
|
|
340
|
-
function onMediaEvent() {
|
|
328
|
+
const onMediaEvent = () => {
|
|
341
329
|
restartInterval();
|
|
342
|
-
|
|
343
|
-
}
|
|
330
|
+
this._generateObservationForEvent(eventName);
|
|
331
|
+
};
|
|
332
|
+
this._mediaElement.addEventListener(eventName, onMediaEvent);
|
|
344
333
|
return () => {
|
|
345
334
|
this._mediaElement.removeEventListener(eventName, onMediaEvent);
|
|
346
335
|
};
|
|
347
336
|
});
|
|
348
|
-
|
|
349
337
|
this._canceller.signal.register(() => {
|
|
350
338
|
clearInterval(intervalId);
|
|
351
339
|
removeEventListeners.forEach(cb => cb());
|
|
352
340
|
returnedSharedReference.finish();
|
|
353
341
|
});
|
|
354
|
-
|
|
355
342
|
return returnedSharedReference;
|
|
356
343
|
|
|
357
|
-
function onInterval() {
|
|
358
|
-
generateObservationForEvent("timeupdate");
|
|
359
|
-
}
|
|
360
344
|
|
|
361
345
|
function restartInterval() {
|
|
362
346
|
clearInterval(intervalId);
|
|
@@ -364,20 +348,123 @@ export default class PlaybackObserver {
|
|
|
364
348
|
}
|
|
365
349
|
}
|
|
366
350
|
|
|
367
|
-
private
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
351
|
+
private _getCurrentObservation(
|
|
352
|
+
event : IPlaybackObserverEventType
|
|
353
|
+
) : IPlaybackObservation {
|
|
354
|
+
/** Actual event emitted through an observation. */
|
|
355
|
+
let tmpEvt: IPlaybackObserverEventType = event;
|
|
356
|
+
|
|
357
|
+
// NOTE: `this._observationRef` may be `undefined` because we might here be
|
|
358
|
+
// called in the constructor when that property is not yet set.
|
|
359
|
+
const previousObservation = this._observationRef === undefined ?
|
|
360
|
+
getInitialObservation(this._mediaElement, this._withMediaSource) :
|
|
361
|
+
this._observationRef.getValue();
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* If `true`, there is a seek operation ongoing but it was done from the
|
|
365
|
+
* `PlaybackObserver`'s `setCurrentTime` method, not from external code.
|
|
366
|
+
*/
|
|
367
|
+
let isInternalSeeking = false;
|
|
368
|
+
|
|
369
|
+
/** If set, the position for which we plan to seek to as soon as possible. */
|
|
370
|
+
let pendingPosition: number | null = this._pendingSeek;
|
|
371
|
+
|
|
372
|
+
/** Initially-polled playback observation, before adjustments. */
|
|
373
|
+
const mediaTimings = getMediaInfos(this._mediaElement, this._withMediaSource);
|
|
374
|
+
|
|
375
|
+
if (tmpEvt === "seeking") {
|
|
376
|
+
// We just began seeking.
|
|
377
|
+
// Let's find out if the seek is internal or external and handle approximate
|
|
378
|
+
// seeking
|
|
379
|
+
if (this._internalSeeksIncoming.length > 0) {
|
|
380
|
+
isInternalSeeking = true;
|
|
381
|
+
tmpEvt = "internal-seeking";
|
|
382
|
+
const startedInternalSeekTime = this._internalSeeksIncoming.shift();
|
|
383
|
+
this._expectedSeekingPosition = isSeekingApproximate ?
|
|
384
|
+
Math.max(mediaTimings.position, startedInternalSeekTime ?? 0) :
|
|
385
|
+
mediaTimings.position;
|
|
386
|
+
} else {
|
|
387
|
+
this._expectedSeekingPosition = mediaTimings.position;
|
|
388
|
+
}
|
|
389
|
+
} else if (mediaTimings.seeking) {
|
|
390
|
+
// we're still seeking, this time without a "seeking" event so it's an
|
|
391
|
+
// already handled one, keep track of the last wanted position we wanted
|
|
392
|
+
// to seek to, to work-around devices re-seeking silently.
|
|
393
|
+
this._expectedSeekingPosition = Math.max(mediaTimings.position,
|
|
394
|
+
this._expectedSeekingPosition ?? 0);
|
|
395
|
+
} else if (isSeekingApproximate &&
|
|
396
|
+
this._expectedSeekingPosition !== null &&
|
|
397
|
+
mediaTimings.position < this._expectedSeekingPosition)
|
|
398
|
+
{
|
|
399
|
+
// We're on a target with aproximate seeking, we're not seeking anymore, but
|
|
400
|
+
// we're not yet at the expected seeking position.
|
|
401
|
+
// Signal to the rest of the application that the intented position is not
|
|
402
|
+
// the current position but the one contained in `this._expectedSeekingPosition`
|
|
403
|
+
pendingPosition = this._expectedSeekingPosition;
|
|
404
|
+
} else {
|
|
405
|
+
this._expectedSeekingPosition = null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (mediaTimings.seeking &&
|
|
409
|
+
previousObservation.seeking === SeekingState.Internal &&
|
|
410
|
+
event !== "seeking")
|
|
411
|
+
{
|
|
412
|
+
isInternalSeeking = true;
|
|
413
|
+
}
|
|
414
|
+
const rebufferingStatus = getRebufferingStatus(
|
|
415
|
+
previousObservation,
|
|
416
|
+
mediaTimings,
|
|
417
|
+
tmpEvt,
|
|
418
|
+
{ lowLatencyMode: this._lowLatencyMode,
|
|
419
|
+
withMediaSource: this._withMediaSource });
|
|
420
|
+
|
|
421
|
+
const freezingStatus = getFreezingStatus(previousObservation, mediaTimings, tmpEvt);
|
|
422
|
+
|
|
423
|
+
const seeking = isInternalSeeking ? SeekingState.Internal :
|
|
424
|
+
mediaTimings.seeking ? SeekingState.External :
|
|
425
|
+
SeekingState.None;
|
|
426
|
+
const timings: IPlaybackObservation = objectAssign(
|
|
427
|
+
{},
|
|
428
|
+
mediaTimings,
|
|
429
|
+
{ position: new ObservationPosition(mediaTimings.position, pendingPosition),
|
|
430
|
+
event: tmpEvt,
|
|
431
|
+
seeking,
|
|
432
|
+
rebuffering: rebufferingStatus,
|
|
433
|
+
freezing: freezingStatus });
|
|
434
|
+
if (log.hasLevel("DEBUG")) {
|
|
435
|
+
log.debug("API: current media element state tick",
|
|
436
|
+
"event", timings.event,
|
|
437
|
+
"position", timings.position.getPolled(),
|
|
438
|
+
"seeking", timings.seeking,
|
|
439
|
+
"internalSeek", isInternalSeeking,
|
|
440
|
+
"rebuffering", timings.rebuffering !== null,
|
|
441
|
+
"freezing", timings.freezing !== null,
|
|
442
|
+
"ended", timings.ended,
|
|
443
|
+
"paused", timings.paused,
|
|
444
|
+
"playbackRate", timings.playbackRate,
|
|
445
|
+
"readyState", timings.readyState);
|
|
446
|
+
}
|
|
447
|
+
return timings;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private _generateObservationForEvent(event : IPlaybackObserverEventType): void {
|
|
451
|
+
const newObservation = this._getCurrentObservation(event);
|
|
452
|
+
if (log.hasLevel("DEBUG")) {
|
|
453
|
+
log.debug("API: current playback timeline:\n" +
|
|
454
|
+
prettyPrintBuffered(newObservation.buffered,
|
|
455
|
+
newObservation.position.getPolled()),
|
|
456
|
+
`\n${event}`);
|
|
457
|
+
}
|
|
458
|
+
this._observationRef.setValue(newObservation);
|
|
374
459
|
}
|
|
375
460
|
}
|
|
376
461
|
|
|
377
462
|
/** "Event" that triggered the playback observation. */
|
|
378
463
|
export type IPlaybackObserverEventType =
|
|
379
464
|
/** First playback observation automatically emitted. */
|
|
380
|
-
"init" |
|
|
465
|
+
"init" |
|
|
466
|
+
/** Observation manually forced by the PlaybackObserver. */
|
|
467
|
+
"manual" |
|
|
381
468
|
/** Regularly emitted playback observation when no event happened in a long time. */
|
|
382
469
|
"timeupdate" |
|
|
383
470
|
/** On the HTML5 event with the same name */
|
|
@@ -439,8 +526,19 @@ interface IMediaInfos {
|
|
|
439
526
|
readyState : number;
|
|
440
527
|
/** Current `seeking` value on the mediaElement. */
|
|
441
528
|
seeking : boolean;
|
|
442
|
-
|
|
443
|
-
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** Categorize a pending seek operation. */
|
|
532
|
+
export const enum SeekingState {
|
|
533
|
+
/** We're not currently seeking. */
|
|
534
|
+
None,
|
|
535
|
+
/**
|
|
536
|
+
* We're currently seeking due to an internal logic of the RxPlayer (e.g.
|
|
537
|
+
* discontinuity skipping).
|
|
538
|
+
*/
|
|
539
|
+
Internal,
|
|
540
|
+
/** We're currently seeking due to a regular seek wanted by the application. */
|
|
541
|
+
External,
|
|
444
542
|
}
|
|
445
543
|
|
|
446
544
|
/**
|
|
@@ -483,7 +581,16 @@ export interface IFreezingStatus {
|
|
|
483
581
|
}
|
|
484
582
|
|
|
485
583
|
/** Information emitted on each playback observation. */
|
|
486
|
-
export interface IPlaybackObservation extends IMediaInfos {
|
|
584
|
+
export interface IPlaybackObservation extends Omit<IMediaInfos, "position" | "seeking"> {
|
|
585
|
+
/** Event that triggered this playback observation. */
|
|
586
|
+
event : IPlaybackObserverEventType;
|
|
587
|
+
/** Current seeking state. */
|
|
588
|
+
seeking : SeekingState;
|
|
589
|
+
/**
|
|
590
|
+
* Information on the current position being played, the position for which
|
|
591
|
+
* media is wanted etc.
|
|
592
|
+
*/
|
|
593
|
+
position : IObservationPosition;
|
|
487
594
|
/**
|
|
488
595
|
* Set if the player is short on audio and/or video media data and is a such,
|
|
489
596
|
* rebuffering.
|
|
@@ -498,11 +605,103 @@ export interface IPlaybackObservation extends IMediaInfos {
|
|
|
498
605
|
* `null` if the player is not frozen.
|
|
499
606
|
*/
|
|
500
607
|
freezing : IFreezingStatus | null;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export type IObservationPosition = ObservationPosition;
|
|
611
|
+
|
|
612
|
+
class ObservationPosition {
|
|
613
|
+
/**
|
|
614
|
+
* Known position at the time the Observation was emitted, in seconds.
|
|
615
|
+
*
|
|
616
|
+
* Note that it might have changed since. If you want truly precize
|
|
617
|
+
* information, you should recuperate it from the HTMLMediaElement directly
|
|
618
|
+
* through another mean.
|
|
619
|
+
*/
|
|
620
|
+
private _last: number;
|
|
621
|
+
/**
|
|
622
|
+
* Actually wanted position in seconds that is not yet reached.
|
|
623
|
+
*
|
|
624
|
+
* This might for example be set to the initial position when the content is
|
|
625
|
+
* loading (and thus potentially at a `0` position) but which will be seeked
|
|
626
|
+
* to a given position once possible. It may also be the position of a seek
|
|
627
|
+
* that has not been properly accounted for by the current device.
|
|
628
|
+
*/
|
|
629
|
+
private _wanted: number | null;
|
|
630
|
+
constructor(last: number, wanted: number | null) {
|
|
631
|
+
this._last = last;
|
|
632
|
+
this._wanted = wanted;
|
|
633
|
+
}
|
|
634
|
+
|
|
501
635
|
/**
|
|
502
|
-
*
|
|
503
|
-
*
|
|
636
|
+
* Returns the playback position actually observed on the media element at
|
|
637
|
+
* the time the playback observation was made.
|
|
638
|
+
*
|
|
639
|
+
* Note that it may be different than the position for which media data is
|
|
640
|
+
* wanted in rare scenarios where the goal position is not yet set on the
|
|
641
|
+
* media element.
|
|
642
|
+
*
|
|
643
|
+
* You should use this value when you want to obtain the actual position set
|
|
644
|
+
* on the media element for browser compatibility purposes. Note that this
|
|
645
|
+
* position was calculated at observation time, it might thus not be
|
|
646
|
+
* up-to-date if what you want is milliseconds-accuracy.
|
|
647
|
+
*
|
|
648
|
+
* If what you want is the actual position which the player is intended to
|
|
649
|
+
* play, you should rely on `getWanted` instead`.
|
|
650
|
+
* @returns {number}
|
|
504
651
|
*/
|
|
505
|
-
|
|
652
|
+
public getPolled(): number {
|
|
653
|
+
return this._last;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Returns the position which the player should consider to load media data
|
|
658
|
+
* at the time the observation was made.
|
|
659
|
+
*
|
|
660
|
+
* It can be different than the value returned by `getPolled` in rare
|
|
661
|
+
* scenarios:
|
|
662
|
+
*
|
|
663
|
+
* - When the initial position has not been set yet.
|
|
664
|
+
*
|
|
665
|
+
* - When the current device do not let the RxPlayer peform precize seeks,
|
|
666
|
+
* usually for perfomance reasons by seeking to a previous IDR frame
|
|
667
|
+
* instead (for now only Tizen may be like this), in which case we
|
|
668
|
+
* prefer to generally rely on the position wanted by the player (this
|
|
669
|
+
* e.g. prevents issues where the RxPlayer logic and the device are
|
|
670
|
+
* seeking back and forth in a loop).
|
|
671
|
+
*
|
|
672
|
+
* - When a wanted position has been "forced" (@see forceWantedPosition).
|
|
673
|
+
* @returns {number}
|
|
674
|
+
*/
|
|
675
|
+
public getWanted(): number {
|
|
676
|
+
return this._wanted ?? this._last;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Method to call if you want to overwrite the currently wanted position.
|
|
681
|
+
* @param {number} pos
|
|
682
|
+
*/
|
|
683
|
+
public forceWantedPosition(pos: number): void {
|
|
684
|
+
this._wanted = pos;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Returns `true` when the position wanted returned by `getWanted` and the
|
|
689
|
+
* actual position returned by `getPolled` may be different, meaning that
|
|
690
|
+
* we're currently not at the position we want to reach.
|
|
691
|
+
*
|
|
692
|
+
* This is a relatively rare situation which only happens when either the
|
|
693
|
+
* initial seek has not yet been performed. on specific targets where the
|
|
694
|
+
* seeking behavior is a little broken (@see getWanted) or when the wanted
|
|
695
|
+
* position has been forced (@see forceWantedPosition).
|
|
696
|
+
*
|
|
697
|
+
* In those situations, you might temporarily refrain from acting upon the
|
|
698
|
+
* actual current media position, as it may change soon.
|
|
699
|
+
*
|
|
700
|
+
* @returns {boolean}
|
|
701
|
+
*/
|
|
702
|
+
public isAwaitingFuturePosition(): boolean {
|
|
703
|
+
return this._wanted !== null;
|
|
704
|
+
}
|
|
506
705
|
}
|
|
507
706
|
|
|
508
707
|
/**
|
|
@@ -640,12 +839,10 @@ function hasLoadedUntilTheEnd(
|
|
|
640
839
|
/**
|
|
641
840
|
* Get basic playback information.
|
|
642
841
|
* @param {HTMLMediaElement} mediaElement
|
|
643
|
-
* @param {string} event
|
|
644
842
|
* @returns {Object}
|
|
645
843
|
*/
|
|
646
844
|
function getMediaInfos(
|
|
647
845
|
mediaElement : HTMLMediaElement,
|
|
648
|
-
event : IPlaybackObserverEventType,
|
|
649
846
|
withMediaSource : boolean
|
|
650
847
|
) : IMediaInfos {
|
|
651
848
|
const { buffered,
|
|
@@ -682,8 +879,7 @@ function getMediaInfos(
|
|
|
682
879
|
paused,
|
|
683
880
|
playbackRate,
|
|
684
881
|
readyState,
|
|
685
|
-
seeking
|
|
686
|
-
event };
|
|
882
|
+
seeking };
|
|
687
883
|
}
|
|
688
884
|
|
|
689
885
|
/**
|
|
@@ -695,18 +891,19 @@ function getMediaInfos(
|
|
|
695
891
|
* @param {Object} currentInfo - Current set of basic information on the
|
|
696
892
|
* `HTMLMediaElement`. This does not need every single property from a regular
|
|
697
893
|
* playback observation.
|
|
894
|
+
* @param {string} currentEvt
|
|
698
895
|
* @param {Object} options
|
|
699
896
|
* @returns {Object|null}
|
|
700
897
|
*/
|
|
701
898
|
function getRebufferingStatus(
|
|
702
899
|
prevObservation : IPlaybackObservation,
|
|
703
900
|
currentInfo : IMediaInfos,
|
|
901
|
+
currentEvt : IPlaybackObserverEventType,
|
|
704
902
|
{ withMediaSource, lowLatencyMode } : IPlaybackObserverOptions
|
|
705
903
|
) : IRebufferingStatus | null {
|
|
706
904
|
|
|
707
905
|
const { REBUFFERING_GAP } = config.getCurrent();
|
|
708
|
-
const {
|
|
709
|
-
position: currentTime,
|
|
906
|
+
const { position: currentTime,
|
|
710
907
|
bufferGap,
|
|
711
908
|
currentRange,
|
|
712
909
|
duration,
|
|
@@ -777,7 +974,7 @@ function getRebufferingStatus(
|
|
|
777
974
|
(
|
|
778
975
|
!paused &&
|
|
779
976
|
currentEvt === "timeupdate" && prevEvt === "timeupdate" &&
|
|
780
|
-
currentTime === prevTime
|
|
977
|
+
currentTime === prevTime.getPolled()
|
|
781
978
|
) ||
|
|
782
979
|
(
|
|
783
980
|
currentEvt === "seeking" && (
|
|
@@ -790,7 +987,7 @@ function getRebufferingStatus(
|
|
|
790
987
|
} else if (
|
|
791
988
|
prevRebuffering !== null &&
|
|
792
989
|
(
|
|
793
|
-
(currentEvt !== "seeking" && currentTime !== prevTime) ||
|
|
990
|
+
(currentEvt !== "seeking" && currentTime !== prevTime.getPolled()) ||
|
|
794
991
|
currentEvt === "canplay" ||
|
|
795
992
|
(bufferGap === undefined && readyState >= 3) ||
|
|
796
993
|
(
|
|
@@ -840,11 +1037,13 @@ function getRebufferingStatus(
|
|
|
840
1037
|
* `null` if not.
|
|
841
1038
|
* @param {Object} prevObservation
|
|
842
1039
|
* @param {Object} currentInfo
|
|
1040
|
+
* @param {string} currentEvt
|
|
843
1041
|
* @returns {Object|null}
|
|
844
1042
|
*/
|
|
845
1043
|
function getFreezingStatus(
|
|
846
1044
|
prevObservation : IPlaybackObservation,
|
|
847
|
-
currentInfo : IMediaInfos
|
|
1045
|
+
currentInfo : IMediaInfos,
|
|
1046
|
+
currentEvt : IPlaybackObserverEventType
|
|
848
1047
|
) : IFreezingStatus | null {
|
|
849
1048
|
const { MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING } = config.getCurrent();
|
|
850
1049
|
if (prevObservation.freezing) {
|
|
@@ -852,21 +1051,21 @@ function getFreezingStatus(
|
|
|
852
1051
|
currentInfo.paused ||
|
|
853
1052
|
currentInfo.readyState === 0 ||
|
|
854
1053
|
currentInfo.playbackRate === 0 ||
|
|
855
|
-
prevObservation.position !== currentInfo.position)
|
|
1054
|
+
prevObservation.position.getPolled() !== currentInfo.position)
|
|
856
1055
|
{
|
|
857
1056
|
return null; // Quit freezing status
|
|
858
1057
|
}
|
|
859
1058
|
return prevObservation.freezing; // Stay in it
|
|
860
1059
|
}
|
|
861
1060
|
|
|
862
|
-
return
|
|
1061
|
+
return currentEvt === "timeupdate" &&
|
|
863
1062
|
currentInfo.bufferGap !== undefined &&
|
|
864
1063
|
currentInfo.bufferGap > MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING &&
|
|
865
1064
|
!currentInfo.ended &&
|
|
866
1065
|
!currentInfo.paused &&
|
|
867
1066
|
currentInfo.readyState >= 1 &&
|
|
868
1067
|
currentInfo.playbackRate !== 0 &&
|
|
869
|
-
currentInfo.position === prevObservation.position ?
|
|
1068
|
+
currentInfo.position === prevObservation.position.getPolled() ?
|
|
870
1069
|
{ timestamp: getMonotonicTimeStamp() } :
|
|
871
1070
|
null;
|
|
872
1071
|
}
|
|
@@ -999,3 +1198,24 @@ function generateReadOnlyObserver<TSource, TDest>(
|
|
|
999
1198
|
},
|
|
1000
1199
|
};
|
|
1001
1200
|
}
|
|
1201
|
+
|
|
1202
|
+
/**
|
|
1203
|
+
* Generate the initial playback observation for when no event has yet been
|
|
1204
|
+
* emitted to lead to one.
|
|
1205
|
+
* @param {HTMLMediaElement} mediaElement
|
|
1206
|
+
* @param {boolean} withMediaSource
|
|
1207
|
+
* @returns {Object}
|
|
1208
|
+
*/
|
|
1209
|
+
function getInitialObservation(
|
|
1210
|
+
mediaElement: HTMLMediaElement,
|
|
1211
|
+
withMediaSource: boolean
|
|
1212
|
+
) : IPlaybackObservation {
|
|
1213
|
+
const mediaTimings = getMediaInfos(mediaElement, withMediaSource);
|
|
1214
|
+
return objectAssign(mediaTimings,
|
|
1215
|
+
{ rebuffering: null,
|
|
1216
|
+
event: "init",
|
|
1217
|
+
seeking: SeekingState.None,
|
|
1218
|
+
position: { last: mediaTimings.position,
|
|
1219
|
+
pending: undefined },
|
|
1220
|
+
freezing: null });
|
|
1221
|
+
}
|