SponsorBlock: removed deprecated AsyncTask and improved performance

This commit is contained in:
polymorphicshade 2020-12-08 00:02:32 -07:00
parent e50a40bc85
commit cbcb0f756a
3 changed files with 93 additions and 97 deletions

View file

@ -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 -> {

View file

@ -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;
}
} }

View file

@ -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));