Compare commits

...
Author SHA1 Message Date
aliveoutside 41763a4b54 master.m3u8 fix 2024-03-26 22:59:32 +03:00
gdlbo d98d81f105 fixed autocache text dialog with dark theme 2024-03-26 17:47:10 +03:00
Artur Skubei 899554a571 Music autocaching v2 (#1591) 2024-03-26 17:36:34 +03:00
7 changed files with 100 additions and 28 deletions
@@ -2,7 +2,6 @@ package com.vk.libvideo;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
@@ -11,7 +10,6 @@ import com.vk.dto.common.VideoFile;
import com.vk.media.player.PlayerTypes;
import com.vk.navigation.NavigatorKeys;
import com.vk.statistic.Statistic;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
@@ -333,6 +331,6 @@ public class VideoTracker {
jsonObject.put("position_sec", 0);
jsonObject.put("cur_quality", "auto");
Metrics.trackEvents(jsonObject);
Metrics.trackEvents(jsonObject, false);
}
}
@@ -11,7 +11,6 @@ import com.vk.music.stats.i.MusicPlaybackParams;
import com.vk.navigation.NavigatorKeys;
import com.vtosters.lite.data.Analytics;
import kotlin.jvm.b.Functions2;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
@@ -185,7 +184,7 @@ public final class VKMusicStatsTracker implements MusicStatsTracker {
}
}
Metrics.trackEvents(event);
Metrics.trackEvents(event, true);
}
private Analytics.l a(MusicPlaybackParams musicPlaybackParams, String str) {
@@ -100,8 +100,8 @@ public class Preferences {
return getBoolValue("vkme", false);
}
public static boolean autocache() {
return getBoolValue("autocache", false);
public static int autocache() {
return Preferences.getPreferences().getInt("autocaching", 0);
}
public static boolean adsstories() {
@@ -30,6 +30,7 @@ import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicTrackUtils;
@@ -50,13 +51,14 @@ public class LastFMScrobbler {
var access_key = !TextUtils.isEmpty(musictrack.J) ? musictrack.J : "";
var album_id = musictrack.I;
var album = album_id != null ? album_id.getTitle() : null;
var isOwnTrack = musictrack.e == AccountManagerUtils.getUserId();
if (TextUtils.isEmpty(uid) || TextUtils.isEmpty(artist) || TextUtils.isEmpty(title) || duration == 0) {
Log.d("Scrobbler", "grabTrackInfo: " + "Empty track, info: " + artist + " - " + title + " - " + duration + " - " + uid);
return;
}
if (Preferences.autocache() && !MusicCacheImpl.isCachedTrack(uid)) {
if (needToCache(isOwnTrack) && !MusicCacheImpl.isCachedTrack(uid)) {
if (LibVKXClient.isIntegrationEnabled()) {
LibVKXClient.getInstance().runOnService(service -> {
try {
@@ -73,6 +75,12 @@ public class LastFMScrobbler {
scrobbleTrack(duration, artist, title, uid, album);
}
private static boolean needToCache(boolean isOwnTrack) {
int autocache = Preferences.autocache();
return autocache == 2 || (autocache == 1 && isOwnTrack);
}
public static void scrobbleTrack(
long duration,
String artist,
@@ -8,9 +8,11 @@ import com.google.android.exoplayer2.source.hls.playlist.e;
import com.google.android.exoplayer2.source.hls.playlist.f;
import com.google.android.exoplayer2.source.hls.playlist.f.a;
import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
@@ -20,7 +22,6 @@ import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.vk.dto.music.Playlist;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.music.converter.ts.MpegDemuxer;
import ru.vtosters.lite.music.interfaces.Callback;
@@ -37,17 +38,29 @@ public final class Mp3Downloader implements ITrackDownloader {
@Override
public void download(MusicTrack track, Callback callback, Playlist playlist) {
String uri = track.D;
if (Objects.requireNonNull(uri).isEmpty()) {
String msg = "link error: " + track.y1() + ", title: " + Mp3Downloader.getTitle(track);
Log.d("Mp3Downloader", msg);
throw new RuntimeException(msg);
}
var tsParser = new com.google.android.exoplayer2.source.hls.playlist.h(e.a(track.D));
var baseUri = track.D.substring(0, track.D.lastIndexOf("/") + 1);
if (Objects.requireNonNull(uri).contains("master.m3u8?siren=1")) {
try {
String content = IOUtils.readAllLines(new URL(uri).openStream());
String replacement = content.split("\n")[2].trim();
uri = uri.replace("master.m3u8?siren=1", replacement);
} catch (IOException e) {
callback.onFailure(e);
return;
}
}
var tsParser = new com.google.android.exoplayer2.source.hls.playlist.h(e.a(uri));
var baseUri = uri.substring(0, uri.lastIndexOf("/") + 1);
try {
var segments = ((f) tsParser.a(Uri.parse(baseUri), IOUtils.openStream(track.D))).o;
var segments = ((f) tsParser.a(Uri.parse(baseUri), IOUtils.openStream(uri))).o;
byte[] buff = getMergedTs(baseUri, segments, callback);
MpegDemuxer.convert(buff, outputFile.getAbsolutePath());
@@ -3,9 +3,12 @@ package ru.vtosters.lite.ui.fragments;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.dto.music.Playlist;
@@ -20,10 +23,13 @@ import ru.vtosters.lite.ui.PreferenceFragmentUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static ru.vtosters.hooks.other.ThemesUtils.getTextAttr;
public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
private static final ExecutorService executor = Executors.newCachedThreadPool();
@@ -93,15 +99,38 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
}
).setEnabled(!MusicCacheImpl.isEmpty());
PreferenceFragmentUtils.addMaterialSwitchPreference(
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"autocache",
"autocache_params",
getString(com.vtosters.lite.R.string.autocache_title),
getString(com.vtosters.lite.R.string.autocache_summ),
getAutocacheSumm(),
null,
false,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("autocache", (boolean) o).apply();
preference -> {
List<String> items = Arrays.asList("Не кешировать", "Только свои", "Все");
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, items) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
textView.setTextColor(getTextAttr());
return textView;
}
};
int selectedItem = Preferences.getPreferences().getInt("autocaching", 0);
if (selectedItem >= 0 && selectedItem < items.size()) {
adapter.getItem(selectedItem);
}
new VkAlertDialog.Builder(getActivity())
.setAdapter(adapter, (dialog, which) -> {
adapter.getItem(which);
Preferences.getPreferences().edit().putInt("autocaching", which).apply();
findPreference("autocache_params").setSummary(getAutocacheSumm());
dialog.cancel();
})
.show();
return true;
}
);
@@ -166,6 +195,7 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
return;
}
Preferences.setMetadataSeparator(separator.getText().toString());
findPreference("metadataSeparator").setSummary(separator.getText().toString());
})
.setNegativeButton("Отмена", (dialog, which) -> dialog.cancel())
.show();
@@ -334,6 +364,15 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
.show();
}
private static String getAutocacheSumm() {
int autocache = Preferences.autocache();
return switch (autocache) {
case 1 -> "Только для своих";
case 2 -> "Кешировать всё";
default -> "Отключено";
};
}
public void updateLastFmPref() {
if (LastFMScrobbler.isLoggedIn()) {
findPreference("lastfm_auth").setSummary(getString(com.vtosters.lite.R.string.lastfm_authorized_as) + " " + LastFMScrobbler.getUserName());
@@ -355,7 +394,8 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
.show();
}
private static void cachedPlaylistsDialog(Context ctx) {
@SuppressLint("DefaultLocale")
private void cachedPlaylistsDialog(Context ctx) {
List<Playlist> playlists = PlaylistCacheDbDelegate.getAllPlaylists(ctx);
String[] playlistNames = new String[playlists.size()];
@@ -370,6 +410,7 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
String playlistId = selectedPlaylist.v1();
PlaylistCacheDbDelegate.deletePlaylist(ctx, playlistId);
AndroidUtils.sendToast("Плейлист удален");
findPreference("cached_playlists").setSummary(String.format("Скачано плейлистов: %d", MusicCacheImpl.getPlaylists().size()));
});
builder.show();
@@ -379,10 +420,11 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
new VkAlertDialog.Builder(ctx)
.setTitle(com.vtosters.lite.R.string.warning)
.setMessage(com.vtosters.lite.R.string.cached_tracks_remove_confirm)
.setPositiveButton(com.vtosters.lite.R.string.yes,
(dialog, which) -> executor.submit(MusicCacheImpl::clear))
.setNeutralButton(com.vtosters.lite.R.string.no,
(dialog, which) -> dialog.cancel())
.setPositiveButton(com.vtosters.lite.R.string.yes, (dialog, which) -> {
executor.submit(MusicCacheImpl::clear);
findPreference("cached_tracks").setSummary(String.format(requireContext().getString(com.vtosters.lite.R.string.cached_tracks_counter), MusicCacheImpl.getTracksCount()));
})
.setNeutralButton(com.vtosters.lite.R.string.no, (dialog, which) -> dialog.cancel())
.show();
}
@@ -24,13 +24,25 @@ import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
public class Metrics {
private static JSONArray events = new JSONArray();
public static void trackEvents(JSONObject object) {
if (!NetworkUtils.isNetworkConnected()) {
events.put(object);
} else if (shouldSaveUserTraffic() || events.length() > 0) {
trackEventList(object);
public static void trackEvents(JSONObject object, boolean isMusic) {
if (NetworkUtils.isNetworkConnected()) {
handleNetworkConnected(object, isMusic);
} else {
handleNetworkDisconnected(object, isMusic);
}
}
private static void handleNetworkConnected(JSONObject object, boolean isMusic) {
if (isMusic || shouldSaveUserTraffic() || events.length() > 0) {
trackEventsImmediately(object);
} else {
trackEventList(object);
}
}
private static void handleNetworkDisconnected(JSONObject object, boolean isMusic) {
if (!isMusic) {
events.put(object);
}
}