From f5742f0cdb8458cbff08f10a9a9b5d3e8cf3f8da Mon Sep 17 00:00:00 2001 From: Julian Obispo Date: Tue, 3 Dec 2024 17:03:33 +0100 Subject: [PATCH] add hibernate method to skip updating manifest or segments --- lib/dash/dash_parser.js | 4 ++++ lib/media/streaming_engine.js | 9 ++++++++- lib/offline/storage.js | 1 + lib/player.js | 13 +++++++++++++ test/dash/dash_parser_content_protection_unit.js | 1 + test/dash/dash_parser_live_unit.js | 1 + test/dash/dash_parser_manifest_unit.js | 1 + test/dash/dash_parser_segment_base_unit.js | 1 + test/dash/dash_parser_segment_list_unit.js | 1 + test/dash/dash_parser_segment_template_unit.js | 1 + test/hls/hls_live_unit.js | 1 + test/hls/hls_parser_unit.js | 1 + test/media/streaming_engine_integration.js | 1 + test/media/streaming_engine_unit.js | 1 + test/mss/mss_parser_unit.js | 1 + test/test/util/dash_parser_util.js | 2 ++ test/test/util/mss_parser_util.js | 2 ++ test/util/content_steering_manager_unit.js | 1 + 18 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index d3fb393c38..569e2bb047 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -1663,6 +1663,10 @@ shaka.dash.DashParser = class { * @private */ async onUpdate_() { + if (this.playerInterface_ && this.playerInterface_.isHibernated()) { + this.setUpdateTimer_(1); + return; + } goog.asserts.assert(this.updatePeriod_ >= 0, 'There should be an update period'); diff --git a/lib/media/streaming_engine.js b/lib/media/streaming_engine.js index 46f392ab67..1b713c64b2 100644 --- a/lib/media/streaming_engine.js +++ b/lib/media/streaming_engine.js @@ -937,6 +937,10 @@ shaka.media.StreamingEngine = class { * @private */ async onUpdate_(mediaState) { + if (this.playerInterface_ && this.playerInterface_.isHibernated()) { + this.scheduleUpdate_(mediaState, 1); + return; + } this.destroyer_.ensureNotDestroyed(); const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState); @@ -2582,7 +2586,8 @@ shaka.media.StreamingEngine = class { * beforeAppendSegment: function( * shaka.util.ManifestParserUtils.ContentType,!BufferSource):Promise, * onMetadata: !function(!Array., number, ?number), - * disableStream: function(!shaka.extern.Stream, number):boolean + * disableStream: function(!shaka.extern.Stream, number):boolean, + * isHibernated: function():boolean * }} * * @property {function():number} getPresentationTime @@ -2617,6 +2622,8 @@ shaka.media.StreamingEngine = class { * @property {function(!shaka.extern.Stream, number):boolean} disableStream * Called to temporarily disable a stream i.e. disabling all variant * containing said stream. + * @property {function():boolean} isHibernated + * Called to check if the player is hibernated. */ shaka.media.StreamingEngine.PlayerInterface; diff --git a/lib/offline/storage.js b/lib/offline/storage.js index c8b381cb71..efc066456c 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -1177,6 +1177,7 @@ shaka.offline.Storage = class { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => config.abr.defaultBandwidthEstimate, + isHibernated: () => false, }; parser.configure(config.manifest); diff --git a/lib/player.js b/lib/player.js index 851b857179..f267a878f5 100644 --- a/lib/player.js +++ b/lib/player.js @@ -753,6 +753,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { 'use the attach method instead.'); this.attach(mediaElement, /* initializeMediaSource= */ true); } + this.hibernate_ = false; } /** @@ -1126,6 +1127,16 @@ shaka.Player = class extends shaka.util.FakeEventTarget { return false; } + /** + * Sets the player to hibernate mode. In hibernate mode, the player will not + * update * the manifest, will not fetch new segments. + * @param {boolean} value + * @export + */ + hibernate(value) { + this.hibernate_ = value; + } + /** * Unloads the currently playing stream, if any. * @@ -1714,6 +1725,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { } }, getBandwidthEstimate: () => this.abrManager_.getBandwidthEstimate(), + isHibernated: () => this.hibernate_, }; const startTime = Date.now() / 1000; @@ -3009,6 +3021,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { this.processTimedMetadataMediaSrc_(metadata, offset, endTime); }, disableStream: (stream, time) => this.disableStream(stream, time), + isHibernated: () => this.hibernate_, }; return new shaka.media.StreamingEngine(this.manifest_, playerInterface); diff --git a/test/dash/dash_parser_content_protection_unit.js b/test/dash/dash_parser_content_protection_unit.js index 8785c6b15c..4592d4c1c4 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', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; const actual = await dashParser.start( diff --git a/test/dash/dash_parser_live_unit.js b/test/dash/dash_parser_live_unit.js index ba72a1310a..7091f409aa 100644 --- a/test/dash/dash_parser_live_unit.js +++ b/test/dash/dash_parser_live_unit.js @@ -38,6 +38,7 @@ describe('DashParser Live', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; }); diff --git a/test/dash/dash_parser_manifest_unit.js b/test/dash/dash_parser_manifest_unit.js index be4ed43dc5..d307e9c6a4 100644 --- a/test/dash/dash_parser_manifest_unit.js +++ b/test/dash/dash_parser_manifest_unit.js @@ -56,6 +56,7 @@ describe('DashParser Manifest', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; }); diff --git a/test/dash/dash_parser_segment_base_unit.js b/test/dash/dash_parser_segment_base_unit.js index d87165e378..68346c8c93 100644 --- a/test/dash/dash_parser_segment_base_unit.js +++ b/test/dash/dash_parser_segment_base_unit.js @@ -42,6 +42,7 @@ describe('DashParser SegmentBase', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; }); diff --git a/test/dash/dash_parser_segment_list_unit.js b/test/dash/dash_parser_segment_list_unit.js index 5bb26754ec..376e45d9a9 100644 --- a/test/dash/dash_parser_segment_list_unit.js +++ b/test/dash/dash_parser_segment_list_unit.js @@ -352,6 +352,7 @@ describe('DashParser SegmentList', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; try { const manifest = await dashParser.start('dummy://foo', playerInterface); diff --git a/test/dash/dash_parser_segment_template_unit.js b/test/dash/dash_parser_segment_template_unit.js index fa0a3c08dc..feaaf09c4c 100644 --- a/test/dash/dash_parser_segment_template_unit.js +++ b/test/dash/dash_parser_segment_template_unit.js @@ -51,6 +51,7 @@ describe('DashParser SegmentTemplate', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; }); diff --git a/test/hls/hls_live_unit.js b/test/hls/hls_live_unit.js index 3329dc1e98..891c6816e9 100644 --- a/test/hls/hls_live_unit.js +++ b/test/hls/hls_live_unit.js @@ -79,6 +79,7 @@ describe('HlsParser live', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; parser = new shaka.hls.HlsParser(); diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index ee18159b0b..afbcdb9517 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -92,6 +92,7 @@ describe('HlsParser', () => { newDrmInfo: shaka.test.Util.spyFunc(newDrmInfoSpy), onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; parser = new shaka.hls.HlsParser(); diff --git a/test/media/streaming_engine_integration.js b/test/media/streaming_engine_integration.js index ffe0ef7288..de4564739c 100644 --- a/test/media/streaming_engine_integration.js +++ b/test/media/streaming_engine_integration.js @@ -267,6 +267,7 @@ describe('StreamingEngine', () => { beforeAppendSegment: () => Promise.resolve(), onMetadata: () => {}, disableStream: (stream, time) => false, + isHibernated: () => false, }; streamingEngine = new shaka.media.StreamingEngine( /** @type {shaka.extern.Manifest} */(manifest), playerInterface); diff --git a/test/media/streaming_engine_unit.js b/test/media/streaming_engine_unit.js index c22ce8935e..f3d4435061 100644 --- a/test/media/streaming_engine_unit.js +++ b/test/media/streaming_engine_unit.js @@ -470,6 +470,7 @@ describe('StreamingEngine', () => { beforeAppendSegment: Util.spyFunc(beforeAppendSegment), onMetadata: Util.spyFunc(onMetadata), disableStream: Util.spyFunc(disableStream), + isHibernated: () => false, }; streamingEngine = new shaka.media.StreamingEngine( /** @type {shaka.extern.Manifest} */(manifest), playerInterface); diff --git a/test/mss/mss_parser_unit.js b/test/mss/mss_parser_unit.js index 41df61695b..e6a22bddb4 100644 --- a/test/mss/mss_parser_unit.js +++ b/test/mss/mss_parser_unit.js @@ -81,6 +81,7 @@ describe('MssParser Manifest', () => { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; }); diff --git a/test/test/util/dash_parser_util.js b/test/test/util/dash_parser_util.js index 32fc6a41ac..808e3c5a3b 100644 --- a/test/test/util/dash_parser_util.js +++ b/test/test/util/dash_parser_util.js @@ -47,6 +47,7 @@ shaka.test.Dash = class { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; try { const manifest = await dashParser.start('dummy://foo', playerInterface); @@ -89,6 +90,7 @@ shaka.test.Dash = class { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; try { diff --git a/test/test/util/mss_parser_util.js b/test/test/util/mss_parser_util.js index 3225f2f41e..3dcde927e7 100644 --- a/test/test/util/mss_parser_util.js +++ b/test/test/util/mss_parser_util.js @@ -47,6 +47,7 @@ shaka.test.Mss = class { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; const manifest = await mssParser.start('dummy://foo', playerInterface); const stream = manifest.variants[0].audio; @@ -85,6 +86,7 @@ shaka.test.Mss = class { newDrmInfo: (stream) => {}, onManifestUpdated: () => {}, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; const p = mssParser.start('dummy://foo', playerInterface); await expectAsync(p).toBeRejectedWith( diff --git a/test/util/content_steering_manager_unit.js b/test/util/content_steering_manager_unit.js index 2df28d3a19..3585f75ecf 100644 --- a/test/util/content_steering_manager_unit.js +++ b/test/util/content_steering_manager_unit.js @@ -29,6 +29,7 @@ describe('ContentSteeringManager', () => { newDrmInfo: fail, onManifestUpdated: fail, getBandwidthEstimate: () => 1e6, + isHibernated: () => false, }; const config = shaka.util.PlayerConfiguration.createDefault().manifest; manager = new shaka.util.ContentSteeringManager(playerInterface);