Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(YouTube - Spoof video streams): Add 'Android Creator' #4262

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,24 @@ public enum ClientType {
ANDROID_VR_NO_AUTH(
28,
"ANDROID_VR",
"Oculus",
"Quest 3",
"Android",
"12",
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
"32", // Android 12.1
"1.56.21",
false,
"Android VR No auth"
),
// Chromecast with Google TV 4K.
// https://dumps.tadiphone.dev/dumps/google/kirkwood
ANDROID_UNPLUGGED(
29,
"ANDROID_UNPLUGGED",
"Google",
"Google TV Streamer",
"Android",
"14",
"com.google.android.apps.youtube.unplugged/8.49.0 (Linux; U; Android 14; GB) gzip",
"34",
Expand All @@ -33,38 +39,56 @@ public enum ClientType {
ANDROID_VR(
ANDROID_VR_NO_AUTH.id,
ANDROID_VR_NO_AUTH.clientName,
ANDROID_VR_NO_AUTH.deviceMake,
ANDROID_VR_NO_AUTH.deviceModel,
ANDROID_VR_NO_AUTH.osName,
ANDROID_VR_NO_AUTH.osVersion,
ANDROID_VR_NO_AUTH.userAgent,
ANDROID_VR_NO_AUTH.androidSdkVersion,
ANDROID_VR_NO_AUTH.clientVersion,
true,
"Android VR"
),
IOS_UNPLUGGED(33,
IOS_UNPLUGGED(
33,
"IOS_UNPLUGGED",
"Apple",
forceAVC()
? "iPhone12,5" // 11 Pro Max (last device with iOS 13)
: "iPhone16,2", // 15 Pro Max
"iOS",
// iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1.
forceAVC()
? "13.7.17H35" // Last release of iOS 13.
: "18.1.1.22B91",
: "18.2.22C152",
forceAVC()
? "com.google.ios.youtubeunplugged/6.45 (iPhone; U; CPU iOS 13_7 like Mac OS X)"
: "com.google.ios.youtubeunplugged/8.33 (iPhone; U; CPU iOS 18_1_1 like Mac OS X)",
? "com.google.ios.youtubeunplugged/6.45 (iPhone12,5; U; CPU iOS 13_7 like Mac OS X)"
: "com.google.ios.youtubeunplugged/8.49 (iPhone16,2; U; CPU iOS 18_2_22 like Mac OS X)",
null,
// Version number should be a valid iOS release.
// https://www.ipa4fun.com/history/152043/
// Some newer versions can also force AVC,
// but 6.45 is the last version that supports iOS 13.
forceAVC()
? "6.45"
: "8.33",
: "8.49",
true,
forceAVC()
? "iOS TV Force AVC"
: "iOS TV"
),
ANDROID_CREATOR(
14,
"ANDROID_CREATOR",
Build.MANUFACTURER,
Build.MODEL,
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
"Android",
"11",
"com.google.android.apps.youtube.creator/24.45.100 (Linux; U; Android 11) gzip",
"30",
"24.45.100",
true,
"Android Creator"
);

private static boolean forceAVC() {
Expand All @@ -80,10 +104,20 @@ private static boolean forceAVC() {
public final String clientName;

/**
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.model)
* Device model, equivalent to {@link Build#MANUFACTURER} (System property: ro.product.vendor.manufacturer)
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
*/
public final String deviceMake;

/**
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.vendor.model)
*/
public final String deviceModel;

/**
* Device OS name.
*/
public final String osName;

/**
* Device OS version.
*/
Expand Down Expand Up @@ -118,7 +152,9 @@ private static boolean forceAVC() {

ClientType(int id,
String clientName,
String deviceMake,
String deviceModel,
String osName,
String osVersion,
String userAgent,
@Nullable String androidSdkVersion,
Expand All @@ -127,7 +163,9 @@ private static boolean forceAVC() {
String friendlyName) {
this.id = id;
this.clientName = clientName;
this.deviceMake = deviceMake;
this.deviceModel = deviceModel;
this.osName = osName;
this.osVersion = osVersion;
this.userAgent = userAgent;
this.androidSdkVersion = androidSdkVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,19 @@ public static void fetchStreams(String url, Map<String, String> requestHeaders)
return;
}

// 'get_drm_license' has no video id and appears to happen when waiting for a paid video to start.
// 'heartbeat' has no video id and appears to be only after playback has started.
// 'refresh' has no video id and appears to happen when waiting for a livestream to start.
// 'ad_break' has no video id.
if (path.contains("heartbeat") || path.contains("refresh") || path.contains("ad_break")) {
if (path.contains("get_drm_license") || path.contains("heartbeat")
|| path.contains("refresh") || path.contains("ad_break")) {
Logger.printDebug(() -> "Ignoring path: " + path);
return;
}

String id = uri.getQueryParameter("id");
if (id == null) {
Logger.printException(() -> "Ignoring request with no id. Url: " + url);
Logger.printException(() -> "Ignoring request with no id: " + url);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ static String createInnertubeBody(ClientType clientType) {
client.put("hl", language.getLanguage());
client.put("clientName", clientType.clientName);
client.put("clientVersion", clientType.clientVersion);
client.put("deviceMake", clientType.deviceMake);
client.put("deviceModel", clientType.deviceModel);
client.put("osName", clientType.osName);
client.put("osVersion", clientType.osVersion);
if (clientType.androidSdkVersion != null) {
client.put("androidSdkVersion", clientType.androidSdkVersion);
Expand All @@ -76,6 +78,7 @@ static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRout

connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", clientType.userAgent);
connection.setRequestProperty("X-YouTube-Client-Version", String.valueOf(clientType.id));

connection.setUseCaches(false);
connection.setDoOutput(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ private static ByteBuffer fetch(String videoId, Map<String, String> playerHeader
// gzip encoding doesn't response with content length (-1),
// but empty response body does.
if (connection.getContentLength() == 0) {
if (BaseSettings.DEBUG.get()) {
Logger.printException(() -> "Ignoring empty client: " + clientType);
if (BaseSettings.DEBUG.get() && BaseSettings.DEBUG_TOAST_ON_ERROR.get()) {
Utils.showToastShort("Ignoring empty spoof stream client: " + clientType);
}
} else {
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,20 @@ private void updateUI() {
(clientType == ClientType.IOS_UNPLUGGED
? "ios_tv"
: "android");
setTitle(str(key + "_title"));
setSummary(str(key + "_summary"));
String title = str(key + "_title");
String summary = str(key + "_summary");

// Android VR supports AV1 but all other clients do not.
if (clientType != ClientType.ANDROID_VR && clientType != ClientType.ANDROID_VR_NO_AUTH) {
summary += '\n' + str("revanced_spoof_video_streams_about_no_av1");

// Android Creator does not support HDR.
if (clientType == ClientType.ANDROID_CREATOR) {
summary += '\n' + str("revanced_spoof_video_streams_about_no_hdr");
}
}

setTitle(title);
setSummary(summary);
}
}
2 changes: 2 additions & 0 deletions patches/src/main/resources/addresources/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,15 @@
<string-array name="revanced_spoof_video_streams_client_type_entries">
<item>Android VR</item>
<item>@string/revanced_spoof_video_streams_client_type_android_vr_no_auth</item>
<item>Android Creator</item>
<item>Android TV</item>
<item>iOS TV</item>
</string-array>
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
<!-- Extension enum names. -->
<item>ANDROID_VR</item>
<item>ANDROID_VR_NO_AUTH</item>
<item>ANDROID_CREATOR</item>
<item>ANDROID_UNPLUGGED</item>
<item>IOS_UNPLUGGED</item>
</string-array>
Expand Down
2 changes: 2 additions & 0 deletions patches/src/main/resources/addresources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,8 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi
<string name="revanced_spoof_video_streams_about_android_summary">"• Audio track menu is missing
• Stable volume is not available
• Force original audio is not available"</string>
<string name="revanced_spoof_video_streams_about_no_av1">• No AV1 video codec</string>
<string name="revanced_spoof_video_streams_about_no_hdr">• No HDR video</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 type is shown in Stats for nerds</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Client is hidden in Stats for nerds</string>
Expand Down
Loading