Skip to content

Commit

Permalink
fix(YouTube - Spoof video streams): Change default spoofing to iOS, a…
Browse files Browse the repository at this point in the history
…llow setting a default language with Android VR (#4171)
  • Loading branch information
LisoUseInAIKyrios authored Dec 20, 2024
1 parent 66f8b0c commit 171b4e7
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public class BaseSettings {
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);

public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, new SpoofiOSAvailability());
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, parent(SPOOF_VIDEO_STREAMS));
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
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));

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public enum ClientType {
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
"32", // Android 12.1
"1.56.21",
true,
false),
true
),
// Specific for kids videos.
IOS(5,
"IOS",
Expand All @@ -39,8 +39,7 @@ public enum ClientType {
// but 17.40 is the last version that supports iOS 13.
? "17.40.5"
: "19.47.7",
false,
true
false
);

private static boolean forceAVC() {
Expand Down Expand Up @@ -87,20 +86,14 @@ private static boolean forceAVC() {
*/
public final boolean canLogin;

/**
* If a language code should be used.
*/
public final boolean useLanguageCode;

ClientType(int id,
String clientName,
String deviceModel,
String osVersion,
String userAgent,
@Nullable String androidSdkVersion,
String clientVersion,
boolean canLogin,
boolean useLanguageCode) {
boolean canLogin) {
this.id = id;
this.clientName = clientName;
this.deviceModel = deviceModel;
Expand All @@ -109,6 +102,5 @@ private static boolean forceAVC() {
this.androidSdkVersion = androidSdkVersion;
this.clientVersion = clientVersion;
this.canLogin = canLogin;
this.useLanguageCode = useLanguageCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.EnumSetting;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;

Expand All @@ -26,6 +27,27 @@ public class SpoofVideoStreamsPatch {
private static final String UNREACHABLE_HOST_URI_STRING = "https://127.0.0.0";
private static final Uri UNREACHABLE_HOST_URI = Uri.parse(UNREACHABLE_HOST_URI_STRING);

/**
* @return If this patch was included during patching.
*/
private static boolean isPatchIncluded() {
return false; // Modified during patching.
}

public static final class NotSpoofingAndroidVrAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
if (SpoofVideoStreamsPatch.isPatchIncluded()) {
EnumSetting<ClientType> clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE;
return clientType.isAvailable() && clientType.get() != ClientType.ANDROID_VR;
}

return true;
}
}



/**
* Injection point.
* Blocks /get_watch requests by returning an unreachable URI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ static String createInnertubeBody(ClientType clientType) {
JSONObject context = new JSONObject();

JSONObject client = new JSONObject();
if (clientType.useLanguageCode) {
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
}
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
client.put("clientName", clientType.clientName);
client.put("clientVersion", clientType.clientVersion);
client.put("deviceModel", clientType.deviceModel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackI
return isOriginal;
} catch (Exception ex) {
Logger.printException(() -> "isDefaultAudioStream failure", ex);
}

return isDefault;
return isDefault;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.settings.Setting.parentsAny;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.NotSpoofingAndroidVrAvailability;
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
Expand Down Expand Up @@ -53,7 +54,7 @@ public class Settings extends BaseSettings {
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
"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);
// Audio
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE);
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new NotSpoofingAndroidVrAvailability());

// Ads
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,12 @@ internal val hlsCurrentTimeFingerprint = fingerprint {
HLS_CURRENT_TIME_FEATURE_FLAG
}
}

internal val patchIncludedExtensionMethodFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
returns("Z")
parameters()
custom { method, classDef ->
classDef.type == EXTENSION_CLASS_DESCRIPTOR && method.name == "isPatchIncluded"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.insertFeatureFlagBooleanOverride
import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
Expand All @@ -39,6 +40,12 @@ fun spoofVideoStreamsPatch(
dependsOn(addResourcesPatch)

execute {
// region Enable extension helper method used by other patches

patchIncludedExtensionMethodFingerprint.method.returnEarly(true)

// endregion

// region Block /initplayback requests to fall back to /get_watch requests.

val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
preferences = setOf(
SwitchPreference("revanced_spoof_video_streams"),
ListPreference(
"revanced_spoof_video_streams_client",
"revanced_spoof_video_streams_client_type",
summaryKey = null,
),
ListPreference(
"revanced_spoof_video_streams_language",
summaryKey = null
),
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
// Preference requires a title but the actual text is chosen at runtime.
NonInteractivePreference(
// Requires a key and title but the actual text is chosen at runtime.
key = "revanced_spoof_video_streams_about_android_vr",
tag = "app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference"
),
Expand Down
4 changes: 2 additions & 2 deletions patches/src/main/resources/addresources/values/arrays.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<resources>
<app id="youtube">
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string-array name="revanced_spoof_video_streams_client_entries">
<string-array name="revanced_spoof_video_streams_client_type_entries">
<!-- Operating system names are not translatable, so no need to use strings.xml -->
<item>Android VR</item>
<item>iOS</item>
</string-array>
<string-array name="revanced_spoof_video_streams_client_entry_values">
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
<!-- Enum names from extension -->
<item>ANDROID_VR</item>
<item>IOS</item>
Expand Down
5 changes: 3 additions & 2 deletions patches/src/main/resources/addresources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,7 @@ Enabling this can unlock higher video qualities"</string>

Video playback may not work"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Turning off this setting may cause video playback issues.</string>
<string name="revanced_spoof_video_streams_client_title">Default client</string>
<string name="revanced_spoof_video_streams_client_type_title">Default client</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Force AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is forced to AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is determined automatically</string>
Expand All @@ -1309,7 +1309,8 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Kids videos may not play
• Audio track menu is missing
• Stable volume is not available"</string>
• Stable volume is not available
• Force original audio is not available"</string>
<string name="revanced_spoof_video_streams_language_title">Default audio stream language</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">App language</string>
<string name="revanced_spoof_video_streams_language_AR">Arabic</string>
Expand Down

0 comments on commit 171b4e7

Please sign in to comment.