Skip to content

Commit 2726231

Browse files
feat(YouTube - Spoof video streams): Add iPadOS client
1 parent 9f0558e commit 2726231

File tree

7 files changed

+78
-15
lines changed

7 files changed

+78
-15
lines changed

extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static app.revanced.extension.shared.settings.Setting.parent;
66
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.AudioStreamLanguageOverrideAvailability;
77

8+
import app.revanced.extension.shared.Logger;
89
import app.revanced.extension.shared.spoof.ClientType;
910

1011
/**
@@ -32,4 +33,11 @@ public class BaseSettings {
3233
public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS));
3334
// Client type must be last spoof setting due to cyclic references.
3435
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));
36+
37+
static {
38+
if (SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED) {
39+
Logger.printInfo(() -> "Migrating from iOS Unplugged to iPadOS");
40+
SPOOF_VIDEO_STREAMS_CLIENT_TYPE.save(ClientType.IPADOS);
41+
}
42+
}
3543
}

extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import app.revanced.extension.shared.Logger;
1212

13+
@SuppressWarnings("ConstantLocale")
1314
public enum ClientType {
1415
/**
1516
* Video not playable: Kids / Paid / Movie / Private / Age-restricted.
@@ -87,6 +88,48 @@ public enum ClientType {
8788
false,
8889
false,
8990
"visionOS"
91+
),
92+
/**
93+
* The device machine id for the iPad 6th Gen (iPad7,6).
94+
* AV1 hardware decoding is not supported.
95+
* See [this GitHub Gist](https://gist.github.com/adamawolf/3048717) for more information.
96+
*
97+
* Based on Google's actions to date, PoToken may not be required on devices with very low specs.
98+
* For example, suppose the User-Agent for a PlayStation 3 (with 256MB of RAM) is used.
99+
* Accessing 'Web' (https://www.youtube.com) will redirect to 'TV' (https://www.youtube.com/tv).
100+
* 'TV' target devices with very low specs, such as embedded devices, game consoles, and blu-ray players, so PoToken is not required.
101+
*
102+
* For this reason, the device machine id for the iPad 6th Gen (with 2GB of RAM),
103+
* the lowest spec device capable of running iPadOS 17, was used.
104+
*/
105+
IPADOS(5,
106+
"IOS",
107+
"Apple",
108+
"iPad7,6",
109+
"iPadOS",
110+
"17.7.10.21H450",
111+
"19.22.3",
112+
"com.google.ios.youtube/19.22.3 (iPad7,6; U; CPU iPadOS 17_7_10 like Mac OS X; " + Locale.getDefault() + ")",
113+
false,
114+
false,
115+
"iPadOS"
116+
),
117+
/**
118+
* Obsolete and broken client. Here only to migrate data.
119+
*/
120+
@Deprecated
121+
IOS_UNPLUGGED(
122+
33,
123+
"IOS_UNPLUGGED",
124+
"Apple",
125+
"iPhone16,2",
126+
"iOS",
127+
"18.2.22C152",
128+
"8.49",
129+
"dummy user-agent",
130+
true,
131+
true,
132+
"iOS TV"
90133
);
91134

92135
/**
@@ -173,7 +216,6 @@ public enum ClientType {
173216
/**
174217
* Android constructor.
175218
*/
176-
@SuppressWarnings("ConstantLocale")
177219
ClientType(int id,
178220
String clientName,
179221
@NonNull String packageName,

extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java

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

extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_CREATOR;
44
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32;
55
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48;
6+
import static app.revanced.extension.shared.spoof.ClientType.IPADOS;
67
import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
78

89
import java.util.List;
@@ -22,6 +23,7 @@ public static void setClientOrderToUse() {
2223
ANDROID_VR_1_61_48,
2324
ANDROID_CREATOR,
2425
VISIONOS,
26+
IPADOS,
2527
// VR 1.43 must be last as spoof streaming data handles it slightly differently.
2628
ANDROID_VR_1_43_32
2729
);

extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,25 @@ private void updateUI() {
7878
Logger.printDebug(() -> "Updating spoof stream side effects preference");
7979
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
8080

81-
String title = str("revanced_spoof_video_streams_about_title");
82-
// Currently only Android VR and VisionOS are supported, and both have the same base side effects.
83-
String summary = str("revanced_spoof_video_streams_about_android_summary");
84-
summary += '\n' + str("revanced_spoof_video_streams_about_kids_videos");
81+
setTitle(str("revanced_spoof_video_streams_about_title"));
8582

86-
if (clientType == ClientType.VISIONOS) {
83+
String summary = str(clientType == ClientType.IPADOS
84+
? "revanced_spoof_video_streams_about_ipados_summary"
85+
// visionOS has same base side effects as Android VR.
86+
: "revanced_spoof_video_streams_about_android_summary");
87+
88+
if (clientType == ClientType.IPADOS) {
89+
summary = str("revanced_spoof_video_streams_about_no_av1")
90+
+ '\n' + summary;
91+
} else if (clientType == ClientType.VISIONOS) {
8792
summary = str("revanced_spoof_video_streams_about_experimental")
8893
+ '\n' + summary
89-
+ '\n' + str("revanced_spoof_video_streams_about_no_av1");
94+
+ '\n' + str("revanced_spoof_video_streams_about_no_av1")
95+
+ '\n' + str("revanced_spoof_video_streams_about_kids_videos");
96+
} else {
97+
summary += '\n' + str("revanced_spoof_video_streams_about_kids_videos");
9098
}
9199

92-
setTitle(title);
93100
setSummary(summary);
94101
}
95102
}

patches/src/main/resources/addresources/values/arrays.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,12 @@
125125
<string-array name="revanced_spoof_video_streams_client_type_entries">
126126
<item>Android VR</item>
127127
<item>visionOS</item>
128+
<item>iPadOS</item>
128129
</string-array>
129130
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
130131
<item>ANDROID_VR_1_61_48</item>
131132
<item>VISIONOS</item>
133+
<item>IPADOS</item>
132134
</string-array>
133135
</patch>
134136
</app>

patches/src/main/resources/addresources/values/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ If changing this setting does not take effect, try switching to Incognito mode."
784784
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
785785
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio track menu is hidden
786786

787-
Audio track menu is not available when \'Spoof video streams\' is enabled"</string>
787+
To show the Audio track menu, change \'Spoof video streams\' to iPadOS"</string>
788788
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
789789
<string name="revanced_hide_player_flyout_watch_in_vr_title">Hide Watch in VR</string>
790790
<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>
16291629
<string name="revanced_spoof_video_streams_about_android_title">Android spoofing side effects</string>
16301630
<string name="revanced_spoof_video_streams_about_android_summary">"• Audio track menu is missing
16311631
• Stable volume is not available"</string>
1632+
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video may stop at 1:00, or may not be available in some regions</string>
16321633
<string name="revanced_spoof_video_streams_about_experimental">• Experimental client and may stop working anytime</string>
16331634
<string name="revanced_spoof_video_streams_about_no_av1">• No AV1 video codec</string>
16341635
<string name="revanced_spoof_video_streams_about_kids_videos">• Kids videos may not play when logged out or in incognito mode</string>

0 commit comments

Comments
 (0)