diff --git a/externs/shaka/manifest_parser.js b/externs/shaka/manifest_parser.js index 6eaa98d1e7..22ec3d6ffe 100644 --- a/externs/shaka/manifest_parser.js +++ b/externs/shaka/manifest_parser.js @@ -140,6 +140,7 @@ shaka.extern.ManifestParser = class { * getBandwidthEstimate: function():number, * onMetadata: function(string, number, ?number, * !Array.), + * closeSegmentIndex: function(shaka.extern.Stream, function()), * disableStream: function(!shaka.extern.Stream), * addFont: function(string, string) * }} @@ -186,6 +187,8 @@ shaka.extern.ManifestParser = class { * @property {function(!shaka.extern.Stream)} disableStream * Called to temporarily disable a stream i.e. disabling all variant * containing said stream. + * @property {function(!shaka.extern.Stream, function())} closeSegmentIndex + * Called to close a segment index. * @property {function(string, string)} addFont * Called when a new font needs to be added. * @exportDoc diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index 3071c3ce20..bb0ec502d2 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -239,6 +239,9 @@ shaka.dash.DashParser = class { this.lowLatencyMode_ = playerInterface.isLowLatencyMode(); this.manifestUris_ = [uri]; this.playerInterface_ = playerInterface; + if (this.periodCombiner_) { + this.periodCombiner_.setPlayerInterface(this.playerInterface_); + } const updateDelay = await this.requestManifest_(); diff --git a/lib/media/streaming_engine.js b/lib/media/streaming_engine.js index eca072ed05..196c0af21b 100644 --- a/lib/media/streaming_engine.js +++ b/lib/media/streaming_engine.js @@ -513,6 +513,32 @@ shaka.media.StreamingEngine = class { } } + /** + * closeSegmentIndex if the stream is not active + * @param {shaka.extern.Stream} stream + * @param {function()} closeSegmentIndex + */ + closeSegmentIndex(stream, closeSegmentIndex) { + const type = /** @type {!shaka.util.ManifestParserUtils.ContentType} */ + (stream.type); + const mediaState = this.mediaStates_.get(type); + if (mediaState) { + /** + * Closes the segmentIndex only if the stream is not active. + * If the stream is active the eviction will be peformed + * by the next onUpdate_(). + */ + const matchedStreams = mediaState.stream.matchedStreams; + const found = matchedStreams.find((match) => match.id === stream.id); + if (!found) { + closeSegmentIndex(); + } + } else { + // type of stream not active + closeSegmentIndex(); + } + } + /** * Handles deferred releases of old SegmentIndexes for the mediaState's diff --git a/lib/offline/storage.js b/lib/offline/storage.js index e73a30822e..9285f9c977 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -1217,6 +1217,7 @@ shaka.offline.Storage = class { onManifestUpdated: () => {}, getBandwidthEstimate: () => config.abr.defaultBandwidthEstimate, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/lib/player.js b/lib/player.js index 6af6b80732..e489765f72 100644 --- a/lib/player.js +++ b/lib/player.js @@ -2169,6 +2169,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget { }); } }, + closeSegmentIndex: (stream, closeSegmentIndex) => { + if (this.streamingEngine_) { + this.streamingEngine_.closeSegmentIndex(stream, closeSegmentIndex); + } else { + closeSegmentIndex(); + } + }, disableStream: (stream) => this.disableStream( stream, this.config_.streaming.maxDisabledTime), addFont: (name, url) => this.addFont(name, url), diff --git a/lib/util/periods.js b/lib/util/periods.js index 2055e944c8..bc6acb76fd 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -48,6 +48,9 @@ shaka.util.PeriodCombiner = class { /** @private {boolean} */ this.useStreamOnce_ = false; + /** @private {?shaka.extern.ManifestParser.PlayerInterface} */ + this.playerInterface_ = null; + /** * The IDs of the periods we have already used to generate streams. * This helps us identify the periods which have been added when a live @@ -80,6 +83,15 @@ shaka.util.PeriodCombiner = class { this.usedPeriodIds_.clear(); } + /** + * @param {?shaka.extern.ManifestParser.PlayerInterface} playerInterface + * + * @export + */ + setPlayerInterface(playerInterface) { + this.playerInterface_ = playerInterface; + } + /** * @return {!Array.} * @@ -155,8 +167,19 @@ shaka.util.PeriodCombiner = class { } } if (stream.segmentIndex) { - stream.closeSegmentIndex(); + if (this.playerInterface_) { + const closeSegmentIndex = () => { + stream.closeSegmentIndex(); + }; + + this.playerInterface_.closeSegmentIndex( + stream, + closeSegmentIndex); + } else { + stream.closeSegmentIndex(); + } } + this.usedPeriodIds_.delete(periodId); } diff --git a/test/dash/dash_parser_content_protection_unit.js b/test/dash/dash_parser_content_protection_unit.js index 1a390b8027..4ec124ec7e 100644 --- a/test/dash/dash_parser_content_protection_unit.js +++ b/test/dash/dash_parser_content_protection_unit.js @@ -47,6 +47,7 @@ describe('DashParser ContentProtection', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/dash/dash_parser_live_unit.js b/test/dash/dash_parser_live_unit.js index 5a3f691a84..c849349f6b 100644 --- a/test/dash/dash_parser_live_unit.js +++ b/test/dash/dash_parser_live_unit.js @@ -39,6 +39,7 @@ describe('DashParser Live', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/dash/dash_parser_manifest_unit.js b/test/dash/dash_parser_manifest_unit.js index 74bfb04732..43fdabb450 100644 --- a/test/dash/dash_parser_manifest_unit.js +++ b/test/dash/dash_parser_manifest_unit.js @@ -60,6 +60,7 @@ describe('DashParser Manifest', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: shaka.test.Util.spyFunc(addFontSpy), }; diff --git a/test/dash/dash_parser_patch_unit.js b/test/dash/dash_parser_patch_unit.js index 70e7b54c23..6ff8d1c231 100644 --- a/test/dash/dash_parser_patch_unit.js +++ b/test/dash/dash_parser_patch_unit.js @@ -50,6 +50,7 @@ describe('DashParser Patch', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/dash/dash_parser_segment_base_unit.js b/test/dash/dash_parser_segment_base_unit.js index 2295722289..cdbff25593 100644 --- a/test/dash/dash_parser_segment_base_unit.js +++ b/test/dash/dash_parser_segment_base_unit.js @@ -43,6 +43,7 @@ describe('DashParser SegmentBase', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/dash/dash_parser_segment_list_unit.js b/test/dash/dash_parser_segment_list_unit.js index a212426623..f9bea13d63 100644 --- a/test/dash/dash_parser_segment_list_unit.js +++ b/test/dash/dash_parser_segment_list_unit.js @@ -353,6 +353,7 @@ describe('DashParser SegmentList', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/dash/dash_parser_segment_template_unit.js b/test/dash/dash_parser_segment_template_unit.js index 169de3246a..f7d1c7023b 100644 --- a/test/dash/dash_parser_segment_template_unit.js +++ b/test/dash/dash_parser_segment_template_unit.js @@ -52,6 +52,7 @@ describe('DashParser SegmentTemplate', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/hls/hls_live_unit.js b/test/hls/hls_live_unit.js index 5c117bfab3..fab21bc732 100644 --- a/test/hls/hls_live_unit.js +++ b/test/hls/hls_live_unit.js @@ -82,6 +82,7 @@ describe('HlsParser live', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index 5f1f8fb62d..bcd90296da 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -96,6 +96,7 @@ describe('HlsParser', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: shaka.test.Util.spyFunc(onMetadataSpy), + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/media/streaming_engine_integration.js b/test/media/streaming_engine_integration.js index 9f47541b27..5f76ce5178 100644 --- a/test/media/streaming_engine_integration.js +++ b/test/media/streaming_engine_integration.js @@ -271,6 +271,8 @@ describe('StreamingEngine', () => { onSegmentAppended: () => playhead.notifyOfBufferingChange(), onInitSegmentAppended: () => {}, beforeAppendSegment: () => Promise.resolve(), + onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream, time) => false, }; streamingEngine = new shaka.media.StreamingEngine( diff --git a/test/media/streaming_engine_unit.js b/test/media/streaming_engine_unit.js index b129ad92e0..f8b86a8f53 100644 --- a/test/media/streaming_engine_unit.js +++ b/test/media/streaming_engine_unit.js @@ -467,6 +467,7 @@ describe('StreamingEngine', () => { onSegmentAppended: Util.spyFunc(onSegmentAppended), onInitSegmentAppended: () => {}, beforeAppendSegment: Util.spyFunc(beforeAppendSegment), + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: Util.spyFunc(disableStream), }; streamingEngine = new shaka.media.StreamingEngine( diff --git a/test/mss/mss_parser_unit.js b/test/mss/mss_parser_unit.js index 071bba0d1a..b6c19573ec 100644 --- a/test/mss/mss_parser_unit.js +++ b/test/mss/mss_parser_unit.js @@ -82,6 +82,7 @@ describe('MssParser Manifest', () => { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/test/util/dash_parser_util.js b/test/test/util/dash_parser_util.js index c047e92617..0202c2fb81 100644 --- a/test/test/util/dash_parser_util.js +++ b/test/test/util/dash_parser_util.js @@ -48,6 +48,7 @@ shaka.test.Dash = class { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; @@ -98,6 +99,7 @@ shaka.test.Dash = class { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/test/util/mss_parser_util.js b/test/test/util/mss_parser_util.js index 13e88b780f..bf228a53da 100644 --- a/test/test/util/mss_parser_util.js +++ b/test/test/util/mss_parser_util.js @@ -48,6 +48,7 @@ shaka.test.Mss = class { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; @@ -89,6 +90,7 @@ shaka.test.Mss = class { onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, }; diff --git a/test/util/content_steering_manager_unit.js b/test/util/content_steering_manager_unit.js index a3a0760517..6bf7e52498 100644 --- a/test/util/content_steering_manager_unit.js +++ b/test/util/content_steering_manager_unit.js @@ -30,6 +30,7 @@ describe('ContentSteeringManager', () => { onManifestUpdated: fail, getBandwidthEstimate: () => 1e6, onMetadata: () => {}, + closeSegmentIndex: (stream, closeSegmentIndex) => {}, disableStream: (stream) => {}, addFont: (name, url) => {}, };