feat(YouTube - Spoof streaming data): Remove Use Android clients only setting, restore Force iOS AVC setting

This commit is contained in:
inotia00 2024-12-31 21:06:47 +09:00
parent 5d79826f4e
commit 83f2d82d0a
10 changed files with 90 additions and 174 deletions

View File

@ -11,8 +11,8 @@ public class PatchStatus {
return false;
}
public static boolean SpoofStreamingDataAndroidOnlyDefaultBoolean() {
// Replace this with true If the Spoof streaming data patch succeeds in YouTube
public static boolean SpoofStreamingDataMusic() {
// Replace this with true If the Spoof streaming data patch succeeds in YouTube Music
return false;
}
}

View File

@ -1,6 +1,6 @@
package app.revanced.extension.shared.patches.client;
import static app.revanced.extension.shared.utils.ResourceUtils.getString;
import static app.revanced.extension.shared.patches.PatchStatus.SpoofStreamingDataMusic;
import android.os.Build;
@ -24,7 +24,9 @@ public class AppClient {
* Store page of the YouTube app</a>, in the {@code Whats New} section.
* </p>
*/
private static final String CLIENT_VERSION_IOS = "19.29.1";
private static final String CLIENT_VERSION_IOS = forceAVC()
? "17.40.5"
: "19.29.1";
/**
* The device machine id for the iPhone 15 Pro Max (iPhone16,2), used to get HDR with AV1 hardware decoding.
*
@ -33,9 +35,15 @@ public class AppClient {
* information.
* </p>
*/
private static final String DEVICE_MODEL_IOS = "iPhone16,2";
private static final String OS_VERSION_IOS = "17.7.2.21H221";
private static final String USER_AGENT_VERSION_IOS = "17_7_2";
private static final String DEVICE_MODEL_IOS = forceAVC()
? "iPhone12,5" // 11 Pro Max. (last device with iOS 13)
: "iPhone16,2"; // 15 Pro Max.
private static final String OS_VERSION_IOS = forceAVC()
? "13.7.17H35" // Last release of iOS 13.
: "17.7.2.21H221";
private static final String USER_AGENT_VERSION_IOS = forceAVC()
? "13_7"
: "17_7_2";
private static final String USER_AGENT_IOS =
iOSUserAgent(PACKAGE_NAME_IOS, CLIENT_VERSION_IOS);
@ -55,7 +63,9 @@ public class AppClient {
* Store page of the YouTube TV app</a>, in the {@code Whats New} section.
* </p>
*/
private static final String CLIENT_VERSION_IOS_UNPLUGGED = "8.33";
private static final String CLIENT_VERSION_IOS_UNPLUGGED = forceAVC()
? "6.45"
: "8.33";
private static final String USER_AGENT_IOS_UNPLUGGED =
iOSUserAgent(PACKAGE_NAME_IOS_UNPLUGGED, CLIENT_VERSION_IOS_UNPLUGGED);
@ -140,20 +150,6 @@ public class AppClient {
androidUserAgent(PACKAGE_NAME_ANDROID_UNPLUGGED, CLIENT_VERSION_ANDROID_UNPLUGGED, OS_VERSION_ANDROID_UNPLUGGED);
// ANDROID CREATOR
/**
* Video not playable: Livestream
* Note: Audio track is not available
*/
private static final String PACKAGE_NAME_ANDROID_CREATOR = "com.google.android.apps.youtube.creator";
private static final String CLIENT_VERSION_ANDROID_CREATOR = "24.14.101";
private static final String DEVICE_MODEL_ANDROID_CREATOR = Build.MODEL;
private static final String OS_VERSION_ANDROID_CREATOR = Build.VERSION.RELEASE;
private static final String ANDROID_SDK_VERSION_ANDROID_CREATOR = String.valueOf(Build.VERSION.SDK_INT);
private static final String USER_AGENT_ANDROID_CREATOR =
androidUserAgent(PACKAGE_NAME_ANDROID_CREATOR, CLIENT_VERSION_ANDROID_CREATOR, OS_VERSION_ANDROID_CREATOR);
private AppClient() {
}
@ -178,21 +174,14 @@ public class AppClient {
}
public enum ClientType {
IOS(5,
DEVICE_MODEL_IOS,
OS_VERSION_IOS,
USER_AGENT_IOS,
null,
CLIENT_VERSION_IOS,
false
),
ANDROID_VR(28,
DEVICE_MODEL_ANDROID_VR,
OS_VERSION_ANDROID_VR,
USER_AGENT_ANDROID_VR,
ANDROID_SDK_VERSION_ANDROID_VR,
CLIENT_VERSION_ANDROID_VR,
true
true,
"Android VR"
),
ANDROID_UNPLUGGED(29,
DEVICE_MODEL_ANDROID_UNPLUGGED,
@ -200,15 +189,8 @@ public class AppClient {
USER_AGENT_ANDROID_UNPLUGGED,
ANDROID_SDK_VERSION_ANDROID_UNPLUGGED,
CLIENT_VERSION_ANDROID_UNPLUGGED,
true
),
ANDROID_CREATOR(14,
DEVICE_MODEL_ANDROID_CREATOR,
OS_VERSION_ANDROID_CREATOR,
USER_AGENT_ANDROID_CREATOR,
ANDROID_SDK_VERSION_ANDROID_CREATOR,
CLIENT_VERSION_ANDROID_CREATOR,
true
true,
"Android TV"
),
IOS_UNPLUGGED(33,
DEVICE_MODEL_IOS,
@ -216,7 +198,21 @@ public class AppClient {
USER_AGENT_IOS_UNPLUGGED,
null,
CLIENT_VERSION_IOS_UNPLUGGED,
true
true,
forceAVC()
? "iOS TV Force AVC"
: "iOS TV"
),
IOS(5,
DEVICE_MODEL_IOS,
OS_VERSION_IOS,
USER_AGENT_IOS,
null,
CLIENT_VERSION_IOS,
false,
forceAVC()
? "iOS Force AVC"
: "iOS"
),
IOS_MUSIC(
26,
@ -225,7 +221,8 @@ public class AppClient {
USER_AGENT_IOS_MUSIC,
null,
CLIENT_VERSION_IOS_MUSIC,
true
true,
"iOS Music"
);
/**
@ -268,13 +265,19 @@ public class AppClient {
*/
public final boolean canLogin;
/**
* Friendly name displayed in stats for nerds.
*/
public final String friendlyName;
ClientType(int id,
String deviceModel,
String osVersion,
String userAgent,
@Nullable String androidSdkVersion,
String clientVersion,
boolean canLogin
boolean canLogin,
String friendlyName
) {
this.id = id;
this.clientName = name();
@ -284,30 +287,29 @@ public class AppClient {
this.androidSdkVersion = androidSdkVersion;
this.userAgent = userAgent;
this.canLogin = canLogin;
this.friendlyName = friendlyName;
}
private static final ClientType[] CLIENT_ORDER_TO_USE_ANDROID = {
ANDROID_VR,
ANDROID_UNPLUGGED,
ANDROID_CREATOR,
};
private static final ClientType[] CLIENT_ORDER_TO_USE_DEFAULT = {
IOS,
private static final ClientType[] CLIENT_ORDER_TO_USE_YOUTUBE = {
ANDROID_VR,
ANDROID_UNPLUGGED,
IOS_UNPLUGGED,
IOS_MUSIC,
IOS,
};
public final String getFriendlyName() {
return getString("revanced_spoof_streaming_data_type_entry_" + name().toLowerCase());
private static final ClientType[] CLIENT_ORDER_TO_USE_YOUTUBE_MUSIC = {
ANDROID_VR,
IOS_MUSIC,
};
}
private static boolean forceAVC() {
return BaseSettings.SPOOF_STREAMING_DATA_IOS_FORCE_AVC.get();
}
public static ClientType[] getAvailableClientTypes() {
return BaseSettings.SPOOF_STREAMING_DATA_ANDROID_ONLY.get()
? ClientType.CLIENT_ORDER_TO_USE_ANDROID
: ClientType.CLIENT_ORDER_TO_USE_DEFAULT;
return SpoofStreamingDataMusic()
? ClientType.CLIENT_ORDER_TO_USE_YOUTUBE_MUSIC
: ClientType.CLIENT_ORDER_TO_USE_YOUTUBE;
}
}

View File

@ -6,6 +6,9 @@ import static app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes.
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.ArrayUtils;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -14,7 +17,6 @@ import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@ -78,14 +80,14 @@ public class StreamingDataRequest {
public static String getLastSpoofedClientName() {
return lastSpoofedClientType == null
? "Unknown"
: lastSpoofedClientType.getFriendlyName();
: lastSpoofedClientType.friendlyName;
}
static {
ClientType[] allClientTypes = getAvailableClientTypes();
ClientType preferredClient = BaseSettings.SPOOF_STREAMING_DATA_TYPE.get();
if (Arrays.stream(allClientTypes).noneMatch(preferredClient::equals)) {
if (ArrayUtils.indexOf(allClientTypes, preferredClient) < 0) {
CLIENT_ORDER_TO_USE = allClientTypes;
} else {
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];

View File

@ -3,7 +3,6 @@ package app.revanced.extension.shared.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.patches.PatchStatus.HideFullscreenAdsDefaultBoolean;
import static app.revanced.extension.shared.patches.PatchStatus.SpoofStreamingDataAndroidOnlyDefaultBoolean;
import app.revanced.extension.shared.patches.ReturnYouTubeUsernamePatch.DisplayFormat;
import app.revanced.extension.shared.patches.client.AppClient.ClientType;
@ -37,9 +36,11 @@ public class BaseSettings {
public static final StringSetting RETURN_YOUTUBE_USERNAME_YOUTUBE_DATA_API_V3_DEVELOPER_KEY = new StringSetting("revanced_return_youtube_username_youtube_data_api_v3_developer_key", "", true, false);
public static final BooleanSetting SPOOF_STREAMING_DATA = new BooleanSetting("revanced_spoof_streaming_data", TRUE, true, "revanced_spoof_streaming_data_user_dialog_message");
public static final EnumSetting<ClientType> SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", ClientType.ANDROID_VR, true);
public static final BooleanSetting SPOOF_STREAMING_DATA_ANDROID_ONLY = new BooleanSetting("revanced_spoof_streaming_data_android_only", SpoofStreamingDataAndroidOnlyDefaultBoolean(), true, "revanced_spoof_streaming_data_android_only_user_dialog_message");
public static final BooleanSetting SPOOF_STREAMING_DATA_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_streaming_data_ios_force_avc", FALSE, true,
"revanced_spoof_streaming_data_ios_force_avc_user_dialog_message");
public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE);
// Client type must be last spoof setting due to cyclic references.
public static final EnumSetting<ClientType> SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", ClientType.ANDROID_VR, true);
/**
* @noinspection DeprecatedIsStillUsed

View File

@ -1,87 +0,0 @@
package app.revanced.extension.youtube.settings.preference;
import static app.revanced.extension.shared.utils.ResourceUtils.getStringArray;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.ListPreference;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import app.revanced.extension.shared.patches.client.AppClient.ClientType;
import app.revanced.extension.shared.settings.EnumSetting;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.utils.Utils;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings({"unused", "deprecation"})
public class SpoofStreamingDataDefaultClientListPreference extends ListPreference {
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
// Because this listener may run before the ReVanced settings fragment updates Settings,
// this could show the prior config and not the current.
//
// Push this call to the end of the main run queue,
// so all other listeners are done and Settings is up to date.
Utils.runOnMainThread(this::updateUI);
};
public SpoofStreamingDataDefaultClientListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public SpoofStreamingDataDefaultClientListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SpoofStreamingDataDefaultClientListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SpoofStreamingDataDefaultClientListPreference(Context context) {
super(context);
}
private void addChangeListener() {
Setting.preferences.preferences.registerOnSharedPreferenceChangeListener(listener);
}
private void removeChangeListener() {
Setting.preferences.preferences.unregisterOnSharedPreferenceChangeListener(listener);
}
@Override
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
super.onAttachedToHierarchy(preferenceManager);
updateUI();
addChangeListener();
}
@Override
protected void onPrepareForRemoval() {
super.onPrepareForRemoval();
removeChangeListener();
}
private void updateUI() {
final boolean spoofStreamingDataAndroidOnly = Settings.SPOOF_STREAMING_DATA_ANDROID_ONLY.get();
final String entryKey = spoofStreamingDataAndroidOnly
? "revanced_spoof_streaming_data_type_android_entries"
: "revanced_spoof_streaming_data_type_android_ios_entries";
final String entryValueKey = spoofStreamingDataAndroidOnly
? "revanced_spoof_streaming_data_type_android_entry_values"
: "revanced_spoof_streaming_data_type_android_ios_entry_values";
final String[] mEntries = getStringArray(entryKey);
final String[] mEntryValues = getStringArray(entryValueKey);
setEntries(mEntries);
setEntryValues(mEntryValues);
final EnumSetting<ClientType> clientType = Settings.SPOOF_STREAMING_DATA_TYPE;
final boolean isAndroid = clientType.get().name().startsWith("ANDROID");
if (spoofStreamingDataAndroidOnly && !isAndroid) {
clientType.resetToDefault();
}
setEnabled(Settings.SPOOF_STREAMING_DATA.get());
}
}

View File

@ -63,13 +63,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
private void updateUI() {
final String clientName = Settings.SPOOF_STREAMING_DATA_TYPE.get().name().toLowerCase();
String summaryTextKey = "revanced_spoof_streaming_data_side_effects_";
if (Settings.SPOOF_STREAMING_DATA_ANDROID_ONLY.get()) {
summaryTextKey += "android";
} else {
summaryTextKey += clientName;
}
final String summaryTextKey = "revanced_spoof_streaming_data_side_effects_" + clientName;
setSummary(str(summaryTextKey));
setEnabled(Settings.SPOOF_STREAMING_DATA.get());

View File

@ -1,5 +1,6 @@
package app.revanced.patches.music.utils.fix.streamingdata
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.compatibility.Constants.YOUTUBE_MUSIC_PACKAGE_NAME
import app.revanced.patches.music.utils.patch.PatchList.SPOOF_STREAMING_DATA
@ -8,8 +9,10 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
import app.revanced.patches.music.utils.settings.addPreferenceWithIntent
import app.revanced.patches.music.utils.settings.addSwitchPreference
import app.revanced.patches.music.utils.settings.settingsPatch
import app.revanced.patches.shared.extension.Constants.PATCHES_PATH
import app.revanced.patches.shared.spoof.streamingdata.baseSpoofStreamingDataPatch
import app.revanced.patches.shared.spoof.useragent.baseSpoofUserAgentPatch
import app.revanced.util.findMethodOrThrow
@Suppress("unused")
val spoofStreamingDataPatch = baseSpoofStreamingDataPatch(
@ -22,6 +25,13 @@ val spoofStreamingDataPatch = baseSpoofStreamingDataPatch(
)
},
{
findMethodOrThrow("$PATCHES_PATH/PatchStatus;") {
name == "SpoofStreamingDataMusic"
}.replaceInstruction(
0,
"const/4 v0, 0x1"
)
addSwitchPreference(
CategoryType.MISC,
"revanced_spoof_streaming_data",

View File

@ -1,7 +1,5 @@
package app.revanced.patches.youtube.utils.fix.streamingdata
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.shared.extension.Constants.PATCHES_PATH
import app.revanced.patches.shared.spoof.streamingdata.baseSpoofStreamingDataPatch
import app.revanced.patches.shared.spoof.useragent.baseSpoofUserAgentPatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
@ -9,7 +7,6 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.YOUTUBE_PACKAG
import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_STREAMING_DATA
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.findMethodOrThrow
val spoofStreamingDataPatch = baseSpoofStreamingDataPatch(
{
@ -21,13 +18,6 @@ val spoofStreamingDataPatch = baseSpoofStreamingDataPatch(
)
},
{
findMethodOrThrow("$PATCHES_PATH/PatchStatus;") {
name == "SpoofStreamingDataAndroidOnlyDefaultBoolean"
}.replaceInstruction(
0,
"const/4 v0, 0x1"
)
addPreference(
arrayOf(
"SETTINGS: SPOOF_STREAMING_DATA"

View File

@ -1918,10 +1918,14 @@ Tap the continue button and allow optimization changes."</string>
<string name="revanced_spoof_streaming_data_side_effects_android">"• Audio track menu is missing.
• Stable volume is not available.
• Disable forced auto audio tracks is not available."</string>
<string name="revanced_spoof_streaming_data_android_only_title">Use Android clients only</string>
<string name="revanced_spoof_streaming_data_android_only_summary_on">Android clients are used to fetch streaming data.</string>
<string name="revanced_spoof_streaming_data_android_only_summary_off">Android and iOS clients are used to fetch streaming data.</string>
<string name="revanced_spoof_streaming_data_android_only_user_dialog_message">Turning off this setting may cause video playback issues.</string>
<string name="revanced_spoof_streaming_data_side_effects_ios">• There may be playback issues (Deprecated).</string>
<string name="revanced_spoof_streaming_data_side_effects_ios_unplugged">• Movies or paid videos may not play.</string>
<string name="revanced_spoof_streaming_data_ios_force_avc_title">Force iOS AVC (H.264)</string>
<string name="revanced_spoof_streaming_data_ios_force_avc_summary_on">Video codec is forced to AVC (H.264).</string>
<string name="revanced_spoof_streaming_data_ios_force_avc_summary_off">Video codec is determined automatically.</string>
<string name="revanced_spoof_streaming_data_ios_force_avc_user_dialog_message">"Enabling this might improve battery life and fix playback stuttering.
AVC 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_streaming_data_stats_for_nerds_title">Show in Stats for nerds</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">Client used to fetch streaming data is shown in Stats for nerds.</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Client used to fetch streaming data is hidden in Stats for nerds.</string>

View File

@ -784,9 +784,9 @@
<!-- SETTINGS: SPOOF_STREAMING_DATA
<PreferenceScreen android:title="@string/revanced_preference_screen_spoof_streaming_data_title" android:key="revanced_preference_screen_spoof_streaming_data" android:summary="@string/revanced_preference_screen_spoof_streaming_data_summary">
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_title" android:key="revanced_spoof_streaming_data" android:summaryOn="@string/revanced_spoof_streaming_data_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_summary_off" />
<app.revanced.extension.youtube.settings.preference.SpoofStreamingDataDefaultClientListPreference android:title="@string/revanced_spoof_streaming_data_type_title" android:key="revanced_spoof_streaming_data_type" />
<ListPreference android:entries="@array/revanced_spoof_streaming_data_type_entries" android:title="@string/revanced_spoof_streaming_data_type_title" android:key="revanced_spoof_streaming_data_type" android:entryValues="@array/revanced_spoof_streaming_data_type_entry_values" android:dependency="revanced_spoof_streaming_data" />
<app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference android:title="@string/revanced_spoof_streaming_data_side_effects_title" />
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_android_only_title" android:key="revanced_spoof_streaming_data_android_only" android:summaryOn="@string/revanced_spoof_streaming_data_android_only_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_android_only_summary_off" android:dependency="revanced_spoof_streaming_data" />
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_ios_force_avc_title" android:key="revanced_spoof_streaming_data_ios_force_avc" android:summaryOn="@string/revanced_spoof_streaming_data_ios_force_avc_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_ios_force_avc_summary_off" android:dependency="revanced_spoof_streaming_data" />
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_stats_for_nerds_title" android:key="revanced_spoof_streaming_data_stats_for_nerds" android:summaryOn="@string/revanced_spoof_streaming_data_stats_for_nerds_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_stats_for_nerds_summary_off" android:dependency="revanced_spoof_streaming_data" />
</PreferenceScreen>SETTINGS: SPOOF_STREAMING_DATA -->