SponsorBlock: Added exclusion list feature
Added the ability to add uploaders to a persistent exclusion list by long-pressing the SponsorBlock icon. Segments won't be skipped, but they will still be marked.
This commit is contained in:
parent
dfb94a2503
commit
4cadf54bc2
9 changed files with 164 additions and 24 deletions
|
@ -76,9 +76,11 @@ import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
|||
import org.schabi.newpipe.player.resolver.MediaSourceTag;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.SerializedCache;
|
||||
import org.schabi.newpipe.util.SponsorBlockMode;
|
||||
import org.schabi.newpipe.util.VideoSegment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
@ -205,7 +207,7 @@ public abstract class BasePlayer implements
|
|||
private Disposable stateLoader;
|
||||
|
||||
protected int currentState = STATE_PREFLIGHT;
|
||||
private boolean isBlockingSponsors;
|
||||
private SponsorBlockMode sponsorBlockMode = SponsorBlockMode.DISABLED;
|
||||
|
||||
public BasePlayer(@NonNull final Context context) {
|
||||
this.context = context;
|
||||
|
@ -237,9 +239,6 @@ public abstract class BasePlayer implements
|
|||
this.renderFactory = new DefaultRenderersFactory(context);
|
||||
|
||||
this.mPrefs = PreferenceManager.getDefaultSharedPreferences(App.getApp());
|
||||
|
||||
isBlockingSponsors = mPrefs.getBoolean(context.getString(R.string.sponsor_block_enable_key),
|
||||
false);
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
|
@ -699,11 +698,25 @@ public abstract class BasePlayer implements
|
|||
if (DEBUG) {
|
||||
Log.d(TAG, "onBlockingSponsorsButtonClicked() called");
|
||||
}
|
||||
isBlockingSponsors = !isBlockingSponsors;
|
||||
|
||||
switch (sponsorBlockMode) {
|
||||
case DISABLED:
|
||||
sponsorBlockMode = SponsorBlockMode.ENABLED;
|
||||
break;
|
||||
case ENABLED:
|
||||
sponsorBlockMode = SponsorBlockMode.DISABLED;
|
||||
break;
|
||||
case EXCLUDE:
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBlockingSponsors() {
|
||||
return isBlockingSponsors;
|
||||
public SponsorBlockMode getSponsorBlockMode() {
|
||||
return sponsorBlockMode;
|
||||
}
|
||||
|
||||
public void setSponsorBlockMode(final SponsorBlockMode mode) {
|
||||
sponsorBlockMode = mode;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -731,9 +744,7 @@ public abstract class BasePlayer implements
|
|||
simpleExoPlayer.getBufferedPercentage()
|
||||
);
|
||||
|
||||
if (isBlockingSponsors
|
||||
&& mPrefs.getBoolean(
|
||||
context.getString(R.string.sponsor_block_enable_key), false)) {
|
||||
if (sponsorBlockMode == SponsorBlockMode.ENABLED) {
|
||||
final VideoSegment segment = getSkippableSegment(currentProgress);
|
||||
if (segment == null) {
|
||||
return;
|
||||
|
@ -1165,11 +1176,22 @@ public abstract class BasePlayer implements
|
|||
initThumbnail(info.getThumbnailUrl());
|
||||
registerView();
|
||||
|
||||
final boolean isSponsorBlockEnabled = mPrefs.getBoolean(
|
||||
context.getString(R.string.sponsor_block_enable_key), false);
|
||||
final Set<String> channelExclusions = mPrefs.getStringSet(
|
||||
context.getString(R.string.sponsor_block_exclusion_list_key), null);
|
||||
|
||||
if (channelExclusions != null && channelExclusions.contains(info.getUploaderName())) {
|
||||
sponsorBlockMode = SponsorBlockMode.EXCLUDE;
|
||||
} else {
|
||||
sponsorBlockMode = isSponsorBlockEnabled
|
||||
? SponsorBlockMode.ENABLED
|
||||
: 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);
|
||||
final boolean isSponsorBlockEnabled = mPrefs
|
||||
.getBoolean(context.getString(R.string.sponsor_block_enable_key), false);
|
||||
|
||||
if (apiUrl != null && !apiUrl.isEmpty() && isSponsorBlockEnabled) {
|
||||
try {
|
||||
|
|
|
@ -100,8 +100,11 @@ import org.schabi.newpipe.util.KoreUtil;
|
|||
import org.schabi.newpipe.util.ListHelper;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.ShareUtils;
|
||||
import org.schabi.newpipe.util.SponsorBlockMode;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static android.content.Context.WINDOW_SERVICE;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
@ -409,7 +412,7 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
channelTextView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
setMuteButton(muteButton, isMuted());
|
||||
setBlockSponsorsButton(blockSponsorsButton, isBlockingSponsors());
|
||||
setBlockSponsorsButton(blockSponsorsButton);
|
||||
|
||||
animateRotation(moreOptionsButton, DEFAULT_CONTROLS_DURATION, 0);
|
||||
}
|
||||
|
@ -483,6 +486,7 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
|
||||
if (blockSponsorsButton != null) {
|
||||
blockSponsorsButton.setOnClickListener(this);
|
||||
blockSponsorsButton.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
settingsContentObserver = new ContentObserver(new Handler()) {
|
||||
|
@ -630,6 +634,8 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
|
||||
showHideKodiButton();
|
||||
|
||||
setBlockSponsorsButton(blockSponsorsButton);
|
||||
|
||||
titleTextView.setText(tag.getMetadata().getName());
|
||||
channelTextView.setText(tag.getMetadata().getUploaderName());
|
||||
|
||||
|
@ -656,13 +662,18 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
@Override
|
||||
public void onBlockingSponsorsButtonClicked() {
|
||||
super.onBlockingSponsorsButtonClicked();
|
||||
setBlockSponsorsButton(blockSponsorsButton, isBlockingSponsors());
|
||||
setBlockSponsorsButton(blockSponsorsButton);
|
||||
|
||||
Toast.makeText(context,
|
||||
isBlockingSponsors()
|
||||
? "SponsorBlock enabled"
|
||||
: "SponsorBlock disabled",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
switch (getSponsorBlockMode()) {
|
||||
case DISABLED:
|
||||
Toast.makeText(context, "SponsorBlock disabled", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case ENABLED:
|
||||
Toast.makeText(context, "SponsorBlock enabled", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case EXCLUDE:
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -857,6 +868,43 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
fragmentListener.onMoreOptionsLongClicked();
|
||||
hideControls(0, 0);
|
||||
hideSystemUIIfNeeded();
|
||||
} else if (v.getId() == blockSponsorsButton.getId()) {
|
||||
final MediaSourceTag currentMetadata = getCurrentMetadata();
|
||||
if (currentMetadata == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Set<String> channelExclusions =
|
||||
mPrefs.getStringSet(
|
||||
context.getString(R.string.sponsor_block_exclusion_list_key),
|
||||
new HashSet<>());
|
||||
|
||||
final String toastText;
|
||||
|
||||
if (getSponsorBlockMode() == SponsorBlockMode.EXCLUDE) {
|
||||
if (channelExclusions != null) {
|
||||
channelExclusions.remove(currentMetadata.getMetadata().getUploaderName());
|
||||
}
|
||||
|
||||
setSponsorBlockMode(SponsorBlockMode.ENABLED);
|
||||
toastText = "Uploader removed from SponsorBlock exclusion list";
|
||||
} else {
|
||||
if (channelExclusions != null) {
|
||||
channelExclusions.add(currentMetadata.getMetadata().getUploaderName());
|
||||
}
|
||||
|
||||
setSponsorBlockMode(SponsorBlockMode.EXCLUDE);
|
||||
toastText = "Uploader excluded from SponsorBlock";
|
||||
}
|
||||
|
||||
mPrefs.edit()
|
||||
.putStringSet(
|
||||
context.getString(R.string.sponsor_block_exclusion_list_key),
|
||||
channelExclusions)
|
||||
.apply();
|
||||
|
||||
setBlockSponsorsButton(blockSponsorsButton);
|
||||
Toast.makeText(context, toastText, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1605,15 +1653,29 @@ public class VideoPlayerImpl extends VideoPlayer
|
|||
? R.drawable.ic_volume_off_white_24dp : R.drawable.ic_volume_up_white_24dp));
|
||||
}
|
||||
|
||||
protected void setBlockSponsorsButton(final ImageButton button,
|
||||
final boolean isBlockingSponsors) {
|
||||
protected void setBlockSponsorsButton(final ImageButton button) {
|
||||
if (button == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.setImageDrawable(AppCompatResources.getDrawable(service, isBlockingSponsors
|
||||
? R.drawable.ic_sponsor_block_enable_white_24dp
|
||||
: R.drawable.ic_sponsor_block_disable_white_24dp));
|
||||
final SponsorBlockMode sponsorBlockMode = getSponsorBlockMode();
|
||||
final int resId;
|
||||
|
||||
switch (sponsorBlockMode) {
|
||||
case DISABLED:
|
||||
resId = R.drawable.ic_sponsor_block_disable_white_24dp;
|
||||
break;
|
||||
case ENABLED:
|
||||
resId = R.drawable.ic_sponsor_block_enable_white_24dp;
|
||||
break;
|
||||
case EXCLUDE:
|
||||
resId = R.drawable.ic_sponsor_block_exclude_white_24dp;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
button.setImageDrawable(AppCompatResources.getDrawable(service, resId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,6 +40,7 @@ import java.io.ObjectInputStream;
|
|||
import java.io.ObjectOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipFile;
|
||||
|
@ -169,6 +170,19 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
updateDependencies(preference, newValue);
|
||||
return true;
|
||||
});
|
||||
|
||||
final Preference sponsorBlockClearExclusionListPreference =
|
||||
findPreference(getString(R.string.sponsor_block_clear_exclusion_list_key));
|
||||
sponsorBlockClearExclusionListPreference.setOnPreferenceClickListener((Preference p) -> {
|
||||
getPreferenceManager()
|
||||
.getSharedPreferences()
|
||||
.edit()
|
||||
.putStringSet(
|
||||
getString(R.string.sponsor_block_exclusion_list_key), new HashSet<>())
|
||||
.apply();
|
||||
Toast.makeText(getContext(), "Exclusion list cleared", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.schabi.newpipe.util;
|
||||
|
||||
public enum SponsorBlockMode {
|
||||
DISABLED,
|
||||
ENABLED,
|
||||
EXCLUDE
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,24c-0.5,0 -1,-0.1 -1.4,-0.4C4.1,19.6 0.1,12.7 0,5.1c0,-1 0.5,-2 1.4,-2.5C8,-0.9 16,-0.9 22.6,2.7C23.5,3.1 24,4.1 24,5.1c-0.1,7.6 -4.1,14.5 -10.5,18.5C13,23.9 12.5,24 12,24zM12,0.8c-3.5,0 -7,0.9 -10.2,2.6c-0.6,0.3 -1,1 -1,1.7C0.9,12.4 4.7,19 11,22.9c0.6,0.4 1.4,0.4 2,0c6.3,-3.8 10,-10.5 10.2,-17.8c0,-0.7 -0.4,-1.4 -1,-1.7C19,1.7 15.5,0.8 12,0.8z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21.7,4.2C15.6,1 8.4,1 2.3,4.2C2,4.4 1.8,4.7 1.8,5.1c0.1,7.2 3.9,13.4 9.7,17c0.3,0.2 0.7,0.2 1,0c5.7,-3.5 9.6,-9.8 9.7,-17C22.2,4.7 22,4.4 21.7,4.2zM12,15.8c0,0 -5,-4 -5,-6.6c0,-1.7 1.1,-2.7 2.5,-2.7c1.2,0 2.5,1.3 2.5,1.3s1.2,-1.3 2.5,-1.3c1.4,0 2.5,0.9 2.5,2.7C17,11.8 12,15.8 12,15.8z"/>
|
||||
</vector>
|
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#FFFFFF">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,24c-0.5,0 -1,-0.1 -1.4,-0.4C4.1,19.6 0.1,12.7 0,5.1c0,-1 0.5,-2 1.4,-2.5C8,-0.9 16,-0.9 22.6,2.7C23.5,3.1 24,4.1 24,5.1c-0.1,7.6 -4.1,14.5 -10.5,18.5C13,23.9 12.5,24 12,24zM12,0.8c-3.5,0 -7,0.9 -10.2,2.6c-0.6,0.3 -1,1 -1,1.7C0.9,12.4 4.7,19 11,22.9c0.6,0.4 1.4,0.4 2,0c6.3,-3.8 10,-10.5 10.2,-17.8c0,-0.7 -0.4,-1.4 -1,-1.7C19,1.7 15.5,0.8 12,0.8z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21.7,4.2C15.6,1 8.4,1 2.3,4.2C2,4.4 1.8,4.7 1.8,5.1c0.1,7.2 3.9,13.4 9.7,17c0.3,0.2 0.7,0.2 1,0c5.7,-3.5 9.6,-9.8 9.7,-17C22.2,4.7 22,4.4 21.7,4.2zM12,15.8c0,0 -5,-4 -5,-6.6c0,-1.7 1.1,-2.7 2.5,-2.7c1.2,0 2.5,1.3 2.5,1.3s1.2,-1.3 2.5,-1.3c1.4,0 2.5,0.9 2.5,2.7C17,11.8 12,15.8 12,15.8z"/>
|
||||
</vector>
|
|
@ -258,6 +258,8 @@
|
|||
<string name="sponsor_block_category_self_promo_color_key" translatable="false">sponsor_block_category_self_promo_color</string>
|
||||
<string name="sponsor_block_category_non_music_key" translatable="false">sponsor_block_category_music</string>
|
||||
<string name="sponsor_block_category_non_music_color_key" translatable="false">sponsor_block_category_music_color</string>
|
||||
<string name="sponsor_block_exclusion_list_key" translatable="false">sponsor_block_exclusion_list</string>
|
||||
<string name="sponsor_block_clear_exclusion_list_key" translatable="false">sponsor_block_clear_exclusion_list</string>
|
||||
|
||||
<!-- FileName Downloads -->
|
||||
<string name="settings_file_charset_key" translatable="false">file_rename_charset</string>
|
||||
|
|
|
@ -706,4 +706,6 @@
|
|||
<string name="sponsor_block_skip_self_promo_message">Skipped unpaid/self promo</string>
|
||||
<string name="sponsor_block_skip_non_music_message">Skipped non-music</string>
|
||||
<string name="sponsor_block_toggle_skipping">Toggle skipping sponsors</string>
|
||||
<string name="sponsor_block_clear_exclusion_list_title">Clear Exclusion List</string>
|
||||
<string name="sponsor_block_clear_exclusion_list_summary">Clear the list of uploaders excluded from SponsorBlock.</string>
|
||||
</resources>
|
||||
|
|
|
@ -164,5 +164,11 @@
|
|||
android:title="@string/settings_category_sponsor_block_categories_title"
|
||||
android:summary="@string/settings_category_sponsor_block_categories_summary"/>
|
||||
|
||||
<Preference
|
||||
app:iconSpaceReserved="false"
|
||||
android:key="@string/sponsor_block_clear_exclusion_list_key"
|
||||
android:summary="@string/sponsor_block_clear_exclusion_list_summary"
|
||||
android:title="@string/sponsor_block_clear_exclusion_list_title"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
|
Loading…
Reference in a new issue