SponsorBlock: improve don't skip short segments option

This commit is contained in:
Yuriy Liskov
2026-03-12 05:54:04 +02:00
parent ded9d0337e
commit 1bb3bc0434
9 changed files with 45 additions and 18 deletions

View File

@@ -383,7 +383,8 @@ public class SponsorBlockController extends BasePlayerController {
long skipPosMs = lastSegment.getEndMs();
// Fix infinite skip loop by ignoring short segments. TextureView has a seek bug.
long skipDurationMs = Math.min(skipPosMs, getPlayer().getDurationMs()) - getPlayer().getPositionMs();
boolean stayQuiet = skipDurationMs < 10_000 && (getPlayerTweaksData().isTextureViewEnabled() || getSponsorBlockData().isStayQuietEnabled());
boolean stayQuiet = (skipDurationMs < 10_000 && getPlayerTweaksData().isTextureViewEnabled())
|| (skipDurationMs < getSponsorBlockData().getQuietDurationMs());
if (!stayQuiet) {
if (type == SponsorBlockData.ACTION_SKIP_ONLY || getPlayer().isInPIPMode() || Utils.isScreenOff(getContext()) || isEmbedPlayer()) {

View File

@@ -6,6 +6,7 @@ import androidx.core.content.ContextCompat;
import com.liskovsoft.smartyoutubetv2.common.R;
import com.liskovsoft.smartyoutubetv2.common.app.models.data.Video;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.controllers.SponsorBlockController.SegmentAction;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionCategory;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionItem;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.UiOptionItem;
import com.liskovsoft.smartyoutubetv2.common.app.presenters.AppDialogPresenter;
@@ -40,6 +41,7 @@ public class SponsorBlockSettingsPresenter extends BasePresenter<Void> {
appendExcludeChannelButton(settingsPresenter);
appendActionsSection(settingsPresenter);
appendColorMarkersSection(settingsPresenter);
appendQuietDurationSection(settingsPresenter);
appendMiscSection(settingsPresenter);
appendLinks(settingsPresenter);
@@ -124,6 +126,11 @@ public class SponsorBlockSettingsPresenter extends BasePresenter<Void> {
settingsPresenter.appendCheckedCategory(getContext().getString(R.string.sponsor_color_markers), options);
}
private void appendQuietDurationSection(AppDialogPresenter settingsPresenter) {
OptionCategory category = AppDialogUtil.createQuietDurationCategory(getContext());
settingsPresenter.appendCategory(category);
}
private void appendLinks(AppDialogPresenter settingsPresenter) {
OptionItem statsCheckOption = UiOptionItem.from(getContext().getString(R.string.content_block_status),
option -> Utils.openLink(getContext(), getContext().getString(R.string.content_block_status_url)));
@@ -137,10 +144,6 @@ public class SponsorBlockSettingsPresenter extends BasePresenter<Void> {
private void appendMiscSection(AppDialogPresenter settingsPresenter) {
List<OptionItem> options = new ArrayList<>();
options.add(UiOptionItem.from(getContext().getString(R.string.dont_skip_short_segements),
optionItem -> mContentBlockData.setStayQuietEnabled(optionItem.isSelected()),
mContentBlockData.isStayQuietEnabled()));
options.add(UiOptionItem.from(getContext().getString(R.string.paid_content_notification),
optionItem -> mContentBlockData.setPaidContentNotificationEnabled(optionItem.isSelected()),

View File

@@ -33,7 +33,7 @@ public class SponsorBlockData {
private final Set<String> mExcludedChannels = new LinkedHashSet<>();
private boolean mIsDontSkipSegmentAgainEnabled;
private boolean mIsPaidContentNotificationEnabled;
private boolean mIsStayQuietEnabled;
private long mQuietDurationMs;
private Map<String, Integer> mSegmentLocalizedMapping;
private Map<String, Integer> mSegmentColorMapping;
private Set<String> mAllCategories;
@@ -225,12 +225,12 @@ public class SponsorBlockData {
persistState();
}
public boolean isStayQuietEnabled() {
return mIsStayQuietEnabled;
public long getQuietDurationMs() {
return mQuietDurationMs;
}
public void setStayQuietEnabled(boolean enable) {
mIsStayQuietEnabled = enable;
public void setQuietDurationMs(long durationMs) {
mQuietDurationMs = durationMs;
persistState();
}
@@ -256,7 +256,7 @@ public class SponsorBlockData {
mIsDontSkipSegmentAgainEnabled = Helpers.parseBoolean(split, 8, false);
String excludedChannels = Helpers.parseStr(split, 9);
mIsPaidContentNotificationEnabled = Helpers.parseBoolean(split, 10, false);
mIsStayQuietEnabled = Helpers.parseBoolean(split, 11, true);
mQuietDurationMs = Helpers.parseLong(split, 11, 10_000);
if (colorCategories != null) {
String[] categoriesArr = Helpers.splitArray(colorCategories);
@@ -312,7 +312,7 @@ public class SponsorBlockData {
mAppPrefs.setData(SPONSOR_BLOCK_DATA, Helpers.mergeData(
mIsSponsorBlockEnabled, null, null, null,
null, null, actions, colorCategories, mIsDontSkipSegmentAgainEnabled,
excludedChannels, mIsPaidContentNotificationEnabled, mIsStayQuietEnabled
excludedChannels, mIsPaidContentNotificationEnabled, mQuietDurationMs
));
}
}

View File

@@ -77,6 +77,7 @@ public class AppDialogUtil {
private static final int AUDIO_VOLUME_ID = 145;
private static final int PLAYER_REPEAT_ID = 146;
private static final int PLAYER_ENGINE_ID = 147;
private static final int QUIET_DURATION_ID = 148;
private static final int SUBTITLE_STYLES_ID = 45;
private static final int SUBTITLE_SIZE_ID = 46;
private static final int SUBTITLE_POSITION_ID = 47;
@@ -863,6 +864,28 @@ public class AppDialogUtil {
);
}
public static OptionCategory createQuietDurationCategory(Context context) {
return createQuietDurationCategory(context, () -> {});
}
public static OptionCategory createQuietDurationCategory(Context context, Runnable onSetCallback) {
SponsorBlockData sponsorBlockData = SponsorBlockData.instance(context);
String title = context.getString(R.string.dont_skip_short_segments);
List<OptionItem> options = new ArrayList<>();
for (int durationMs : Helpers.range(0, 20_000, 500)) {
options.add(UiOptionItem.from(context.getString(R.string.audio_shift_sec, Helpers.toString(durationMs / 1_000f)),
optionItem -> {
sponsorBlockData.setQuietDurationMs(durationMs);
onSetCallback.run();
},
durationMs == sponsorBlockData.getQuietDurationMs()));
}
return OptionCategory.from(QUIET_DURATION_ID, OptionCategory.TYPE_RADIO_LIST, title, options);
}
public static OptionItem createSubscriptionsBackupButton(Context context) {
AppDialogPresenter dialogPresenter = AppDialogPresenter.instance(context);
List<OptionItem> options = new ArrayList<>();

View File

@@ -722,5 +722,5 @@
<string name="player_time_stretching">Растяжение аудио во времени</string>
<string name="player_time_stretching_desc">Сохраняет естественное звучание голоса при изменении скорости. Может значительно снизить производительность на некоторых устройствах.</string>
<string name="queue_respects_playback_mode">Очередь учитывает режим воспроизведения</string>
<string name="dont_skip_short_segements">Не пропускать короткие сегменты (&lt; 10 сек)</string>
<string name="dont_skip_short_segments">Не пропускать короткие сегменты</string>
</resources>

View File

@@ -732,5 +732,5 @@
<string name="player_time_stretching">Ses zaman esnetme</string>
<string name="player_time_stretching_desc">Hız değiştirildiğinde sesi doğal tutar. Bazı cihazlarda performansı önemli ölçüde düşürebilir.</string>
<string name="queue_respects_playback_mode">Kuyruk oynatma modunu dikkate alır</string>
<string name="dont_skip_short_segements">Kısa bölümleri atlama (&lt; 10 sn)</string>
<string name="dont_skip_short_segments">Kısa bölümleri atlama</string>
</resources>

View File

@@ -720,5 +720,5 @@
<string name="player_time_stretching">Розтягування аудіо в часі</string>
<string name="player_time_stretching_desc">Зберігає природний голос при зміні швидкості. Може суттєво знизити продуктивність на деяких пристроях.</string>
<string name="queue_respects_playback_mode">Черга враховує режим відтворення</string>
<string name="dont_skip_short_segements">Не пропускати короткі сегменти (&lt; 10 с)</string>
<string name="dont_skip_short_segments">Не пропускати короткі сегменти</string>
</resources>

View File

@@ -732,5 +732,5 @@
<string name="player_time_stretching">Audio time stretching</string>
<string name="player_time_stretching_desc">Keeps voice natural when changing speed. May significantly reduce performance on some devices.</string>
<string name="queue_respects_playback_mode">Queue respects playback mode</string>
<string name="dont_skip_short_segements">Don\'t skip short segments (&lt; 10sec)</string>
<string name="dont_skip_short_segments">Don\'t skip short segments</string>
</resources>

View File

@@ -127,11 +127,11 @@ android {
productFlavors {
stbeta {
applicationId "org.smarttube.beta"
targetSdkVersion project.properties.compileSdkVersion
targetSdkVersion 27 // Since 28+ GridLayoutManager navigation is totally broken
}
ststable {
applicationId "org.smarttube.stable"
targetSdkVersion project.properties.compileSdkVersion
targetSdkVersion 27 // Since 28+ GridLayoutManager navigation is totally broken
}
stfdroid {
applicationId "app.smarttube.fdroid"