From 82f3f76cc7a9696b5cca429ab7e2b8ed8a50883d Mon Sep 17 00:00:00 2001 From: Alvaro Velad Date: Wed, 27 Apr 2022 09:12:18 +0200 Subject: [PATCH] fix(offline): offline downloads are slow --- demo/common/message_ids.js | 1 + demo/config.js | 4 +++- demo/locales/en.json | 1 + demo/locales/source.json | 4 ++++ demo/main.js | 3 +++ externs/shaka/player.js | 9 ++++++++- lib/offline/storage.js | 11 ++++++++++- lib/util/player_configuration.js | 2 ++ 8 files changed, 32 insertions(+), 3 deletions(-) diff --git a/demo/common/message_ids.js b/demo/common/message_ids.js index 76b4eab01c..479ec88326 100644 --- a/demo/common/message_ids.js +++ b/demo/common/message_ids.js @@ -223,6 +223,7 @@ shakaDemo.MessageIds = { NUMBER_INTEGER_WARNING: 'DEMO_NUMBER_INTEGER_WARNING', NUMBER_NONZERO_DECIMAL_WARNING: 'DEMO_NUMBER_NONZERO_DECIMAL_WARNING', NUMBER_NONZERO_INTEGER_WARNING: 'DEMO_NUMBER_NONZERO_INTEGER_WARNING', + NUMBER_OF_PARALLEL_SEGMENTS_BY_STREAM: 'DEMO_NUMBER_OF_PARALLEL_SEGMENTS_BY_STREAM', OFFLINE_SECTION_HEADER: 'DEMO_OFFLINE_SECTION_HEADER', PREFER_FORCED_SUBS: 'DEMO_PREFER_FORCED_SUBS', PREFER_NATIVE_HLS: 'DEMO_PREFER_NATIVE_HLS', diff --git a/demo/config.js b/demo/config.js index b44071df05..1169630e6d 100644 --- a/demo/config.js +++ b/demo/config.js @@ -341,7 +341,9 @@ shakaDemo.Config = class { const docLink = this.resolveExternLink_('.OfflineConfiguration'); this.addSection_(MessageIds.OFFLINE_SECTION_HEADER, docLink) .addBoolInput_(MessageIds.USE_PERSISTENT_LICENSES, - 'offline.usePersistentLicense'); + 'offline.usePersistentLicense') + .addNumberInput_(MessageIds.NUMBER_OF_PARALLEL_SEGMENTS_BY_STREAM, + 'offline.numberOfParallelSegmentsByStream'); } /** @private */ diff --git a/demo/locales/en.json b/demo/locales/en.json index 080c9457ac..73d184764a 100644 --- a/demo/locales/en.json +++ b/demo/locales/en.json @@ -159,6 +159,7 @@ "DEMO_NUMBER_INTEGER_WARNING": "Must be a positive integer.", "DEMO_NUMBER_NONZERO_DECIMAL_WARNING": "Must be a positive, nonzero number.", "DEMO_NUMBER_NONZERO_INTEGER_WARNING": "Must be a positive, nonzero integer.", + "DEMO_NUMBER_OF_PARALLEL_SEGMENTS_BY_STREAM": "Number of parallel segments by stream", "DEMO_OBSERVE_QUALITY_CHANGES": "Observe media quality changes", "DEMO_OFFLINE": "Downloadable", "DEMO_OFFLINE_SEARCH": "Filters for assets that can be stored offline.", diff --git a/demo/locales/source.json b/demo/locales/source.json index 753888df71..dd515e3e9e 100644 --- a/demo/locales/source.json +++ b/demo/locales/source.json @@ -639,6 +639,10 @@ "description": "A warning on number inputs, telling the user what the expected input format is.", "message": "Must be a positive, nonzero integer." }, + "DEMO_NUMBER_OF_PARALLEL_SEGMENTS_BY_STREAM": { + "description": "The name of a configuration value.", + "message": "Number of parallel segments by stream." + }, "DEMO_OBSERVE_QUALITY_CHANGES": { "description": "The name of a configuration value.", "message": "Observe media quality changes" diff --git a/demo/main.js b/demo/main.js index c3d3b26092..95a24da1ba 100644 --- a/demo/main.js +++ b/demo/main.js @@ -582,7 +582,10 @@ shakaDemo.Main = class { }; asset.storedProgress = 0; this.dispatchEventWithName_('shaka-main-offline-progress'); + const start = Date.now(); const stored = await storage.store(asset.manifestUri, metadata).promise; + const end = Date.now(); + console.log('Download time:', end - start); asset.storedContent = stored; } catch (error) { this.onError_(/** @type {!shaka.util.Error} */ (error)); diff --git a/externs/shaka/player.js b/externs/shaka/player.js index 886fffb5f8..0fbb0e7d77 100644 --- a/externs/shaka/player.js +++ b/externs/shaka/player.js @@ -1075,7 +1075,8 @@ shaka.extern.CmcdConfiguration; * function(shaka.extern.TrackList):!Promise, * downloadSizeCallback: function(number):!Promise, * progressCallback: function(shaka.extern.StoredContent,number), - * usePersistentLicense: boolean + * usePersistentLicense: boolean, + * numberOfParallelSegmentsByStream: number * }} * * @property {function(shaka.extern.TrackList):!Promise} @@ -1098,6 +1099,12 @@ shaka.extern.CmcdConfiguration; * license. A network will be required to retrieve a temporary license to * view. * Defaults to true. + * @property {number} numberOfParallelSegmentsByStream + * Number of parallel segments by stream. Putting a number other than the + * default can help reduce download time. + * Note: normally browsers limit to 5 request in parallel, so putting a + * number higher than this will not help it download faster. + * Defaults to 1. * @exportDoc */ shaka.extern.OfflineConfiguration; diff --git a/lib/offline/storage.js b/lib/offline/storage.js index 04eb8eca93..3acc03a007 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -1334,10 +1334,19 @@ shaka.offline.Storage = class { if (!toDownload.has(pendingSegmentRefId)) { const estimateId = downloader.addDownloadEstimate( estimator.getSegmentEstimate(stream.id, segment)); + let groupId = stream.id; + const numberOfParallelSegmentsByStream = + config.offline.numberOfParallelSegmentsByStream; + if (numberOfParallelSegmentsByStream > 1) { + // Note: 1000 is a random number to not coincide with other groups + // of other streams + groupId += 1000 + Math.floor(Math.random() * + numberOfParallelSegmentsByStream); + } const segmentDownload = new shaka.offline.DownloadInfo( segment, estimateId, - stream.id, + groupId, /* isInitSegment= */ false); toDownload.set(pendingSegmentRefId, segmentDownload); } diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index 6a6eda9c4a..f4d8863a25 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -222,6 +222,8 @@ shaka.util.PlayerConfiguration = class { // unexpected behaviours when someone tries to plays downloaded content // without a persistent license. usePersistentLicense: true, + + numberOfParallelSegmentsByStream: 1, }; const abr = {