diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
index 93a7815024..ddf170f78c 100644
--- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
@@ -1,12 +1,11 @@
package app.revanced.extension.shared.spoof;
-import static app.revanced.extension.shared.spoof.DeviceHardwareSupport.allowAV1;
-import static app.revanced.extension.shared.spoof.DeviceHardwareSupport.allowVP9;
-
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
@@ -16,31 +15,35 @@ public enum ClientType {
"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.
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.47.7 (iPhone; U; CPU iOS 17_5_1 like Mac OS X)"
- : "com.google.ios.youtube/19.47.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.47.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
* client type
@@ -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;
}
}
diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java
deleted file mode 100644
index 019a13eeb7..0000000000
--- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package app.revanced.extension.shared.spoof;
-
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.os.Build;
-
-import app.revanced.extension.shared.Logger;
-import app.revanced.extension.shared.settings.BaseSettings;
-
-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 && !BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
- }
-
- public static boolean allowAV1() {
- return allowVP9() && DEVICE_HAS_HARDWARE_DECODING_AV1;
- }
-}
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java
deleted file mode 100644
index b3faebf8f9..0000000000
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package app.revanced.extension.youtube.settings.preference;
-
-import static app.revanced.extension.shared.StringRef.str;
-import static app.revanced.extension.shared.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();
- }
-}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
index a6181db7e4..a3f26744a3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -40,10 +40,7 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
"revanced_spoof_video_streams_client",
summaryKey = null,
),
- SwitchPreference(
- "revanced_spoof_video_streams_ios_force_avc",
- tag = "app.revanced.extension.youtube.settings.preference.ForceAVCSpoofingPreference",
- ),
+ SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
),
diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml
index 51b21c2a11..c1142d08aa 100644
--- a/patches/src/main/resources/addresources/values/strings.xml
+++ b/patches/src/main/resources/addresources/values/strings.xml
@@ -1220,10 +1220,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
Turning off this setting may cause video playback issues.
Default client
Force AVC (H.264)
- Video codec is AVC (H.264)
- Video codec is VP9 or AV1
- Your device does not have VP9 hardware decoding, and this setting is always on when Client spoofing is enabled
- 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.
+ Video codec is forced to AVC (H.264)
+ Video codec is determined automatically
+ 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.
iOS spoofing side effects
• Private kids videos may not play\n• Livestreams start from the beginning\n• Videos may end 1 second early
Android VR spoofing side effects