[music] playlist caching

This commit is contained in:
aliveoutside
2022-09-19 20:11:43 +03:00
parent 827f10392f
commit c18bdb3abb
5 changed files with 62 additions and 35 deletions
@@ -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));
}
}
@@ -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")) {
@@ -87,6 +87,10 @@ public class CacheDatabaseDelegate {
}
}
public static void insertTracks(List<MusicTrack> tracks) {
for (var track : tracks) insertTrack(track);
}
public static void clear() {
getHelper().getReadableDatabase().execSQL(String.format("DELETE FROM %s", TABLE_NAME));
deleteRecursive(getCacheDir());
@@ -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<MusicTrack> 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) {}
});
}
}
}
@@ -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) {