From 193a19d9d109872c8945c7ec3a9035f24252e158 Mon Sep 17 00:00:00 2001 From: polymorphicshade Date: Thu, 14 May 2020 22:16:09 -0600 Subject: [PATCH] SponsorBlock: Made changes requested in code review See: TeamNewPipe#3205 --- .../schabi/newpipe/SponsorBlockApiTask.java | 132 ++---------------- .../org/schabi/newpipe/player/BasePlayer.java | 8 +- .../newpipe/player/MainVideoPlayer.java | 128 ----------------- .../schabi/newpipe/player/VideoPlayer.java | 4 +- .../settings/ContentSettingsFragment.java | 9 -- .../activity_main_player.xml | 16 --- .../main/res/layout/activity_main_player.xml | 16 --- app/src/main/res/values/settings_keys.xml | 18 +-- app/src/main/res/values/strings.xml | 7 + app/src/main/res/xml/content_settings.xml | 13 -- 10 files changed, 27 insertions(+), 324 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/SponsorBlockApiTask.java b/app/src/main/java/org/schabi/newpipe/SponsorBlockApiTask.java index 1c5924c71..3aff9e695 100644 --- a/app/src/main/java/org/schabi/newpipe/SponsorBlockApiTask.java +++ b/app/src/main/java/org/schabi/newpipe/SponsorBlockApiTask.java @@ -1,6 +1,5 @@ package org.schabi.newpipe; -import android.annotation.SuppressLint; import android.app.Application; import android.content.Context; import android.net.ConnectivityManager; @@ -13,39 +12,18 @@ import org.json.JSONObject; import org.schabi.newpipe.util.SponsorTimeInfo; import org.schabi.newpipe.util.TimeFrame; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Random; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; public class SponsorBlockApiTask extends AsyncTask { private static final Application APP = App.getApp(); - private static final String SPONSOR_BLOCK_API_URL = "https://api.sponsor.ajay.app/api/"; - private static final int TIMEOUT_PERIOD = 30; + private static final String SPONSOR_BLOCK_API_URL = "https://sponsor.ajay.app/api/"; private static final String TAG = SponsorBlockApiTask.class.getSimpleName(); private static final boolean DEBUG = MainActivity.DEBUG; - private OkHttpClient client; - // api methods - public SponsorTimeInfo getVideoSponsorTimes(final String url) throws ExecutionException, - InterruptedException, JSONException { - String videoId = parseIdFromUrl(url); - String apiSuffix = "getVideoSponsorTimes?videoID=" + videoId; + public SponsorTimeInfo getYouTubeVideoSponsorTimes(final String videoId) + throws ExecutionException, InterruptedException, JSONException { - JSONObject obj = execute(apiSuffix).get(); + JSONObject obj = execute("getVideoSponsorTimes?videoID=" + videoId).get(); JSONArray arrayObj = obj.getJSONArray("sponsorTimes"); SponsorTimeInfo result = new SponsorTimeInfo(); @@ -64,26 +42,6 @@ public class SponsorBlockApiTask extends AsyncTask { return result; } - public void postVideoSponsorTimes(final String url, final double startTime, - final double endTime, final String userId) { - double dStartTime = startTime / 1000.0; - double dEndTime = endTime / 1000.0; - - String videoId = parseIdFromUrl(url); - String apiSuffix = "postVideoSponsorTimes?videoID=" - + videoId - + "&startTime=" - + dStartTime - + "&endTime=" - + dEndTime - + "&userID=" + (userId == null - ? getRandomUserId() - : userId); - - execute(apiSuffix); - } - - // task methods @Override protected JSONObject doInBackground(final String... strings) { if (isCancelled() || !isConnected()) { @@ -91,23 +49,13 @@ public class SponsorBlockApiTask extends AsyncTask { } try { - if (client == null) { - client = getUnsafeOkHttpClient() - .newBuilder() - .readTimeout(TIMEOUT_PERIOD, TimeUnit.SECONDS) - .build(); - } + String responseBody = + DownloaderImpl + .getInstance() + .get(SPONSOR_BLOCK_API_URL + strings[0]) + .responseBody(); - Request request = new Request.Builder() - .url(SPONSOR_BLOCK_API_URL + strings[0]) - .build(); - - Response response = client.newCall(request).execute(); - ResponseBody responseBody = response.body(); - - return responseBody == null - ? null - : new JSONObject(responseBody.string()); + return new JSONObject(responseBody); } catch (Exception ex) { if (DEBUG) { @@ -118,70 +66,10 @@ public class SponsorBlockApiTask extends AsyncTask { return null; } - // helper methods private boolean isConnected() { ConnectivityManager cm = (ConnectivityManager) APP.getSystemService(Context.CONNECTIVITY_SERVICE); return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected(); } - - private OkHttpClient getUnsafeOkHttpClient() - throws NoSuchAlgorithmException, KeyManagementException { - final TrustManager[] trustAllCerts = new TrustManager[] { - new X509TrustManager() { - @SuppressLint("TrustAllX509TrustManager") - @Override - public void checkClientTrusted(final java.security.cert.X509Certificate[] chain, - final String authType) { - } - - @SuppressLint("TrustAllX509TrustManager") - @Override - public void checkServerTrusted(final java.security.cert.X509Certificate[] chain, - final String authType) { - } - - @Override - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[] {}; - } - } - }; - - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); - - SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); - - return new OkHttpClient - .Builder() - .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]) - .hostnameVerifier((hostname, session) -> true) - .build(); - } - - private String parseIdFromUrl(final String youTubeUrl) { - String pattern = "(?<=youtu.be/|watch\\?v=|/videos/|embed/)[^#&?]*"; - Pattern compiledPattern = Pattern.compile(pattern); - Matcher matcher = compiledPattern.matcher(youTubeUrl); - if (matcher.find()) { - return matcher.group(); - } else { - return null; - } - } - - private String getRandomUserId() { - String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - StringBuilder salt = new StringBuilder(); - Random random = new Random(); - - while (salt.length() < 36) { - int index = (int) (random.nextFloat() * chars.length()); - salt.append(chars.charAt(index)); - } - - return salt.toString(); - } } diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index fbc14a5fc..e384ff816 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -1060,11 +1060,13 @@ public abstract class BasePlayer implements initThumbnail(info.getThumbnailUrl()); registerView(); - if (mPrefs.getBoolean(context.getString(R.string.sponsorblock_enable), false)) { + if (info.getUrl().startsWith("https://www.youtube.com") + && mPrefs.getBoolean(context.getString(R.string.sponsorblock_enable), false)) { try { - sponsorTimeInfo = new SponsorBlockApiTask().getVideoSponsorTimes(getVideoUrl()); + sponsorTimeInfo = new SponsorBlockApiTask() + .getYouTubeVideoSponsorTimes(info.getId()); } catch (Exception e) { - Log.e("SPONSOR_BLOCK", "Error getting video sponsor times.", e); + Log.e("SPONSOR_BLOCK", "Error getting YouTube video sponsor times.", e); } } } diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index d9af00622..29203fe59 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -20,7 +20,6 @@ package org.schabi.newpipe.player; -import android.app.AlertDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -71,7 +70,6 @@ import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.SubtitleView; import org.schabi.newpipe.R; -import org.schabi.newpipe.SponsorBlockApiTask; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.player.helper.PlaybackParameterDialog; @@ -89,15 +87,10 @@ import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.ShareUtils; -import org.schabi.newpipe.util.SponsorTimeInfo; import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.ThemeHelper; -import org.schabi.newpipe.util.TimeFrame; import org.schabi.newpipe.views.FocusOverlayView; -import org.schabi.newpipe.views.MarkableSeekBar; -import org.schabi.newpipe.views.SeekBarMarker; -import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.UUID; @@ -557,7 +550,6 @@ public final class MainVideoPlayer extends AppCompatActivity private ImageButton switchPopupButton; private ImageButton switchBackgroundButton; private ImageButton muteButton; - private ImageButton submitSponsorTimesButton; private RelativeLayout windowRootLayout; private View secondaryControls; @@ -595,17 +587,6 @@ public final class MainVideoPlayer extends AppCompatActivity this.toggleOrientationButton = view.findViewById(R.id.toggleOrientation); this.switchBackgroundButton = view.findViewById(R.id.switchBackground); this.muteButton = view.findViewById(R.id.switchMute); - - this.submitSponsorTimesButton = view.findViewById(R.id.submitSponsorTimes); - this.submitSponsorTimesButton.setTag(false); - this.submitSponsorTimesButton.setOnLongClickListener(v -> { - onSponsorBlockButtonLongClicked(); - return true; - }); - if (!defaultPreferences.getBoolean(getString(R.string.sponsorblock_enable), false)) { - this.submitSponsorTimesButton.setVisibility(View.GONE); - } - this.switchPopupButton = view.findViewById(R.id.switchPopup); this.queueLayout = findViewById(R.id.playQueuePanel); @@ -655,7 +636,6 @@ public final class MainVideoPlayer extends AppCompatActivity toggleOrientationButton.setOnClickListener(this); switchBackgroundButton.setOnClickListener(this); muteButton.setOnClickListener(this); - submitSponsorTimesButton.setOnClickListener(this); switchPopupButton.setOnClickListener(this); getRootView().addOnLayoutChangeListener((view, l, t, r, b, ol, ot, or, ob) -> { @@ -836,110 +816,6 @@ public final class MainVideoPlayer extends AppCompatActivity setMuteButton(muteButton, playerImpl.isMuted()); } - private void onSponsorBlockButtonClicked() { - if (DEBUG) { - Log.d(TAG, "onSponsorBlockButtonClicked() called"); - } - if (playerImpl.getPlayer() == null) { - return; - } - - if ((boolean) submitSponsorTimesButton.getTag()) { - TimeFrame customTimeFrame = - new TimeFrame(customSponsorStartTime, simpleExoPlayer.getCurrentPosition()); - customTimeFrame.tag = "custom"; - - SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo(); - if (sponsorTimeInfo == null) { - sponsorTimeInfo = new SponsorTimeInfo(); - - setSponsorTimeInfo(sponsorTimeInfo); - } - - sponsorTimeInfo.timeFrames.add(customTimeFrame); - - SeekBarMarker marker = - new SeekBarMarker(customTimeFrame.startTime, customTimeFrame.endTime, - (int) simpleExoPlayer.getDuration(), Color.BLUE); - marker.tag = "custom"; - - MarkableSeekBar markableSeekBar = (MarkableSeekBar) getPlaybackSeekBar(); - markableSeekBar.seekBarMarkers.add(marker); - markableSeekBar.invalidate(); - - submitSponsorTimesButton.setTag(false); - submitSponsorTimesButton.setImageResource(R.drawable.ic_sponsor_block); - } else { - customSponsorStartTime = (int) simpleExoPlayer.getCurrentPosition(); - - submitSponsorTimesButton.setTag(true); - submitSponsorTimesButton.setImageResource(R.drawable.ic_sponsor_block_stop); - } - } - - private void onSponsorBlockButtonLongClicked() { - if (DEBUG) { - Log.d(TAG, "onSponsorBlockButtonLongClicked() called"); - } - if (playerImpl.getPlayer() == null) { - return; - } - - ArrayList customMarkers = new ArrayList<>(); - ArrayList customTimeFrames = new ArrayList<>(); - - for (SeekBarMarker marker : ((MarkableSeekBar) getPlaybackSeekBar()).seekBarMarkers) { - if (marker.tag == "custom") { - customMarkers.add(marker); - } - } - - if (customMarkers.size() == 0) { - return; - } - - SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo(); - if (sponsorTimeInfo != null) { - for (TimeFrame timeFrame : sponsorTimeInfo.timeFrames) { - if (timeFrame.tag == "custom") { - customTimeFrames.add(timeFrame); - } - } - } - - new AlertDialog - .Builder(context) - .setMessage("Submit " + customMarkers.size() + " sponsor time segment(s)?") - .setPositiveButton("Yes", (dialog, id) -> { - String username = defaultPreferences - .getString(getString(R.string.sponsorblock_username), null); - for (TimeFrame timeFrame : customTimeFrames) { - try { - new SponsorBlockApiTask() - .postVideoSponsorTimes(getVideoUrl(), timeFrame.startTime, - timeFrame.endTime, username); - } catch (Exception e) { - Log.e("SPONSOR_BLOCK", "Error getting video sponsor times.", e); - } - } - }) - .setNegativeButton("No", null) - .setNeutralButton("Clear", (dialog, id) -> { - for (SeekBarMarker marker : customMarkers) { - ((MarkableSeekBar) getPlaybackSeekBar()).seekBarMarkers.remove(marker); - } - - if (sponsorTimeInfo != null) { - for (TimeFrame timeFrame : customTimeFrames) { - sponsorTimeInfo.timeFrames.remove(timeFrame); - } - } - }) - .create() - .show(); - } - - @Override public void onClick(final View v) { super.onClick(v); @@ -970,10 +846,6 @@ public final class MainVideoPlayer extends AppCompatActivity onPlayBackgroundButtonClicked(); } else if (v.getId() == muteButton.getId()) { onMuteUnmuteButtonClicked(); - - } else if (v.getId() == submitSponsorTimesButton.getId()) { - onSponsorBlockButtonClicked(); - } else if (v.getId() == closeButton.getId()) { onPlaybackShutdown(); return; diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 1477cc594..c43fc49fb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -625,7 +625,7 @@ public abstract class VideoPlayer extends BasePlayer super.onPrepared(playWhenReady); - tryMarkSponsorTimes(); + markSponsorTimes(); if (simpleExoPlayer.getCurrentPosition() != 0 && !isControlsVisible()) { controlsVisibilityHandler.removeCallbacksAndMessages(null); @@ -634,7 +634,7 @@ public abstract class VideoPlayer extends BasePlayer } } - private void tryMarkSponsorTimes() { + private void markSponsorTimes() { SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo(); if (sponsorTimeInfo == null) { diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index e92fef186..a88b6386d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -148,15 +148,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { startActivity(i); return true; }); - - Preference sponsorblockLeaderboardsPreference = - findPreference(getString(R.string.sponsorblock_leaderboards)); - sponsorblockLeaderboardsPreference.setOnPreferenceClickListener((Preference p) -> { - Intent i = new Intent(Intent.ACTION_VIEW, - Uri.parse("https://api.sponsor.ajay.app/stats")); - startActivity(i); - return true; - }); } @Override diff --git a/app/src/main/res/layout-large-land/activity_main_player.xml b/app/src/main/res/layout-large-land/activity_main_player.xml index 09376d006..a863b1b89 100644 --- a/app/src/main/res/layout-large-land/activity_main_player.xml +++ b/app/src/main/res/layout-large-land/activity_main_player.xml @@ -414,22 +414,6 @@ android:contentDescription="@string/switch_to_background" tools:ignore="RtlHardcoded" /> - - downloads_storage_ask storage_use_saf - skip_sponsors - Skip Sponsors - Use the SponsorBlock API to automatically skip sponsors in videos. - sponsorblock_notifications - Notify when sponsors are skipped - Send a notification to your device when a sponsor is automatically skipped. - sponsorblock_username - Set Username - Set a username used when submitting sponsor times. Leave empty to use a default randomized username. - sponsorblock_status - View Online Status - View the online status of the SponsorBlock servers. - sponsorblock_leaderboards - View Leaderboards - View the online leaderboards for SponsorBlock. + skip_sponsors + sponsorblock_notifications + sponsorblock_status file_rename_charset diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f390eb29d..3f91cdede 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -661,4 +661,11 @@ Created by %s By %s Playlist page + + Skip Sponsors + Use the SponsorBlock API to automatically skip sponsors in videos. + Notify when sponsors are skipped + Send a notification to your device when a sponsor is automatically skipped. + View Online Status + View the online status of the SponsorBlock servers. \ No newline at end of file diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 5c6ad3977..fedb9bfff 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -137,23 +137,10 @@ android:title="@string/sponsorblock_notifications_title" app:iconSpaceReserved="false" /> - - - -