From 06982defa0d278a9bb870ed18fbba02db88cf687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Velad=20Galv=C3=A1n?= Date: Tue, 30 Mar 2021 18:04:30 +0200 Subject: [PATCH] feat(thumbnails): Allow download thumbnails (for offline usage) (#3280) --- demo/common/assets.js | 4 ++++ lib/offline/storage.js | 14 ++++++++++++++ lib/offline/stream_bandwidth_estimator.js | 22 ++++++++++++++++++++++ lib/util/player_configuration.js | 6 +++--- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/demo/common/assets.js b/demo/common/assets.js index cf7b289720..c85bd3adc4 100644 --- a/demo/common/assets.js +++ b/demo/common/assets.js @@ -798,6 +798,7 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.DASH) .addFeature(shakaAssets.Feature.ULTRA_HIGH_DEFINITION) .addFeature(shakaAssets.Feature.MP4) + .addFeature(shakaAssets.Feature.OFFLINE) .addFeature(shakaAssets.Feature.THUMBNAILS), new ShakaDemoAssetInfo( /* name= */ 'DASH-IF THUMBNAILS - Single adaptation set, 4 tiles at 10x1, each thumb 205x115', @@ -807,6 +808,7 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.DASH) .addFeature(shakaAssets.Feature.ULTRA_HIGH_DEFINITION) .addFeature(shakaAssets.Feature.MP4) + .addFeature(shakaAssets.Feature.OFFLINE) .addFeature(shakaAssets.Feature.THUMBNAILS), new ShakaDemoAssetInfo( /* name= */ 'DASH-IF THUMBNAILS - Single adaptation set, 1 tile at 10x20, each thumb 102x58', @@ -816,6 +818,7 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.DASH) .addFeature(shakaAssets.Feature.ULTRA_HIGH_DEFINITION) .addFeature(shakaAssets.Feature.MP4) + .addFeature(shakaAssets.Feature.OFFLINE) .addFeature(shakaAssets.Feature.THUMBNAILS), new ShakaDemoAssetInfo( /* name= */ 'DASH-IF THUMBNAILS - Two adaptation sets with different thumb resolutions', @@ -825,6 +828,7 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.DASH) .addFeature(shakaAssets.Feature.ULTRA_HIGH_DEFINITION) .addFeature(shakaAssets.Feature.MP4) + .addFeature(shakaAssets.Feature.OFFLINE) .addFeature(shakaAssets.Feature.THUMBNAILS), new ShakaDemoAssetInfo( /* name= */ 'DASH-IF THUMBNAILS - Live stream, Single adaptation set, 1x1 tiles (livesim)', diff --git a/lib/offline/storage.js b/lib/offline/storage.js index d1f0a77892..3f0bc66110 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -549,6 +549,8 @@ shaka.offline.Storage = class { const variantIds = new Set(); /** @type {!Set.} */ const textIds = new Set(); + /** @type {!Set.} */ + const imageIds = new Set(); // Collect the IDs of the chosen tracks. for (const track of chosenTracks) { @@ -558,6 +560,9 @@ shaka.offline.Storage = class { if (track.type == 'text') { textIds.add(track.id); } + if (track.type == 'image') { + imageIds.add(track.id); + } } // Filter the manifest to keep only what the app chose. @@ -565,6 +570,8 @@ shaka.offline.Storage = class { manifest.variants.filter((variant) => variantIds.has(variant.id)); manifest.textStreams = manifest.textStreams.filter((stream) => textIds.has(stream.id)); + manifest.imageStreams = + manifest.imageStreams.filter((stream) => imageIds.has(stream.id)); // Check the post-filtered manifest for characteristics that may indicate // issues with how the app selected tracks. @@ -1063,6 +1070,9 @@ shaka.offline.Storage = class { for (const text of manifest.textStreams) { estimator.addText(text); } + for (const image of manifest.imageStreams) { + estimator.addImage(image); + } // TODO(joeyparrish): Break out stack-based state and method params into a // separate class to clean up. See: @@ -1487,6 +1497,10 @@ shaka.offline.Storage = class { set.add(text); } + for (const image of manifest.imageStreams) { + set.add(image); + } + for (const variant of manifest.variants) { if (variant.audio) { set.add(variant.audio); diff --git a/lib/offline/stream_bandwidth_estimator.js b/lib/offline/stream_bandwidth_estimator.js index 3ddb8ebb5a..1904615109 100644 --- a/lib/offline/stream_bandwidth_estimator.js +++ b/lib/offline/stream_bandwidth_estimator.js @@ -93,6 +93,16 @@ shaka.offline.StreamBandwidthEstimator = class { shaka.offline.StreamBandwidthEstimator.DEFAULT_TEXT_BITRATE_; } + /** + * Create an estimate for the image stream. + * + * @param {shaka.extern.Stream} image + */ + addImage(image) { + this.estimateByStreamId_[image.id] = image.bandwidth || + shaka.offline.StreamBandwidthEstimator.DEFAULT_IMAGE_BITRATE_; + } + /** * Get the estimate for a segment that is part of a stream that has already * added to the estimator. @@ -171,3 +181,15 @@ shaka.offline.StreamBandwidthEstimator.DEFAULT_AUDIO_BITRATE_ = 393216; */ shaka.offline.StreamBandwidthEstimator.DEFAULT_TEXT_BITRATE_ = 52; + +/** + * Since we don't normally get the bitrate for image, we still want to create + * some approximation so that it can influence progress. + * + * The size of the thumbnail usually is 2KB. + * + * @const {number} + * @private + */ +shaka.offline.StreamBandwidthEstimator.DEFAULT_IMAGE_BITRATE_ = 2048; + diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index 279d4ee34d..550c9c8a4b 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -381,11 +381,11 @@ shaka.util.PlayerConfiguration = class { // Since this default callback is used primarily by our own demo app and by // app developers who haven't thought about which tracks they want, we - // should select all text tracks, regardless of language. This makes for a - // better demo for us, and does not rely on user preferences for the + // should select all image/text tracks, regardless of language. This makes + // for a better demo for us, and does not rely on user preferences for the // unconfigured app. for (const track of tracks) { - if (track.type == ContentType.TEXT) { + if (track.type == ContentType.TEXT || track.type == ContentType.IMAGE) { selectedTracks.push(track); } }