diff --git a/app/src/main/java/app/revanced/integrations/patches/SpoofSignaturePatch.java b/app/src/main/java/app/revanced/integrations/patches/SpoofSignaturePatch.java
new file mode 100644
index 00000000..ca523a4d
--- /dev/null
+++ b/app/src/main/java/app/revanced/integrations/patches/SpoofSignaturePatch.java
@@ -0,0 +1,90 @@
+package app.revanced.integrations.patches;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import app.revanced.integrations.settings.SettingsEnum;
+import app.revanced.integrations.shared.PlayerType;
+import app.revanced.integrations.utils.LogHelper;
+
+import static app.revanced.integrations.utils.ReVancedUtils.containsAny;
+
+/** @noinspection unused*/
+public class SpoofSignaturePatch {
+ /**
+ * Parameter (also used by
+ * yt-dlp)
+ * to fix playback issues.
+ */
+ private static final String INCOGNITO_PARAMETERS = "CgIQBg==";
+
+ /**
+ * Parameters causing playback issues.
+ */
+ private static final String[] AUTOPLAY_PARAMETERS = {
+ "YAHI", // Autoplay in feed.
+ "SAFg" // Autoplay in scrim.
+ };
+
+ /**
+ * Parameter used for autoplay in scrim.
+ * Prepend this parameter to mute video playback (for autoplay in feed).
+ */
+ private static final String SCRIM_PARAMETER = "SAFgAXgB";
+
+
+ /**
+ * Parameters used in YouTube Shorts.
+ */
+ private static final String SHORTS_PLAYER_PARAMETERS = "8AEB";
+
+ private static boolean isPlayingShorts;
+
+ /**
+ * Injection point.
+ *
+ * @param parameters Original protobuf parameter value.
+ */
+ public static String spoofParameter(String parameters) {
+ LogHelper.printDebug(() -> "Original protobuf parameter value: " + parameters);
+
+ if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) return parameters;
+
+ // Shorts do not need to be spoofed.
+ //noinspection AssignmentUsedAsCondition
+ if (isPlayingShorts = parameters.startsWith(SHORTS_PLAYER_PARAMETERS)) return parameters;
+
+ boolean isPlayingFeed = PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL && containsAny(parameters, AUTOPLAY_PARAMETERS);
+ if (isPlayingFeed) return SettingsEnum.SPOOF_SIGNATURE_IN_FEED.getBoolean() ?
+ // Prepend the scrim parameter to mute videos in feed.
+ SCRIM_PARAMETER + INCOGNITO_PARAMETERS :
+ // In order to prevent videos that are auto-played in feed to be added to history,
+ // only spoof the parameter if the video is not playing in the feed.
+ // This will cause playback issues in the feed, but it's better than manipulating the history.
+ parameters;
+
+ return INCOGNITO_PARAMETERS;
+ }
+
+ /**
+ * Injection point.
+ */
+ public static boolean getSeekbarThumbnailOverrideValue() {
+ return SettingsEnum.SPOOF_SIGNATURE.getBoolean();
+ }
+
+ /**
+ * Injection point.
+ *
+ * @param view seekbar thumbnail view. Includes both shorts and regular videos.
+ */
+ public static void seekbarImageViewCreated(ImageView view) {
+ if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) return;
+ if (isPlayingShorts) return;
+
+ view.setVisibility(View.GONE);
+ // Also hide the border around the thumbnail (otherwise a 1 pixel wide bordered frame is visible).
+ ViewGroup parentLayout = (ViewGroup) view.getParent();
+ parentLayout.setPadding(0, 0, 0, 0);
+ }
+}
diff --git a/app/src/main/java/app/revanced/integrations/patches/SpoofSignatureVerificationPatch.java b/app/src/main/java/app/revanced/integrations/patches/SpoofSignatureVerificationPatch.java
deleted file mode 100644
index 37c7a51d..00000000
--- a/app/src/main/java/app/revanced/integrations/patches/SpoofSignatureVerificationPatch.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package app.revanced.integrations.patches;
-
-import static app.revanced.integrations.utils.ReVancedUtils.containsAny;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import app.revanced.integrations.settings.SettingsEnum;
-import app.revanced.integrations.shared.PlayerType;
-import app.revanced.integrations.utils.LogHelper;
-
-public class SpoofSignatureVerificationPatch {
- /**
- * Enable/disable all workarounds that are required due to signature spoofing.
- */
- private static final boolean WORKAROUND = true;
-
- /**
- * Protobuf parameters used for autoplay in scrim.
- * Prepend this parameter to mute video playback (for autoplay in feed)
- */
- private static final String PROTOBUF_PARAMETER_SCRIM = "SAFgAXgB";
-
- /**
- * Protobuf parameter also used by
- * yt-dlp
- *
- * Known issue: captions are positioned on upper area in the player.
- */
- private static final String PROTOBUF_PLAYER_PARAMS = "CgIQBg==";
-
- /**
- * Target Protobuf parameters.
- */
- private static final String[] PROTOBUF_PARAMETER_TARGETS = {
- "YAHI", // Autoplay in feed
- "SAFg" // Autoplay in scrim
- };
-
- /**
- * Injection point.
- *
- * @param originalValue originalValue protobuf parameter
- */
- public static String overrideProtobufParameter(String originalValue) {
- try {
- if (!SettingsEnum.SPOOF_SIGNATURE_VERIFICATION.getBoolean()) {
- return originalValue;
- }
-
- LogHelper.printDebug(() -> "Original protobuf parameter value: " + originalValue);
-
- if (!WORKAROUND) return PROTOBUF_PLAYER_PARAMS;
-
- var isPlayingVideo = originalValue.contains(PROTOBUF_PLAYER_PARAMS);
- if (isPlayingVideo) return originalValue;
-
- boolean isPlayingFeed = containsAny(originalValue, PROTOBUF_PARAMETER_TARGETS) && PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL;
- if (isPlayingFeed) {
- // Videos in feed won't autoplay with sound.
- return PROTOBUF_PARAMETER_SCRIM + PROTOBUF_PLAYER_PARAMS;
- } else {
- // Spoof the parameter to prevent playback issues.
- return PROTOBUF_PLAYER_PARAMS;
- }
- } catch (Exception ex) {
- LogHelper.printException(() -> "overrideProtobufParameter failure", ex);
- }
-
- return originalValue;
- }
-
- /**
- * Injection point.
- */
- public static boolean getSeekbarThumbnailOverrideValue() {
- return SettingsEnum.SPOOF_SIGNATURE_VERIFICATION.getBoolean();
- }
-
- /**
- * Injection point.
- *
- * @param view seekbar thumbnail view. Includes both shorts and regular videos.
- */
- public static void seekbarImageViewCreated(ImageView view) {
- if (SettingsEnum.SPOOF_SIGNATURE_VERIFICATION.getBoolean()) {
- view.setVisibility(View.GONE);
- // Also hide the border around the thumbnail (otherwise a 1 pixel wide bordered frame is visible).
- ViewGroup parentLayout = (ViewGroup) view.getParent();
- parentLayout.setPadding(0, 0, 0, 0);
- }
- }
-
-}
diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java
index 7b578a63..3ab42ddd 100644
--- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java
+++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java
@@ -165,8 +165,10 @@ public enum SettingsEnum {
EXTERNAL_BROWSER("revanced_external_browser", BOOLEAN, TRUE, true),
AUTO_REPEAT("revanced_auto_repeat", BOOLEAN, FALSE),
SEEKBAR_TAPPING("revanced_seekbar_tapping", BOOLEAN, TRUE),
- SPOOF_SIGNATURE_VERIFICATION("revanced_spoof_signature_verification", BOOLEAN, TRUE, true,
- "revanced_spoof_signature_verification_user_dialog_message"),
+ SPOOF_SIGNATURE("revanced_spoof_signature_verification_enabled", BOOLEAN, TRUE, true,
+ "revanced_spoof_signature_verification_enabled_user_dialog_message"),
+ SPOOF_SIGNATURE_IN_FEED("revanced_spoof_signature_in_feed_enabled", BOOLEAN, FALSE, false,
+ parents(SPOOF_SIGNATURE)),
// Swipe controls
SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE),