mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-07 18:03:55 +01:00
Compare commits
16 Commits
v5.2.3-dev
...
v5.3.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c94376bc4c | ||
|
|
87fe83aacf | ||
|
|
92d282e963 | ||
|
|
4a88f650c2 | ||
|
|
8b67716506 | ||
|
|
95d56b1529 | ||
|
|
b1f3b12fa1 | ||
|
|
cf4456c2ba | ||
|
|
d509a3f397 | ||
|
|
d1ae1f1da7 | ||
|
|
9c1c90864c | ||
|
|
5ae76f4df8 | ||
|
|
87eaf61ef1 | ||
|
|
35594d0a20 | ||
|
|
e3c54d8a64 | ||
|
|
06202c8807 |
56
CHANGELOG.md
56
CHANGELOG.md
@@ -1,3 +1,59 @@
|
||||
# [5.3.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.3.0-dev.3...v5.3.0-dev.4) (2024-12-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Nyx:** Remove broken `Unlock pro` patch ([1fe8b16](https://github.com/ReVanced/revanced-patches/commit/1fe8b164eab0c4fa80ab2da2581977f5111a2858))
|
||||
|
||||
# [5.3.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.3.0-dev.2...v5.3.0-dev.3) (2024-12-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof video streams:** Update `Force AVC` client data ([#4064](https://github.com/ReVanced/revanced-patches/issues/4064)) ([7d537dd](https://github.com/ReVanced/revanced-patches/commit/7d537ddff4bb5421fa320741275131a66ef5c7bb))
|
||||
|
||||
# [5.3.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.3.0-dev.1...v5.3.0-dev.2) (2024-12-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Reddit:** Fix patches by using correct extension class ([70bdc68](https://github.com/ReVanced/revanced-patches/commit/70bdc6840d465399625aa1ae0259f49e72711955))
|
||||
|
||||
# [5.3.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.2.4-dev.3...v5.3.0-dev.1) (2024-12-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube Music:** Add `Spoof video streams` patch to fix playback ([#4065](https://github.com/ReVanced/revanced-patches/issues/4065)) ([cf3116a](https://github.com/ReVanced/revanced-patches/commit/cf3116a7583d09c25c798a85687a056f143656f0))
|
||||
|
||||
## [5.2.4-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.4-dev.2...v5.2.4-dev.3) (2024-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof video streams:** Enable opus codec by updating iOS client version ([#4063](https://github.com/ReVanced/revanced-patches/issues/4063)) ([0af156f](https://github.com/ReVanced/revanced-patches/commit/0af156f18972c5f089af4bb69824968d2a47d18f))
|
||||
|
||||
## [5.2.4-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.4-dev.1...v5.2.4-dev.2) (2024-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Sync for Reddit:** Fix patches by using correct extension name ([030093e](https://github.com/ReVanced/revanced-patches/commit/030093e913aab3fab43935eedbaeba0f6c0491bb))
|
||||
|
||||
## [5.2.4-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.2.3...v5.2.4-dev.1) (2024-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Twitter:** Merge correct extension by depending on correct extension patch ([8281cf6](https://github.com/ReVanced/revanced-patches/commit/8281cf6a3eead8cc25a277371e0b0ab2be982497))
|
||||
|
||||
## [5.2.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.2...v5.2.3) (2024-12-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube Music - GmsCore support:** Resolve patching errors ([#4056](https://github.com/ReVanced/revanced-patches/issues/4056)) ([38a4bad](https://github.com/ReVanced/revanced-patches/commit/38a4bad5b890e3906d77d22efeabd8f38653508b))
|
||||
|
||||
## [5.2.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.2.2...v5.2.3-dev.1) (2024-12-06)
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package app.revanced.extension.patches;
|
||||
package app.revanced.extension.reddit.patches;
|
||||
|
||||
import com.reddit.domain.model.ILink;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class FilterPromotedLinksPatch {
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Filters list from promoted links.
|
||||
**/
|
||||
public static List<?> filterChildren(final Iterable<?> links) {
|
||||
@@ -1,12 +1,15 @@
|
||||
package app.revanced.extension.shared.settings;
|
||||
|
||||
import app.revanced.extension.shared.spoof.ClientType;
|
||||
import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||
|
||||
/**
|
||||
* Settings shared across multiple apps.
|
||||
*
|
||||
* <p>
|
||||
* To ensure this class is loaded when the UI is created, app specific setting bundles should extend
|
||||
* or reference this class.
|
||||
*/
|
||||
@@ -16,4 +19,10 @@ public class BaseSettings {
|
||||
public static final BooleanSetting DEBUG_TOAST_ON_ERROR = new BooleanSetting("revanced_debug_toast_on_error", TRUE, "revanced_debug_toast_on_error_user_dialog_message");
|
||||
|
||||
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
|
||||
|
||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
|
||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
|
||||
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
|
||||
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +1,49 @@
|
||||
package app.revanced.extension.youtube.patches.spoof;
|
||||
|
||||
import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.allowAV1;
|
||||
import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.allowVP9;
|
||||
package app.revanced.extension.shared.spoof;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
|
||||
public enum ClientType {
|
||||
// Specific purpose for age restricted, or private videos, because the iOS client is not logged in.
|
||||
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
||||
ANDROID_VR(28,
|
||||
"Quest 3",
|
||||
"12",
|
||||
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
|
||||
"32", // Android 12.1
|
||||
"1.56.21",
|
||||
"ANDROID_VR",
|
||||
true
|
||||
),
|
||||
// Specific for kids videos.
|
||||
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
||||
IOS(5,
|
||||
// iPhone 15 supports AV1 hardware decoding.
|
||||
// Only use if this Android device also has hardware decoding.
|
||||
allowAV1()
|
||||
? "iPhone16,2" // 15 Pro Max
|
||||
: "iPhone11,4", // XS Max
|
||||
// iOS 14+ forces VP9.
|
||||
allowVP9()
|
||||
? "17.5.1.21F90"
|
||||
: "13.7.17H35",
|
||||
allowVP9()
|
||||
? "com.google.ios.youtube/19.10.7 (iPhone; U; CPU iOS 17_5_1 like Mac OS X)"
|
||||
: "com.google.ios.youtube/19.10.7 (iPhone; U; CPU iOS 13_7 like Mac OS X)",
|
||||
forceAVC()
|
||||
? "iPhone12,5" // 11 Pro Max (last device with iOS 13)
|
||||
: "iPhone16,2", // 15 Pro Max
|
||||
// iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1.
|
||||
forceAVC()
|
||||
? "13.7.17H35" // Last release of iOS 13.
|
||||
: "17.5.1.21F90",
|
||||
forceAVC()
|
||||
? "com.google.ios.youtube/17.40.5 (iPhone; U; CPU iOS 13_7 like Mac OS X)"
|
||||
: "com.google.ios.youtube/19.47.7 (iPhone; U; CPU iOS 17_5_1 like Mac OS X)",
|
||||
null,
|
||||
// Version number should be a valid iOS release.
|
||||
// https://www.ipa4fun.com/history/185230
|
||||
"19.10.7",
|
||||
"IOS",
|
||||
forceAVC()
|
||||
// Some newer versions can also force AVC,
|
||||
// but 17.40 is the last version that supports iOS 13.
|
||||
? "17.40.5"
|
||||
: "19.47.7",
|
||||
false
|
||||
);
|
||||
|
||||
private static boolean forceAVC() {
|
||||
return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* YouTube
|
||||
* <a href="https://github.com/zerodytrash/YouTube-Internal-Clients?tab=readme-ov-file#clients">client type</a>
|
||||
@@ -69,11 +72,6 @@ public enum ClientType {
|
||||
@Nullable
|
||||
public final String androidSdkVersion;
|
||||
|
||||
/**
|
||||
* Client name.
|
||||
*/
|
||||
public final String clientName;
|
||||
|
||||
/**
|
||||
* App version.
|
||||
*/
|
||||
@@ -90,7 +88,6 @@ public enum ClientType {
|
||||
String userAgent,
|
||||
@Nullable String androidSdkVersion,
|
||||
String clientVersion,
|
||||
String clientName,
|
||||
boolean canLogin
|
||||
) {
|
||||
this.id = id;
|
||||
@@ -99,7 +96,6 @@ public enum ClientType {
|
||||
this.userAgent = userAgent;
|
||||
this.androidSdkVersion = androidSdkVersion;
|
||||
this.clientVersion = clientVersion;
|
||||
this.clientName = clientName;
|
||||
this.canLogin = canLogin;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.extension.youtube.patches.spoof;
|
||||
package app.revanced.extension.shared.spoof;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
@@ -12,20 +12,12 @@ import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.youtube.patches.spoof.requests.StreamingDataRequest;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SpoofVideoStreamsPatch {
|
||||
public static final class ForceiOSAVCAvailability implements Setting.Availability {
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return Settings.SPOOF_VIDEO_STREAMS.get() && Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
|
||||
}
|
||||
}
|
||||
|
||||
private static final boolean SPOOF_STREAMING_DATA = Settings.SPOOF_VIDEO_STREAMS.get();
|
||||
|
||||
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
|
||||
/**
|
||||
* Any unreachable ip address. Used to intentionally fail requests.
|
||||
*/
|
||||
@@ -165,4 +157,11 @@ public class SpoofVideoStreamsPatch {
|
||||
|
||||
return postData;
|
||||
}
|
||||
|
||||
public static final class ForceiOSAVCAvailability implements Setting.Availability {
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return BaseSettings.SPOOF_VIDEO_STREAMS.get() && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.extension.youtube.patches.spoof.requests;
|
||||
package app.revanced.extension.shared.spoof.requests;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -10,7 +10,7 @@ import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.requests.Requester;
|
||||
import app.revanced.extension.shared.requests.Route;
|
||||
import app.revanced.extension.youtube.patches.spoof.ClientType;
|
||||
import app.revanced.extension.shared.spoof.ClientType;
|
||||
|
||||
final class PlayerRoutes {
|
||||
static final Route.CompiledRoute GET_STREAMING_DATA = new Route(
|
||||
@@ -1,6 +1,6 @@
|
||||
package app.revanced.extension.youtube.patches.spoof.requests;
|
||||
package app.revanced.extension.shared.spoof.requests;
|
||||
|
||||
import static app.revanced.extension.youtube.patches.spoof.requests.PlayerRoutes.GET_STREAMING_DATA;
|
||||
import static app.revanced.extension.shared.spoof.requests.PlayerRoutes.GET_STREAMING_DATA;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -22,8 +22,7 @@ import java.util.concurrent.TimeoutException;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.youtube.patches.spoof.ClientType;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.spoof.ClientType;
|
||||
|
||||
/**
|
||||
* Video streaming data. Fetching is tied to the behavior YT uses,
|
||||
@@ -70,7 +69,7 @@ public class StreamingDataRequest {
|
||||
|
||||
static {
|
||||
ClientType[] allClientTypes = ClientType.values();
|
||||
ClientType preferredClient = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||
ClientType preferredClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||
|
||||
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
|
||||
CLIENT_ORDER_TO_USE[0] = preferredClient;
|
||||
@@ -1,12 +0,0 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class FullscreenPanelsRemoverPatch {
|
||||
public static int getFullscreenPanelsVisibility() {
|
||||
return Settings.HIDE_FULLSCREEN_PANELS.get() ? View.GONE : View.VISIBLE;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package app.revanced.extension.youtube.patches.spoof;
|
||||
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaCodecList;
|
||||
import android.os.Build;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
public class DeviceHardwareSupport {
|
||||
public static final boolean DEVICE_HAS_HARDWARE_DECODING_VP9;
|
||||
public static final boolean DEVICE_HAS_HARDWARE_DECODING_AV1;
|
||||
|
||||
static {
|
||||
boolean vp9found = false;
|
||||
boolean av1found = false;
|
||||
MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
|
||||
final boolean deviceIsAndroidTenOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
|
||||
|
||||
for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) {
|
||||
final boolean isHardwareAccelerated = deviceIsAndroidTenOrLater
|
||||
? codecInfo.isHardwareAccelerated()
|
||||
: !codecInfo.getName().startsWith("OMX.google"); // Software decoder.
|
||||
if (isHardwareAccelerated && !codecInfo.isEncoder()) {
|
||||
for (String type : codecInfo.getSupportedTypes()) {
|
||||
if (type.equalsIgnoreCase("video/x-vnd.on2.vp9")) {
|
||||
vp9found = true;
|
||||
} else if (type.equalsIgnoreCase("video/av01")) {
|
||||
av1found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEVICE_HAS_HARDWARE_DECODING_VP9 = vp9found;
|
||||
DEVICE_HAS_HARDWARE_DECODING_AV1 = av1found;
|
||||
|
||||
Logger.printDebug(() -> DEVICE_HAS_HARDWARE_DECODING_AV1
|
||||
? "Device supports AV1 hardware decoding\n"
|
||||
: "Device does not support AV1 hardware decoding\n"
|
||||
+ (DEVICE_HAS_HARDWARE_DECODING_VP9
|
||||
? "Device supports VP9 hardware decoding"
|
||||
: "Device does not support VP9 hardware decoding"));
|
||||
}
|
||||
|
||||
public static boolean allowVP9() {
|
||||
return DEVICE_HAS_HARDWARE_DECODING_VP9 && !Settings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
|
||||
}
|
||||
|
||||
public static boolean allowAV1() {
|
||||
return allowVP9() && DEVICE_HAS_HARDWARE_DECODING_AV1;
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,42 @@ package app.revanced.extension.youtube.settings;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static app.revanced.extension.shared.settings.Setting.*;
|
||||
import static app.revanced.extension.shared.settings.Setting.Availability;
|
||||
import static app.revanced.extension.shared.settings.Setting.migrateFromOldPreferences;
|
||||
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
|
||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||
import static app.revanced.extension.shared.settings.Setting.parentsAny;
|
||||
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MINIMAL;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_1;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_2;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_3;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.PHONE;
|
||||
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
||||
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.*;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.settings.*;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.settings.EnumSetting;
|
||||
import app.revanced.extension.shared.settings.FloatSetting;
|
||||
import app.revanced.extension.shared.settings.IntegerSetting;
|
||||
import app.revanced.extension.shared.settings.LongSetting;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.settings.StringSetting;
|
||||
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime;
|
||||
import app.revanced.extension.youtube.patches.spoof.ClientType;
|
||||
import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch;
|
||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
|
||||
public class Settings extends BaseSettings {
|
||||
@@ -37,17 +54,17 @@ public class Settings extends BaseSettings {
|
||||
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
|
||||
|
||||
// Ads
|
||||
public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_GENERAL_ADS = new BooleanSetting("revanced_hide_general_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_GET_PREMIUM = new BooleanSetting("revanced_hide_get_premium", TRUE);
|
||||
public static final BooleanSetting HIDE_HIDE_LATEST_POSTS = new BooleanSetting("revanced_hide_latest_posts_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_MERCHANDISE_BANNERS = new BooleanSetting("revanced_hide_merchandise_banners", TRUE);
|
||||
public static final BooleanSetting HIDE_PAID_PROMOTION_LABEL = new BooleanSetting("revanced_hide_paid_promotion_label", TRUE);
|
||||
public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_STORE_SHELF = new BooleanSetting("revanced_hide_player_store_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE);
|
||||
public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE);
|
||||
public static final BooleanSetting HIDE_SELF_SPONSOR = new BooleanSetting("revanced_hide_self_sponsor_ads", TRUE);
|
||||
public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE);
|
||||
public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_hide_video_ads", TRUE, true);
|
||||
public static final BooleanSetting HIDE_VISIT_STORE_BUTTON = new BooleanSetting("revanced_hide_visit_store_button", TRUE);
|
||||
public static final BooleanSetting HIDE_WEB_SEARCH_RESULTS = new BooleanSetting("revanced_hide_web_search_results", TRUE);
|
||||
@@ -55,9 +72,27 @@ public class Settings extends BaseSettings {
|
||||
// Feed
|
||||
public static final BooleanSetting HIDE_ALBUM_CARDS = new BooleanSetting("revanced_hide_album_cards", FALSE, true);
|
||||
public static final BooleanSetting HIDE_ARTIST_CARDS = new BooleanSetting("revanced_hide_artist_cards", FALSE);
|
||||
public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE);
|
||||
public static final BooleanSetting HIDE_CHIPS_SHELF = new BooleanSetting("revanced_hide_chips_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE);
|
||||
public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE);
|
||||
public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true);
|
||||
public static final BooleanSetting HIDE_DOODLES = new BooleanSetting("revanced_hide_doodles", FALSE, true, "revanced_hide_doodles_user_dialog_message");
|
||||
|
||||
public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE);
|
||||
public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_FOR_YOU_SHELF = new BooleanSetting("revanced_hide_for_you_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_HORIZONTAL_SHELVES = new BooleanSetting("revanced_hide_horizontal_shelves", TRUE);
|
||||
public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
|
||||
public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE);
|
||||
public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYABLES = new BooleanSetting("revanced_hide_playables", TRUE);
|
||||
public static final BooleanSetting HIDE_SEARCH_RESULT_RECOMMENDATIONS = new BooleanSetting("revanced_hide_search_result_recommendations", TRUE);
|
||||
public static final BooleanSetting HIDE_SEARCH_RESULT_SHELF_HEADER = new BooleanSetting("revanced_hide_search_result_shelf_header", FALSE);
|
||||
public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
|
||||
// Alternative thumbnails
|
||||
public static final EnumSetting<ThumbnailOption> ALT_THUMBNAIL_HOME = new EnumSetting<>("revanced_alt_thumbnail_home", ThumbnailOption.ORIGINAL);
|
||||
public static final EnumSetting<ThumbnailOption> ALT_THUMBNAIL_SUBSCRIPTIONS = new EnumSetting<>("revanced_alt_thumbnail_subscription", ThumbnailOption.ORIGINAL);
|
||||
@@ -69,7 +104,6 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST = new BooleanSetting("revanced_alt_thumbnail_dearrow_connection_toast", TRUE, new DeArrowAvailability());
|
||||
public static final EnumSetting<ThumbnailStillTime> ALT_THUMBNAIL_STILLS_TIME = new EnumSetting<>("revanced_alt_thumbnail_stills_time", ThumbnailStillTime.MIDDLE, new StillImagesAvailability());
|
||||
public static final BooleanSetting ALT_THUMBNAIL_STILLS_FAST = new BooleanSetting("revanced_alt_thumbnail_stills_fast", FALSE, new StillImagesAvailability());
|
||||
|
||||
// Hide keyword content
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_HOME = new BooleanSetting("revanced_hide_keyword_content_home", FALSE);
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_keyword_content_subscriptions", FALSE);
|
||||
@@ -77,61 +111,35 @@ public class Settings extends BaseSettings {
|
||||
public static final StringSetting HIDE_KEYWORD_CONTENT_PHRASES = new StringSetting("revanced_hide_keyword_content_phrases", "",
|
||||
parentsAny(HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS, HIDE_KEYWORD_CONTENT_SEARCH));
|
||||
|
||||
// Uncategorized layout related settings. Do not add to this section, and instead move these out and categorize them.
|
||||
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
|
||||
public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
|
||||
public static final BooleanSetting HIDE_HORIZONTAL_SHELVES = new BooleanSetting("revanced_hide_horizontal_shelves", TRUE);
|
||||
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
|
||||
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE);
|
||||
public static final BooleanSetting HIDE_CHANNEL_MEMBER_SHELF = new BooleanSetting("revanced_hide_channel_member_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_CHIPS_SHELF = new BooleanSetting("revanced_hide_chips_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_community_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE);
|
||||
public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE);
|
||||
public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true);
|
||||
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
|
||||
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
|
||||
public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true);
|
||||
public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_FULLSCREEN_PANELS = new BooleanSetting("revanced_hide_fullscreen_panels", TRUE, true);
|
||||
public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE);
|
||||
public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
|
||||
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
|
||||
public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
|
||||
public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE);
|
||||
public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYABLES = new BooleanSetting("revanced_hide_playables", TRUE);
|
||||
public static final BooleanSetting HIDE_QUICK_ACTIONS = new BooleanSetting("revanced_hide_quick_actions", FALSE);
|
||||
public static final BooleanSetting HIDE_RELATED_VIDEOS = new BooleanSetting("revanced_hide_related_videos", FALSE);
|
||||
public static final BooleanSetting HIDE_SEARCH_RESULT_SHELF_HEADER = new BooleanSetting("revanced_hide_search_result_shelf_header", FALSE);
|
||||
public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE);
|
||||
public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
|
||||
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
|
||||
public static final BooleanSetting HIDE_FOR_YOU_SHELF = new BooleanSetting("revanced_hide_for_you_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_SEARCH_RESULT_RECOMMENDATIONS = new BooleanSetting("revanced_hide_search_result_recommendations", TRUE);
|
||||
public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity",100, true);
|
||||
public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
|
||||
|
||||
// Player
|
||||
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
|
||||
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
|
||||
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
|
||||
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true);
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
|
||||
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
|
||||
public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
|
||||
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
|
||||
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
|
||||
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
|
||||
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
|
||||
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
|
||||
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE);
|
||||
public static final BooleanSetting HIDE_CHANNEL_MEMBER_SHELF = new BooleanSetting("revanced_hide_channel_member_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_community_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
|
||||
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
|
||||
public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE);
|
||||
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
|
||||
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
|
||||
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true);
|
||||
public static final BooleanSetting HIDE_QUICK_ACTIONS = new BooleanSetting("revanced_hide_quick_actions", FALSE);
|
||||
public static final BooleanSetting HIDE_RELATED_VIDEOS = new BooleanSetting("revanced_hide_related_videos", FALSE);
|
||||
public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE);
|
||||
public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE);
|
||||
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
|
||||
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
|
||||
|
||||
public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
|
||||
public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity", 100, true);
|
||||
// Miniplayer
|
||||
public static final EnumSetting<MiniplayerType> MINIPLAYER_TYPE = new EnumSetting<>("revanced_miniplayer_type", MiniplayerType.ORIGINAL, true);
|
||||
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
|
||||
@@ -144,21 +152,18 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting MINIPLAYER_ROUNDED_CORNERS = new BooleanSetting("revanced_miniplayer_rounded_corners", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||
public static final IntegerSetting MINIPLAYER_WIDTH_DIP = new IntegerSetting("revanced_miniplayer_width_dip", 192, true, MINIPLAYER_ANY_MODERN);
|
||||
public static final IntegerSetting MINIPLAYER_OPACITY = new IntegerSetting("revanced_miniplayer_opacity", 100, true, MINIPLAYER_TYPE.availability(MODERN_1));
|
||||
|
||||
// External downloader
|
||||
public static final BooleanSetting EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_external_downloader", FALSE);
|
||||
public static final BooleanSetting EXTERNAL_DOWNLOADER_ACTION_BUTTON = new BooleanSetting("revanced_external_downloader_action_button", FALSE);
|
||||
public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME = new StringSetting("revanced_external_downloader_name",
|
||||
"org.schabi.newpipe" /* NewPipe */, parentsAny(EXTERNAL_DOWNLOADER, EXTERNAL_DOWNLOADER_ACTION_BUTTON));
|
||||
|
||||
// Comments
|
||||
public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
|
||||
|
||||
// Description
|
||||
public static final BooleanSetting HIDE_ATTRIBUTES_SECTION = new BooleanSetting("revanced_hide_attributes_section", FALSE);
|
||||
public static final BooleanSetting HIDE_CHAPTERS_SECTION = new BooleanSetting("revanced_hide_chapters_section", TRUE);
|
||||
@@ -166,47 +171,43 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting HIDE_KEY_CONCEPTS_SECTION = new BooleanSetting("revanced_hide_key_concepts_section", FALSE);
|
||||
public static final BooleanSetting HIDE_PODCAST_SECTION = new BooleanSetting("revanced_hide_podcast_section", TRUE);
|
||||
public static final BooleanSetting HIDE_TRANSCRIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE);
|
||||
|
||||
// Action buttons
|
||||
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
|
||||
public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
|
||||
public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE);
|
||||
public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
|
||||
public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", TRUE);
|
||||
public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE);
|
||||
public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
|
||||
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYLIST_BUTTON = new BooleanSetting("revanced_hide_playlist_button", FALSE);
|
||||
|
||||
public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE);
|
||||
public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
|
||||
public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", TRUE);
|
||||
// Player flyout menu items
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_CAPTIONS = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_ADDITIONAL_SETTINGS = new BooleanSetting("revanced_hide_player_flyout_additional_settings", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOOP_VIDEO = new BooleanSetting("revanced_hide_player_flyout_loop_video", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_AMBIENT_MODE = new BooleanSetting("revanced_hide_player_flyout_ambient_mode", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_HELP = new BooleanSetting("revanced_hide_player_flyout_help", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_SPEED = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_MORE_INFO = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOCK_SCREEN = new BooleanSetting("revanced_hide_player_flyout_lock_screen", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_AUDIO_TRACK = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_CAPTIONS = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_HELP = new BooleanSetting("revanced_hide_player_flyout_help", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOCK_SCREEN = new BooleanSetting("revanced_hide_player_flyout_lock_screen", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOOP_VIDEO = new BooleanSetting("revanced_hide_player_flyout_loop_video", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_MORE_INFO = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_SLEEP_TIMER = new BooleanSetting("revanced_hide_player_flyout_sleep_timer", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_SPEED = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_STABLE_VOLUME = new BooleanSetting("revanced_hide_player_flyout_stable_volume", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_player_flyout_video_quality_footer", FALSE);
|
||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
|
||||
|
||||
// General layout
|
||||
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
|
||||
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
||||
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.35.36" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
||||
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
|
||||
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
||||
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
|
||||
public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
|
||||
public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE,
|
||||
"revanced_remove_viewer_discretion_dialog_user_dialog_message");
|
||||
|
||||
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
||||
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
|
||||
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
||||
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
|
||||
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.35.36" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
||||
// Custom filter
|
||||
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
|
||||
public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER));
|
||||
|
||||
// Navigation buttons
|
||||
public static final BooleanSetting HIDE_HOME_BUTTON = new BooleanSetting("revanced_hide_home_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_CREATE_BUTTON = new BooleanSetting("revanced_hide_create_button", TRUE, true);
|
||||
@@ -216,71 +217,67 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON = new BooleanSetting("revanced_switch_create_with_notifications_button", TRUE, true);
|
||||
|
||||
// Shorts
|
||||
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
||||
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_subscriptions", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SEARCH = new BooleanSetting("revanced_hide_shorts_search", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_PAUSED_OVERLAY_BUTTONS = new BooleanSetting("revanced_hide_shorts_paused_overlay_buttons", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SHOP_BUTTON = new BooleanSetting("revanced_hide_shorts_shop_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_TAGGED_PRODUCTS = new BooleanSetting("revanced_hide_shorts_tagged_products", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LOCATION_LABEL = new BooleanSetting("revanced_hide_shorts_location_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SAVE_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_save_sound_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_USE_TEMPLATE_BUTTON = new BooleanSetting("revanced_hide_shorts_use_template_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE);
|
||||
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SEARCH_SUGGESTIONS = new BooleanSetting("revanced_hide_shorts_search_suggestions", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_like_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_REMIX_BUTTON = new BooleanSetting("revanced_hide_shorts_remix_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SHARE_BUTTON = new BooleanSetting("revanced_hide_shorts_share_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_sound_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_VIDEO_TITLE = new BooleanSetting("revanced_hide_shorts_video_title", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SOUND_METADATA_LABEL = new BooleanSetting("revanced_hide_shorts_sound_metadata_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_like_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_LOCATION_LABEL = new BooleanSetting("revanced_hide_shorts_location_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_NAVIGATION_BAR = new BooleanSetting("revanced_hide_shorts_navigation_bar", FALSE, true);
|
||||
public static final BooleanSetting HIDE_SHORTS_PAUSED_OVERLAY_BUTTONS = new BooleanSetting("revanced_hide_shorts_paused_overlay_buttons", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_REMIX_BUTTON = new BooleanSetting("revanced_hide_shorts_remix_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SAVE_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_save_sound_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SEARCH = new BooleanSetting("revanced_hide_shorts_search", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SEARCH_SUGGESTIONS = new BooleanSetting("revanced_hide_shorts_search_suggestions", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SHARE_BUTTON = new BooleanSetting("revanced_hide_shorts_share_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SHOP_BUTTON = new BooleanSetting("revanced_hide_shorts_shop_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_sound_button", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SOUND_METADATA_LABEL = new BooleanSetting("revanced_hide_shorts_sound_metadata_label", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_subscriptions", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_TAGGED_PRODUCTS = new BooleanSetting("revanced_hide_shorts_tagged_products", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_USE_TEMPLATE_BUTTON = new BooleanSetting("revanced_hide_shorts_use_template_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_VIDEO_TITLE = new BooleanSetting("revanced_hide_shorts_video_title", FALSE);
|
||||
public static final BooleanSetting SHORTS_AUTOPLAY = new BooleanSetting("revanced_shorts_autoplay", FALSE);
|
||||
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);
|
||||
|
||||
// Seekbar
|
||||
|
||||
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE);
|
||||
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
|
||||
public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
|
||||
public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
|
||||
public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
|
||||
"revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
|
||||
public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true);
|
||||
public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE);
|
||||
public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
|
||||
public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
|
||||
public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
|
||||
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
|
||||
public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
|
||||
"revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
|
||||
public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
|
||||
public static final StringSetting SEEKBAR_CUSTOM_COLOR_VALUE = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR));
|
||||
|
||||
// Misc
|
||||
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
|
||||
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
|
||||
public static final BooleanSetting AUTO_CAPTIONS = new BooleanSetting("revanced_auto_captions", FALSE);
|
||||
public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE);
|
||||
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
|
||||
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
|
||||
public static final BooleanSetting DISABLE_ZOOM_HAPTICS = new BooleanSetting("revanced_disable_zoom_haptics", TRUE);
|
||||
public static final BooleanSetting EXTERNAL_BROWSER = new BooleanSetting("revanced_external_browser", TRUE, true);
|
||||
public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE);
|
||||
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
|
||||
public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true,
|
||||
"revanced_spoof_device_dimensions_user_dialog_message");
|
||||
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
|
||||
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
|
||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true,"revanced_spoof_video_streams_user_dialog_message");
|
||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
|
||||
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
|
||||
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
|
||||
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
|
||||
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
|
||||
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
|
||||
|
||||
// Debugging
|
||||
/**
|
||||
* When enabled, share the debug logs with care.
|
||||
* The buffer contains select user data, including the client ip address and information that could identify the end user.
|
||||
@@ -298,6 +295,8 @@ public class Settings extends BaseSettings {
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127, true,
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
|
||||
// Debugging
|
||||
public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 22, true,
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true,
|
||||
@@ -320,7 +319,6 @@ public class Settings extends BaseSettings {
|
||||
* Do not use directly, instead use {@link SponsorBlockSettings}
|
||||
*/
|
||||
public static final StringSetting SB_PRIVATE_USER_ID = new StringSetting("sb_private_user_id_Do_Not_Share", "");
|
||||
public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
|
||||
public static final IntegerSetting SB_CREATE_NEW_SEGMENT_STEP = new IntegerSetting("sb_create_new_segment_step", 150, parent(SB_ENABLED));
|
||||
public static final BooleanSetting SB_VOTING_BUTTON = new BooleanSetting("sb_voting_button", FALSE, parent(SB_ENABLED));
|
||||
public static final BooleanSetting SB_CREATE_NEW_SEGMENT = new BooleanSetting("sb_create_new_segment", FALSE, parent(SB_ENABLED));
|
||||
@@ -331,34 +329,38 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED));
|
||||
public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED));
|
||||
public static final BooleanSetting SB_VIDEO_LENGTH_WITHOUT_SEGMENTS = new BooleanSetting("sb_video_length_without_segments", TRUE, parent(SB_ENABLED));
|
||||
public static final StringSetting SB_API_URL = new StringSetting("sb_api_url","https://sponsor.ajay.app");
|
||||
public static final StringSetting SB_API_URL = new StringSetting("sb_api_url", "https://sponsor.ajay.app");
|
||||
public static final BooleanSetting SB_USER_IS_VIP = new BooleanSetting("sb_user_is_vip", FALSE);
|
||||
public static final IntegerSetting SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS = new IntegerSetting("sb_local_time_saved_number_segments", 0);
|
||||
public static final LongSetting SB_LOCAL_TIME_SAVED_MILLISECONDS = new LongSetting("sb_local_time_saved_milliseconds", 0L);
|
||||
public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false);
|
||||
public static final BooleanSetting SB_HIDE_EXPORT_WARNING = new BooleanSetting("sb_hide_export_warning", FALSE, false, false);
|
||||
public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false);
|
||||
|
||||
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color","#00D400");
|
||||
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
|
||||
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color","#FFFF00");
|
||||
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
|
||||
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color","#CC00FF");
|
||||
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
|
||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color","#FF1684");
|
||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
|
||||
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color","#00FFFF");
|
||||
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
|
||||
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color","#0202ED");
|
||||
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
|
||||
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color","#008FD6");
|
||||
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
|
||||
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color","#7300FF");
|
||||
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
|
||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color","#FF9900");
|
||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
|
||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color","#FFFFFF");
|
||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
|
||||
|
||||
// Deprecated migrations
|
||||
public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
|
||||
|
||||
static {
|
||||
// region Migration
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package app.revanced.extension.youtube.settings.preference;
|
||||
|
||||
import static app.revanced.extension.shared.StringRef.str;
|
||||
import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.DEVICE_HAS_HARDWARE_DECODING_VP9;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
@SuppressWarnings({"unused", "deprecation"})
|
||||
public class ForceAVCSpoofingPreference extends SwitchPreference {
|
||||
{
|
||||
if (!DEVICE_HAS_HARDWARE_DECODING_VP9) {
|
||||
setSummaryOn(str("revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on"));
|
||||
}
|
||||
}
|
||||
|
||||
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ForceAVCSpoofingPreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
if (DEVICE_HAS_HARDWARE_DECODING_VP9) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Temporarily remove the preference key to allow changing this preference without
|
||||
// causing the settings UI listeners from showing reboot dialogs by the changes made here.
|
||||
String key = getKey();
|
||||
setKey(null);
|
||||
|
||||
// This setting cannot be changed by the user.
|
||||
super.setEnabled(false);
|
||||
super.setChecked(true);
|
||||
|
||||
setKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
super.setChecked(checked);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
||||
org.gradle.parallel = true
|
||||
android.useAndroidX = true
|
||||
kotlin.code.style = official
|
||||
version = 5.2.3-dev.1
|
||||
version = 5.3.0-dev.4
|
||||
|
||||
@@ -320,6 +320,10 @@ public final class app/revanced/patches/music/misc/gms/GmsCoreSupportPatchKt {
|
||||
public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatchKt {
|
||||
public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/myexpenses/misc/pro/UnlockProPatchKt {
|
||||
public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
@@ -753,6 +757,11 @@ public final class app/revanced/patches/shared/misc/settings/preference/TextPref
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatchKt {
|
||||
public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatchKt {
|
||||
public static final fun getRemoveFileSizeLimitPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
@@ -1359,6 +1368,14 @@ public final class app/revanced/patches/youtube/misc/settings/SettingsPatchKt {
|
||||
public static final fun newIntent (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatchKt {
|
||||
public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/spoof/UserAgentClientSpoofPatchKt {
|
||||
public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatchKt {
|
||||
public static final fun getZoomHapticsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import app.revanced.patcher.patch.Option
|
||||
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
|
||||
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
||||
import app.revanced.patches.music.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.shared.castContextFetchFingerprint
|
||||
import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
|
||||
import app.revanced.patches.shared.primeMethodFingerprint
|
||||
@@ -20,6 +21,8 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
dependsOn(spoofVideoStreamsPatch)
|
||||
|
||||
compatibleWith(MUSIC_PACKAGE_NAME)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package app.revanced.patches.music.misc.spoof
|
||||
|
||||
import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
|
||||
|
||||
val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
})
|
||||
@@ -3,10 +3,9 @@ package app.revanced.patches.nyx.misc.pro
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
@Deprecated("This patch will be removed in the future.")
|
||||
@Suppress("unused")
|
||||
val unlockProPatch = bytecodePatch(
|
||||
name = "Unlock pro",
|
||||
) {
|
||||
val unlockProPatch = bytecodePatch {
|
||||
compatibleWith("com.awedea.nyx")
|
||||
|
||||
execute {
|
||||
|
||||
@@ -3,4 +3,4 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.extension
|
||||
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.hooks.initHook
|
||||
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
||||
|
||||
val sharedExtensionPatch = sharedExtensionPatch("sync", initHook)
|
||||
val sharedExtensionPatch = sharedExtensionPatch("syncforreddit", initHook)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
package app.revanced.patches.shared.misc.spoof
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
@@ -27,7 +27,6 @@ internal val buildPlayerRequestURIFingerprint = fingerprint {
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
strings(
|
||||
"youtubei/v1",
|
||||
"key",
|
||||
"asig",
|
||||
)
|
||||
@@ -0,0 +1,206 @@
|
||||
package app.revanced.patches.shared.misc.spoof
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
|
||||
|
||||
fun spoofVideoStreamsPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
) = bytecodePatch(
|
||||
name = "Spoof video streams",
|
||||
description = "Spoofs the client video streams to fix playback.",
|
||||
) {
|
||||
block()
|
||||
|
||||
dependsOn(addResourcesPatch)
|
||||
|
||||
execute {
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
|
||||
|
||||
buildInitPlaybackRequestFingerprint.method.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
val invokeToStringIndex = buildPlayerRequestURIFingerprint.patternMatch!!.startIndex
|
||||
|
||||
buildPlayerRequestURIFingerprint.method.apply {
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get replacement streams at player requests.
|
||||
|
||||
buildRequestFingerprint.method.apply {
|
||||
val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "newUrlRequestBuilder"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(newRequestBuilderIndex + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
newRequestBuilderIndex,
|
||||
"""
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Replace the streaming data with the replacement streams.
|
||||
|
||||
createStreamingDataFingerprint.method.apply {
|
||||
val setStreamDataMethodName = "patch_setStreamingData"
|
||||
val resultMethodType = createStreamingDataFingerprint.classDef.type
|
||||
val videoDetailsIndex = createStreamingDataFingerprint.patternMatch!!.endIndex
|
||||
val videoDetailsRegister = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA
|
||||
val videoDetailsClass = getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
videoDetailsIndex + 1,
|
||||
"invoke-direct { p0, v$videoDetailsRegister }, " +
|
||||
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
|
||||
)
|
||||
|
||||
val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass
|
||||
val setStreamingDataIndex = createStreamingDataFingerprint.patternMatch!!.startIndex
|
||||
|
||||
val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
|
||||
.getReference<FieldReference>()!!.definingClass
|
||||
|
||||
val setStreamingDataField = getInstruction(setStreamingDataIndex).getReference<FieldReference>()
|
||||
|
||||
val getStreamingDataField = getInstruction(
|
||||
indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.definingClass == playerProtoClass
|
||||
},
|
||||
).getReference<FieldReference>()
|
||||
|
||||
// Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
|
||||
createStreamingDataFingerprint.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
resultMethodType,
|
||||
setStreamDataMethodName,
|
||||
listOf(ImmutableMethodParameter(videoDetailsClass, null, "videoDetails")),
|
||||
"V",
|
||||
AccessFlags.PRIVATE.value or AccessFlags.FINAL.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(9),
|
||||
).toMutable().apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :disabled
|
||||
|
||||
# Get video id.
|
||||
iget-object v2, p1, $videoDetailsClass->c:Ljava/lang/String;
|
||||
if-eqz v2, :disabled
|
||||
|
||||
# Get streaming data.
|
||||
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
|
||||
move-result-object v3
|
||||
if-eqz v3, :disabled
|
||||
|
||||
# Parse streaming data.
|
||||
sget-object v4, $playerProtoClass->a:$playerProtoClass
|
||||
invoke-static { v4, v3 }, $protobufClass->parseFrom(${protobufClass}Ljava/nio/ByteBuffer;)$protobufClass
|
||||
move-result-object v5
|
||||
check-cast v5, $playerProtoClass
|
||||
|
||||
# Set streaming data.
|
||||
iget-object v6, v5, $getStreamingDataField
|
||||
if-eqz v6, :disabled
|
||||
iput-object v6, p0, $setStreamingDataField
|
||||
|
||||
:disabled
|
||||
return-void
|
||||
""",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove /videoplayback request body to fix playback.
|
||||
// It is assumed, YouTube makes a request with a body tuned for Android.
|
||||
// Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
|
||||
// A proper fix may include modifying the request body to match the platforms expected body.
|
||||
|
||||
buildMediaDataSourceFingerprint.method.apply {
|
||||
val targetIndex = instructions.lastIndex
|
||||
|
||||
// Instructions are added just before the method returns,
|
||||
// so there's no concern of clobbering in-use registers.
|
||||
addInstructions(
|
||||
targetIndex,
|
||||
"""
|
||||
# Field a: Stream uri.
|
||||
# Field c: Http method.
|
||||
# Field d: Post data.
|
||||
move-object v0, p0 # method has over 15 registers and must copy p0 to a lower register.
|
||||
iget-object v1, v0, $definingClass->a:Landroid/net/Uri;
|
||||
iget v2, v0, $definingClass->c:I
|
||||
iget-object v3, v0, $definingClass->d:[B
|
||||
invoke-static { v1, v2, v3 }, $EXTENSION_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $definingClass->d:[B
|
||||
""",
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
||||
executeBlock()
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.reddit.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
|
||||
import java.io.InvalidClassException
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,243 +1,9 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;"
|
||||
|
||||
val spoofVideoStreamsPatch = bytecodePatch(
|
||||
name = "Spoof video streams",
|
||||
description = "Spoofs the client video streams to allow video playback.",
|
||||
) {
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
),
|
||||
)
|
||||
|
||||
dependsOn(
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
userAgentClientSpoofPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")
|
||||
|
||||
PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreenPreference(
|
||||
key = "revanced_spoof_video_streams_screen",
|
||||
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_video_streams"),
|
||||
ListPreference(
|
||||
"revanced_spoof_video_streams_client",
|
||||
summaryKey = null,
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_spoof_video_streams_ios_force_avc",
|
||||
tag = "app.revanced.extension.youtube.settings.preference.ForceAVCSpoofingPreference",
|
||||
),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
|
||||
|
||||
buildInitPlaybackRequestFingerprint.method.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
val invokeToStringIndex = buildPlayerRequestURIFingerprint.patternMatch!!.startIndex
|
||||
|
||||
buildPlayerRequestURIFingerprint.method.apply {
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get replacement streams at player requests.
|
||||
|
||||
buildRequestFingerprint.method.apply {
|
||||
val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "newUrlRequestBuilder"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(newRequestBuilderIndex + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
newRequestBuilderIndex,
|
||||
"""
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Replace the streaming data with the replacement streams.
|
||||
|
||||
createStreamingDataFingerprint.method.apply {
|
||||
val setStreamDataMethodName = "patch_setStreamingData"
|
||||
val resultMethodType = createStreamingDataFingerprint.classDef.type
|
||||
val videoDetailsIndex = createStreamingDataFingerprint.patternMatch!!.endIndex
|
||||
val videoDetailsRegister = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA
|
||||
val videoDetailsClass = getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
videoDetailsIndex + 1,
|
||||
"invoke-direct { p0, v$videoDetailsRegister }, " +
|
||||
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
|
||||
)
|
||||
|
||||
val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass
|
||||
val setStreamingDataIndex = createStreamingDataFingerprint.patternMatch!!.startIndex
|
||||
|
||||
val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
|
||||
.getReference<FieldReference>()!!.definingClass
|
||||
|
||||
val setStreamingDataField = getInstruction(setStreamingDataIndex).getReference<FieldReference>()
|
||||
|
||||
val getStreamingDataField = getInstruction(
|
||||
indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.definingClass == playerProtoClass
|
||||
},
|
||||
).getReference<FieldReference>()
|
||||
|
||||
// Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
|
||||
createStreamingDataFingerprint.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
resultMethodType,
|
||||
setStreamDataMethodName,
|
||||
listOf(ImmutableMethodParameter(videoDetailsClass, null, "videoDetails")),
|
||||
"V",
|
||||
AccessFlags.PRIVATE.value or AccessFlags.FINAL.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(9),
|
||||
).toMutable().apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :disabled
|
||||
|
||||
# Get video id.
|
||||
iget-object v2, p1, $videoDetailsClass->c:Ljava/lang/String;
|
||||
if-eqz v2, :disabled
|
||||
|
||||
# Get streaming data.
|
||||
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
|
||||
move-result-object v3
|
||||
if-eqz v3, :disabled
|
||||
|
||||
# Parse streaming data.
|
||||
sget-object v4, $playerProtoClass->a:$playerProtoClass
|
||||
invoke-static { v4, v3 }, $protobufClass->parseFrom(${protobufClass}Ljava/nio/ByteBuffer;)$protobufClass
|
||||
move-result-object v5
|
||||
check-cast v5, $playerProtoClass
|
||||
|
||||
# Set streaming data.
|
||||
iget-object v6, v5, $getStreamingDataField
|
||||
if-eqz v6, :disabled
|
||||
iput-object v6, p0, $setStreamingDataField
|
||||
|
||||
:disabled
|
||||
return-void
|
||||
""",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove /videoplayback request body to fix playback.
|
||||
// It is assumed, YouTube makes a request with a body tuned for Android.
|
||||
// Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
|
||||
// A proper fix may include modifying the request body to match the platforms expected body.
|
||||
|
||||
buildMediaDataSourceFingerprint.method.apply {
|
||||
val targetIndex = instructions.lastIndex
|
||||
|
||||
// Instructions are added just before the method returns,
|
||||
// so there's no concern of clobbering in-use registers.
|
||||
addInstructions(
|
||||
targetIndex,
|
||||
"""
|
||||
# Field a: Stream uri.
|
||||
# Field c: Http method.
|
||||
# Field d: Post data.
|
||||
move-object v0, p0 # method has over 15 registers and must copy p0 to a lower register.
|
||||
iget-object v1, v0, $definingClass->a:Landroid/net/Uri;
|
||||
iget v2, v0, $definingClass->c:I
|
||||
iget-object v3, v0, $definingClass->d:[B
|
||||
invoke-static { v1, v2, v3 }, $EXTENSION_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $definingClass->d:[B
|
||||
""",
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
@Deprecated("Use app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch instead.")
|
||||
@Suppress("unused")
|
||||
val spoofVideoStreamsPatch = bytecodePatch {
|
||||
dependsOn(app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch)
|
||||
}
|
||||
|
||||
@@ -1,82 +1,9 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
|
||||
private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
|
||||
"Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
|
||||
|
||||
val userAgentClientSpoofPatch = transformInstructionsPatch(
|
||||
filterMap = { classDef, _, instruction, instructionIndex ->
|
||||
filterMapInstruction35c<MethodCall>(
|
||||
"Lapp/revanced/extension",
|
||||
classDef,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
},
|
||||
transform = transform@{ mutableMethod, entry ->
|
||||
val (_, _, instructionIndex) = entry
|
||||
|
||||
// Replace the result of context.getPackageName(), if it is used in a user agent string.
|
||||
mutableMethod.apply {
|
||||
// After context.getPackageName() the result is moved to a register.
|
||||
val targetRegister = (
|
||||
getInstruction(instructionIndex + 1)
|
||||
as? OneRegisterInstruction ?: return@transform
|
||||
).registerA
|
||||
|
||||
// IndexOutOfBoundsException is technically possible here,
|
||||
// but no such occurrences are present in the app.
|
||||
val referee = getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
|
||||
|
||||
// Only replace string builder usage.
|
||||
if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
|
||||
return@transform
|
||||
}
|
||||
|
||||
// Do not change the package name in methods that use resources, or for methods that use GmsCore.
|
||||
// Changing these package names will result in playback limitations,
|
||||
// particularly Android VR background audio only playback.
|
||||
val resourceOrGmsStringInstructionIndex = indexOfFirstInstruction {
|
||||
val reference = getReference<StringReference>()
|
||||
opcode == Opcode.CONST_STRING &&
|
||||
(reference?.string == "android.resource://" || reference?.string == "gcore_")
|
||||
}
|
||||
if (resourceOrGmsStringInstructionIndex >= 0) {
|
||||
return@transform
|
||||
}
|
||||
|
||||
// Overwrite the result of context.getPackageName() with the original package name.
|
||||
replaceInstruction(
|
||||
instructionIndex + 1,
|
||||
"const-string v$targetRegister, \"$ORIGINAL_PACKAGE_NAME\"",
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
@Deprecated("Use app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch instead.")
|
||||
@Suppress("unused")
|
||||
private enum class MethodCall(
|
||||
override val definedClassName: String,
|
||||
override val methodName: String,
|
||||
override val methodParams: Array<String>,
|
||||
override val returnType: String,
|
||||
) : IMethodCall {
|
||||
GetPackageName(
|
||||
"Landroid/content/Context;",
|
||||
"getPackageName",
|
||||
emptyArray(),
|
||||
"Ljava/lang/String;",
|
||||
),
|
||||
val userAgentClientSpoofPatch = bytecodePatch {
|
||||
dependsOn(app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch)
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||
import app.revanced.patches.shared.primeMethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.buttons.overlay.hidePlayerOverlayButtonsPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.fix.playback.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package app.revanced.patches.youtube.misc.spoof
|
||||
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
|
||||
val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
),
|
||||
)
|
||||
|
||||
dependsOn(
|
||||
userAgentClientSpoofPatch,
|
||||
settingsPatch,
|
||||
)
|
||||
}, {
|
||||
addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")
|
||||
|
||||
PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreenPreference(
|
||||
key = "revanced_spoof_video_streams_screen",
|
||||
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_video_streams"),
|
||||
ListPreference(
|
||||
"revanced_spoof_video_streams_client",
|
||||
summaryKey = null,
|
||||
),
|
||||
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,82 @@
|
||||
package app.revanced.patches.youtube.misc.spoof
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
|
||||
private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
|
||||
"Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
|
||||
|
||||
val userAgentClientSpoofPatch = transformInstructionsPatch(
|
||||
filterMap = { classDef, _, instruction, instructionIndex ->
|
||||
filterMapInstruction35c<MethodCall>(
|
||||
"Lapp/revanced/extension",
|
||||
classDef,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
},
|
||||
transform = transform@{ mutableMethod, entry ->
|
||||
val (_, _, instructionIndex) = entry
|
||||
|
||||
// Replace the result of context.getPackageName(), if it is used in a user agent string.
|
||||
mutableMethod.apply {
|
||||
// After context.getPackageName() the result is moved to a register.
|
||||
val targetRegister = (
|
||||
getInstruction(instructionIndex + 1)
|
||||
as? OneRegisterInstruction ?: return@transform
|
||||
).registerA
|
||||
|
||||
// IndexOutOfBoundsException is technically possible here,
|
||||
// but no such occurrences are present in the app.
|
||||
val referee = getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
|
||||
|
||||
// Only replace string builder usage.
|
||||
if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
|
||||
return@transform
|
||||
}
|
||||
|
||||
// Do not change the package name in methods that use resources, or for methods that use GmsCore.
|
||||
// Changing these package names will result in playback limitations,
|
||||
// particularly Android VR background audio only playback.
|
||||
val resourceOrGmsStringInstructionIndex = indexOfFirstInstruction {
|
||||
val reference = getReference<StringReference>()
|
||||
opcode == Opcode.CONST_STRING &&
|
||||
(reference?.string == "android.resource://" || reference?.string == "gcore_")
|
||||
}
|
||||
if (resourceOrGmsStringInstructionIndex >= 0) {
|
||||
return@transform
|
||||
}
|
||||
|
||||
// Overwrite the result of context.getPackageName() with the original package name.
|
||||
replaceInstruction(
|
||||
instructionIndex + 1,
|
||||
"const-string v$targetRegister, \"$ORIGINAL_PACKAGE_NAME\"",
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@Suppress("unused")
|
||||
private enum class MethodCall(
|
||||
override val definedClassName: String,
|
||||
override val methodName: String,
|
||||
override val methodParams: Array<String>,
|
||||
override val returnType: String,
|
||||
) : IMethodCall {
|
||||
GetPackageName(
|
||||
"Landroid/content/Context;",
|
||||
"getPackageName",
|
||||
emptyArray(),
|
||||
"Ljava/lang/String;",
|
||||
),
|
||||
}
|
||||
@@ -1220,12 +1220,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Turning off this setting may cause video playback issues.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">Default client</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Force AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is VP9 or AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Your device does not have VP9 hardware decoding, and this setting is always on when Client spoofing is enabled</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, and video playback will use more internet data than VP9 or AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is forced to AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is determined automatically</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, Opus audio codec is not available, and video playback will use more internet data than VP9 or AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS spoofing side effects</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Private kids videos may not play\n• Livestreams start from the beginning\n• Videos may end 1 second early\n• No opus audio codec</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Private kids videos may not play\n• Livestreams start from the beginning\n• Videos may end 1 second early</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Kids videos may not play\n• Audio track menu is missing\n• Stable volume is not available</string>
|
||||
</patch>
|
||||
|
||||
Reference in New Issue
Block a user