feat(YouTube - Spoof video streams): Add iPadOS client

This commit is contained in:
LisoUseInAIKyrios
2025-09-16 15:33:55 +04:00
parent 9f0558e494
commit 2726231404
7 changed files with 78 additions and 15 deletions

View File

@@ -5,6 +5,7 @@ import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.AudioStreamLanguageOverrideAvailability;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.spoof.ClientType;
/**
@@ -32,4 +33,11 @@ public class BaseSettings {
public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS));
// Client type must be last spoof setting due to cyclic references.
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_61_48, true, parent(SPOOF_VIDEO_STREAMS));
static {
if (SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED) {
Logger.printInfo(() -> "Migrating from iOS Unplugged to iPadOS");
SPOOF_VIDEO_STREAMS_CLIENT_TYPE.save(ClientType.IPADOS);
}
}
}

View File

@@ -10,6 +10,7 @@ import java.util.Objects;
import app.revanced.extension.shared.Logger;
@SuppressWarnings("ConstantLocale")
public enum ClientType {
/**
* Video not playable: Kids / Paid / Movie / Private / Age-restricted.
@@ -87,6 +88,48 @@ public enum ClientType {
false,
false,
"visionOS"
),
/**
* The device machine id for the iPad 6th Gen (iPad7,6).
* AV1 hardware decoding is not supported.
* See [this GitHub Gist](https://gist.github.com/adamawolf/3048717) for more information.
*
* Based on Google's actions to date, PoToken may not be required on devices with very low specs.
* For example, suppose the User-Agent for a PlayStation 3 (with 256MB of RAM) is used.
* Accessing 'Web' (https://www.youtube.com) will redirect to 'TV' (https://www.youtube.com/tv).
* 'TV' target devices with very low specs, such as embedded devices, game consoles, and blu-ray players, so PoToken is not required.
*
* For this reason, the device machine id for the iPad 6th Gen (with 2GB of RAM),
* the lowest spec device capable of running iPadOS 17, was used.
*/
IPADOS(5,
"IOS",
"Apple",
"iPad7,6",
"iPadOS",
"17.7.10.21H450",
"19.22.3",
"com.google.ios.youtube/19.22.3 (iPad7,6; U; CPU iPadOS 17_7_10 like Mac OS X; " + Locale.getDefault() + ")",
false,
false,
"iPadOS"
),
/**
* Obsolete and broken client. Here only to migrate data.
*/
@Deprecated
IOS_UNPLUGGED(
33,
"IOS_UNPLUGGED",
"Apple",
"iPhone16,2",
"iOS",
"18.2.22C152",
"8.49",
"dummy user-agent",
true,
true,
"iOS TV"
);
/**
@@ -173,7 +216,6 @@ public enum ClientType {
/**
* Android constructor.
*/
@SuppressWarnings("ConstantLocale")
ClientType(int id,
String clientName,
@NonNull String packageName,

View File

@@ -14,12 +14,13 @@ public class ForceOriginalAudioPatch {
* Injection point.
*/
public static void setPreferredLanguage() {
if (Settings.FORCE_ORIGINAL_AUDIO.get()) {
// None of the current spoof clients support audio track menu,
// And all are un-authenticated and can request any language code
// (authenticated requests ignore the language code and always use the account language).
// To still support force original audio, if it's enabled then pick a language
// that is not auto-dubbed by YouTube: https://support.google.com/youtube/answer/15569972
if (Settings.FORCE_ORIGINAL_AUDIO.get()
&& SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams()) {
// If client spoofing does not use authentication and lacks multi-audio streams,
// then can use any language code for the request and if that requested language is
// not available YT uses the original audio language. Authenticated requests ignore
// the language code and always use the account language. Use a language that is
// not auto-dubbed by YouTube: https://support.google.com/youtube/answer/15569972
// but the language is also supported natively by the Meta Quest device that
// Android VR is spoofing.
AppLanguage override = AppLanguage.SV;

View File

@@ -3,6 +3,7 @@ package app.revanced.extension.youtube.patches.spoof;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_CREATOR;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48;
import static app.revanced.extension.shared.spoof.ClientType.IPADOS;
import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
import java.util.List;
@@ -22,6 +23,7 @@ public class SpoofVideoStreamsPatch {
ANDROID_VR_1_61_48,
ANDROID_CREATOR,
VISIONOS,
IPADOS,
// VR 1.43 must be last as spoof streaming data handles it slightly differently.
ANDROID_VR_1_43_32
);

View File

@@ -78,18 +78,25 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
Logger.printDebug(() -> "Updating spoof stream side effects preference");
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
String title = str("revanced_spoof_video_streams_about_title");
// Currently only Android VR and VisionOS are supported, and both have the same base side effects.
String summary = str("revanced_spoof_video_streams_about_android_summary");
summary += '\n' + str("revanced_spoof_video_streams_about_kids_videos");
setTitle(str("revanced_spoof_video_streams_about_title"));
if (clientType == ClientType.VISIONOS) {
String summary = str(clientType == ClientType.IPADOS
? "revanced_spoof_video_streams_about_ipados_summary"
// visionOS has same base side effects as Android VR.
: "revanced_spoof_video_streams_about_android_summary");
if (clientType == ClientType.IPADOS) {
summary = str("revanced_spoof_video_streams_about_no_av1")
+ '\n' + summary;
} else if (clientType == ClientType.VISIONOS) {
summary = str("revanced_spoof_video_streams_about_experimental")
+ '\n' + summary
+ '\n' + str("revanced_spoof_video_streams_about_no_av1");
+ '\n' + str("revanced_spoof_video_streams_about_no_av1")
+ '\n' + str("revanced_spoof_video_streams_about_kids_videos");
} else {
summary += '\n' + str("revanced_spoof_video_streams_about_kids_videos");
}
setTitle(title);
setSummary(summary);
}
}

View File

@@ -125,10 +125,12 @@
<string-array name="revanced_spoof_video_streams_client_type_entries">
<item>Android VR</item>
<item>visionOS</item>
<item>iPadOS</item>
</string-array>
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
<item>ANDROID_VR_1_61_48</item>
<item>VISIONOS</item>
<item>IPADOS</item>
</string-array>
</patch>
</app>

View File

@@ -784,7 +784,7 @@ If changing this setting does not take effect, try switching to Incognito mode."
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio track menu is hidden
Audio track menu is not available when \'Spoof video streams\' is enabled"</string>
To show the Audio track menu, change \'Spoof video streams\' to iPadOS"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
<string name="revanced_hide_player_flyout_watch_in_vr_title">Hide Watch in VR</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Watch in VR menu is hidden</string>
@@ -1629,6 +1629,7 @@ Enabling this can unlock higher video qualities"</string>
<string name="revanced_spoof_video_streams_about_android_title">Android spoofing side effects</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Audio track menu is missing
• Stable volume is not available"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video may stop at 1:00, or may not be available in some regions</string>
<string name="revanced_spoof_video_streams_about_experimental">• Experimental client and may stop working anytime</string>
<string name="revanced_spoof_video_streams_about_no_av1">• No AV1 video codec</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Kids videos may not play when logged out or in incognito mode</string>