Skip to content

Commit 86abfb2

Browse files
fix(YouTube - Spoof video streams): Remove iOS, add clients Android TV and Android Creator (ReVanced#4180)
1 parent 33d6b8e commit 86abfb2

File tree

11 files changed

+37
-195
lines changed

11 files changed

+37
-195
lines changed

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

+1-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static java.lang.Boolean.FALSE;
44
import static java.lang.Boolean.TRUE;
55
import static app.revanced.extension.shared.settings.Setting.parent;
6-
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability;
76

87
import app.revanced.extension.shared.spoof.AudioStreamLanguage;
98
import app.revanced.extension.shared.spoof.ClientType;
@@ -23,8 +22,6 @@ public class BaseSettings {
2322

2423
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
2524
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, parent(SPOOF_VIDEO_STREAMS));
26-
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
27-
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
28-
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.IOS, true, parent(SPOOF_VIDEO_STREAMS));
25+
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
2926

3027
}

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

+21-34
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,35 @@
44

55
import androidx.annotation.Nullable;
66

7-
import app.revanced.extension.shared.settings.BaseSettings;
8-
97
public enum ClientType {
10-
// Specific purpose for age restricted, or private videos, because the iOS client is not logged in.
118
// https://dumps.tadiphone.dev/dumps/oculus/eureka
12-
ANDROID_VR(28,
13-
"ANDROID_VR",
9+
ANDROID_VR(
10+
28,
1411
"Quest 3",
1512
"12",
1613
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
1714
"32", // Android 12.1
1815
"1.56.21",
1916
true
2017
),
21-
// Specific for kids videos.
22-
IOS(5,
23-
"IOS",
24-
forceAVC()
25-
? "iPhone12,5" // 11 Pro Max (last device with iOS 13)
26-
: "iPhone17,2", // 16 Pro Max
27-
// iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1.
28-
forceAVC()
29-
? "13.7.17H35" // Last release of iOS 13.
30-
: "18.1.1.22B91",
31-
forceAVC()
32-
? "com.google.ios.youtube/17.40.5 (iPhone; U; CPU iOS 13_7 like Mac OS X)"
33-
: "com.google.ios.youtube/19.49.5 (iPhone; U; CPU iOS 18_1_1 like Mac OS X)",
34-
null,
35-
// Version number should be a valid iOS release.
36-
// https://www.ipa4fun.com/history/185230
37-
forceAVC()
38-
// Some newer versions can also force AVC,
39-
// but 17.40 is the last version that supports iOS 13.
40-
? "17.40.5"
41-
: "19.49.5",
42-
false
43-
);
44-
45-
private static boolean forceAVC() {
46-
return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
47-
}
18+
ANDROID_UNPLUGGED(
19+
29,
20+
"Google TV Streamer",
21+
"14",
22+
"com.google.android.apps.youtube.unplugged/8.49.0 (Linux; U; Android 14; GB) gzip",
23+
"34",
24+
"8.49.0",
25+
true
26+
),
27+
ANDROID_CREATOR(
28+
14,
29+
"Android",
30+
"11",
31+
"com.google.android.apps.youtube.creator/24.45.100 (Linux; U; Android 11) gzip",
32+
"30",
33+
"24.45.100",
34+
true
35+
);
4836

4937
/**
5038
* YouTube
@@ -87,15 +75,14 @@ private static boolean forceAVC() {
8775
public final boolean canLogin;
8876

8977
ClientType(int id,
90-
String clientName,
9178
String deviceModel,
9279
String osVersion,
9380
String userAgent,
9481
@Nullable String androidSdkVersion,
9582
String clientVersion,
9683
boolean canLogin) {
9784
this.id = id;
98-
this.clientName = clientName;
85+
this.clientName = name();
9986
this.deviceModel = deviceModel;
10087
this.osVersion = osVersion;
10188
this.userAgent = userAgent;

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

+4-29
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
public class SpoofVideoStreamsPatch {
1919
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
2020

21-
private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA
22-
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
23-
2421
/**
2522
* Any unreachable ip address. Used to intentionally fail requests.
2623
*/
@@ -34,20 +31,19 @@ private static boolean isPatchIncluded() {
3431
return false; // Modified during patching.
3532
}
3633

37-
public static final class NotSpoofingAndroidVrAvailability implements Setting.Availability {
34+
public static final class NotSpoofingAndroidAvailability implements Setting.Availability {
3835
@Override
3936
public boolean isAvailable() {
4037
if (SpoofVideoStreamsPatch.isPatchIncluded()) {
41-
EnumSetting<ClientType> clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE;
42-
return clientType.isAvailable() && clientType.get() != ClientType.ANDROID_VR;
38+
EnumSetting<ClientType> setting = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE;
39+
ClientType type = setting.get();
40+
return setting.isAvailable() && type.androidSdkVersion == null;
4341
}
4442

4543
return true;
4644
}
4745
}
4846

49-
50-
5147
/**
5248
* Injection point.
5349
* Blocks /get_watch requests by returning an unreachable URI.
@@ -190,25 +186,4 @@ public static byte[] removeVideoPlaybackPostBody(Uri uri, int method, byte[] pos
190186

191187
return postData;
192188
}
193-
194-
/**
195-
* Injection point.
196-
*
197-
* Fixes iOS livestreams starting from the beginning.
198-
*/
199-
public static boolean fixHLSCurrentTime(boolean original) {
200-
if (FIX_HLS_CURRENT_TIME) {
201-
return false;
202-
}
203-
204-
return original;
205-
}
206-
207-
public static final class SpoofiOSAvailability implements Setting.Availability {
208-
@Override
209-
public boolean isAvailable() {
210-
return BaseSettings.SPOOF_VIDEO_STREAMS.get()
211-
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
212-
}
213-
}
214189
}

extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
88
import static app.revanced.extension.shared.settings.Setting.parent;
99
import static app.revanced.extension.shared.settings.Setting.parentsAny;
10-
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.NotSpoofingAndroidVrAvailability;
10+
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.NotSpoofingAndroidAvailability;
1111
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
1212
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
1313
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
@@ -54,7 +54,7 @@ public class Settings extends BaseSettings {
5454
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
5555
"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);
5656
// Audio
57-
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new NotSpoofingAndroidVrAvailability());
57+
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new NotSpoofingAndroidAvailability());
5858

5959
// Ads
6060
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);

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

