From 0cbbafcdf00446388c9ddb27f6f88fdd761528f2 Mon Sep 17 00:00:00 2001 From: "Warren R. Bank" Date: Tue, 6 Jun 2023 20:20:39 -0700 Subject: [PATCH] change how 'Download' button saves the current video to offline cache background: =========== * when video caching is enabled as an API parameter, - for example: curl --silent -X POST \ -H "Content-Type: text/parameters" \ --data-binary "Content-Location: ${video_url}\nUse-Cache: true" \ "http://${airplay_ip}/play" - then: * downloading starts when playback starts * if the video is added to the end of a queue, this doesn't happen immediately - and, most importantly: * only the "default" tracks in an adaptive manifest will download previously: =========== * when video caching is not enabled as an API parameter, but enabled during playback, by clicking the 'Download' toggle button in the video player UI - then: * only the "default" tracks in an adaptive manifest will download now: ==== * when the user enables video caching for the current video, by clicking the 'Download' toggle button in the video player UI - then: * only the tracks that are currently enabled will download - where: * the 'Select Tracks' button in the video player UI allows the user to selectively enable or disable individual tracks * any such track selections made before enabling video caching will be applied to the download process, but only for the current video - with the caveat: * additional tracks cannot be added after a download is started * the only way to do so is to: - stop the download, which deletes all previously selected tracks from cache - start again, with a different selection of tracks enabled example: ======== * test setup: - adaptive master manifest with streams for resolutions: 2592x1944, 2048x1536, 1920x1080, 1280x960, 1280x720, 704x576, 640x480 - ExoAirPlayer v3.4.4 - TCL A501DL w/ 854x480 screen * test results: - downloading only the "default" tracks * requests ts video segments for: 640x480 - downloading with enabled tracks: 1280x720 * requests ts video segments for: 1280x720 - downloading with enabled tracks: 1920x1080, 1280x960, 1280x720 * requests ts video segments for: 1920x1080, 1280x960, 1280x720 --- .../exoplayer2/DownloadTracker.java | 21 ++++++++++++------- .../exoplayer2/PlayerManager.java | 6 +++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/DownloadTracker.java b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/DownloadTracker.java index 8321d6e..d30355b 100644 --- a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/DownloadTracker.java +++ b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/DownloadTracker.java @@ -18,6 +18,7 @@ import androidx.media3.common.Format; import androidx.media3.common.MediaItem; import androidx.media3.common.TrackGroup; +import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.util.Log; import androidx.media3.common.util.Util; import androidx.media3.datasource.HttpDataSource; @@ -148,15 +149,16 @@ public void startDownloadService() { public void startDownload(MediaItem mediaItem, RenderersFactory renderersFactory) { @Nullable Download download = downloads.get(checkNotNull(mediaItem.playbackProperties).uri); - startDownload(download, mediaItem, renderersFactory); + startDownload(download, mediaItem, renderersFactory, null); } - public void startDownload(Download download, MediaItem mediaItem, RenderersFactory renderersFactory) { + public void startDownload(Download download, MediaItem mediaItem, RenderersFactory renderersFactory, TrackSelectionParameters trackSelectionParameters) { if (download == null || download.state == Download.STATE_FAILED) { - new StartDownloadHelper( - DownloadHelper.forMediaItem(context, mediaItem, renderersFactory, httpDataSourceFactory), - mediaItem - ); + if (trackSelectionParameters == null) { + trackSelectionParameters = DownloadHelper.getDefaultTrackSelectorParameters(context); + } + DownloadHelper downloadHelper = DownloadHelper.forMediaItem(mediaItem, trackSelectionParameters, renderersFactory, httpDataSourceFactory); + new StartDownloadHelper(downloadHelper, mediaItem); } } @@ -171,13 +173,13 @@ public void stopDownload(Download download) { } } - public void toggleDownload(MediaItem mediaItem, RenderersFactory renderersFactory) { + public void toggleDownload(MediaItem mediaItem, RenderersFactory renderersFactory, TrackSelectionParameters trackSelectionParameters) { @Nullable Download download = downloads.get(checkNotNull(mediaItem.playbackProperties).uri); if (download != null && download.state != Download.STATE_FAILED) { stopDownload(download); } else { - startDownload(download, mediaItem, renderersFactory); + startDownload(download, mediaItem, renderersFactory, trackSelectionParameters); } } @@ -362,6 +364,9 @@ private void startDownload() { } private void startDownload(DownloadRequest downloadRequest) { + if ((downloadRequest == null) || downloadRequest.streamKeys.isEmpty()) + return; + DownloadService.sendAddDownload(context, MyDownloadService.class, downloadRequest, /* foreground= */ false); } diff --git a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java index ce75954..a572f2a 100644 --- a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java +++ b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java @@ -755,7 +755,11 @@ public void toggleCurrentItemUseCache() { if (mediaItem == null) return; sample.updateUseCache(!sample.useCache); - downloadTracker.toggleDownload(mediaItem, renderersFactory); + downloadTracker.toggleDownload( + mediaItem, + renderersFactory, + ((exoPlayer == null) ? null : exoPlayer.getTrackSelectionParameters()) + ); } // AirPlay functionality (exposed by HTTP endpoints)