fix(YouTube - Client Spoof): Restore missing high qualities by spoofing the iOS client user agent (#668)

Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
Zain Arbani 2024-07-28 21:51:17 +07:00 committed by GitHub
parent ab0093ff83
commit fbf629fd62
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 21 deletions

View File

@ -6,11 +6,13 @@ import android.net.Uri;
import android.os.Build;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.youtube.settings.Settings;
import org.chromium.net.ExperimentalUrlRequest;
@SuppressWarnings("unused")
public class SpoofClientPatch {
private static final boolean SPOOF_CLIENT_ENABLED = Settings.SPOOF_CLIENT.get();
private static final ClientType SPOOF_CLIENT_TYPE = Settings.SPOOF_CLIENT_USE_IOS.get() ? ClientType.IOS : ClientType.ANDROID_VR;
private static final boolean SPOOFING_TO_IOS = SPOOF_CLIENT_ENABLED && SPOOF_CLIENT_TYPE == ClientType.IOS;
/**
* Any unreachable ip address. Used to intentionally fail requests.
@ -52,7 +54,7 @@ public class SpoofClientPatch {
/**
* Injection point.
*
* <p>
* Blocks /initplayback requests.
*/
public static String blockInitPlaybackRequest(String originalUrlString) {
@ -78,33 +80,29 @@ public class SpoofClientPatch {
* Injection point.
*/
public static int getClientTypeId(int originalClientTypeId) {
if (SPOOF_CLIENT_ENABLED) {
return SPOOF_CLIENT_TYPE.id;
}
return originalClientTypeId;
return SPOOF_CLIENT_ENABLED ? SPOOF_CLIENT_TYPE.id : originalClientTypeId;
}
/**
* Injection point.
*/
public static String getClientVersion(String originalClientVersion) {
if (SPOOF_CLIENT_ENABLED) {
return SPOOF_CLIENT_TYPE.version;
}
return originalClientVersion;
return SPOOF_CLIENT_ENABLED ? SPOOF_CLIENT_TYPE.version : originalClientVersion;
}
/**
* Injection point.
*/
public static String getClientModel(String originalClientModel) {
if (SPOOF_CLIENT_ENABLED) {
return SPOOF_CLIENT_TYPE.model;
}
return SPOOF_CLIENT_ENABLED ? SPOOF_CLIENT_TYPE.model : originalClientModel;
}
return originalClientModel;
/**
* Injection point.
* Fix video qualities missing, if spoofing to iOS by using the correct client OS version.
*/
public static String getOsVersion(String originalOsVersion) {
return SPOOFING_TO_IOS ? ClientType.IOS.osVersion : originalOsVersion;
}
/**
@ -127,11 +125,23 @@ public class SpoofClientPatch {
* Return true to force create the playback speed menu.
*/
public static boolean forceCreatePlaybackSpeedMenu(boolean original) {
if (SPOOF_CLIENT_ENABLED && SPOOF_CLIENT_TYPE == ClientType.IOS) {
return true;
return SPOOFING_TO_IOS || original;
}
/**
* Injection point.
* Fix video qualities missing, if spoofing to iOS by using the correct iOS user-agent.
*/
public static ExperimentalUrlRequest overrideUserAgent(ExperimentalUrlRequest.Builder builder, String url) {
if (SPOOFING_TO_IOS) {
String path = Uri.parse(url).getPath();
if (path != null && path.contains("player")) {
return builder.addHeader("User-Agent", ClientType.IOS.userAgent).build();
}
}
return original;
return builder.build();
}
/**
@ -149,7 +159,12 @@ public class SpoofClientPatch {
private enum ClientType {
// https://dumps.tadiphone.dev/dumps/oculus/eureka
ANDROID_VR(28, "Quest 3", "1.56.21"),
ANDROID_VR(28,
"Quest 3",
"1.56.21",
"12",
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip"
),
// 11,4 = iPhone XS Max.
// 16,2 = iPhone 15 Pro Max.
// Since the 15 supports AV1 hardware decoding, only spoof that device if this
@ -157,7 +172,12 @@ public class SpoofClientPatch {
//
// Version number should be a valid iOS release.
// https://www.ipa4fun.com/history/185230
IOS(5, deviceHasAV1HardwareDecoding() ? "iPhone16,2" : "iPhone11,4", "19.10.7");
IOS(5,
deviceHasAV1HardwareDecoding() ? "iPhone16,2" : "iPhone11,4",
"19.10.7",
"17.5.1.21F90",
"com.google.ios.youtube/19.10.7 (iPhone; U; CPU iOS 17_5_1 like Mac OS X)"
);
/**
* YouTube
@ -175,10 +195,22 @@ public class SpoofClientPatch {
*/
final String version;
ClientType(int id, String model, String version) {
/**
* Device OS version.
*/
final String osVersion;
/**
* Player user-agent.
*/
final String userAgent;
ClientType(int id, String model, String version, String osVersion, String userAgent) {
this.id = id;
this.model = model;
this.version = version;
this.osVersion = osVersion;
this.userAgent = userAgent;
}
}

View File

@ -0,0 +1,8 @@
package org.chromium.net;
public abstract class ExperimentalUrlRequest {
public abstract class Builder {
public abstract ExperimentalUrlRequest.Builder addHeader(String name, String value);
public abstract ExperimentalUrlRequest build();
}
}