-85
This file was deleted.

patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt

-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package app.revanced.patches.shared.misc.spoof
22

33
import app.revanced.patcher.fingerprint
4-
import app.revanced.util.literal
54
import com.android.tools.smali.dexlib2.AccessFlags
65
import com.android.tools.smali.dexlib2.Opcode
76

@@ -112,16 +111,6 @@ internal val buildMediaDataSourceFingerprint = fingerprint {
112111
)
113112
}
114113

115-
internal const val HLS_CURRENT_TIME_FEATURE_FLAG = 45355374L
116-
117-
internal val hlsCurrentTimeFingerprint = fingerprint {
118-
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
119-
parameters("Z", "L")
120-
literal {
121-
HLS_CURRENT_TIME_FEATURE_FLAG
122-
}
123-
}
124-
125114
internal val patchIncludedExtensionMethodFingerprint = fingerprint {
126115
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
127116
returns("Z")

patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt

-10
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu
1212
import app.revanced.patches.all.misc.resources.addResourcesPatch
1313
import app.revanced.util.getReference
1414
import app.revanced.util.indexOfFirstInstructionOrThrow
15-
import app.revanced.util.insertFeatureFlagBooleanOverride
1615
import app.revanced.util.returnEarly
1716
import com.android.tools.smali.dexlib2.AccessFlags
1817
import com.android.tools.smali.dexlib2.Opcode
@@ -209,15 +208,6 @@ fun spoofVideoStreamsPatch(
209208
}
210209
// endregion
211210

212-
// region Fix iOS livestream current time.
213-
214-
hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride(
215-
HLS_CURRENT_TIME_FEATURE_FLAG,
216-
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
217-
)
218-
219-
// endregion
220-
221211
executeBlock()
222212
}
223213
}

patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt

+1-6
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
4444
"revanced_spoof_video_streams_language",
4545
summaryKey = null
4646
),
47-
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
48-
NonInteractivePreference(
49-
// Requires a key and title but the actual text is chosen at runtime.
50-
key = "revanced_spoof_video_streams_about_android_vr",
51-
tag = "app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference"
52-
),
47+
NonInteractivePreference("revanced_spoof_video_streams_about_android")
5348
),
5449
),
5550
)

patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
3131
@Suppress("unused")
3232
val forceOriginalAudioPatch = bytecodePatch(
3333
name = "Force original audio",
34-
description = "Adds an option to always use the original audio track.",
34+
description = "Adds an option to always use the original audio track. " +
35+
"This patch does nothing if 'Spoof video streams' is enabled.",
3536
) {
3637
dependsOn(
3738
sharedExtensionPatch,

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
<string-array name="revanced_spoof_video_streams_client_type_entries">
55
<!-- Operating system names are not translatable, so no need to use strings.xml -->
66
<item>Android VR</item>
7-
<item>iOS</item>
7+
<item>Android TV</item>
8+
<item>Android Creator</item>
89
</string-array>
910
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
1011
<!-- Enum names from extension -->
1112
<item>ANDROID_VR</item>
12-
<item>IOS</item>
13+
<item>ANDROID_UNPLUGGED</item>
14+
<item>ANDROID_CREATOR</item>
1315
</string-array>
1416
<string-array name="revanced_spoof_video_streams_language_entries">
1517
<item>@string/revanced_spoof_video_streams_language_DEFAULT</item>

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

+2-11
Original file line numberDiff line numberDiff line change
@@ -1297,17 +1297,8 @@ Enabling this can unlock higher video qualities"</string>
12971297
Video playback may not work"</string>
12981298
<string name="revanced_spoof_video_streams_user_dialog_message">Turning off this setting may cause video playback issues.</string>
12991299
<string name="revanced_spoof_video_streams_client_type_title">Default client</string>
1300-
<string name="revanced_spoof_video_streams_ios_force_avc_title">Force AVC (H.264)</string>
1301-
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is forced to AVC (H.264)</string>
1302-
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is determined automatically</string>
1303-
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Enabling this might improve battery life and fix playback stuttering.
1304-
1305-
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>
1306-
<string name="revanced_spoof_video_streams_about_ios_title">iOS spoofing side effects</string>
1307-
<string name="revanced_spoof_video_streams_about_ios_summary">"• Private kids videos may not play
1308-
• Videos end 1 second early"</string>
1309-
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string>
1310-
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Kids videos may not play
1300+
<string name="revanced_spoof_video_streams_about_android_title">Android spoofing side effects</string>
1301+
<string name="revanced_spoof_video_streams_about_android_summary">"• Kids videos may not play
13111302
• Audio track menu is missing
13121303
• Stable volume is not available
13131304
• Force original audio is not available"</string>

0 commit comments

Comments
 (0)