shaka-player 3.3.0 → 3.3.3
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/pull_request_template.md +6 -34
- 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 +145 -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 +1722 -1640
- 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 +196 -169
- package/build/docker/Dockerfile +20 -0
- package/build/docker/docker-compose.yml +10 -0
- package/build/gendeps.py +18 -15
- package/build/shaka-lab.yaml +163 -0
- package/build/shakaBuildHelpers.py +4 -29
- package/build/test.py +93 -28
- package/build/types/polyfill +1 -0
- 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 +3 -3
- 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 +233 -226
- package/dist/locales.js +30 -30
- 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 +272 -238
- package/dist/shaka-player.compiled.debug.d.ts +272 -238
- package/dist/shaka-player.compiled.debug.externs.js +53 -16
- package/dist/shaka-player.compiled.debug.js +393 -394
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +53 -16
- package/dist/shaka-player.compiled.js +840 -843
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +318 -293
- package/dist/shaka-player.ui.debug.d.ts +318 -293
- package/dist/shaka-player.ui.debug.externs.js +55 -27
- package/dist/shaka-player.ui.debug.js +415 -417
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +55 -27
- package/dist/shaka-player.ui.js +997 -1000
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/REDESIGN.md +33 -33
- package/docs/design/bg-fetch.md +2 -2
- 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/externs/cmcd.js +186 -0
- package/externs/shaka/player.js +8 -0
- package/externs/shaka/text.js +10 -0
- 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 +41 -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/quality_observer.js +17 -34
- package/lib/media/region_observer.js +39 -33
- package/lib/media/region_timeline.js +17 -19
- package/lib/media/segment_index.js +2 -1
- package/lib/media/segment_reference.js +19 -1
- package/lib/media/streaming_engine.js +12 -9
- 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 +87 -41
- package/lib/polyfill/all.js +2 -3
- package/lib/polyfill/encryption_scheme.js +1 -1
- package/lib/polyfill/media_capabilities.js +32 -17
- package/lib/polyfill/mediasource.js +1 -1
- package/lib/polyfill/symbol.js +46 -0
- package/lib/text/cue.js +7 -1
- package/lib/text/simple_text_displayer.js +2 -1
- package/lib/text/ttml_text_parser.js +92 -63
- package/lib/text/ui_text_displayer.js +18 -12
- package/lib/util/buffer_utils.js +1 -3
- package/lib/util/cmcd_manager.js +47 -201
- 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 +10 -11
- package/lib/util/platform.js +3 -3
- package/lib/util/pssh.js +1 -4
- package/lib/util/stream_utils.js +88 -11
- package/lib/util/string_utils.js +3 -5
- package/lib/util/uint8array_utils.js +3 -5
- package/lib/util/xml_utils.js +34 -7
- package/package.json +62 -40
- package/roadmap.md +17 -17
- package/shaka-player.uncompiled.js +1 -0
- 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 +7 -27
- 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/quality_observer_unit.js +4 -5
- 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 +11 -37
- package/test/media/streaming_engine_unit.js +155 -34
- 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 -27
- package/test/player_external.js +2 -10
- package/test/player_integration.js +63 -36
- 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 +41 -15
- package/test/player_unit.js +71 -46
- package/test/routing/walker_unit.js +0 -8
- package/test/test/assets/chapters.vtt +2 -2
- package/test/test/assets/chapters2.vtt +10 -0
- 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 +79 -0
- 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 +10 -23
- 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 +499 -239
- 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/cmcd_manager_unit.js +29 -18
- 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 +39 -38
- 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/third_party/closure-uri/uri.js +21 -0
- package/ui/controls.js +3 -0
- package/ui/less/ad_controls.less +4 -4
- package/ui/less/buttons.less +5 -5
- package/ui/less/containers.less +9 -11
- package/ui/less/overflow_menu.less +4 -4
- package/ui/less/range_elements.less +5 -0
- package/ui/less/tooltip.less +1 -1
- package/ui/locales/sjn-translations.yaml +257 -0
- package/ui/locales/sjn.json +42 -0
- package/ui/localization.js +12 -36
- package/ui/text_selection.js +1 -0
- package/externs/media_capabilities.js +0 -16
- package/externs/svgelement.js +0 -18
- package/externs/webcrypto.js +0 -18
package/lib/dash/dash_parser.js
CHANGED
|
@@ -22,7 +22,6 @@ goog.require('shaka.text.TextEngine');
|
|
|
22
22
|
goog.require('shaka.util.CmcdManager');
|
|
23
23
|
goog.require('shaka.util.Error');
|
|
24
24
|
goog.require('shaka.util.Functional');
|
|
25
|
-
goog.require('shaka.util.Iterables');
|
|
26
25
|
goog.require('shaka.util.LanguageUtils');
|
|
27
26
|
goog.require('shaka.util.ManifestParserUtils');
|
|
28
27
|
goog.require('shaka.util.MimeUtils');
|
|
@@ -104,7 +103,7 @@ shaka.dash.DashParser = class {
|
|
|
104
103
|
|
|
105
104
|
/**
|
|
106
105
|
* Period IDs seen in previous manifest.
|
|
107
|
-
* @private {!Array.<
|
|
106
|
+
* @private {!Array.<string>}
|
|
108
107
|
*/
|
|
109
108
|
this.lastManifestUpdatePeriodIds_ = [];
|
|
110
109
|
|
|
@@ -383,7 +382,7 @@ shaka.dash.DashParser = class {
|
|
|
383
382
|
// This gives us confidence that our state is maintained correctly, and
|
|
384
383
|
// that the complex logic of multi-Period eviction and period-flattening
|
|
385
384
|
// is correct. See also:
|
|
386
|
-
// https://github.com/
|
|
385
|
+
// https://github.com/shaka-project/shaka-player/issues/3169#issuecomment-823580634
|
|
387
386
|
for (const stream of Object.values(this.streamMap_)) {
|
|
388
387
|
if (stream.segmentIndex) {
|
|
389
388
|
stream.segmentIndex.evict(
|
|
@@ -410,6 +409,24 @@ shaka.dash.DashParser = class {
|
|
|
410
409
|
this.config_.dash.autoCorrectDrift);
|
|
411
410
|
}
|
|
412
411
|
|
|
412
|
+
presentationTimeline.setStatic(mpdType == 'static');
|
|
413
|
+
|
|
414
|
+
const isLive = presentationTimeline.isLive();
|
|
415
|
+
|
|
416
|
+
// If it's live, we check for an override.
|
|
417
|
+
if (isLive && !isNaN(this.config_.availabilityWindowOverride)) {
|
|
418
|
+
segmentAvailabilityDuration = this.config_.availabilityWindowOverride;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// If it's null, that means segments are always available. This is always
|
|
422
|
+
// the case for VOD, and sometimes the case for live.
|
|
423
|
+
if (segmentAvailabilityDuration == null) {
|
|
424
|
+
segmentAvailabilityDuration = Infinity;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
presentationTimeline.setSegmentAvailabilityDuration(
|
|
428
|
+
segmentAvailabilityDuration);
|
|
429
|
+
|
|
413
430
|
const profiles = mpd.getAttribute('profiles') || '';
|
|
414
431
|
|
|
415
432
|
/** @type {shaka.dash.DashParser.Context} */
|
|
@@ -432,7 +449,6 @@ shaka.dash.DashParser = class {
|
|
|
432
449
|
const duration = periodsAndDuration.duration;
|
|
433
450
|
const periods = periodsAndDuration.periods;
|
|
434
451
|
|
|
435
|
-
presentationTimeline.setStatic(mpdType == 'static');
|
|
436
452
|
if (mpdType == 'static' ||
|
|
437
453
|
!periodsAndDuration.durationDerivedFromPeriods) {
|
|
438
454
|
// Ignore duration calculated from Period lengths if this is dynamic.
|
|
@@ -451,6 +467,7 @@ shaka.dash.DashParser = class {
|
|
|
451
467
|
this.lowLatencyMode_ = this.playerInterface_.isLowLatencyMode();
|
|
452
468
|
}
|
|
453
469
|
}
|
|
470
|
+
|
|
454
471
|
if (this.lowLatencyMode_) {
|
|
455
472
|
presentationTimeline.setAvailabilityTimeOffset(
|
|
456
473
|
this.minTotalAvailabilityTimeOffset_);
|
|
@@ -464,22 +481,6 @@ shaka.dash.DashParser = class {
|
|
|
464
481
|
'https://bit.ly/3clctcj for details.');
|
|
465
482
|
}
|
|
466
483
|
|
|
467
|
-
const isLive = presentationTimeline.isLive();
|
|
468
|
-
|
|
469
|
-
// If it's live, we check for an override.
|
|
470
|
-
if (isLive && !isNaN(this.config_.availabilityWindowOverride)) {
|
|
471
|
-
segmentAvailabilityDuration = this.config_.availabilityWindowOverride;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// If it's null, that means segments are always available. This is always
|
|
475
|
-
// the case for VOD, and sometimes the case for live.
|
|
476
|
-
if (segmentAvailabilityDuration == null) {
|
|
477
|
-
segmentAvailabilityDuration = Infinity;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
presentationTimeline.setSegmentAvailabilityDuration(
|
|
481
|
-
segmentAvailabilityDuration);
|
|
482
|
-
|
|
483
484
|
// Use @maxSegmentDuration to override smaller, derived values.
|
|
484
485
|
presentationTimeline.notifyMaxSegmentDuration(maxSegmentDuration || 1);
|
|
485
486
|
if (goog.DEBUG) {
|
|
@@ -553,10 +554,9 @@ shaka.dash.DashParser = class {
|
|
|
553
554
|
const periods = [];
|
|
554
555
|
let prevEnd = 0;
|
|
555
556
|
const periodNodes = XmlUtils.findChildren(mpd, 'Period');
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
for (const {i, item: elem, next} of enumerate(periodNodes)) {
|
|
557
|
+
for (let i = 0; i < periodNodes.length; i++) {
|
|
558
|
+
const elem = periodNodes[i];
|
|
559
|
+
const next = periodNodes[i + 1];
|
|
560
560
|
const start = /** @type {number} */ (
|
|
561
561
|
XmlUtils.parseAttr(elem, 'start', XmlUtils.parseDuration, prevEnd));
|
|
562
562
|
const periodId = elem.id;
|
|
@@ -714,8 +714,12 @@ shaka.dash.DashParser = class {
|
|
|
714
714
|
|
|
715
715
|
const eventStreamNodes =
|
|
716
716
|
XmlUtils.findChildren(periodInfo.node, 'EventStream');
|
|
717
|
+
const availabilityStart =
|
|
718
|
+
context.presentationTimeline.getSegmentAvailabilityStart();
|
|
719
|
+
|
|
717
720
|
for (const node of eventStreamNodes) {
|
|
718
|
-
this.parseEventStream_(
|
|
721
|
+
this.parseEventStream_(
|
|
722
|
+
periodInfo.start, periodInfo.duration, node, availabilityStart);
|
|
719
723
|
}
|
|
720
724
|
|
|
721
725
|
const adaptationSetNodes =
|
|
@@ -758,7 +762,7 @@ shaka.dash.DashParser = class {
|
|
|
758
762
|
for (const stream of normalSet.streams) {
|
|
759
763
|
// There may be multiple trick mode streams, but we do not
|
|
760
764
|
// currently support that. Just choose one.
|
|
761
|
-
// TODO: https://github.com/
|
|
765
|
+
// TODO: https://github.com/shaka-project/shaka-player/issues/1528
|
|
762
766
|
stream.trickModeVideo = trickModeSet.streams.find((trickStream) =>
|
|
763
767
|
shaka.util.MimeUtils.getCodecBase(stream.codecs) ==
|
|
764
768
|
shaka.util.MimeUtils.getCodecBase(trickStream.codecs));
|
|
@@ -1151,7 +1155,7 @@ shaka.dash.DashParser = class {
|
|
|
1151
1155
|
// does not make sense in the DASH spec's bandwidth formulas.
|
|
1152
1156
|
// In some content, however, the attribute is missing or zero.
|
|
1153
1157
|
// To avoid NaN at the variant level on broken content, fall back to zero.
|
|
1154
|
-
// https://github.com/
|
|
1158
|
+
// https://github.com/shaka-project/shaka-player/issues/938#issuecomment-317278180
|
|
1155
1159
|
context.bandwidth =
|
|
1156
1160
|
XmlUtils.parseAttr(node, 'bandwidth', XmlUtils.parsePositiveInt) || 0;
|
|
1157
1161
|
|
|
@@ -1230,7 +1234,7 @@ shaka.dash.DashParser = class {
|
|
|
1230
1234
|
|
|
1231
1235
|
let forced = false;
|
|
1232
1236
|
if (isText) {
|
|
1233
|
-
// See: https://github.com/
|
|
1237
|
+
// See: https://github.com/shaka-project/shaka-player/issues/2122 and
|
|
1234
1238
|
// https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/165
|
|
1235
1239
|
forced = roles.includes('forced_subtitle') ||
|
|
1236
1240
|
roles.includes('forced-subtitle');
|
|
@@ -1378,7 +1382,7 @@ shaka.dash.DashParser = class {
|
|
|
1378
1382
|
// NOTE: An updatePeriod_ of -1 means the attribute was missing.
|
|
1379
1383
|
// An attribute which is present and set to 0 should still result in
|
|
1380
1384
|
// periodic updates. For more, see:
|
|
1381
|
-
// https://github.com/
|
|
1385
|
+
// https://github.com/shaka-project/shaka-player/issues/331
|
|
1382
1386
|
if (this.updatePeriod_ < 0) {
|
|
1383
1387
|
return;
|
|
1384
1388
|
}
|
|
@@ -1769,9 +1773,10 @@ shaka.dash.DashParser = class {
|
|
|
1769
1773
|
* @param {number} periodStart
|
|
1770
1774
|
* @param {?number} periodDuration
|
|
1771
1775
|
* @param {!Element} elem
|
|
1776
|
+
* @param {number} availabilityStart
|
|
1772
1777
|
* @private
|
|
1773
1778
|
*/
|
|
1774
|
-
parseEventStream_(periodStart, periodDuration, elem) {
|
|
1779
|
+
parseEventStream_(periodStart, periodDuration, elem, availabilityStart) {
|
|
1775
1780
|
const XmlUtils = shaka.util.XmlUtils;
|
|
1776
1781
|
const parseNumber = XmlUtils.parseNonNegativeInt;
|
|
1777
1782
|
|
|
@@ -1794,6 +1799,11 @@ shaka.dash.DashParser = class {
|
|
|
1794
1799
|
endTime = Math.min(endTime, periodStart + periodDuration);
|
|
1795
1800
|
}
|
|
1796
1801
|
|
|
1802
|
+
// Don't add unavailable regions to the timeline.
|
|
1803
|
+
if (endTime < availabilityStart) {
|
|
1804
|
+
continue;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1797
1807
|
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
1798
1808
|
const region = {
|
|
1799
1809
|
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');
|
|
@@ -222,7 +221,7 @@ shaka.dash.SegmentList = class {
|
|
|
222
221
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
223
222
|
const references = [];
|
|
224
223
|
let prevEndTime = info.startTime;
|
|
225
|
-
for (
|
|
224
|
+
for (let i = 0; i < max; i++) {
|
|
226
225
|
const segment = info.mediaSegments[i];
|
|
227
226
|
const mediaUri = ManifestParserUtils.resolveUris(
|
|
228
227
|
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');
|
|
@@ -504,8 +503,9 @@ shaka.dash.SegmentTemplate = class {
|
|
|
504
503
|
|
|
505
504
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
506
505
|
const references = [];
|
|
507
|
-
|
|
508
|
-
|
|
506
|
+
for (let i = 0; i < info.timeline.length; i++) {
|
|
507
|
+
const {start, unscaledStart, end} = info.timeline[i];
|
|
508
|
+
|
|
509
509
|
// Note: i = k - 1, where k indicates the k'th segment listed in the MPD.
|
|
510
510
|
// (See section 5.3.9.5.3 of the DASH spec.)
|
|
511
511
|
const segmentReplacement = i + info.startNumber;
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -30,7 +30,6 @@ goog.require('shaka.util.DataViewReader');
|
|
|
30
30
|
goog.require('shaka.util.Error');
|
|
31
31
|
goog.require('shaka.util.FakeEvent');
|
|
32
32
|
goog.require('shaka.util.Functional');
|
|
33
|
-
goog.require('shaka.util.Iterables');
|
|
34
33
|
goog.require('shaka.util.LanguageUtils');
|
|
35
34
|
goog.require('shaka.util.ManifestParserUtils');
|
|
36
35
|
goog.require('shaka.util.MimeUtils');
|
|
@@ -919,7 +918,7 @@ shaka.hls.HlsParser = class {
|
|
|
919
918
|
// the content. This means that if the content changes profiles, it should
|
|
920
919
|
// include both. Since all known browsers support changing profiles
|
|
921
920
|
// without any other work, just ignore them. See also:
|
|
922
|
-
// https://github.com/
|
|
921
|
+
// https://github.com/shaka-project/shaka-player/issues/1817
|
|
923
922
|
const shortCodec = shaka.util.MimeUtils.getCodecBase(codec);
|
|
924
923
|
if (!seen.has(shortCodec)) {
|
|
925
924
|
ret.push(codec);
|
|
@@ -1281,6 +1280,30 @@ shaka.hls.HlsParser = class {
|
|
|
1281
1280
|
if (this.uriToStreamInfosMap_.has(verbatimImagePlaylistUri)) {
|
|
1282
1281
|
return this.uriToStreamInfosMap_.get(verbatimImagePlaylistUri);
|
|
1283
1282
|
}
|
|
1283
|
+
|
|
1284
|
+
// Parse misc attributes.
|
|
1285
|
+
const resolution = tag.getAttributeValue('RESOLUTION');
|
|
1286
|
+
if (resolution) {
|
|
1287
|
+
// The RESOLUTION tag represents the resolution of a single thumbnail, not
|
|
1288
|
+
// of the entire sheet at once (like we expect in the output).
|
|
1289
|
+
// So multiply by the layout size.
|
|
1290
|
+
|
|
1291
|
+
const reference = streamInfo.stream.segmentIndex.get(0);
|
|
1292
|
+
const layout = reference.getTilesLayout();
|
|
1293
|
+
if (layout) {
|
|
1294
|
+
streamInfo.stream.width =
|
|
1295
|
+
Number(resolution.split('x')[0]) * Number(layout.split('x')[0]);
|
|
1296
|
+
streamInfo.stream.height =
|
|
1297
|
+
Number(resolution.split('x')[1]) * Number(layout.split('x')[1]);
|
|
1298
|
+
// TODO: What happens if there are multiple grids, with different
|
|
1299
|
+
// layout sizes, inside this image stream?
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
const bandwidth = tag.getAttributeValue('BANDWIDTH');
|
|
1303
|
+
if (bandwidth) {
|
|
1304
|
+
streamInfo.stream.bandwidth = Number(bandwidth);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1284
1307
|
this.uriToStreamInfosMap_.set(verbatimImagePlaylistUri, streamInfo);
|
|
1285
1308
|
return streamInfo;
|
|
1286
1309
|
}
|
|
@@ -1736,8 +1759,8 @@ shaka.hls.HlsParser = class {
|
|
|
1736
1759
|
// Create SegmentReferences for the partial segments.
|
|
1737
1760
|
const partialSegmentRefs = [];
|
|
1738
1761
|
if (this.lowLatencyMode_ && hlsSegment.partialSegments.length) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1762
|
+
for (let i = 0; i < hlsSegment.partialSegments.length; i++) {
|
|
1763
|
+
const item = hlsSegment.partialSegments[i];
|
|
1741
1764
|
const pPreviousReference = i == 0 ?
|
|
1742
1765
|
previousReference : partialSegmentRefs[partialSegmentRefs.length - 1];
|
|
1743
1766
|
const pStartTime = (i == 0) ? startTime : pPreviousReference.endTime;
|
|
@@ -1758,6 +1781,9 @@ shaka.hls.HlsParser = class {
|
|
|
1758
1781
|
this.parseByteRange_(pPreviousReference, pByterange);
|
|
1759
1782
|
}
|
|
1760
1783
|
const pUri = item.getAttributeValue('URI');
|
|
1784
|
+
if (!pUri) {
|
|
1785
|
+
continue;
|
|
1786
|
+
}
|
|
1761
1787
|
const pAbsoluteUri = shaka.hls.Utils.constructAbsoluteUri(
|
|
1762
1788
|
absoluteMediaPlaylistUri, pUri);
|
|
1763
1789
|
|
|
@@ -1814,6 +1840,7 @@ shaka.hls.HlsParser = class {
|
|
|
1814
1840
|
}
|
|
1815
1841
|
|
|
1816
1842
|
let tilesLayout = '';
|
|
1843
|
+
let tileDuration = null;
|
|
1817
1844
|
if (type == shaka.util.ManifestParserUtils.ContentType.IMAGE) {
|
|
1818
1845
|
// By default in HLS the tilesLayout is 1x1
|
|
1819
1846
|
tilesLayout = '1x1';
|
|
@@ -1821,6 +1848,10 @@ shaka.hls.HlsParser = class {
|
|
|
1821
1848
|
shaka.hls.Utils.getFirstTagWithName(tags, 'EXT-X-TILES');
|
|
1822
1849
|
if (tilesTag) {
|
|
1823
1850
|
tilesLayout = tilesTag.getRequiredAttrValue('LAYOUT');
|
|
1851
|
+
const duration = tilesTag.getAttributeValue('DURATION');
|
|
1852
|
+
if (duration) {
|
|
1853
|
+
tileDuration = Number(duration);
|
|
1854
|
+
}
|
|
1824
1855
|
}
|
|
1825
1856
|
}
|
|
1826
1857
|
|
|
@@ -1836,6 +1867,7 @@ shaka.hls.HlsParser = class {
|
|
|
1836
1867
|
/* appendWindowEnd= */ Infinity,
|
|
1837
1868
|
partialSegmentRefs,
|
|
1838
1869
|
tilesLayout,
|
|
1870
|
+
tileDuration,
|
|
1839
1871
|
);
|
|
1840
1872
|
}
|
|
1841
1873
|
|
|
@@ -1959,9 +1991,9 @@ shaka.hls.HlsParser = class {
|
|
|
1959
1991
|
// With delta updates, the DISCONTINUITY may be skipped. Check if
|
|
1960
1992
|
// the discontintuity Sequence Number based on the media sequence
|
|
1961
1993
|
// number.
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
position) {
|
|
1994
|
+
const disconMap = discontinuityToMediaSequence;
|
|
1995
|
+
while (disconMap.has(discontintuitySequenceNum + 1) &&
|
|
1996
|
+
disconMap.get(discontintuitySequenceNum + 1) < position) {
|
|
1965
1997
|
discontintuitySequenceNum++;
|
|
1966
1998
|
}
|
|
1967
1999
|
}
|
|
@@ -1972,8 +2004,8 @@ shaka.hls.HlsParser = class {
|
|
|
1972
2004
|
/** @type {!Array.<!shaka.media.SegmentReference>} */
|
|
1973
2005
|
const references = [];
|
|
1974
2006
|
|
|
1975
|
-
|
|
1976
|
-
|
|
2007
|
+
for (let i = 0; i < hlsSegments.length; i++) {
|
|
2008
|
+
const item = hlsSegments[i];
|
|
1977
2009
|
const previousReference = references[references.length - 1];
|
|
1978
2010
|
const startTime = (i == 0) ? firstStartTime :
|
|
1979
2011
|
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,48 +8,40 @@ goog.provide('shaka.media.QualityObserver');
|
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.media.IPlayheadObserver');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
+
goog.require('shaka.util.FakeEvent');
|
|
12
|
+
goog.require('shaka.util.FakeEventTarget');
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
|
-
* Monitors the quality of content being appended to the source
|
|
14
|
-
*
|
|
15
|
-
* at the playhead changes.
|
|
15
|
+
* Monitors the quality of content being appended to the source buffers and
|
|
16
|
+
* fires 'qualitychange' events when the media quality at the playhead changes.
|
|
16
17
|
*
|
|
17
18
|
* @implements {shaka.media.IPlayheadObserver}
|
|
18
19
|
* @final
|
|
19
20
|
*/
|
|
20
|
-
shaka.media.QualityObserver = class {
|
|
21
|
+
shaka.media.QualityObserver = class extends shaka.util.FakeEventTarget {
|
|
21
22
|
/**
|
|
22
23
|
* Creates a new QualityObserver.
|
|
23
24
|
*
|
|
24
25
|
* @param {!function():!shaka.extern.BufferedInfo} getBufferedInfo
|
|
25
|
-
*
|
|
26
|
-
*
|
|
26
|
+
* Buffered info is needed to purge QualityChanges that are no
|
|
27
|
+
* longer relevant.
|
|
27
28
|
*/
|
|
28
29
|
constructor(getBufferedInfo) {
|
|
30
|
+
super();
|
|
31
|
+
|
|
29
32
|
/**
|
|
30
33
|
* @private {!Map.<string,!shaka.media.QualityObserver.ContentTypeState>}
|
|
31
34
|
*/
|
|
32
35
|
this.contentTypeStates_ = new Map();
|
|
33
36
|
|
|
34
|
-
/** @private {shaka.media.QualityObserver.EventListener} */
|
|
35
|
-
this.onQualityChange_ = (mediaQuality, position) => {};
|
|
36
|
-
|
|
37
37
|
/** @private function():!shaka.extern.BufferedInfo */
|
|
38
38
|
this.getBufferedInfo_ = getBufferedInfo;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
/**
|
|
42
|
-
* Set all the listeners. This overrides any previous calls to |setListeners|.
|
|
43
|
-
*
|
|
44
|
-
* @param {shaka.media.QualityObserver.EventListener} onQualityChange
|
|
45
|
-
*/
|
|
46
|
-
setListeners(onQualityChange) {
|
|
47
|
-
this.onQualityChange_ = onQualityChange;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
41
|
/** @override */
|
|
51
42
|
release() {
|
|
52
43
|
this.contentTypeStates_.clear();
|
|
44
|
+
super.release();
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
/**
|
|
@@ -169,10 +161,15 @@ shaka.media.QualityObserver = class {
|
|
|
169
161
|
if (this.positionIsBuffered_(
|
|
170
162
|
positionInSeconds, qualityAtPosition.contentType)) {
|
|
171
163
|
contentTypeState.currentQuality = qualityAtPosition;
|
|
164
|
+
|
|
172
165
|
shaka.log.debug('Media quality changed at position ' +
|
|
173
166
|
positionInSeconds + ' ' + JSON.stringify(qualityAtPosition));
|
|
174
|
-
|
|
175
|
-
|
|
167
|
+
|
|
168
|
+
const event = new shaka.util.FakeEvent('qualitychange', new Map([
|
|
169
|
+
['quality', qualityAtPosition],
|
|
170
|
+
['position', positionInSeconds],
|
|
171
|
+
]));
|
|
172
|
+
this.dispatchEvent(event);
|
|
176
173
|
}
|
|
177
174
|
}
|
|
178
175
|
}
|
|
@@ -237,20 +234,6 @@ shaka.media.QualityObserver = class {
|
|
|
237
234
|
}
|
|
238
235
|
};
|
|
239
236
|
|
|
240
|
-
/**
|
|
241
|
-
* @typedef {function(shaka.extern.MediaQualityInfo, number)}
|
|
242
|
-
*
|
|
243
|
-
* @description
|
|
244
|
-
* A callback function used to notify the player when media quality changes
|
|
245
|
-
* are detected at the playhead.
|
|
246
|
-
*
|
|
247
|
-
* The first argument is information about media quality at the playhead
|
|
248
|
-
* position.
|
|
249
|
-
*
|
|
250
|
-
* The second argument is the playhead position in seconds.
|
|
251
|
-
*/
|
|
252
|
-
shaka.media.QualityObserver.EventListener;
|
|
253
|
-
|
|
254
237
|
/**
|
|
255
238
|
* @typedef {{
|
|
256
239
|
* mediaQuality: !shaka.extern.MediaQualityInfo,
|