SponsorBlock: removed deprecated AsyncTask and improved performance
This commit is contained in:
parent
e50a40bc85
commit
cbcb0f756a
3 changed files with 93 additions and 97 deletions
|
@ -103,7 +103,9 @@ import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
import org.schabi.newpipe.util.PermissionHelper;
|
import org.schabi.newpipe.util.PermissionHelper;
|
||||||
import org.schabi.newpipe.util.ShareUtils;
|
import org.schabi.newpipe.util.ShareUtils;
|
||||||
|
import org.schabi.newpipe.util.SponsorBlockUtils;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
import org.schabi.newpipe.util.VideoSegment;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
import org.schabi.newpipe.views.LargeTextMovementMethod;
|
import org.schabi.newpipe.views.LargeTextMovementMethod;
|
||||||
|
|
||||||
|
@ -192,6 +194,7 @@ public final class VideoDetailFragment
|
||||||
private int selectedVideoStreamIndex = -1;
|
private int selectedVideoStreamIndex = -1;
|
||||||
private BottomSheetBehavior<FrameLayout> bottomSheetBehavior;
|
private BottomSheetBehavior<FrameLayout> bottomSheetBehavior;
|
||||||
private BroadcastReceiver broadcastReceiver;
|
private BroadcastReceiver broadcastReceiver;
|
||||||
|
private VideoSegment[] videoSegments;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Views
|
// Views
|
||||||
|
@ -262,6 +265,8 @@ public final class VideoDetailFragment
|
||||||
final MainPlayer connectedPlayerService,
|
final MainPlayer connectedPlayerService,
|
||||||
final boolean playAfterConnect) {
|
final boolean playAfterConnect) {
|
||||||
player = connectedPlayer;
|
player = connectedPlayer;
|
||||||
|
player.setVideoSegments(videoSegments);
|
||||||
|
|
||||||
playerService = connectedPlayerService;
|
playerService = connectedPlayerService;
|
||||||
|
|
||||||
// It will do nothing if the player is not in fullscreen mode
|
// It will do nothing if the player is not in fullscreen mode
|
||||||
|
@ -945,7 +950,43 @@ public final class VideoDetailFragment
|
||||||
|
|
||||||
private void runWorker(final boolean forceLoad, final boolean addToBackStack) {
|
private void runWorker(final boolean forceLoad, final boolean addToBackStack) {
|
||||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||||
|
|
||||||
|
final String apiUrl = prefs.getString(getContext()
|
||||||
|
.getString(R.string.sponsor_block_api_url_key), null);
|
||||||
|
final boolean isSponsorBlockEnabled = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_enable_key), false);
|
||||||
|
final boolean includeSponsorCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_sponsor_key), false);
|
||||||
|
final boolean includeIntroCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_intro_key), false);
|
||||||
|
final boolean includeOutroCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_outro_key), false);
|
||||||
|
final boolean includeInteractionCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_interaction_key), false);
|
||||||
|
final boolean includeSelfPromoCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_self_promo_key), false);
|
||||||
|
final boolean includeMusicCategory = prefs.getBoolean(getContext()
|
||||||
|
.getString(R.string.sponsor_block_category_non_music_key), false);
|
||||||
|
|
||||||
currentWorker = ExtractorHelper.getStreamInfo(serviceId, url, forceLoad)
|
currentWorker = ExtractorHelper.getStreamInfo(serviceId, url, forceLoad)
|
||||||
|
.flatMap(streamInfo -> Single.fromCallable(() -> {
|
||||||
|
if (isSponsorBlockEnabled
|
||||||
|
&& streamInfo.getUrl().startsWith("https://www.youtube.com")
|
||||||
|
&& apiUrl != null
|
||||||
|
&& !apiUrl.isEmpty()) {
|
||||||
|
this.videoSegments = SponsorBlockUtils.getYouTubeVideoSegments(
|
||||||
|
apiUrl,
|
||||||
|
streamInfo.getId(),
|
||||||
|
includeSponsorCategory,
|
||||||
|
includeIntroCategory,
|
||||||
|
includeOutroCategory,
|
||||||
|
includeInteractionCategory,
|
||||||
|
includeSelfPromoCategory,
|
||||||
|
includeMusicCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return streamInfo;
|
||||||
|
}))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(result -> {
|
.subscribe(result -> {
|
||||||
|
|
|
@ -59,7 +59,6 @@ import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.DownloaderImpl;
|
import org.schabi.newpipe.DownloaderImpl;
|
||||||
import org.schabi.newpipe.MainActivity;
|
import org.schabi.newpipe.MainActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.SponsorBlockApiTask;
|
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.player.helper.AudioReactor;
|
import org.schabi.newpipe.player.helper.AudioReactor;
|
||||||
|
@ -118,6 +117,7 @@ public abstract class BasePlayer implements
|
||||||
@NonNull
|
@NonNull
|
||||||
protected final SharedPreferences mPrefs;
|
protected final SharedPreferences mPrefs;
|
||||||
|
|
||||||
|
private boolean wereSponsorsMarked;
|
||||||
private VideoSegment[] videoSegments;
|
private VideoSegment[] videoSegments;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1211,65 +1211,11 @@ public abstract class BasePlayer implements
|
||||||
context.getString(R.string.sponsor_block_whitelist_key), null);
|
context.getString(R.string.sponsor_block_whitelist_key), null);
|
||||||
|
|
||||||
if (uploaderWhitelist != null && uploaderWhitelist.contains(info.getUploaderName())) {
|
if (uploaderWhitelist != null && uploaderWhitelist.contains(info.getUploaderName())) {
|
||||||
sponsorBlockMode = SponsorBlockMode.IGNORE;
|
setSponsorBlockMode(SponsorBlockMode.IGNORE);
|
||||||
} else {
|
} else {
|
||||||
sponsorBlockMode = isSponsorBlockEnabled
|
setSponsorBlockMode(isSponsorBlockEnabled
|
||||||
? SponsorBlockMode.ENABLED
|
? SponsorBlockMode.ENABLED
|
||||||
: SponsorBlockMode.DISABLED;
|
: SponsorBlockMode.DISABLED);
|
||||||
}
|
|
||||||
|
|
||||||
if (info.getUrl().startsWith("https://www.youtube.com")) {
|
|
||||||
final String apiUrl = mPrefs
|
|
||||||
.getString(context.getString(R.string.sponsor_block_api_url_key), null);
|
|
||||||
|
|
||||||
if (apiUrl != null && !apiUrl.isEmpty() && isSponsorBlockEnabled) {
|
|
||||||
try {
|
|
||||||
final boolean includeSponsorCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_sponsor_key),
|
|
||||||
false);
|
|
||||||
|
|
||||||
final boolean includeIntroCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_intro_key),
|
|
||||||
false);
|
|
||||||
|
|
||||||
final boolean includeOutroCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_outro_key),
|
|
||||||
false);
|
|
||||||
|
|
||||||
final boolean includeInteractionCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_interaction_key),
|
|
||||||
false);
|
|
||||||
final boolean includeSelfPromoCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_self_promo_key),
|
|
||||||
false);
|
|
||||||
final boolean includeMusicCategory =
|
|
||||||
mPrefs.getBoolean(
|
|
||||||
context.getString(
|
|
||||||
R.string.sponsor_block_category_non_music_key),
|
|
||||||
false);
|
|
||||||
|
|
||||||
videoSegments = new SponsorBlockApiTask(apiUrl)
|
|
||||||
.getYouTubeVideoSegments(info.getId(),
|
|
||||||
includeSponsorCategory,
|
|
||||||
includeIntroCategory,
|
|
||||||
includeOutroCategory,
|
|
||||||
includeInteractionCategory,
|
|
||||||
includeSelfPromoCategory,
|
|
||||||
includeMusicCategory);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.e("SPONSOR_BLOCK", "Error getting YouTube video segments.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1822,4 +1768,15 @@ public abstract class BasePlayer implements
|
||||||
public VideoSegment[] getVideoSegments() {
|
public VideoSegment[] getVideoSegments() {
|
||||||
return videoSegments;
|
return videoSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVideoSegments(final VideoSegment[] videoSegments) {
|
||||||
|
// use a flag to ignore null values later (i.e. when the video goes fullscreen)
|
||||||
|
// TODO: there's probably a better way to deal with stuff like that
|
||||||
|
if (wereSponsorsMarked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.videoSegments = videoSegments;
|
||||||
|
wereSponsorsMarked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe.util;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
@ -11,34 +10,34 @@ import com.grack.nanojson.JsonArray;
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
import com.grack.nanojson.JsonParser;
|
import com.grack.nanojson.JsonParser;
|
||||||
|
|
||||||
import org.schabi.newpipe.util.VideoSegment;
|
import org.schabi.newpipe.App;
|
||||||
|
import org.schabi.newpipe.DownloaderImpl;
|
||||||
|
import org.schabi.newpipe.MainActivity;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class SponsorBlockApiTask extends AsyncTask<String, Void, JsonArray> {
|
public final class SponsorBlockUtils {
|
||||||
private static final Application APP = App.getApp();
|
private static final Application APP = App.getApp();
|
||||||
private String apiUrl;
|
private static final String TAG = SponsorBlockUtils.class.getSimpleName();
|
||||||
private static final String TAG = SponsorBlockApiTask.class.getSimpleName();
|
|
||||||
private static final boolean DEBUG = MainActivity.DEBUG;
|
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||||
|
|
||||||
public SponsorBlockApiTask(final String apiUrl) {
|
private SponsorBlockUtils() {
|
||||||
this.apiUrl = apiUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoSegment[] getYouTubeVideoSegments(final String videoId,
|
@SuppressWarnings("CheckStyle")
|
||||||
|
public static VideoSegment[] getYouTubeVideoSegments(final String apiUrl,
|
||||||
|
final String videoId,
|
||||||
final boolean includeSponsorCategory,
|
final boolean includeSponsorCategory,
|
||||||
final boolean includeIntroCategory,
|
final boolean includeIntroCategory,
|
||||||
final boolean includeOutroCategory,
|
final boolean includeOutroCategory,
|
||||||
final boolean includeInteractionCategory,
|
final boolean includeInteractionCategory,
|
||||||
final boolean includeSelfPromoCategory,
|
final boolean includeSelfPromoCategory,
|
||||||
final boolean includeMusicCategory)
|
final boolean includeMusicCategory)
|
||||||
throws ExecutionException, InterruptedException, UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
|
|
||||||
final ArrayList<String> categoryParamList = new ArrayList<>();
|
final ArrayList<String> categoryParamList = new ArrayList<>();
|
||||||
|
|
||||||
if (includeSponsorCategory) {
|
if (includeSponsorCategory) {
|
||||||
|
@ -76,7 +75,30 @@ public class SponsorBlockApiTask extends AsyncTask<String, Void, JsonArray> {
|
||||||
final String params = "skipSegments/" + videoIdHash.substring(0, 4)
|
final String params = "skipSegments/" + videoIdHash.substring(0, 4)
|
||||||
+ "?categories=" + categoryParams;
|
+ "?categories=" + categoryParams;
|
||||||
|
|
||||||
final JsonArray responseArray = execute(params).get();
|
if (!isConnected()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray responseArray = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final String responseBody =
|
||||||
|
DownloaderImpl
|
||||||
|
.getInstance()
|
||||||
|
.get(apiUrl + params)
|
||||||
|
.responseBody();
|
||||||
|
|
||||||
|
responseArray = JsonParser.array().from(responseBody);
|
||||||
|
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.w(TAG, Log.getStackTraceString(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseArray == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final ArrayList<VideoSegment> result = new ArrayList<>();
|
final ArrayList<VideoSegment> result = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -113,38 +135,14 @@ public class SponsorBlockApiTask extends AsyncTask<String, Void, JsonArray> {
|
||||||
return result.toArray(new VideoSegment[0]);
|
return result.toArray(new VideoSegment[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static boolean isConnected() {
|
||||||
protected JsonArray doInBackground(final String... strings) {
|
|
||||||
if (isCancelled() || !isConnected()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final String responseBody =
|
|
||||||
DownloaderImpl
|
|
||||||
.getInstance()
|
|
||||||
.get(apiUrl + strings[0])
|
|
||||||
.responseBody();
|
|
||||||
|
|
||||||
return JsonParser.array().from(responseBody);
|
|
||||||
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.w(TAG, Log.getStackTraceString(ex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isConnected() {
|
|
||||||
final ConnectivityManager cm =
|
final ConnectivityManager cm =
|
||||||
(ConnectivityManager) APP.getSystemService(Context.CONNECTIVITY_SERVICE);
|
(ConnectivityManager) APP.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
return cm.getActiveNetworkInfo() != null
|
return cm.getActiveNetworkInfo() != null
|
||||||
&& cm.getActiveNetworkInfo().isConnected();
|
&& cm.getActiveNetworkInfo().isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toSha256(final String videoId) {
|
private static String toSha256(final String videoId) {
|
||||||
try {
|
try {
|
||||||
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
final byte[] bytes = digest.digest(videoId.getBytes(StandardCharsets.UTF_8));
|
final byte[] bytes = digest.digest(videoId.getBytes(StandardCharsets.UTF_8));
|
Loading…
Reference in a new issue