caching/downloading own music (without playlists)

This commit is contained in:
gdlbo
2022-09-19 22:14:55 +03:00
parent c18bdb3abb
commit 4534ed1156
5 changed files with 156 additions and 5 deletions
@@ -1,6 +1,7 @@
package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.music.cache.FileCacheImplementation.getTrackFolder;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.os.Environment;
@@ -18,6 +19,7 @@ import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
import ru.vtosters.lite.music.cache.FileCacheImplementation;
import ru.vtosters.lite.music.callback.MusicCallbackBuilder;
import ru.vtosters.lite.music.converter.playlist.PlaylistConverter;
import ru.vtosters.lite.music.downloader.AudioGet;
import ru.vtosters.lite.music.downloader.PlaylistDownloader;
import ru.vtosters.lite.music.downloader.TrackDownloader;
import ru.vtosters.lite.music.notification.MusicNotificationBuilder;
@@ -83,6 +85,37 @@ public class AudioDownloader {
);
}
public static void cacheAllAudios() {
var tracks = AudioGet.getAudios();
var notificationId = getUserId();
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
PlaylistDownloader.cachePlaylist(
tracks,
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId)
);
}
public static void downloadAllAudios() {
var tracks = AudioGet.getAudios();
var notificationId = getUserId();
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
var playlistName = "Audios of " + getUserId();
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
var downloadPath = musicPath + File.separator + playlistName;
PlaylistDownloader.downloadPlaylist(
tracks,
playlistName,
downloadPath,
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId)
);
}
private static void downloadM3U8(MusicTrack track, boolean cache) {
if (track.D == null) {
ToastUtils.a(getString("link_audio_error"));
@@ -0,0 +1,81 @@
package ru.vtosters.lite.music.downloader;
import static ru.vtosters.lite.hooks.DateHook.getLocale;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.core.util.DeviceIdProvider;
import com.vk.dto.music.MusicTrack;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java8.util.concurrent.CompletableFuture;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.utils.AndroidUtils;
public class AudioGet{
public static List<MusicTrack> getAudios(){
var tracks = requestAudios(0);
return tracks != null ? tracks.stream().filter(track -> !track.D.isEmpty()).collect(Collectors.toList()) : null;
}
private static List<MusicTrack> requestAudios(int offset){
var audioCount = 1000;
var requestUrl = "https://" + getApi() + "/method/audio.get" +
"?v=5.119" +
"&https=1" +
"&count=" + audioCount +
"&device_id=" + DeviceIdProvider.d(AndroidUtils.getGlobalContext()) +
"&owner_id=" + getUserId() +
"&access_key=" + getUserToken() +
"&lang=" + getLocale() +
"&offset=" + offset +
"&access_token=" + getUserToken();
var request = new Request.a()
.b(requestUrl)
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
try {
var response = CompletableFuture.supplyAsync(() -> {
try {
return new OkHttpClient().a(request).execute().a().g();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
).get();
var jsonObj = new JSONObject(response);
if (!jsonObj.has("response"))
return null;
Log.d("AudioGet", jsonObj.toString());
var audios = new JSONObject(response).getJSONObject("response").getJSONArray("items");
var tracks = new ArrayList<MusicTrack>();
for (int i = 0; i < audios.length(); i++) {
var track = new MusicTrack(audios.getJSONObject(i));
tracks.add(track);
}
if (tracks.size() == audioCount) {
tracks.addAll(requestAudios(offset + audioCount));
}
return tracks;
} catch (JSONException | ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
@@ -11,6 +11,7 @@ import androidx.core.app.NotificationManagerCompat;
import com.vk.dto.music.MusicTrack;
import ru.vtosters.lite.downloaders.notifications.NotificationChannels;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
public class MusicNotificationBuilder {
@@ -42,6 +43,19 @@ public class MusicNotificationBuilder {
return notificationBuilder;
}
public static NotificationCompat.Builder buildAllAudiosDownloadNotification(int id) {
var notificationBuilder = new NotificationCompat.Builder(AndroidUtils.getGlobalContext(), NotificationChannels.MUSIC_PLAYLIST_DOWNLOAD_CHANNEL_ID)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle("Скачивание всех аудио")
.setContentText("Все аудио " + AccountManagerUtils.getUsername())
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
.setAutoCancel(true)
.setProgress(100, 0, false);
notificationManager.notify(id, notificationBuilder.build());
return notificationBuilder;
}
public static void notifySavingToCache(MusicTrack track) {
Notification.Builder builder;
@@ -39,10 +39,13 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.downloaders.VideoDownloader;
import ru.vtosters.lite.music.Scrobbler;
import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
@@ -51,11 +54,7 @@ import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils;
public class MediaFragment extends MaterialPreferenceToolbarFragment {
private final int REQUEST_CODE_SET_DOWNLOAD_DIRECTORY = 665;
private final int REQUEST_CODE_SET_MUSIC_DIRECTORY = 666;
private final int REQUEST_CODE_SET_PHOTOS_DIRECTORY = 667;
private final int REQUEST_CODE_SET_VIDEOS_DIRECTORY = 668;
private static final ExecutorService executor = Executors.newCachedThreadPool();
@Override
public void onCreate(Bundle bundle) {
@@ -102,6 +101,11 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("audio_download").setOnPreferenceClickListener(preference -> {
dlaudio(requireContext());
return true;
});
if (!isVkxInstalled()){
findPreference("vkx_sett").setVisible(false);
}
@@ -201,6 +205,22 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getResources().getColor(com.vtosters.lite.R.color.red));
}
private void dlaudio(Context ctx) {
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(ctx);
alertDialog.setTitle("Способ скачивания");
alertDialog.setMessage("Выберите способ скачивания всех своих аудио (без плейлистов)");
alertDialog.setPositiveButton("В кеш", (dialog, which) -> {
executor.submit(AudioDownloader::cacheAllAudios);
});
alertDialog.setNegativeButton("Как mp3", (dialog, which) -> {
executor.submit(AudioDownloader::downloadAllAudios);
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
alert.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(getAccentColor());;
}
public static void deleteVideoHistory() {
Thread thread = new Thread(() -> {
try {