From c18bdb3abba4dcd3de602349a7cd54f4aef561b6 Mon Sep 17 00:00:00 2001 From: aliveoutside <53598473+aliveoutside@users.noreply.github.com> Date: Mon, 19 Sep 2022 20:11:43 +0300 Subject: [PATCH] [music] playlist caching --- .../lite/downloaders/AudioDownloader.java | 47 +++++++++---------- .../lite/hooks/ui/MusicBottomSheetHook.java | 2 +- .../music/cache/CacheDatabaseDelegate.java | 4 ++ .../music/downloader/PlaylistDownloader.java | 27 ++++++++++- .../music/downloader/TrackDownloader.java | 17 +++---- 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/downloaders/AudioDownloader.java b/app/src/main/java/ru/vtosters/lite/downloaders/AudioDownloader.java index cf3e96cd6..338c42818 100644 --- a/app/src/main/java/ru/vtosters/lite/downloaders/AudioDownloader.java +++ b/app/src/main/java/ru/vtosters/lite/downloaders/AudioDownloader.java @@ -12,11 +12,8 @@ import com.vk.dto.music.Playlist; import java.io.File; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.stream.Collectors; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; -import java8.util.concurrent.CompletableFuture; -import ru.vtosters.lite.downloaders.notifications.NotificationChannels; import ru.vtosters.lite.music.cache.CacheDatabaseDelegate; import ru.vtosters.lite.music.cache.FileCacheImplementation; import ru.vtosters.lite.music.callback.MusicCallbackBuilder; @@ -50,7 +47,7 @@ public class AudioDownloader { tracks, IOUtils.getValidFileName(playlist.g), downloadPath, - MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId) + MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId) ); } @@ -59,22 +56,6 @@ public class AudioDownloader { downloadM3U8(track, false); } - private static void downloadM3U8(MusicTrack track, boolean cache) { - if (track.D == null) { - ToastUtils.a(getString("link_audio_error")); - return; - } - - var musicPath = cache - ? getTrackFolder(LibVKXClient.asId(track)).getAbsolutePath() - : Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath(); - var tempId = track.d; - var downloadPath = musicPath + File.separator; - var notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId); - - TrackDownloader.downloadTrack(track, downloadPath, MusicCallbackBuilder.buildOneTrackCallback(tempId, notification), cache); - } - public static void cacheTrack(MusicTrack track) { var trackId = track.y1(); if (CacheDatabaseDelegate.isCached(trackId)) { @@ -88,17 +69,33 @@ public class AudioDownloader { downloadM3U8(track, true); MusicNotificationBuilder.notifySavingToCache(track); CacheDatabaseDelegate.insertTrack(track); - NotificationChannels.getNotificationManager().cancel(trackId.hashCode()); } public static void cachePlaylist(Playlist playlist) { var tracks = PlaylistConverter.getPlaylist(playlist); - var tracksWithUrls = tracks.stream().filter(track -> !track.D.isEmpty()).collect(Collectors.toList()); - for (MusicTrack musicTrack : tracksWithUrls) { - CompletableFuture.runAsync(() -> cacheTrack(musicTrack), executor); - } + var notificationId = playlist.g.hashCode(); + var notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlist.g, notificationId); + + PlaylistDownloader.cachePlaylist( + tracks, + MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId) + ); } + private static void downloadM3U8(MusicTrack track, boolean cache) { + if (track.D == null) { + ToastUtils.a(getString("link_audio_error")); + return; + } + var musicPath = cache + ? getTrackFolder(LibVKXClient.asId(track)).getAbsolutePath() + : Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath(); + var tempId = track.d; + var downloadPath = musicPath + File.separator; + var notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId); + + TrackDownloader.downloadTrack(track, downloadPath, MusicCallbackBuilder.buildOneTrackCallback(tempId, notification)); + } } diff --git a/app/src/main/java/ru/vtosters/lite/hooks/ui/MusicBottomSheetHook.java b/app/src/main/java/ru/vtosters/lite/hooks/ui/MusicBottomSheetHook.java index bf8ff990d..6695a00ff 100644 --- a/app/src/main/java/ru/vtosters/lite/hooks/ui/MusicBottomSheetHook.java +++ b/app/src/main/java/ru/vtosters/lite/hooks/ui/MusicBottomSheetHook.java @@ -131,7 +131,7 @@ public class MusicBottomSheetHook { if (actionId == AndroidUtils.getIdentifier("add_to_cache", "id")) { executor.submit(() -> AudioDownloader.cachePlaylist(playlist)); - return true; + return true; } if (actionId == AndroidUtils.getIdentifier("download_mp3", "id")) { diff --git a/app/src/main/java/ru/vtosters/lite/music/cache/CacheDatabaseDelegate.java b/app/src/main/java/ru/vtosters/lite/music/cache/CacheDatabaseDelegate.java index 4244a6603..11d22191c 100644 --- a/app/src/main/java/ru/vtosters/lite/music/cache/CacheDatabaseDelegate.java +++ b/app/src/main/java/ru/vtosters/lite/music/cache/CacheDatabaseDelegate.java @@ -87,6 +87,10 @@ public class CacheDatabaseDelegate { } } + public static void insertTracks(List tracks) { + for (var track : tracks) insertTrack(track); + } + public static void clear() { getHelper().getReadableDatabase().execSQL(String.format("DELETE FROM %s", TABLE_NAME)); deleteRecursive(getCacheDir()); diff --git a/app/src/main/java/ru/vtosters/lite/music/downloader/PlaylistDownloader.java b/app/src/main/java/ru/vtosters/lite/music/downloader/PlaylistDownloader.java index 6e2c2cd3c..6a4589ec3 100644 --- a/app/src/main/java/ru/vtosters/lite/music/downloader/PlaylistDownloader.java +++ b/app/src/main/java/ru/vtosters/lite/music/downloader/PlaylistDownloader.java @@ -12,6 +12,7 @@ import java.util.concurrent.atomic.AtomicInteger; import ru.vtosters.lite.downloaders.notifications.NotificationChannels; import ru.vtosters.lite.music.Callback; +import ru.vtosters.lite.music.cache.CacheDatabaseDelegate; public class PlaylistDownloader { private static NotificationManagerCompat notificationManager = NotificationChannels.getNotificationManager(); @@ -42,7 +43,31 @@ public class PlaylistDownloader { @Override public void onSizeReceived(long size, long header) {} - }, false); + }); + } + } + + public static void cachePlaylist(List playlist, Callback callback) { + var downloadedTracks = new AtomicInteger(0); + + for (MusicTrack musicTrack : playlist) { + TrackDownloader.cacheTrack(musicTrack, new Callback() { + @Override + public void onProgress(int progress) {} + + @Override + public void onSuccess() { + var currentProgress = downloadedTracks.incrementAndGet(); + callback.onProgress(currentProgress); + CacheDatabaseDelegate.insertTrack(musicTrack); + } + + @Override + public void onFailure() {} + + @Override + public void onSizeReceived(long size, long header) {} + }); } } } \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/music/downloader/TrackDownloader.java b/app/src/main/java/ru/vtosters/lite/music/downloader/TrackDownloader.java index fa69fc586..9f38a2f9b 100644 --- a/app/src/main/java/ru/vtosters/lite/music/downloader/TrackDownloader.java +++ b/app/src/main/java/ru/vtosters/lite/music/downloader/TrackDownloader.java @@ -6,19 +6,20 @@ import com.vk.dto.music.MusicTrack; import java.io.File; +import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import ru.vtosters.lite.music.Callback; import ru.vtosters.lite.music.M3UDownloader; +import ru.vtosters.lite.music.cache.FileCacheImplementation; import ru.vtosters.lite.music.interfaces.ITrackDownloader; public class TrackDownloader { - /** - * Download track - * @param track Track to download - * @param path Folder where to put track - * @param callback Callback to call when download status changes - */ - public static void downloadTrack(MusicTrack track, String path, Callback callback, boolean cache) { - download(track, path, callback, M3UDownloader.getInstance(), cache); + public static void downloadTrack(MusicTrack track, String path, Callback callback) { + download(track, path, callback, M3UDownloader.getInstance(), false); + } + + public static void cacheTrack(MusicTrack track, Callback callback) { + var path = FileCacheImplementation.getTrackFolder(LibVKXClient.asId(track)).getAbsolutePath(); + download(track, path, callback, M3UDownloader.getInstance(), true); } private static void download(MusicTrack track, String path, Callback callback, ITrackDownloader downloader, boolean cache) {