shaka-player 3.2.3 → 3.2.6
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/.csslintrc +11 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/workflows/build-and-test.yaml +130 -0
- package/.github/workflows/custom-actions/prep-for-appspot/action.yaml +56 -0
- package/.github/workflows/custom-actions/set-commit-status/action.yaml +41 -0
- package/.github/workflows/demo-version-index.yaml +29 -0
- package/.github/workflows/nightly-demo.yaml +42 -0
- package/.github/workflows/release-please.yaml +147 -0
- package/.github/workflows/safari-homedir-launcher.sh +18 -0
- package/.github/workflows/selenium-lab-tests.yaml +93 -0
- package/AUTHORS +2 -0
- package/CHANGELOG.md +1587 -1551
- package/CONTRIBUTING.md +2 -2
- package/CONTRIBUTORS +2 -0
- package/README.md +7 -7
- package/app-engine/README.md +9 -0
- package/app-engine/demo-version-index/README.md +14 -0
- package/app-engine/demo-version-index/app.yaml +2 -0
- package/app-engine/demo-version-index/main.py +162 -0
- package/app-engine/demo-version-index/requirements.txt +6 -0
- package/app-engine/demo-version-index/templates/index.html +114 -0
- package/app-engine/shaka-player-demo/README.md +18 -0
- package/app-engine/shaka-player-demo/app.yaml +61 -0
- package/app-engine/shaka-player-demo/main.py +95 -0
- package/app-engine/shaka-player-demo/posters/10yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/10yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/1yo.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/audioOnly.gif +0 -0
- package/app-engine/shaka-player-demo/posters/audioRickRoll.gif +0 -0
- package/app-engine/shaka-player-demo/posters/colorbars.gif +0 -0
- package/app-engine/shaka-player-demo/posters/fireworks.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/party-hat.png +0 -0
- package/app-engine/shaka-player-demo/posters/sources.txt +46 -0
- package/app-engine/shaka-player-demo/posters/standard.png +0 -0
- package/app-engine/shaka-player-demo/posters/trek.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/valentines.png +0 -0
- package/app-engine/shaka-player-demo/posters/zombie.jpg +0 -0
- package/app-engine/shaka-player-demo/posters.py +110 -0
- package/app-engine/shaka-player-demo/requirements.txt +5 -0
- package/app-engine/shaka-player-demo/time.txt +1 -0
- package/build/README.md +1 -1
- package/build/checkversion.py +1 -1
- package/build/conformance.textproto +13 -0
- package/build/docker/Dockerfile +20 -0
- package/build/docker/docker-compose.yml +10 -0
- package/build/gendeps.py +18 -15
- package/build/generateTsDefs.py +2 -0
- package/build/shaka-lab.yaml +163 -0
- package/build/shakaBuildHelpers.py +4 -29
- package/build/test.py +93 -28
- package/build/wrapper.template.js +2 -2
- package/demo/TengwarTelcontar.woff2 +0 -0
- package/demo/asset_card.js +1 -2
- package/demo/cast_receiver/index.html +1 -1
- package/demo/cast_receiver/receiver_app.css +14 -14
- package/demo/common/assets.js +2 -0
- package/demo/config.js +0 -1
- package/demo/custom.js +0 -1
- package/demo/customWarning.txt +2 -2
- package/demo/demo.less +29 -18
- package/demo/demo_uncompiled.js +1 -13
- package/demo/index.html +1 -1
- package/demo/main.js +3 -3
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +191 -194
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +191 -194
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +225 -219
- package/dist/locales.js +27 -27
- package/dist/receiver.compiled.debug.js +43 -45
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +43 -45
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +228 -225
- package/dist/shaka-player.compiled.debug.d.ts +228 -225
- package/dist/shaka-player.compiled.debug.externs.js +21 -15
- package/dist/shaka-player.compiled.debug.js +326 -333
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +21 -15
- package/dist/shaka-player.compiled.js +818 -821
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +272 -278
- package/dist/shaka-player.ui.debug.d.ts +272 -278
- package/dist/shaka-player.ui.debug.externs.js +23 -26
- package/dist/shaka-player.ui.debug.js +259 -267
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +23 -26
- package/dist/shaka-player.ui.js +963 -968
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/REDESIGN.md +33 -33
- package/docs/design/codec_preferences.md +1 -1
- package/docs/design/dash-audio-channels.md +3 -3
- package/docs/design/dash-manifests.md +1 -1
- package/docs/design/gap-jumping.md +3 -3
- package/docs/design/preload.md +2 -2
- package/docs/tutorials/faq.md +8 -8
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/plugins.md +3 -3
- package/docs/tutorials/selenium-grid-config.md +122 -0
- package/docs/tutorials/welcome.md +10 -2
- package/karma.conf.js +156 -45
- package/lib/abr/simple_abr_manager.js +12 -6
- package/lib/ads/ad_manager.js +1 -0
- package/lib/cast/cast_proxy.js +6 -4
- package/lib/cast/cast_receiver.js +3 -0
- package/lib/cea/cea608_data_channel.js +2 -2
- package/lib/cea/cea708_service.js +5 -4
- package/lib/cea/mp4_cea_parser.js +11 -5
- package/lib/cea/sei_processor.js +6 -3
- package/lib/dash/dash_parser.js +40 -30
- package/lib/dash/mpd_utils.js +4 -5
- package/lib/dash/segment_list.js +1 -2
- package/lib/dash/segment_template.js +3 -3
- package/lib/hls/hls_parser.js +11 -9
- package/lib/hls/manifest_text_parser.js +4 -3
- package/lib/media/adaptation_set.js +1 -2
- package/lib/media/content_workarounds.js +2 -2
- package/lib/media/drm_engine.js +3 -2
- package/lib/media/media_source_engine.js +3 -2
- package/lib/media/mp4_segment_index_parser.js +1 -4
- package/lib/media/playhead.js +2 -2
- package/lib/media/presentation_timeline.js +18 -8
- package/lib/media/region_observer.js +39 -33
- package/lib/media/region_timeline.js +17 -19
- package/lib/media/streaming_engine.js +7 -7
- package/lib/media/time_ranges_utils.js +1 -3
- package/lib/media/video_wrapper.js +1 -1
- package/lib/net/networking_engine.js +5 -1
- package/lib/offline/storage.js +12 -13
- package/lib/player.js +58 -24
- package/lib/polyfill/all.js +2 -3
- package/lib/polyfill/encryption_scheme.js +1 -1
- package/lib/polyfill/media_capabilities.js +3 -3
- package/lib/polyfill/mediasource.js +1 -1
- package/lib/text/cue.js +1 -1
- package/lib/text/simple_text_displayer.js +2 -1
- package/lib/text/ttml_text_parser.js +8 -5
- package/lib/text/ui_text_displayer.js +1 -1
- package/lib/util/buffer_utils.js +1 -3
- package/lib/util/ebml_parser.js +3 -3
- package/lib/util/error.js +1 -1
- package/lib/util/fake_event_target.js +21 -1
- package/lib/util/iterables.js +0 -46
- package/lib/util/mp4_box_parsers.js +1 -4
- package/lib/util/mp4_parser.js +5 -7
- package/lib/util/periods.js +8 -9
- package/lib/util/platform.js +3 -3
- package/lib/util/pssh.js +1 -4
- package/lib/util/stream_utils.js +4 -3
- package/lib/util/string_utils.js +3 -5
- package/lib/util/uint8array_utils.js +3 -5
- package/lib/util/xml_utils.js +15 -7
- package/package.json +62 -40
- package/roadmap.md +17 -17
- package/test/abr/simple_abr_manager_unit.js +3 -8
- package/test/ads/ad_manager_unit.js +0 -6
- package/test/cast/cast_proxy_unit.js +0 -8
- package/test/cast/cast_receiver_integration.js +1 -18
- package/test/cast/cast_receiver_unit.js +1 -9
- package/test/cast/cast_sender_unit.js +0 -6
- package/test/cast/cast_utils_unit.js +0 -13
- package/test/cea/cea608_memory_unit.js +0 -5
- package/test/cea/cea708_service_unit.js +0 -7
- package/test/cea/cea708_window_unit.js +0 -5
- package/test/cea/cea_decoder_unit.js +0 -6
- package/test/cea/dtvcc_packet_builder_unit.js +0 -3
- package/test/cea/dtvcc_packet_unit.js +0 -5
- package/test/cea/mp4_cea_parser_unit.js +0 -4
- package/test/dash/dash_parser_content_protection_unit.js +1 -10
- package/test/dash/dash_parser_live_unit.js +45 -15
- package/test/dash/dash_parser_manifest_unit.js +4 -17
- package/test/dash/dash_parser_segment_base_unit.js +1 -8
- package/test/dash/dash_parser_segment_list_unit.js +1 -7
- package/test/dash/dash_parser_segment_template_unit.js +0 -9
- package/test/dash/mpd_utils_unit.js +3 -11
- package/test/demo/demo_unit.js +0 -5
- package/test/deprecate/enforcer_unit.js +0 -4
- package/test/deprecate/version_unit.js +0 -2
- package/test/hls/hls_live_unit.js +2 -14
- package/test/hls/hls_parser_unit.js +76 -15
- package/test/hls/manifest_text_parser_unit.js +0 -10
- package/test/media/adaptation_set_criteria_unit.js +3 -7
- package/test/media/adaptation_set_unit.js +0 -2
- package/test/media/buffering_observer_unit.js +1 -4
- package/test/media/closed_caption_parser_unit.js +0 -3
- package/test/media/drm_engine_integration.js +2 -15
- package/test/media/drm_engine_unit.js +4 -24
- package/test/media/manifest_parser_unit.js +0 -4
- package/test/media/media_source_engine_integration.js +0 -7
- package/test/media/media_source_engine_unit.js +1 -14
- package/test/media/mp4_segment_index_parser_unit.js +0 -4
- package/test/media/play_rate_controller_unit.js +0 -4
- package/test/media/playhead_unit.js +8 -16
- package/test/media/presentation_timeline_unit.js +4 -7
- package/test/media/region_observer_unit.js +40 -10
- package/test/media/region_timeline_unit.js +40 -25
- package/test/media/segment_index_unit.js +0 -6
- package/test/media/segment_reference_unit.js +0 -3
- package/test/media/stall_detector_unit.js +0 -5
- package/test/media/streaming_engine_integration.js +9 -36
- package/test/media/streaming_engine_unit.js +11 -35
- package/test/media/time_ranges_utils_unit.js +0 -2
- package/test/media/transmuxer_integration.js +0 -6
- package/test/media/webm_segment_index_parser_unit.js +0 -4
- package/test/net/data_uri_plugin_unit.js +0 -7
- package/test/net/http_plugin_unit.js +0 -9
- package/test/net/networking_engine_unit.js +0 -11
- package/test/offline/download_progress_estimator_unit.js +0 -2
- package/test/offline/indexeddb_storage_unit.js +0 -6
- package/test/offline/manifest_convert_unit.js +0 -8
- package/test/offline/offline_integration.js +1 -10
- package/test/offline/offline_manifest_parser_unit.js +0 -6
- package/test/offline/offline_scheme_unit.js +0 -8
- package/test/offline/offline_uri_unit.js +0 -2
- package/test/offline/storage_compatibility_unit.js +1 -14
- package/test/offline/storage_integration.js +1 -25
- package/test/player_external.js +2 -10
- package/test/player_integration.js +21 -28
- package/test/player_load_graph_integration.js +1 -6
- package/test/player_src_equals_external.js +3 -9
- package/test/player_src_equals_integration.js +0 -7
- package/test/player_unit.js +52 -37
- package/test/routing/walker_unit.js +0 -8
- package/test/test/assets/large_file.mpd +1 -1
- package/test/test/boot.js +75 -22
- package/test/test/externs/jasmine.js +2 -2
- package/test/test/externs/karma.js +4 -0
- package/test/test/namespace.js +10 -0
- package/test/test/util/canned_idb.js +0 -8
- package/test/test/util/cea_utils.js +0 -6
- package/test/test/util/dash_parser_util.js +0 -13
- package/test/test/util/fake_ad.js +0 -3
- package/test/test/util/fake_ad_manager.js +0 -9
- package/test/test/util/fake_demo_main.js +0 -5
- package/test/test/util/fake_drm_engine.js +0 -6
- package/test/test/util/fake_media_source_engine.js +0 -7
- package/test/test/util/fake_networking_engine.js +0 -5
- package/test/test/util/fake_text_displayer.js +0 -5
- package/test/test/util/indexeddb_utils.js +1 -10
- package/test/test/util/jasmine_fetch.js +0 -1
- package/test/test/util/loader.js +0 -18
- package/test/test/util/manifest_generator.js +9 -14
- package/test/test/util/manifest_parser_util.js +0 -6
- package/test/test/util/offline_utils.js +0 -5
- package/test/test/util/simple_fakes.js +9 -26
- package/test/test/util/stream_generator.js +0 -14
- package/test/test/util/streaming_engine_util.js +0 -15
- package/test/test/util/test_scheme.js +1 -19
- package/test/test/util/ttml_utils.js +0 -2
- package/test/test/util/ui_utils.js +0 -9
- package/test/test/util/util.js +15 -26
- package/test/test/util/waiter.js +84 -43
- package/test/text/cue_integration.js +0 -4
- package/test/text/lrc_text_parser_unit.js +0 -4
- package/test/text/mp4_ttml_parser_unit.js +0 -6
- package/test/text/mp4_vtt_parser_unit.js +1 -7
- package/test/text/sbv_text_parser_unit.js +0 -4
- package/test/text/simple_text_displayer_unit.js +1 -8
- package/test/text/srt_text_parser_unit.js +0 -4
- package/test/text/ssa_text_parser_unit.js +0 -5
- package/test/text/text_engine_unit.js +2 -7
- package/test/text/text_track_integration.js +0 -2
- package/test/text/ttml_text_parser_unit.js +2 -11
- package/test/text/ui_text_displayer_unit.js +44 -41
- package/test/text/vtt_text_parser_unit.js +0 -9
- package/test/text/web_vtt_generator_unit.js +0 -3
- package/test/ui/ad_ui_unit.js +0 -11
- package/test/ui/localization_unit.js +0 -3
- package/test/ui/text_displayer_layout_unit.js +9 -19
- package/test/ui/ui_customization_unit.js +0 -6
- package/test/ui/ui_integration.js +0 -16
- package/test/ui/ui_unit.js +1 -17
- package/test/util/abortable_operation_unit.js +4 -9
- package/test/util/array_utils_unit.js +0 -2
- package/test/util/buffer_utils_unit.js +0 -2
- package/test/util/data_view_reader_unit.js +0 -4
- package/test/util/ebml_parser_unit.js +0 -4
- package/test/util/event_manager_unit.js +0 -3
- package/test/util/fake_event_target_unit.js +0 -5
- package/test/util/functional_unit.js +1 -1
- package/test/util/iterables_unit.js +0 -64
- package/test/util/language_utils_unit.js +0 -3
- package/test/util/manifest_parser_utils_unit.js +0 -2
- package/test/util/mp4_box_parsers_unit.js +0 -5
- package/test/util/mp4_parser_unit.js +0 -4
- package/test/util/multi_map_unit.js +0 -3
- package/test/util/object_utils_unit.js +0 -2
- package/test/util/periods_unit.js +14 -7
- package/test/util/pssh_unit.js +0 -5
- package/test/util/state_history_unit.js +0 -2
- package/test/util/stream_utils_unit.js +3 -8
- package/test/util/string_utils_unit.js +0 -6
- package/test/util/text_parser_unit.js +0 -2
- package/test/util/xml_utils_unit.js +0 -4
- package/ui/controls.js +3 -0
- package/ui/less/ad_controls.less +6 -6
- package/ui/less/buttons.less +6 -6
- package/ui/less/containers.less +9 -11
- package/ui/less/overflow_menu.less +4 -4
- package/ui/less/range_elements.less +7 -2
- package/ui/locales/sjn-translations.yaml +257 -0
- package/ui/locales/sjn.json +42 -0
- package/ui/localization.js +12 -36
- package/ui/seek_bar.js +2 -1
- package/externs/svgelement.js +0 -18
package/lib/dash/dash_parser.js
CHANGED
|
@@ -21,7 +21,6 @@ goog.require('shaka.net.NetworkingEngine');
|
|
|
21
21
|
goog.require('shaka.text.TextEngine');
|
|
22
22
|
goog.require('shaka.util.Error');
|
|
23
23
|
goog.require('shaka.util.Functional');
|
|
24
|
-
goog.require('shaka.util.Iterables');
|
|
25
24
|
goog.require('shaka.util.LanguageUtils');
|
|
26
25
|
goog.require('shaka.util.ManifestParserUtils');
|
|
27
26
|
goog.require('shaka.util.MimeUtils');
|
|
@@ -103,7 +102,7 @@ shaka.dash.DashParser = class {
|
|
|
103
102
|
|
|
104
103
|
/**
|
|
105
104
|
* Period IDs seen in previous manifest.
|
|
106
|
-
* @private {!Array.<
|
|
105
|
+
* @private {!Array.<string>}
|
|
107
106
|
*/
|
|
108
107
|
this.lastManifestUpdatePeriodIds_ = [];
|
|
109
108
|
|
|
@@ -377,7 +376,7 @@ shaka.dash.DashParser = class {
|
|
|
377
376
|
// This gives us confidence that our state is maintained correctly, and
|
|
378
377
|
// that the complex logic of multi-Period eviction and period-flattening
|
|
379
378
|
// is correct. See also:
|
|
380
|
-
// https://github.com/
|
|
379
|
+
// https://github.com/shaka-project/shaka-player/issues/3169#issuecomment-823580634
|
|
381
380
|
for (const segmentIndex of Object.values(this.segmentIndexMap_)) {
|
|
382
381
|
segmentIndex.evict(presentationTimeline.getSegmentAvailabilityStart());
|
|
383
382
|
}
|
|
@@ -401,6 +400,24 @@ shaka.dash.DashParser = class {
|
|
|
401
400
|
this.config_.dash.autoCorrectDrift);
|
|
402
401
|
}
|
|
403
402
|
|
|
403
|
+
presentationTimeline.setStatic(mpdType == 'static');
|
|
404
|
+
|
|
405
|
+
const isLive = presentationTimeline.isLive();
|
|
406
|
+
|
|
407
|
+
// If it's live, we check for an override.
|
|
408
|
+
if (isLive && !isNaN(this.config_.availabilityWindowOverride)) {
|
|
409
|
+
segmentAvailabilityDuration = this.config_.availabilityWindowOverride;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// If it's null, that means segments are always available. This is always
|
|
413
|
+
// the case for VOD, and sometimes the case for live.
|
|
414
|
+
if (segmentAvailabilityDuration == null) {
|
|
415
|
+
segmentAvailabilityDuration = Infinity;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
presentationTimeline.setSegmentAvailabilityDuration(
|
|
419
|
+
segmentAvailabilityDuration);
|
|
420
|
+
|
|
404
421
|
const profiles = mpd.getAttribute('profiles') || '';
|
|
405
422
|
|
|
406
423
|
/** @type {shaka.dash.DashParser.Context} */
|
|
@@ -423,7 +440,6 @@ shaka.dash.DashParser = class {
|
|
|
423
440
|
const duration = periodsAndDuration.duration;
|
|
424
441
|
const periods = periodsAndDuration.periods;
|
|
425
442
|
|
|
426
|
-
presentationTimeline.setStatic(mpdType == 'static');
|
|
427
443
|
if (mpdType == 'static' ||
|
|
428
444
|
!periodsAndDuration.durationDerivedFromPeriods) {
|
|
429
445
|
// Ignore duration calculated from Period lengths if this is dynamic.
|
|
@@ -442,6 +458,7 @@ shaka.dash.DashParser = class {
|
|
|
442
458
|
this.lowLatencyMode_ = this.playerInterface_.isLowLatencyMode();
|
|
443
459
|
}
|
|
444
460
|
}
|
|
461
|
+
|
|
445
462
|
if (this.lowLatencyMode_) {
|
|
446
463
|
presentationTimeline.setAvailabilityTimeOffset(
|
|
447
464
|
this.minTotalAvailabilityTimeOffset_);
|
|
@@ -455,22 +472,6 @@ shaka.dash.DashParser = class {
|
|
|
455
472
|
'https://bit.ly/3clctcj for details.');
|
|
456
473
|
}
|
|
457
474
|
|
|
458
|
-
const isLive = presentationTimeline.isLive();
|
|
459
|
-
|
|
460
|
-
// If it's live, we check for an override.
|
|
461
|
-
if (isLive && !isNaN(this.config_.availabilityWindowOverride)) {
|
|
462
|
-
segmentAvailabilityDuration = this.config_.availabilityWindowOverride;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// If it's null, that means segments are always available. This is always
|
|
466
|
-
// the case for VOD, and sometimes the case for live.
|
|
467
|
-
if (segmentAvailabilityDuration == null) {
|
|
468
|
-
segmentAvailabilityDuration = Infinity;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
presentationTimeline.setSegmentAvailabilityDuration(
|
|
472
|
-
segmentAvailabilityDuration);
|
|
473
|
-
|
|
474
475
|
// Use @maxSegmentDuration to override smaller, derived values.
|
|
475
476
|
presentationTimeline.notifyMaxSegmentDuration(maxSegmentDuration || 1);
|
|
476
477
|
if (goog.DEBUG) {
|
|
@@ -544,10 +545,9 @@ shaka.dash.DashParser = class {
|
|
|
544
545
|
const periods = [];
|
|
545
546
|
let prevEnd = 0;
|
|
546
547
|
const periodNodes = XmlUtils.findChildren(mpd, 'Period');
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
for (const {i, item: elem, next} of enumerate(periodNodes)) {
|
|
548
|
+
for (let i = 0; i < periodNodes.length; i++) {
|
|
549
|
+
const elem = periodNodes[i];
|
|
550
|
+
const next = periodNodes[i + 1];
|
|
551
551
|
const start = /** @type {number} */ (
|
|
552
552
|
XmlUtils.parseAttr(elem, 'start', XmlUtils.parseDuration, prevEnd));
|
|
553
553
|
const periodId = elem.id;
|
|
@@ -705,8 +705,12 @@ shaka.dash.DashParser = class {
|
|
|
705
705
|
|
|
706
706
|
const eventStreamNodes =
|
|
707
707
|
XmlUtils.findChildren(periodInfo.node, 'EventStream');
|
|
708
|
+
const availabilityStart =
|
|
709
|
+
context.presentationTimeline.getSegmentAvailabilityStart();
|
|
710
|
+
|
|
708
711
|
for (const node of eventStreamNodes) {
|
|
709
|
-
this.parseEventStream_(
|
|
712
|
+
this.parseEventStream_(
|
|
713
|
+
periodInfo.start, periodInfo.duration, node, availabilityStart);
|
|
710
714
|
}
|
|
711
715
|
|
|
712
716
|
const adaptationSetNodes =
|
|
@@ -749,7 +753,7 @@ shaka.dash.DashParser = class {
|
|
|
749
753
|
for (const stream of normalSet.streams) {
|
|
750
754
|
// There may be multiple trick mode streams, but we do not
|
|
751
755
|
// currently support that. Just choose one.
|
|
752
|
-
// TODO: https://github.com/
|
|
756
|
+
// TODO: https://github.com/shaka-project/shaka-player/issues/1528
|
|
753
757
|
stream.trickModeVideo = trickModeSet.streams.find((trickStream) =>
|
|
754
758
|
shaka.util.MimeUtils.getCodecBase(stream.codecs) ==
|
|
755
759
|
shaka.util.MimeUtils.getCodecBase(trickStream.codecs));
|
|
@@ -1142,7 +1146,7 @@ shaka.dash.DashParser = class {
|
|
|
1142
1146
|
// does not make sense in the DASH spec's bandwidth formulas.
|
|
1143
1147
|
// In some content, however, the attribute is missing or zero.
|
|
1144
1148
|
// To avoid NaN at the variant level on broken content, fall back to zero.
|
|
1145
|
-
// https://github.com/
|
|
1149
|
+
// https://github.com/shaka-project/shaka-player/issues/938#issuecomment-317278180
|
|
1146
1150
|
context.bandwidth =
|
|
1147
1151
|
XmlUtils.parseAttr(node, 'bandwidth', XmlUtils.parsePositiveInt) || 0;
|
|
1148
1152
|
|
|
@@ -1220,7 +1224,7 @@ shaka.dash.DashParser = class {
|
|
|
1220
1224
|
|
|
1221
1225
|
let forced = false;
|
|
1222
1226
|
if (isText) {
|
|
1223
|
-
// See: https://github.com/
|
|
1227
|
+
// See: https://github.com/shaka-project/shaka-player/issues/2122 and
|
|
1224
1228
|
// https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/165
|
|
1225
1229
|
forced = roles.includes('forced_subtitle') ||
|
|
1226
1230
|
roles.includes('forced-subtitle');
|
|
@@ -1346,7 +1350,7 @@ shaka.dash.DashParser = class {
|
|
|
1346
1350
|
// NOTE: An updatePeriod_ of -1 means the attribute was missing.
|
|
1347
1351
|
// An attribute which is present and set to 0 should still result in
|
|
1348
1352
|
// periodic updates. For more, see:
|
|
1349
|
-
// https://github.com/
|
|
1353
|
+
// https://github.com/shaka-project/shaka-player/issues/331
|
|
1350
1354
|
if (this.updatePeriod_ < 0) {
|
|
1351
1355
|
return;
|
|
1352
1356
|
}
|
|
@@ -1737,9 +1741,10 @@ shaka.dash.DashParser = class {
|
|
|
1737
1741
|
* @param {number} periodStart
|
|
1738
1742
|
* @param {?number} periodDuration
|
|
1739
1743
|
* @param {!Element} elem
|
|
1744
|
+
* @param {number} availabilityStart
|
|
1740
1745
|
* @private
|
|
1741
1746
|
*/
|
|
1742
|
-
parseEventStream_(periodStart, periodDuration, elem) {
|
|
1747
|
+
parseEventStream_(periodStart, periodDuration, elem, availabilityStart) {
|
|
1743
1748
|
const XmlUtils = shaka.util.XmlUtils;
|
|
1744
1749
|
const parseNumber = XmlUtils.parseNonNegativeInt;
|
|
1745
1750
|
|
|
@@ -1762,6 +1767,11 @@ shaka.dash.DashParser = class {
|
|
|
1762
1767
|
endTime = Math.min(endTime, periodStart + periodDuration);
|
|
1763
1768
|
}
|
|
1764
1769
|
|
|
1770
|
+
// Don't add unavailable regions to the timeline.
|
|
1771
|
+
if (endTime < availabilityStart) {
|
|
1772
|
+
continue;
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1765
1775
|
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
1766
1776
|
const region = {
|
|
1767
1777
|
schemeIdUri: schemeIdUri,
|
package/lib/dash/mpd_utils.js
CHANGED
|
@@ -12,7 +12,6 @@ goog.require('shaka.net.NetworkingEngine');
|
|
|
12
12
|
goog.require('shaka.util.AbortableOperation');
|
|
13
13
|
goog.require('shaka.util.Error');
|
|
14
14
|
goog.require('shaka.util.Functional');
|
|
15
|
-
goog.require('shaka.util.Iterables');
|
|
16
15
|
goog.require('shaka.util.ManifestParserUtils');
|
|
17
16
|
goog.require('shaka.util.XmlUtils');
|
|
18
17
|
goog.requireType('shaka.dash.DashParser');
|
|
@@ -142,8 +141,9 @@ shaka.dash.MpdUtils = class {
|
|
|
142
141
|
const timeline = [];
|
|
143
142
|
let lastEndTime = -unscaledPresentationTimeOffset;
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
for (let i = 0; i < timePoints.length; ++i) {
|
|
145
|
+
const timePoint = timePoints[i];
|
|
146
|
+
const next = timePoints[i + 1];
|
|
147
147
|
let t = XmlUtils.parseAttr(timePoint, 't', XmlUtils.parseNonNegativeInt);
|
|
148
148
|
const d =
|
|
149
149
|
XmlUtils.parseAttr(timePoint, 'd', XmlUtils.parseNonNegativeInt);
|
|
@@ -225,8 +225,7 @@ shaka.dash.MpdUtils = class {
|
|
|
225
225
|
timeline[timeline.length - 1].end = startTime / timescale;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
for (
|
|
229
|
-
shaka.util.Functional.ignored(_);
|
|
228
|
+
for (let j = 0; j <= repeat; ++j) {
|
|
230
229
|
const endTime = startTime + d;
|
|
231
230
|
const item = {
|
|
232
231
|
start: startTime / timescale,
|
package/lib/dash/segment_list.js
CHANGED
|
@@ -15,7 +15,6 @@ goog.require('shaka.media.SegmentIndex');
|
|
|
15
15
|
goog.require('shaka.media.SegmentReference');
|
|
16
16
|
goog.require('shaka.util.Error');
|
|
17
17
|
goog.require('shaka.util.Functional');
|
|
18
|
-
goog.require('shaka.util.Iterables');
|
|
19
18
|
goog.require('shaka.util.ManifestParserUtils');
|
|
20
19
|
goog.require('shaka.util.XmlUtils');
|
|
21
20
|
goog.requireType('shaka.dash.DashParser');
|
|
@@ -213,7 +212,7 @@ shaka.dash.SegmentList = class {
|
|
|
213
212
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
214
213
|
const references = [];
|
|
215
214
|
let prevEndTime = info.startTime;
|
|
216
|
-
for (
|
|
215
|
+
for (let i = 0; i < max; i++) {
|
|
217
216
|
const segment = info.mediaSegments[i];
|
|
218
217
|
const mediaUri = ManifestParserUtils.resolveUris(
|
|
219
218
|
baseUris, [segment.mediaUri]);
|
|
@@ -14,7 +14,6 @@ goog.require('shaka.media.InitSegmentReference');
|
|
|
14
14
|
goog.require('shaka.media.SegmentIndex');
|
|
15
15
|
goog.require('shaka.media.SegmentReference');
|
|
16
16
|
goog.require('shaka.util.Error');
|
|
17
|
-
goog.require('shaka.util.Iterables');
|
|
18
17
|
goog.require('shaka.util.ManifestParserUtils');
|
|
19
18
|
goog.require('shaka.util.ObjectUtils');
|
|
20
19
|
goog.requireType('shaka.dash.DashParser');
|
|
@@ -491,8 +490,9 @@ shaka.dash.SegmentTemplate = class {
|
|
|
491
490
|
|
|
492
491
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
493
492
|
const references = [];
|
|
494
|
-
|
|
495
|
-
|
|
493
|
+
for (let i = 0; i < info.timeline.length; i++) {
|
|
494
|
+
const {start, unscaledStart, end} = info.timeline[i];
|
|
495
|
+
|
|
496
496
|
// Note: i = k - 1, where k indicates the k'th segment listed in the MPD.
|
|
497
497
|
// (See section 5.3.9.5.3 of the DASH spec.)
|
|
498
498
|
const segmentReplacement = i + info.startNumber;
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -29,7 +29,6 @@ goog.require('shaka.util.DataViewReader');
|
|
|
29
29
|
goog.require('shaka.util.Error');
|
|
30
30
|
goog.require('shaka.util.FakeEvent');
|
|
31
31
|
goog.require('shaka.util.Functional');
|
|
32
|
-
goog.require('shaka.util.Iterables');
|
|
33
32
|
goog.require('shaka.util.LanguageUtils');
|
|
34
33
|
goog.require('shaka.util.ManifestParserUtils');
|
|
35
34
|
goog.require('shaka.util.MimeUtils');
|
|
@@ -918,7 +917,7 @@ shaka.hls.HlsParser = class {
|
|
|
918
917
|
// the content. This means that if the content changes profiles, it should
|
|
919
918
|
// include both. Since all known browsers support changing profiles
|
|
920
919
|
// without any other work, just ignore them. See also:
|
|
921
|
-
// https://github.com/
|
|
920
|
+
// https://github.com/shaka-project/shaka-player/issues/1817
|
|
922
921
|
const shortCodec = shaka.util.MimeUtils.getCodecBase(codec);
|
|
923
922
|
if (!seen.has(shortCodec)) {
|
|
924
923
|
ret.push(codec);
|
|
@@ -1757,8 +1756,8 @@ shaka.hls.HlsParser = class {
|
|
|
1757
1756
|
// Create SegmentReferences for the partial segments.
|
|
1758
1757
|
const partialSegmentRefs = [];
|
|
1759
1758
|
if (this.lowLatencyMode_ && hlsSegment.partialSegments.length) {
|
|
1760
|
-
|
|
1761
|
-
|
|
1759
|
+
for (let i = 0; i < hlsSegment.partialSegments.length; i++) {
|
|
1760
|
+
const item = hlsSegment.partialSegments[i];
|
|
1762
1761
|
const pPreviousReference = i == 0 ?
|
|
1763
1762
|
previousReference : partialSegmentRefs[partialSegmentRefs.length - 1];
|
|
1764
1763
|
const pStartTime = (i == 0) ? startTime : pPreviousReference.endTime;
|
|
@@ -1779,6 +1778,9 @@ shaka.hls.HlsParser = class {
|
|
|
1779
1778
|
this.parseByteRange_(pPreviousReference, pByterange);
|
|
1780
1779
|
}
|
|
1781
1780
|
const pUri = item.getAttributeValue('URI');
|
|
1781
|
+
if (!pUri) {
|
|
1782
|
+
continue;
|
|
1783
|
+
}
|
|
1782
1784
|
const pAbsoluteUri = shaka.hls.Utils.constructAbsoluteUri(
|
|
1783
1785
|
absoluteMediaPlaylistUri, pUri);
|
|
1784
1786
|
|
|
@@ -1983,9 +1985,9 @@ shaka.hls.HlsParser = class {
|
|
|
1983
1985
|
// With delta updates, the DISCONTINUITY may be skipped. Check if
|
|
1984
1986
|
// the discontintuity Sequence Number based on the media sequence
|
|
1985
1987
|
// number.
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
position) {
|
|
1988
|
+
const disconMap = discontinuityToMediaSequence;
|
|
1989
|
+
while (disconMap.has(discontintuitySequenceNum + 1) &&
|
|
1990
|
+
disconMap.get(discontintuitySequenceNum + 1) < position) {
|
|
1989
1991
|
discontintuitySequenceNum++;
|
|
1990
1992
|
}
|
|
1991
1993
|
}
|
|
@@ -1996,8 +1998,8 @@ shaka.hls.HlsParser = class {
|
|
|
1996
1998
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
1997
1999
|
const references = [];
|
|
1998
2000
|
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
+
for (let i = 0; i < hlsSegments.length; i++) {
|
|
2002
|
+
const item = hlsSegments[i];
|
|
2001
2003
|
const previousReference = references[references.length - 1];
|
|
2002
2004
|
const startTime = (i == 0) ? firstStartTime :
|
|
2003
2005
|
previousReference.endTime;
|
|
@@ -13,7 +13,6 @@ goog.require('shaka.hls.Segment');
|
|
|
13
13
|
goog.require('shaka.hls.Tag');
|
|
14
14
|
goog.require('shaka.hls.Utils');
|
|
15
15
|
goog.require('shaka.util.Error');
|
|
16
|
-
goog.require('shaka.util.Iterables');
|
|
17
16
|
goog.require('shaka.util.StringUtils');
|
|
18
17
|
goog.require('shaka.util.TextParser');
|
|
19
18
|
|
|
@@ -82,8 +81,9 @@ shaka.hls.ManifestTextParser = class {
|
|
|
82
81
|
const tags = [];
|
|
83
82
|
// Initialize to "true" to skip the first element.
|
|
84
83
|
skip = true;
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
for (let i = 0; i < lines.length; i++) {
|
|
85
|
+
const line = lines[i];
|
|
86
|
+
const next = lines[i + 1];
|
|
87
87
|
// Skip comments
|
|
88
88
|
if (shaka.hls.Utils.isComment(line) || skip) {
|
|
89
89
|
skip = false;
|
|
@@ -277,6 +277,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
277
277
|
const attrValue = blockAttrs[2] || blockAttrs[3];
|
|
278
278
|
const attribute = new shaka.hls.Attribute(attrName, attrValue);
|
|
279
279
|
attributes.push(attribute);
|
|
280
|
+
parser.skipWhitespace();
|
|
280
281
|
}
|
|
281
282
|
}
|
|
282
283
|
|
|
@@ -8,7 +8,6 @@ goog.provide('shaka.media.AdaptationSet');
|
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
-
goog.require('shaka.util.Iterables');
|
|
12
11
|
goog.require('shaka.util.MimeUtils');
|
|
13
12
|
|
|
14
13
|
|
|
@@ -215,7 +214,7 @@ shaka.media.AdaptationSet = class {
|
|
|
215
214
|
codecsA.sort();
|
|
216
215
|
codecsB.sort();
|
|
217
216
|
|
|
218
|
-
for (
|
|
217
|
+
for (let i = 0; i < codecsA.length; i++) {
|
|
219
218
|
if (codecsA[i] != codecsB[i]) {
|
|
220
219
|
return false;
|
|
221
220
|
}
|
|
@@ -31,7 +31,7 @@ shaka.media.ContentWorkarounds = class {
|
|
|
31
31
|
*
|
|
32
32
|
* @param {!BufferSource} initSegmentBuffer
|
|
33
33
|
* @return {!Uint8Array}
|
|
34
|
-
* @see https://github.com/
|
|
34
|
+
* @see https://github.com/shaka-project/shaka-player/issues/2759
|
|
35
35
|
*/
|
|
36
36
|
static fakeEncryption(initSegmentBuffer) {
|
|
37
37
|
const ContentWorkarounds = shaka.media.ContentWorkarounds;
|
|
@@ -283,7 +283,7 @@ shaka.media.ContentWorkarounds = class {
|
|
|
283
283
|
*
|
|
284
284
|
* @const {!shaka.util.Lazy.<!Uint8Array>}
|
|
285
285
|
* @private
|
|
286
|
-
* @see https://github.com/
|
|
286
|
+
* @see https://github.com/shaka-project/shaka-player/issues/2759
|
|
287
287
|
*/
|
|
288
288
|
shaka.media.ContentWorkarounds.CANNED_SINF_BOX_ =
|
|
289
289
|
new shaka.util.Lazy(() => new Uint8Array([
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -655,7 +655,7 @@ shaka.media.DrmEngine = class {
|
|
|
655
655
|
// first MIME type even if the others are supported. To work around this,
|
|
656
656
|
// we say that Edge supports everything.
|
|
657
657
|
//
|
|
658
|
-
// See https://github.com/
|
|
658
|
+
// See https://github.com/shaka-project/shaka-player/issues/1495 for details.
|
|
659
659
|
if (shaka.util.Platform.isLegacyEdge()) {
|
|
660
660
|
return true;
|
|
661
661
|
}
|
|
@@ -667,7 +667,8 @@ shaka.media.DrmEngine = class {
|
|
|
667
667
|
// Some Tizen devices seem to misreport AC-3 support. This works around
|
|
668
668
|
// the issue, by falling back to EC-3, which seems to be supported on the
|
|
669
669
|
// same devices and be correctly reported in all cases we have observed.
|
|
670
|
-
// See https://github.com/
|
|
670
|
+
// See https://github.com/shaka-project/shaka-player/issues/2989 for
|
|
671
|
+
// details.
|
|
671
672
|
const fallback = contentType.replace('ac-3', 'ec-3');
|
|
672
673
|
return this.supportedTypes_.has(contentType) ||
|
|
673
674
|
this.supportedTypes_.has(fallback);
|
|
@@ -830,7 +830,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
830
830
|
* @private
|
|
831
831
|
*/
|
|
832
832
|
setTimestampOffset_(contentType, timestampOffset) {
|
|
833
|
-
// Work around for
|
|
833
|
+
// Work around for
|
|
834
|
+
// https://github.com/shaka-project/shaka-player/issues/1281:
|
|
834
835
|
// TODO(https://bit.ly/2ttKiBU): follow up when this is fixed in Edge
|
|
835
836
|
if (timestampOffset < 0) {
|
|
836
837
|
// Try to prevent rounding errors in Edge from removing the first
|
|
@@ -1100,7 +1101,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1100
1101
|
// then insert fake encryption metadata for init segments that lack it.
|
|
1101
1102
|
// The MP4 requirement is because we can currently only do this
|
|
1102
1103
|
// transformation on MP4 containers.
|
|
1103
|
-
// See: https://github.com/
|
|
1104
|
+
// See: https://github.com/shaka-project/shaka-player/issues/2759
|
|
1104
1105
|
if (isInitSegment &&
|
|
1105
1106
|
encryptionExpected &&
|
|
1106
1107
|
shaka.util.Platform.requiresEncryptionInfoInAllInitSegments() &&
|
|
@@ -11,8 +11,6 @@ goog.require('shaka.log');
|
|
|
11
11
|
goog.require('shaka.media.InitSegmentReference');
|
|
12
12
|
goog.require('shaka.media.SegmentReference');
|
|
13
13
|
goog.require('shaka.util.Error');
|
|
14
|
-
goog.require('shaka.util.Functional');
|
|
15
|
-
goog.require('shaka.util.Iterables');
|
|
16
14
|
goog.require('shaka.util.Mp4Parser');
|
|
17
15
|
|
|
18
16
|
|
|
@@ -123,8 +121,7 @@ shaka.media.Mp4SegmentIndexParser = class {
|
|
|
123
121
|
let unscaledStartTime = earliestPresentationTime;
|
|
124
122
|
let startByte = sidxOffset + box.size + firstOffset;
|
|
125
123
|
|
|
126
|
-
for (
|
|
127
|
-
shaka.util.Functional.ignored(_);
|
|
124
|
+
for (let i = 0; i < referenceCount; i++) {
|
|
128
125
|
// |chunk| is 1 bit for |referenceType|, and 31 bits for |referenceSize|.
|
|
129
126
|
const chunk = box.reader.readUint32();
|
|
130
127
|
const referenceType = (chunk & 0x80000000) >>> 31;
|
package/lib/media/playhead.js
CHANGED
|
@@ -256,7 +256,7 @@ shaka.media.MediaSourcePlayhead = class {
|
|
|
256
256
|
// We don't buffer when the livestream video is paused and the playhead time
|
|
257
257
|
// is out of the seek range; thus, we do not clamp the current time when the
|
|
258
258
|
// video is paused.
|
|
259
|
-
// https://github.com/
|
|
259
|
+
// https://github.com/shaka-project/shaka-player/issues/1121
|
|
260
260
|
if (this.mediaElement_.readyState > 0 && !this.mediaElement_.paused) {
|
|
261
261
|
return this.clampTime_(time);
|
|
262
262
|
}
|
|
@@ -362,7 +362,7 @@ shaka.media.MediaSourcePlayhead = class {
|
|
|
362
362
|
* presentation duration. Seeking to or starting at duration does not work
|
|
363
363
|
* consistently across browsers.
|
|
364
364
|
*
|
|
365
|
-
* @see https://github.com/
|
|
365
|
+
* @see https://github.com/shaka-project/shaka-player/issues/979
|
|
366
366
|
* @param {number} time
|
|
367
367
|
* @return {number} The adjusted seek time.
|
|
368
368
|
* @private
|
|
@@ -355,14 +355,23 @@ shaka.media.PresentationTimeline = class {
|
|
|
355
355
|
* starting after this time should be assumed to be unavailable.
|
|
356
356
|
*
|
|
357
357
|
* @return {number} The current segment availability end time, in seconds,
|
|
358
|
-
* relative to the start of the presentation.
|
|
359
|
-
*
|
|
358
|
+
* relative to the start of the presentation. For VOD, the availability
|
|
359
|
+
* end time is the content's duration. If the Player's playRangeEnd
|
|
360
|
+
* configuration is used, this can override the duration.
|
|
360
361
|
* @export
|
|
361
362
|
*/
|
|
362
363
|
getSegmentAvailabilityEnd() {
|
|
363
364
|
if (!this.isLive() && !this.isInProgress()) {
|
|
364
365
|
// It's a static manifest (can also be a dynamic->static conversion)
|
|
365
|
-
|
|
366
|
+
if (this.maxSegmentEndTime_) {
|
|
367
|
+
// If we know segment times, use the min of that and duration.
|
|
368
|
+
// Note that the playRangeEnd configuration changes this.duration_.
|
|
369
|
+
// See https://github.com/shaka-project/shaka-player/issues/4026
|
|
370
|
+
return Math.min(this.maxSegmentEndTime_, this.duration_);
|
|
371
|
+
} else {
|
|
372
|
+
// If we don't have segment times, use duration.
|
|
373
|
+
return this.duration_;
|
|
374
|
+
}
|
|
366
375
|
}
|
|
367
376
|
// Can be either live or "in-progress recording" (live with known duration)
|
|
368
377
|
return Math.min(this.getLiveEdge_() + this.availabilityTimeOffset_,
|
|
@@ -389,10 +398,11 @@ shaka.media.PresentationTimeline = class {
|
|
|
389
398
|
// For VOD, the offset and end time are ignored, and we just return the
|
|
390
399
|
// earliest segment time. All segments are "safe" in VOD. However, we
|
|
391
400
|
// should round up to the nearest millisecond to avoid issues like
|
|
392
|
-
// https://github.com/
|
|
393
|
-
// seek repeatedly to catch up to the seek range, and never
|
|
394
|
-
// "arrived" within it. The video's currentTime is not as
|
|
395
|
-
// JS number representing the earliest segment time for
|
|
401
|
+
// https://github.com/shaka-project/shaka-player/issues/2831, in which we
|
|
402
|
+
// tried to seek repeatedly to catch up to the seek range, and never
|
|
403
|
+
// actually "arrived" within it. The video's currentTime is not as
|
|
404
|
+
// accurate as the JS number representing the earliest segment time for
|
|
405
|
+
// some content.
|
|
396
406
|
if (this.segmentAvailabilityDuration_ == Infinity) {
|
|
397
407
|
return Math.ceil(earliestSegmentTime * 1e3) / 1e3;
|
|
398
408
|
}
|
|
@@ -407,7 +417,7 @@ shaka.media.PresentationTimeline = class {
|
|
|
407
417
|
// Add the offset to the availability start to ensure that we don't fall
|
|
408
418
|
// outside the availability window while we buffer; we don't need to add the
|
|
409
419
|
// offset to earliestSegmentTime since that won't change over time.
|
|
410
|
-
// Also see: https://github.com/
|
|
420
|
+
// Also see: https://github.com/shaka-project/shaka-player/issues/692
|
|
411
421
|
const desiredStart =
|
|
412
422
|
Math.min(availabilityStart + offset, this.getSeekRangeEnd());
|
|
413
423
|
return Math.max(earliestSegmentTime, desiredStart);
|
|
@@ -8,16 +8,19 @@ goog.provide('shaka.media.RegionObserver');
|
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.media.IPlayheadObserver');
|
|
10
10
|
goog.require('shaka.media.RegionTimeline');
|
|
11
|
+
goog.require('shaka.util.EventManager');
|
|
12
|
+
goog.require('shaka.util.FakeEvent');
|
|
13
|
+
goog.require('shaka.util.FakeEventTarget');
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* The region observer watches a region timeline and playhead, and fires events
|
|
15
|
-
* (
|
|
18
|
+
* ('enter', 'exit', 'skip') as the playhead moves.
|
|
16
19
|
*
|
|
17
20
|
* @implements {shaka.media.IPlayheadObserver}
|
|
18
21
|
* @final
|
|
19
22
|
*/
|
|
20
|
-
shaka.media.RegionObserver = class {
|
|
23
|
+
shaka.media.RegionObserver = class extends shaka.util.FakeEventTarget {
|
|
21
24
|
/**
|
|
22
25
|
* Create a region observer for the given timeline. The observer does not
|
|
23
26
|
* own the timeline, only uses it. This means that the observer should NOT
|
|
@@ -26,6 +29,8 @@ shaka.media.RegionObserver = class {
|
|
|
26
29
|
* @param {!shaka.media.RegionTimeline} timeline
|
|
27
30
|
*/
|
|
28
31
|
constructor(timeline) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
29
34
|
/** @private {shaka.media.RegionTimeline} */
|
|
30
35
|
this.timeline_ = timeline;
|
|
31
36
|
|
|
@@ -39,13 +44,6 @@ shaka.media.RegionObserver = class {
|
|
|
39
44
|
*/
|
|
40
45
|
this.oldPosition_ = new Map();
|
|
41
46
|
|
|
42
|
-
/** @private {shaka.media.RegionObserver.EventListener} */
|
|
43
|
-
this.onEnter_ = (region, seeking) => {};
|
|
44
|
-
/** @private {shaka.media.RegionObserver.EventListener} */
|
|
45
|
-
this.onExit_ = (region, seeking) => {};
|
|
46
|
-
/** @private {shaka.media.RegionObserver.EventListener} */
|
|
47
|
-
this.onSkip_ = (region, seeking) => {};
|
|
48
|
-
|
|
49
47
|
// To make the rules easier to read, alias all the relative positions.
|
|
50
48
|
const RelativePosition = shaka.media.RegionObserver.RelativePosition_;
|
|
51
49
|
const BEFORE_THE_REGION = RelativePosition.BEFORE_THE_REGION;
|
|
@@ -62,39 +60,48 @@ shaka.media.RegionObserver = class {
|
|
|
62
60
|
{
|
|
63
61
|
weWere: null,
|
|
64
62
|
weAre: IN_THE_REGION,
|
|
65
|
-
invoke: (region, seeking) => this.
|
|
63
|
+
invoke: (region, seeking) => this.onEvent_('enter', region, seeking),
|
|
66
64
|
},
|
|
67
65
|
{
|
|
68
66
|
weWere: BEFORE_THE_REGION,
|
|
69
67
|
weAre: IN_THE_REGION,
|
|
70
|
-
invoke: (region, seeking) => this.
|
|
68
|
+
invoke: (region, seeking) => this.onEvent_('enter', region, seeking),
|
|
71
69
|
},
|
|
72
70
|
{
|
|
73
71
|
weWere: AFTER_THE_REGION,
|
|
74
72
|
weAre: IN_THE_REGION,
|
|
75
|
-
invoke: (region, seeking) => this.
|
|
73
|
+
invoke: (region, seeking) => this.onEvent_('enter', region, seeking),
|
|
76
74
|
},
|
|
77
75
|
{
|
|
78
76
|
weWere: IN_THE_REGION,
|
|
79
77
|
weAre: BEFORE_THE_REGION,
|
|
80
|
-
invoke: (region, seeking) => this.
|
|
78
|
+
invoke: (region, seeking) => this.onEvent_('exit', region, seeking),
|
|
81
79
|
},
|
|
82
80
|
{
|
|
83
81
|
weWere: IN_THE_REGION,
|
|
84
82
|
weAre: AFTER_THE_REGION,
|
|
85
|
-
invoke: (region, seeking) => this.
|
|
83
|
+
invoke: (region, seeking) => this.onEvent_('exit', region, seeking),
|
|
86
84
|
},
|
|
87
85
|
{
|
|
88
86
|
weWere: BEFORE_THE_REGION,
|
|
89
87
|
weAre: AFTER_THE_REGION,
|
|
90
|
-
invoke: (region, seeking) => this.
|
|
88
|
+
invoke: (region, seeking) => this.onEvent_('skip', region, seeking),
|
|
91
89
|
},
|
|
92
90
|
{
|
|
93
91
|
weWere: AFTER_THE_REGION,
|
|
94
92
|
weAre: BEFORE_THE_REGION,
|
|
95
|
-
invoke: (region, seeking) => this.
|
|
93
|
+
invoke: (region, seeking) => this.onEvent_('skip', region, seeking),
|
|
96
94
|
},
|
|
97
95
|
];
|
|
96
|
+
|
|
97
|
+
/** @private {shaka.util.EventManager} */
|
|
98
|
+
this.eventManager_ = new shaka.util.EventManager();
|
|
99
|
+
|
|
100
|
+
this.eventManager_.listen(this.timeline_, 'regionremove', (event) => {
|
|
101
|
+
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
102
|
+
const region = event['region'];
|
|
103
|
+
this.oldPosition_.delete(region);
|
|
104
|
+
});
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
/** @override */
|
|
@@ -105,11 +112,10 @@ shaka.media.RegionObserver = class {
|
|
|
105
112
|
// needed.
|
|
106
113
|
this.oldPosition_.clear();
|
|
107
114
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.onSkip_ = (region, seeking) => {};
|
|
115
|
+
this.eventManager_.release();
|
|
116
|
+
this.eventManager_ = null;
|
|
117
|
+
|
|
118
|
+
super.release();
|
|
113
119
|
}
|
|
114
120
|
|
|
115
121
|
/** @override */
|
|
@@ -134,20 +140,20 @@ shaka.media.RegionObserver = class {
|
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
/**
|
|
137
|
-
*
|
|
143
|
+
* Dispatch events of the given type. All event types in this class have the
|
|
144
|
+
* same parameters: region and seeking.
|
|
138
145
|
*
|
|
139
|
-
* @param {
|
|
140
|
-
*
|
|
141
|
-
* @param {
|
|
142
|
-
*
|
|
143
|
-
* @param {shaka.media.RegionObserver.EventListener} onSkip
|
|
144
|
-
* The callback for when we move from before to after a region or from
|
|
145
|
-
* after to before a region.
|
|
146
|
+
* @param {string} eventType
|
|
147
|
+
* @param {shaka.extern.TimelineRegionInfo} region
|
|
148
|
+
* @param {boolean} seeking
|
|
149
|
+
* @private
|
|
146
150
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
onEvent_(eventType, region, seeking) {
|
|
152
|
+
const event = new shaka.util.FakeEvent(eventType, new Map([
|
|
153
|
+
['region', region],
|
|
154
|
+
['seeking', seeking],
|
|
155
|
+
]));
|
|
156
|
+
this.dispatchEvent(event);
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
/**
|