From 9fe88b9886a78ccd07ee5f05fd0edbfd56be5150 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:31:10 +0400 Subject: [PATCH 01/14] feat(YouTube): Add `Change default audio track` patch --- .../shared/settings/BaseSettings.java | 2 - .../shared/spoof/AudioStreamLanguage.java | 25 +- .../extension/shared/spoof/ClientType.java | 31 +-- .../shared/spoof/SpoofVideoStreamsPatch.java | 8 - .../shared/spoof/requests/PlayerRoutes.java | 8 +- .../ChangeDefaultAudioLanguagePatch.java | 75 ++++++ .../extension/youtube/settings/Settings.java | 3 + .../ReVancedPreferenceFragment.java | 37 +-- patches/api/patches.api | 4 + .../misc/spoof/SpoofVideoStreamsPatch.kt | 8 - .../misc/spoof/SpoofVideoStreamsPatch.kt | 4 - .../audio/ChangeDefaultAudioLanguagePatch.kt | 135 +++++++++++ .../youtube/video/audio/Fingerprints.kt | 23 ++ .../resources/addresources/values/arrays.xml | 226 +++++++++--------- .../resources/addresources/values/strings.xml | 116 ++++----- 15 files changed, 470 insertions(+), 235 deletions(-) create mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 9a62db4332..7072ea07af 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -5,7 +5,6 @@ import static app.revanced.extension.shared.settings.Setting.parent; import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.ForceiOSAVCAvailability; -import app.revanced.extension.shared.spoof.AudioStreamLanguage; import app.revanced.extension.shared.spoof.ClientType; /** @@ -22,7 +21,6 @@ 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 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 ForceiOSAVCAvailability()); public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS)); diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java index 0d9070e2fd..c5455ae4c5 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java @@ -3,8 +3,21 @@ import java.util.Locale; public enum AudioStreamLanguage { + /** + * Change nothing, same as unpatched. + */ DEFAULT, + /** + * Original language of the video. + */ + ORIGINAL, + + /** + * Current language the app is set to. + */ + APP_LANGUAGE, + // Language codes found in locale_config.xml // Region specific variants of Chinese/English/Spanish/French have been removed. AF, @@ -86,15 +99,21 @@ public enum AudioStreamLanguage { private final String iso639_1; AudioStreamLanguage() { - iso639_1 = name().replace('_', '-'); + String name = name(); + final int regionSeparatorIndex = name.indexOf('_'); + if (regionSeparatorIndex >= 0) { + iso639_1 = name.substring(0, regionSeparatorIndex).toLowerCase(Locale.US) + + name.substring(regionSeparatorIndex); + } else { + iso639_1 = name().toLowerCase(Locale.US); + } } public String getIso639_1() { // Changing the app language does not force the app to completely restart, // so the default needs to be the current language and not a static field. if (this == DEFAULT) { - // Android VR requires uppercase language code. - return Locale.getDefault().toLanguageTag().toUpperCase(Locale.US); + return Locale.getDefault().toLanguageTag(); } return iso639_1; diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java index f51779a15a..032d420ec4 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java @@ -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, - true), + true + ), // Specific for kids videos. IOS(5, "IOS", @@ -39,22 +39,8 @@ public enum ClientType { // but 17.40 is the last version that supports iOS 13. ? "17.40.5" : "19.47.7", - false, - true), - /** - * Android VR with no language code. - * Used for age restricted videos and YouTube Music to disable stable volume. - */ - ANDROID_VR_NO_HL( - ANDROID_VR.id, - ANDROID_VR.clientName, - ANDROID_VR.deviceModel, - ANDROID_VR.osVersion, - ANDROID_VR.userAgent, - ANDROID_VR.androidSdkVersion, - ANDROID_VR.clientVersion, - ANDROID_VR.canLogin, - false); + false + ); private static boolean forceAVC() { return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get(); @@ -100,11 +86,6 @@ 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, @@ -112,8 +93,7 @@ private static boolean forceAVC() { String userAgent, @Nullable String androidSdkVersion, String clientVersion, - boolean canLogin, - boolean useLanguageCode) { + boolean canLogin) { this.id = id; this.clientName = clientName; this.deviceModel = deviceModel; @@ -122,6 +102,5 @@ private static boolean forceAVC() { this.androidSdkVersion = androidSdkVersion; this.clientVersion = clientVersion; this.canLogin = canLogin; - this.useLanguageCode = useLanguageCode; } } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java index 5ad672f126..4016c8ef99 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java @@ -22,14 +22,6 @@ 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); - /** - * Injection point. Used by YT Music to disable stable volume. - */ - public static void setClientTypeToAndroidVrNoHl() { - Logger.printDebug(() -> "Setting stream spoofing to: " + ClientType.ANDROID_VR_NO_HL); - BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.save(ClientType.ANDROID_VR_NO_HL); - } - /** * Injection point. * Blocks /get_watch requests by returning an unreachable URI. diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java index ca1a0eb897..80c4632e0e 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java @@ -5,11 +5,11 @@ import java.io.IOException; import java.net.HttpURLConnection; +import java.util.Locale; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.requests.Requester; import app.revanced.extension.shared.requests.Route; -import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.spoof.ClientType; final class PlayerRoutes { @@ -35,9 +35,9 @@ 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()); - } + // Changing the app language does not force the app to completely restart, + // so the default needs to be the current language and not a static field. + client.put("hl", Locale.getDefault().toLanguageTag()); client.put("clientName", clientType.clientName); client.put("clientVersion", clientType.clientVersion); client.put("deviceModel", clientType.deviceModel); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java new file mode 100644 index 0000000000..eec276618e --- /dev/null +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java @@ -0,0 +1,75 @@ +package app.revanced.extension.youtube.patches; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.spoof.AudioStreamLanguage; +import app.revanced.extension.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class ChangeDefaultAudioLanguagePatch { + + private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original"; + + /** + * Audio track identifier. + * + * Examples: + * fr-FR.10 + * it.10 + */ + private static final Pattern AUDIO_TRACK_ID_PATTERN = + Pattern.compile("^([a-z]{2})(-[A-Z]{2})?(\\.\\d+)"); + + private static void printDebug(Logger.LogMessage message) { + // Do not log by default as it's spammy. + final boolean logAudioStreams = false; + + //noinspection ConstantConditions + if (logAudioStreams) { + Logger.printDebug(message); + } + } + + /** + * Injection point. + */ + public static boolean setAudioStreamAsDefault(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { + try { + AudioStreamLanguage defaultLanguage = Settings.AUDIO_DEFAULT_LANGUAGE.get(); + if (defaultLanguage == AudioStreamLanguage.DEFAULT) { + return isDefault; // Do nothing. + } + + printDebug(() -> "isDefault: " + isDefault + " audioTrackId: " + audioTrackId + + " audioTrackDisplayName:" + audioTrackDisplayName); + + if (defaultLanguage == AudioStreamLanguage.ORIGINAL) { + final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); + if (isOriginal) { + printDebug(() -> "Using original audio language: " + audioTrackId); + } + + return isOriginal; + } + + Matcher matcher = AUDIO_TRACK_ID_PATTERN.matcher(audioTrackId); + if (!matcher.matches()) { + Logger.printException(() -> "Cannot set default audio, unknown track: " + audioTrackId); + return isDefault; + } + + String desiredIso639 = defaultLanguage.getIso639_1(); + if (desiredIso639.equals(matcher.group(1)) + || desiredIso639.equals(matcher.group(2))) { + printDebug(() -> "Using preferred audio language: " + audioTrackId); + return true; + } + } catch (Exception ex) { + Logger.printException(() -> "setAudioStreamAsDefault failure", ex); + } + + return isDefault; + } +} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 950f34be4d..1bc1ddea04 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -34,6 +34,7 @@ import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.settings.preference.SharedPrefCategory; +import app.revanced.extension.shared.spoof.AudioStreamLanguage; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption; @@ -52,6 +53,8 @@ public class Settings extends BaseSettings { public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", -2.0f); 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 EnumSetting AUDIO_DEFAULT_LANGUAGE = new EnumSetting<>("revanced_audio_default_language", AudioStreamLanguage.DEFAULT); // Ads public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index ed4502aef4..24bb9d1315 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -48,35 +48,44 @@ public static Drawable getBackButtonDrawable() { /** * Sorts a preference list by menu entries, but preserves the first value as the first entry. + * + * @noinspection SameParameterValue */ - private static void sortListPreferenceByValues(ListPreference listPreference) { + private static void sortListPreferenceByValues(ListPreference listPreference, int firstEntriesToPreserve) { CharSequence[] entries = listPreference.getEntries(); CharSequence[] entryValues = listPreference.getEntryValues(); final int entrySize = entries.length; if (entrySize != entryValues.length) { + // Xml array declaration has a missing/extra entry. throw new IllegalStateException(); } - // Ensure the first entry remains the first after sorting. - CharSequence firstEntry = entries[0]; - CharSequence firstEntryValue = entryValues[0]; + List> firstPairs = new ArrayList<>(firstEntriesToPreserve); + List> pairsToSort = new ArrayList<>(entrySize); - List> entryPairs = new ArrayList<>(entrySize); - for (int i = 1; i < entrySize; i++) { - entryPairs.add(new Pair<>(entries[i].toString(), entryValues[i].toString())); + for (int i = 0; i < entrySize; i++) { + Pair pair = new Pair<>(entries[i].toString(), entryValues[i].toString()); + if (i < firstEntriesToPreserve) { + firstPairs.add(pair); + } else { + pairsToSort.add(pair); + } } - Collections.sort(entryPairs, (pair1, pair2) -> pair1.first.compareToIgnoreCase(pair2.first)); + Collections.sort(pairsToSort, (pair1, pair2) -> pair1.first.compareToIgnoreCase(pair2.first)); CharSequence[] sortedEntries = new CharSequence[entrySize]; CharSequence[] sortedEntryValues = new CharSequence[entrySize]; - sortedEntries[0] = firstEntry; - sortedEntryValues[0] = firstEntryValue; + int i = 0; + for (Pair pair : firstPairs) { + sortedEntries[i] = pair.first; + sortedEntryValues[i] = pair.second; + i++; + } - int i = 1; - for (Pair pair : entryPairs) { + for (Pair pair : pairsToSort) { sortedEntries[i] = pair.first; sortedEntryValues[i] = pair.second; i++; @@ -100,9 +109,9 @@ protected void initialize() { CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference); } - preference = findPreference(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE.key); + preference = findPreference(Settings.AUDIO_DEFAULT_LANGUAGE.key); if (preference instanceof ListPreference languagePreference) { - sortListPreferenceByValues(languagePreference); + sortListPreferenceByValues(languagePreference, 3); } } catch (Exception ex) { Logger.printException(() -> "initialize failure", ex); diff --git a/patches/api/patches.api b/patches/api/patches.api index 5f7861ff2f..21c40715d5 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1392,6 +1392,10 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt { public static final fun getRollingNumberTextViewAnimationUpdateFingerprint ()Lapp/revanced/patcher/Fingerprint; } +public final class app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatchKt { + public static final fun getChangeDefaultAudioLanguagePatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt { public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt index 573ac0c154..21eb321569 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt @@ -1,15 +1,7 @@ package app.revanced.patches.music.misc.spoof -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint -import app.revanced.patches.shared.misc.spoof.EXTENSION_CLASS_DESCRIPTOR import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch val spoofVideoStreamsPatch = spoofVideoStreamsPatch({ compatibleWith("com.google.android.apps.youtube.music") -}, { - musicActivityOnCreateFingerprint.method.addInstruction( - 0, - "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setClientTypeToAndroidVrNoHl()V" - ) }) \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt index 45bdfc0c89..a9c945f754 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt @@ -40,10 +40,6 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({ "revanced_spoof_video_streams_client", 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( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt new file mode 100644 index 0000000000..82e5391a1a --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt @@ -0,0 +1,135 @@ +package app.revanced.patches.youtube.video.audio + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.ListPreference +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.settings.PreferenceScreen +import app.revanced.patches.youtube.misc.settings.settingsPatch +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.immutable.ImmutableMethod +import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch;" + +@Suppress("unused") +val changeDefaultAudioLanguagePatch = bytecodePatch( + name = "Change default audio track", + description = "Adds an option to set a video default audio language .", +) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + + compatibleWith( + "com.google.android.youtube"( + "18.38.44", + "18.49.37", + "19.16.39", + "19.25.37", + "19.34.42", + "19.43.41", + "19.45.38", + "19.46.42", + ), + ) + + execute { + addResources("youtube", "video.audio.changeDefaultAudioTrackPatch") + + PreferenceScreen.VIDEO.addPreferences( + ListPreference( + "revanced_audio_default_language", + summaryKey = null + ) + ) + + fun Method.firstFormatStreamingModelCall( + returnType: String = "Ljava/lang/String;" + ): MutableMethod { + val audioTrackIdIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;" + && reference.returnType == returnType + } + + return navigate(this).to(audioTrackIdIndex).stop() + } + + // Accessor methods of FormatStreamModel have no string constants and + // opcodes are identical to other methods in the same class, + // so must walk from another class that use the methods. + val isDefaultMethod = streamingModelBuilderFingerprint.originalMethod.firstFormatStreamingModelCall("Z") + val audioTrackIdMethod = menuItemAudioTrackFingerprint.originalMethod.firstFormatStreamingModelCall() + val audioTrackDisplayNameMethod = audioStreamingTypeSelector.originalMethod.firstFormatStreamingModelCall() + val formatStreamModelClass = proxy(classes.first { + it.type == audioTrackIdMethod.definingClass + }).mutableClass + + formatStreamModelClass.apply { + // Add a helper method because the isDefaultAudioTrack() has only 2 registers and 3 are needed. + val helperMethodClass = type + val helperMethodName = "extensions_isDefaultAudioTrack" + val helperMethod = ImmutableMethod( + helperMethodClass, + helperMethodName, + listOf(ImmutableMethodParameter("Z", null, null)), + "Z", + AccessFlags.PRIVATE.value, + null, + null, + MutableMethodImplementation(4), + ).toMutable().apply { + // This is the equivalent of + // String featureName = feature.toString() + // + // return null + addInstructions( + 0, + """ + invoke-virtual { p0 }, $audioTrackIdMethod + move-result-object v0 + + invoke-virtual { p0 }, $audioTrackDisplayNameMethod + move-result-object v1 + + invoke-static { p1, v0, v1 }, $EXTENSION_CLASS_DESCRIPTOR->setAudioStreamAsDefault(ZLjava/lang/String;Ljava/lang/String;)Z + move-result v0 + + return v0 + """ + ) + } + methods.add(helperMethod) + + // Modify isDefaultAudioTrack() to call extension helper method. + isDefaultMethod.apply { + val index = indexOfFirstInstructionOrThrow(Opcode.RETURN) + val register = getInstruction(index).registerA + + addInstructions( + index, + """ + invoke-direct { p0, v$register }, $helperMethodClass->$helperMethodName(Z)Z + move-result v$register + """ + ) + } + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt new file mode 100644 index 0000000000..a338ea6b7d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.youtube.video.audio + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal val streamingModelBuilderFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("L") + strings("vprng") +} + +internal val menuItemAudioTrackFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("L") + returns("V") + strings("menu_item_audio_track") +} + +internal val audioStreamingTypeSelector = fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) + returns("L") + strings("raw") // String is not unique +} \ No newline at end of file diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index c600e86b7e..ef86eae874 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -11,116 +11,6 @@ ANDROID_VR IOS - - @string/revanced_spoof_video_streams_language_DEFAULT - @string/revanced_spoof_video_streams_language_AR - @string/revanced_spoof_video_streams_language_AZ - @string/revanced_spoof_video_streams_language_BG - @string/revanced_spoof_video_streams_language_BN - @string/revanced_spoof_video_streams_language_CA - @string/revanced_spoof_video_streams_language_CS - @string/revanced_spoof_video_streams_language_DA - @string/revanced_spoof_video_streams_language_DE - @string/revanced_spoof_video_streams_language_EL - @string/revanced_spoof_video_streams_language_EN - @string/revanced_spoof_video_streams_language_ES - @string/revanced_spoof_video_streams_language_ET - @string/revanced_spoof_video_streams_language_FA - @string/revanced_spoof_video_streams_language_FI - @string/revanced_spoof_video_streams_language_FR - @string/revanced_spoof_video_streams_language_GU - @string/revanced_spoof_video_streams_language_HI - @string/revanced_spoof_video_streams_language_HR - @string/revanced_spoof_video_streams_language_HU - @string/revanced_spoof_video_streams_language_ID - @string/revanced_spoof_video_streams_language_IT - @string/revanced_spoof_video_streams_language_JA - @string/revanced_spoof_video_streams_language_KK - @string/revanced_spoof_video_streams_language_KO - @string/revanced_spoof_video_streams_language_LT - @string/revanced_spoof_video_streams_language_LV - @string/revanced_spoof_video_streams_language_MK - @string/revanced_spoof_video_streams_language_MN - @string/revanced_spoof_video_streams_language_MR - @string/revanced_spoof_video_streams_language_MS - @string/revanced_spoof_video_streams_language_MY - @string/revanced_spoof_video_streams_language_NL - @string/revanced_spoof_video_streams_language_OR - @string/revanced_spoof_video_streams_language_PA - @string/revanced_spoof_video_streams_language_PL - @string/revanced_spoof_video_streams_language_PT_BR - @string/revanced_spoof_video_streams_language_PT_PT - @string/revanced_spoof_video_streams_language_RO - @string/revanced_spoof_video_streams_language_RU - @string/revanced_spoof_video_streams_language_SK - @string/revanced_spoof_video_streams_language_SL - @string/revanced_spoof_video_streams_language_SR - @string/revanced_spoof_video_streams_language_SV - @string/revanced_spoof_video_streams_language_SW - @string/revanced_spoof_video_streams_language_TA - @string/revanced_spoof_video_streams_language_TE - @string/revanced_spoof_video_streams_language_TH - @string/revanced_spoof_video_streams_language_TR - @string/revanced_spoof_video_streams_language_UK - @string/revanced_spoof_video_streams_language_UR - @string/revanced_spoof_video_streams_language_VI - @string/revanced_spoof_video_streams_language_ZH - - - DEFAULT - AR - AZ - BG - BN - CA - CS - DA - DE - EL - EN - ES - ET - FA - FI - FR - GU - HI - HR - HU - ID - IT - JA - KK - KO - LT - LV - MK - MN - MR - MS - MY - NL - OR - PA - PL - PT_BR - PT_PT - RO - RU - SK - SL - SR - SV - SW - TA - TE - TH - TR - UK - UR - VI - ZH - @@ -270,6 +160,122 @@ 144 + + + @string/revanced_audio_default_language_DEFAULT + @string/revanced_audio_default_language_ORIGINAL + @string/revanced_audio_default_language_APP_LANGUAGE + @string/revanced_audio_default_language_AR + @string/revanced_audio_default_language_AZ + @string/revanced_audio_default_language_BG + @string/revanced_audio_default_language_BN + @string/revanced_audio_default_language_CA + @string/revanced_audio_default_language_CS + @string/revanced_audio_default_language_DA + @string/revanced_audio_default_language_DE + @string/revanced_audio_default_language_EL + @string/revanced_audio_default_language_EN + @string/revanced_audio_default_language_ES + @string/revanced_audio_default_language_ET + @string/revanced_audio_default_language_FA + @string/revanced_audio_default_language_FI + @string/revanced_audio_default_language_FR + @string/revanced_audio_default_language_GU + @string/revanced_audio_default_language_HI + @string/revanced_audio_default_language_HR + @string/revanced_audio_default_language_HU + @string/revanced_audio_default_language_ID + @string/revanced_audio_default_language_IT + @string/revanced_audio_default_language_JA + @string/revanced_audio_default_language_KK + @string/revanced_audio_default_language_KO + @string/revanced_audio_default_language_LT + @string/revanced_audio_default_language_LV + @string/revanced_audio_default_language_MK + @string/revanced_audio_default_language_MN + @string/revanced_audio_default_language_MR + @string/revanced_audio_default_language_MS + @string/revanced_audio_default_language_MY + @string/revanced_audio_default_language_NL + @string/revanced_audio_default_language_OR + @string/revanced_audio_default_language_PA + @string/revanced_audio_default_language_PL + @string/revanced_audio_default_language_PT_BR + @string/revanced_audio_default_language_PT_PT + @string/revanced_audio_default_language_RO + @string/revanced_audio_default_language_RU + @string/revanced_audio_default_language_SK + @string/revanced_audio_default_language_SL + @string/revanced_audio_default_language_SR + @string/revanced_audio_default_language_SV + @string/revanced_audio_default_language_SW + @string/revanced_audio_default_language_TA + @string/revanced_audio_default_language_TE + @string/revanced_audio_default_language_TH + @string/revanced_audio_default_language_TR + @string/revanced_audio_default_language_UK + @string/revanced_audio_default_language_UR + @string/revanced_audio_default_language_VI + @string/revanced_audio_default_language_ZH + + + DEFAULT + ORIGINAL + APP_LANGUAGE + AR + AZ + BG + BN + CA + CS + DA + DE + EL + EN + ES + ET + FA + FI + FR + GU + HI + HR + HU + ID + IT + JA + KK + KO + LT + LV + MK + MN + MR + MS + MY + NL + OR + PA + PL + PT_BR + PT_PT + RO + RU + SK + SL + SR + SV + SW + TA + TE + TH + TR + UK + UR + VI + ZH + + diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 56db255896..2ce8e0c4ed 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1226,6 +1226,64 @@ Enabling this can unlock higher video qualities" Haptics are disabled Haptics are enabled + + Default audio stream language + Default + Original video language + App language + Arabic + Azerbaijani + Bulgarian + Bengali + Catalan + Czech + Danish + German + Greek + English + Spanish + Estonian + Persian + Finnish + French + Gujarati + Hindi + Croatian + Hungarian + Indonesian + Italian + Japanese + Kazakh + Korean + Lithuanian + Latvian + Macedonian + Mongolian + Marathi + Malay + Burmese + Dutch + Odia + Punjabi + Polish + Portuguese (Brazil) + Portuguese (Portugal) + Romanian + Russian + Slovak + Slovene + Serbian + Swedish + Swahili + Tamil + Telugu + Thai + Turkish + Ukrainian + Urdu + Vietnamese + Chinese + Auto @@ -1292,62 +1350,8 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi • Videos end 1 second early" Android VR spoofing side effects "• Kids videos may not play -• Livestreams start from the beginning -• Videos end 1 second early" - Default audio stream language - App language - Arabic - Azerbaijani - Bulgarian - Bengali - Catalan - Czech - Danish - German - Greek - English - Spanish - Estonian - Persian - Finnish - French - Gujarati - Hindi - Croatian - Hungarian - Indonesian - Italian - Japanese - Kazakh - Korean - Lithuanian - Latvian - Macedonian - Mongolian - Marathi - Malay - Burmese - Dutch - Odia - Punjabi - Polish - Portuguese (Brazil) - Portuguese (Portugal) - Romanian - Russian - Slovak - Slovene - Serbian - Swedish - Swahili - Tamil - Telugu - Thai - Turkish - Ukrainian - Urdu - Vietnamese - Chinese +• Audio track menu is missing +• Stable volume is not available" From 9f2062b5e2fccbadd5d6ad1875885e5509f8bf68 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:34:15 +0400 Subject: [PATCH 02/14] fix patching error on oldest versions --- .../misc/debugging/EnableDebuggingPatch.kt | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt index 9c0dc3e855..d2ef79a4f4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt @@ -110,22 +110,22 @@ val enableDebuggingPatch = bytecodePatch( """ ) } - } - experimentalStringFeatureFlagFingerprint.match( - experimentalFeatureFlagParentFingerprint.originalClassDef - ).method.apply { - val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT) + experimentalStringFeatureFlagFingerprint.match( + experimentalFeatureFlagParentFingerprint.originalClassDef + ).method.apply { + val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT) - addInstructions( - insertIndex, - """ - move-result-object v0 - invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String; - move-result-object v0 - return-object v0 - """ - ) + addInstructions( + insertIndex, + """ + move-result-object v0 + invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String; + move-result-object v0 + return-object v0 + """ + ) + } } // There exists other experimental accessor methods for byte[] From 41e053fb4556c0456dbef44d93fbfc611f2e088c Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:39:38 +0400 Subject: [PATCH 03/14] refactor: Save off override to a field. Logging is still spammy --- .../ChangeDefaultAudioLanguagePatch.java | 18 ++----- .../audio/ChangeDefaultAudioLanguagePatch.kt | 49 ++++++++++++++----- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java index eec276618e..a69a283c6a 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java @@ -22,33 +22,23 @@ public class ChangeDefaultAudioLanguagePatch { private static final Pattern AUDIO_TRACK_ID_PATTERN = Pattern.compile("^([a-z]{2})(-[A-Z]{2})?(\\.\\d+)"); - private static void printDebug(Logger.LogMessage message) { - // Do not log by default as it's spammy. - final boolean logAudioStreams = false; - - //noinspection ConstantConditions - if (logAudioStreams) { - Logger.printDebug(message); - } - } - /** * Injection point. */ - public static boolean setAudioStreamAsDefault(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { + public static boolean isAudioStreamAsDefault(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { try { AudioStreamLanguage defaultLanguage = Settings.AUDIO_DEFAULT_LANGUAGE.get(); if (defaultLanguage == AudioStreamLanguage.DEFAULT) { return isDefault; // Do nothing. } - printDebug(() -> "isDefault: " + isDefault + " audioTrackId: " + audioTrackId + Logger.printDebug(() -> "isDefault: " + String.format("%-5s", isDefault) + " audioTrackId: " + audioTrackId + " audioTrackDisplayName:" + audioTrackDisplayName); if (defaultLanguage == AudioStreamLanguage.ORIGINAL) { final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); if (isOriginal) { - printDebug(() -> "Using original audio language: " + audioTrackId); + Logger.printDebug(() -> "Using original audio language: " + audioTrackId); } return isOriginal; @@ -63,7 +53,7 @@ public static boolean setAudioStreamAsDefault(boolean isDefault, String audioTra String desiredIso639 = defaultLanguage.getIso639_1(); if (desiredIso639.equals(matcher.group(1)) || desiredIso639.equals(matcher.group(2))) { - printDebug(() -> "Using preferred audio language: " + audioTrackId); + Logger.printDebug(() -> "Using preferred audio language: " + audioTrackId); return true; } } catch (Exception ex) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt index 82e5391a1a..a7b45f87cb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt @@ -1,8 +1,10 @@ package app.revanced.patches.youtube.video.audio import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.all.misc.resources.addResources @@ -19,6 +21,7 @@ import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter @@ -82,9 +85,24 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( }).mutableClass formatStreamModelClass.apply { + // Add a new field to store the override, otherwise it's an + // extension call with regex parsing on every call. + val helperFieldName = "isDefaultAudioTrackOverride" + fields.add( + ImmutableField( + type, + helperFieldName, + "Ljava/lang/Boolean;", + AccessFlags.PRIVATE.value, + null, + null, + null + ).toMutable() + ) + // Add a helper method because the isDefaultAudioTrack() has only 2 registers and 3 are needed. val helperMethodClass = type - val helperMethodName = "extensions_isDefaultAudioTrack" + val helperMethodName = "extension_isDefaultAudioTrack" val helperMethod = ImmutableMethod( helperMethodClass, helperMethodName, @@ -93,25 +111,30 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( AccessFlags.PRIVATE.value, null, null, - MutableMethodImplementation(4), + MutableMethodImplementation(6), ).toMutable().apply { - // This is the equivalent of - // String featureName = feature.toString() - // - // return null - addInstructions( + addInstructionsWithLabels( 0, """ + iget-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean; + if-eqz v0, :call_extension + invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z + move-result v3 + return v3 + + :call_extension invoke-virtual { p0 }, $audioTrackIdMethod - move-result-object v0 + move-result-object v1 invoke-virtual { p0 }, $audioTrackDisplayNameMethod - move-result-object v1 + move-result-object v2 - invoke-static { p1, v0, v1 }, $EXTENSION_CLASS_DESCRIPTOR->setAudioStreamAsDefault(ZLjava/lang/String;Ljava/lang/String;)Z - move-result v0 - - return v0 + invoke-static { p1, v1, v2 }, $EXTENSION_CLASS_DESCRIPTOR->isAudioStreamAsDefault(ZLjava/lang/String;Ljava/lang/String;)Z + move-result v3 + invoke-static { v3 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean; + move-result-object v0 + iput-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean; + return v3 """ ) } From 098c113408383d0a2b0a5853eeec4fc41058fb75 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:49:27 +0400 Subject: [PATCH 04/14] fix: Handle empty audio streams --- .../patches/ChangeDefaultAudioLanguagePatch.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java index a69a283c6a..88330139f2 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java @@ -27,13 +27,19 @@ public class ChangeDefaultAudioLanguagePatch { */ public static boolean isAudioStreamAsDefault(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { try { + if (audioTrackId.isEmpty()) { + // Older app targets can have empty audio tracks and these might be placeholders. + // The real audio tracks are called after these. + return isDefault; + } + AudioStreamLanguage defaultLanguage = Settings.AUDIO_DEFAULT_LANGUAGE.get(); if (defaultLanguage == AudioStreamLanguage.DEFAULT) { return isDefault; // Do nothing. } - Logger.printDebug(() -> "isDefault: " + String.format("%-5s", isDefault) + " audioTrackId: " + audioTrackId - + " audioTrackDisplayName:" + audioTrackDisplayName); + Logger.printDebug(() -> "isDefault: " + String.format("%-5s", isDefault) + " audioTrackId: " + + audioTrackId + " audioTrackDisplayName:" + audioTrackDisplayName); if (defaultLanguage == AudioStreamLanguage.ORIGINAL) { final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); From fd16b2f274891b4d70b0c10afff8b2ac6fc8f252 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:56:21 +0400 Subject: [PATCH 05/14] fix: Method is called from multiple threads --- .../youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt index a7b45f87cb..0b19ada202 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt @@ -93,7 +93,11 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( type, helperFieldName, "Ljava/lang/Boolean;", - AccessFlags.PRIVATE.value, + // Boolean is a 100% immutable class (all fields are final) + // and safe to write to a shared field without volatile/synchronization, + // but without volatile the field can show stale data + // and it's calculated by more than one thread. + AccessFlags.PRIVATE.value or AccessFlags.VOLATILE.value, null, null, null From 240c597322a62586e5b8c6854c9156792240574b Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:12:42 +0400 Subject: [PATCH 06/14] refactor --- .../patches/ChangeDefaultAudioLanguagePatch.java | 12 ++++++------ .../video/audio/ChangeDefaultAudioLanguagePatch.kt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java index 88330139f2..bb223dfeee 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java @@ -20,7 +20,7 @@ public class ChangeDefaultAudioLanguagePatch { * it.10 */ private static final Pattern AUDIO_TRACK_ID_PATTERN = - Pattern.compile("^([a-z]{2})(-[A-Z]{2})?(\\.\\d+)"); + Pattern.compile("^([a-z]{2})(-[A-Z]{2})?.*"); /** * Injection point. @@ -38,13 +38,13 @@ public static boolean isAudioStreamAsDefault(boolean isDefault, String audioTrac return isDefault; // Do nothing. } - Logger.printDebug(() -> "isDefault: " + String.format("%-5s", isDefault) + " audioTrackId: " - + audioTrackId + " audioTrackDisplayName:" + audioTrackDisplayName); + Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: " + + String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName); if (defaultLanguage == AudioStreamLanguage.ORIGINAL) { final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); if (isOriginal) { - Logger.printDebug(() -> "Using original audio language: " + audioTrackId); + Logger.printDebug(() -> "Using audio: " + audioTrackId); } return isOriginal; @@ -59,11 +59,11 @@ public static boolean isAudioStreamAsDefault(boolean isDefault, String audioTrac String desiredIso639 = defaultLanguage.getIso639_1(); if (desiredIso639.equals(matcher.group(1)) || desiredIso639.equals(matcher.group(2))) { - Logger.printDebug(() -> "Using preferred audio language: " + audioTrackId); + Logger.printDebug(() -> "Using audio: " + audioTrackId); return true; } } catch (Exception ex) { - Logger.printException(() -> "setAudioStreamAsDefault failure", ex); + Logger.printException(() -> "isAudioStreamAsDefault failure", ex); } return isDefault; diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt index 0b19ada202..16e23eb400 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt @@ -96,7 +96,7 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( // Boolean is a 100% immutable class (all fields are final) // and safe to write to a shared field without volatile/synchronization, // but without volatile the field can show stale data - // and it's calculated by more than one thread. + // and the same field is calculated more than once by different threads. AccessFlags.PRIVATE.value or AccessFlags.VOLATILE.value, null, null, From 185add798ae7f9ccbe240dd37d4190402be62430 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:27:07 +0400 Subject: [PATCH 07/14] refactor --- .../extension/shared/spoof/requests/PlayerRoutes.java | 2 ++ .../youtube/patches/ChangeDefaultAudioLanguagePatch.java | 2 +- .../youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java index 80c4632e0e..bc49490d38 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java @@ -19,7 +19,9 @@ final class PlayerRoutes { "?fields=streamingData" + "&alt=proto" ).compile(); + private static final String YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/"; + /** * TCP connection and HTTP read timeout */ diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java index bb223dfeee..622e627421 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java @@ -25,7 +25,7 @@ public class ChangeDefaultAudioLanguagePatch { /** * Injection point. */ - public static boolean isAudioStreamAsDefault(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { + public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { try { if (audioTrackId.isEmpty()) { // Older app targets can have empty audio tracks and these might be placeholders. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt index 16e23eb400..57f7a2b7ff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt @@ -30,8 +30,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR = @Suppress("unused") val changeDefaultAudioLanguagePatch = bytecodePatch( - name = "Change default audio track", - description = "Adds an option to set a video default audio language .", + name = "Change default audio language", + description = "Adds an option to set a default audio language.", ) { dependsOn( sharedExtensionPatch, @@ -133,8 +133,9 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( invoke-virtual { p0 }, $audioTrackDisplayNameMethod move-result-object v2 - invoke-static { p1, v1, v2 }, $EXTENSION_CLASS_DESCRIPTOR->isAudioStreamAsDefault(ZLjava/lang/String;Ljava/lang/String;)Z + invoke-static { p1, v1, v2 }, $EXTENSION_CLASS_DESCRIPTOR->isDefaultAudioStream(ZLjava/lang/String;Ljava/lang/String;)Z move-result v3 + invoke-static { v3 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean; move-result-object v0 iput-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean; From 735d1caaf9e8926fd9423eed7001c47703f5c26f Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:29:52 +0400 Subject: [PATCH 08/14] refactor into DisableAutoAudioTracksPatch --- .../shared/settings/BaseSettings.java | 6 +- .../shared/spoof/AudioStreamLanguage.java | 5 - .../shared/spoof/SpoofVideoStreamsPatch.java | 5 +- .../shared/spoof/requests/PlayerRoutes.java | 6 +- .../ChangeDefaultAudioLanguagePatch.java | 71 ------ .../patches/DisableAutoAudioTracksPatch.java | 41 ++++ .../extension/youtube/settings/Settings.java | 3 +- .../ReVancedPreferenceFragment.java | 4 +- patches/api/patches.api | 4 +- .../misc/spoof/SpoofVideoStreamsPatch.kt | 4 + ...atch.kt => DisableAutoAudioTracksPatch.kt} | 17 +- .../resources/addresources/values/arrays.xml | 228 +++++++++--------- .../resources/addresources/values/strings.xml | 116 ++++----- 13 files changed, 237 insertions(+), 273 deletions(-) delete mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java create mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java rename patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/{ChangeDefaultAudioLanguagePatch.kt => DisableAutoAudioTracksPatch.kt} (92%) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 7072ea07af..ad1741d9d9 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -3,8 +3,9 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static app.revanced.extension.shared.settings.Setting.parent; -import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.ForceiOSAVCAvailability; +import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability; +import app.revanced.extension.shared.spoof.AudioStreamLanguage; import app.revanced.extension.shared.spoof.ClientType; /** @@ -21,8 +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 SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, new SpoofiOSAvailability()); 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 ForceiOSAVCAvailability()); + "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability()); public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS)); } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java index c5455ae4c5..bce49c0a05 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java @@ -8,11 +8,6 @@ public enum AudioStreamLanguage { */ DEFAULT, - /** - * Original language of the video. - */ - ORIGINAL, - /** * Current language the app is set to. */ diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java index 4016c8ef99..9e61eca990 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java @@ -165,10 +165,11 @@ public static byte[] removeVideoPlaybackPostBody(Uri uri, int method, byte[] pos return postData; } - public static final class ForceiOSAVCAvailability implements Setting.Availability { + public static final class SpoofiOSAvailability implements Setting.Availability { @Override public boolean isAvailable() { - return BaseSettings.SPOOF_VIDEO_STREAMS.get() && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS; + return BaseSettings.SPOOF_VIDEO_STREAMS.get() + && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS; } } } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java index bc49490d38..9832a08a7f 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java @@ -5,11 +5,11 @@ import java.io.IOException; import java.net.HttpURLConnection; -import java.util.Locale; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.requests.Requester; import app.revanced.extension.shared.requests.Route; +import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.spoof.ClientType; final class PlayerRoutes { @@ -37,9 +37,7 @@ static String createInnertubeBody(ClientType clientType) { JSONObject context = new JSONObject(); JSONObject client = new JSONObject(); - // Changing the app language does not force the app to completely restart, - // so the default needs to be the current language and not a static field. - client.put("hl", Locale.getDefault().toLanguageTag()); + 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); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java deleted file mode 100644 index 622e627421..0000000000 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch.java +++ /dev/null @@ -1,71 +0,0 @@ -package app.revanced.extension.youtube.patches; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import app.revanced.extension.shared.Logger; -import app.revanced.extension.shared.spoof.AudioStreamLanguage; -import app.revanced.extension.youtube.settings.Settings; - -@SuppressWarnings("unused") -public class ChangeDefaultAudioLanguagePatch { - - private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original"; - - /** - * Audio track identifier. - * - * Examples: - * fr-FR.10 - * it.10 - */ - private static final Pattern AUDIO_TRACK_ID_PATTERN = - Pattern.compile("^([a-z]{2})(-[A-Z]{2})?.*"); - - /** - * Injection point. - */ - public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { - try { - if (audioTrackId.isEmpty()) { - // Older app targets can have empty audio tracks and these might be placeholders. - // The real audio tracks are called after these. - return isDefault; - } - - AudioStreamLanguage defaultLanguage = Settings.AUDIO_DEFAULT_LANGUAGE.get(); - if (defaultLanguage == AudioStreamLanguage.DEFAULT) { - return isDefault; // Do nothing. - } - - Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: " - + String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName); - - if (defaultLanguage == AudioStreamLanguage.ORIGINAL) { - final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); - if (isOriginal) { - Logger.printDebug(() -> "Using audio: " + audioTrackId); - } - - return isOriginal; - } - - Matcher matcher = AUDIO_TRACK_ID_PATTERN.matcher(audioTrackId); - if (!matcher.matches()) { - Logger.printException(() -> "Cannot set default audio, unknown track: " + audioTrackId); - return isDefault; - } - - String desiredIso639 = defaultLanguage.getIso639_1(); - if (desiredIso639.equals(matcher.group(1)) - || desiredIso639.equals(matcher.group(2))) { - Logger.printDebug(() -> "Using audio: " + audioTrackId); - return true; - } - } catch (Exception ex) { - Logger.printException(() -> "isAudioStreamAsDefault failure", ex); - } - - return isDefault; - } -} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java new file mode 100644 index 0000000000..43469fd6b2 --- /dev/null +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java @@ -0,0 +1,41 @@ +package app.revanced.extension.youtube.patches; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class DisableAutoAudioTracksPatch { + + private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original"; + + /** + * Injection point. + */ + public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { + try { + if (!Settings.DISABLE_AUTO_AUDIO_TRACKS.get()) { + return isDefault; + } + + if (audioTrackDisplayName.isEmpty()) { + // Older app targets can have empty audio tracks and these might be placeholders. + // The real audio tracks are called after these. + return isDefault; + } + + Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: " + + String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName); + + final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER); + if (isOriginal) { + Logger.printDebug(() -> "Using audio: " + audioTrackId); + } + + return isOriginal; + } catch (Exception ex) { + Logger.printException(() -> "isDefaultAudioStream failure", ex); + } + + return isDefault; + } +} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 1bc1ddea04..73179027e3 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -34,7 +34,6 @@ import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.settings.preference.SharedPrefCategory; -import app.revanced.extension.shared.spoof.AudioStreamLanguage; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption; @@ -54,7 +53,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 EnumSetting AUDIO_DEFAULT_LANGUAGE = new EnumSetting<>("revanced_audio_default_language", AudioStreamLanguage.DEFAULT); + public static final BooleanSetting DISABLE_AUTO_AUDIO_TRACKS = new BooleanSetting("revanced_disable_auto_audio_tracks", TRUE); // Ads public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 24bb9d1315..7be29bd3e4 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -109,9 +109,9 @@ protected void initialize() { CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference); } - preference = findPreference(Settings.AUDIO_DEFAULT_LANGUAGE.key); + preference = findPreference(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE.key); if (preference instanceof ListPreference languagePreference) { - sortListPreferenceByValues(languagePreference, 3); + sortListPreferenceByValues(languagePreference, 2); } } catch (Exception ex) { Logger.printException(() -> "initialize failure", ex); diff --git a/patches/api/patches.api b/patches/api/patches.api index 21c40715d5..2fc61a12dd 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1392,8 +1392,8 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt { public static final fun getRollingNumberTextViewAnimationUpdateFingerprint ()Lapp/revanced/patcher/Fingerprint; } -public final class app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatchKt { - public static final fun getChangeDefaultAudioLanguagePatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatchKt { + public static final fun getDisableAutoAudioTracksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt index a9c945f754..45bdfc0c89 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt @@ -40,6 +40,10 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({ "revanced_spoof_video_streams_client", 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( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt similarity index 92% rename from patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt rename to patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt index 57f7a2b7ff..455b925fda 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ChangeDefaultAudioLanguagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt @@ -9,7 +9,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.ListPreference +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch @@ -26,12 +26,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter private const val EXTENSION_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/ChangeDefaultAudioLanguagePatch;" + "Lapp/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch;" @Suppress("unused") -val changeDefaultAudioLanguagePatch = bytecodePatch( - name = "Change default audio language", - description = "Adds an option to set a default audio language.", +val disableAutoAudioTracksPatch = bytecodePatch( + name = "Disable auto audio tracks", + description = "Adds an option to disable audio tracks from being automatically enabled.", ) { dependsOn( sharedExtensionPatch, @@ -53,13 +53,10 @@ val changeDefaultAudioLanguagePatch = bytecodePatch( ) execute { - addResources("youtube", "video.audio.changeDefaultAudioTrackPatch") + addResources("youtube", "video.audio.disableAutoAudioTracksPatch") PreferenceScreen.VIDEO.addPreferences( - ListPreference( - "revanced_audio_default_language", - summaryKey = null - ) + SwitchPreference("revanced_disable_auto_audio_tracks") ) fun Method.firstFormatStreamingModelCall( diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index ef86eae874..5ac5a6124d 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -11,6 +11,118 @@ ANDROID_VR IOS + + @string/revanced_spoof_video_streams_language_DEFAULT + @string/revanced_spoof_video_streams_language_APP_LANGUAGE + @string/revanced_spoof_video_streams_language_AR + @string/revanced_spoof_video_streams_language_AZ + @string/revanced_spoof_video_streams_language_BG + @string/revanced_spoof_video_streams_language_BN + @string/revanced_spoof_video_streams_language_CA + @string/revanced_spoof_video_streams_language_CS + @string/revanced_spoof_video_streams_language_DA + @string/revanced_spoof_video_streams_language_DE + @string/revanced_spoof_video_streams_language_EL + @string/revanced_spoof_video_streams_language_EN + @string/revanced_spoof_video_streams_language_ES + @string/revanced_spoof_video_streams_language_ET + @string/revanced_spoof_video_streams_language_FA + @string/revanced_spoof_video_streams_language_FI + @string/revanced_spoof_video_streams_language_FR + @string/revanced_spoof_video_streams_language_GU + @string/revanced_spoof_video_streams_language_HI + @string/revanced_spoof_video_streams_language_HR + @string/revanced_spoof_video_streams_language_HU + @string/revanced_spoof_video_streams_language_ID + @string/revanced_spoof_video_streams_language_IT + @string/revanced_spoof_video_streams_language_JA + @string/revanced_spoof_video_streams_language_KK + @string/revanced_spoof_video_streams_language_KO + @string/revanced_spoof_video_streams_language_LT + @string/revanced_spoof_video_streams_language_LV + @string/revanced_spoof_video_streams_language_MK + @string/revanced_spoof_video_streams_language_MN + @string/revanced_spoof_video_streams_language_MR + @string/revanced_spoof_video_streams_language_MS + @string/revanced_spoof_video_streams_language_MY + @string/revanced_spoof_video_streams_language_NL + @string/revanced_spoof_video_streams_language_OR + @string/revanced_spoof_video_streams_language_PA + @string/revanced_spoof_video_streams_language_PL + @string/revanced_spoof_video_streams_language_PT_BR + @string/revanced_spoof_video_streams_language_PT_PT + @string/revanced_spoof_video_streams_language_RO + @string/revanced_spoof_video_streams_language_RU + @string/revanced_spoof_video_streams_language_SK + @string/revanced_spoof_video_streams_language_SL + @string/revanced_spoof_video_streams_language_SR + @string/revanced_spoof_video_streams_language_SV + @string/revanced_spoof_video_streams_language_SW + @string/revanced_spoof_video_streams_language_TA + @string/revanced_spoof_video_streams_language_TE + @string/revanced_spoof_video_streams_language_TH + @string/revanced_spoof_video_streams_language_TR + @string/revanced_spoof_video_streams_language_UK + @string/revanced_spoof_video_streams_language_UR + @string/revanced_spoof_video_streams_language_VI + @string/revanced_spoof_video_streams_language_ZH + + + DEFAULT + APP_LANGUAGE + AR + AZ + BG + BN + CA + CS + DA + DE + EL + EN + ES + ET + FA + FI + FR + GU + HI + HR + HU + ID + IT + JA + KK + KO + LT + LV + MK + MN + MR + MS + MY + NL + OR + PA + PL + PT_BR + PT_PT + RO + RU + SK + SL + SR + SV + SW + TA + TE + TH + TR + UK + UR + VI + ZH + @@ -160,122 +272,6 @@ 144 - - - @string/revanced_audio_default_language_DEFAULT - @string/revanced_audio_default_language_ORIGINAL - @string/revanced_audio_default_language_APP_LANGUAGE - @string/revanced_audio_default_language_AR - @string/revanced_audio_default_language_AZ - @string/revanced_audio_default_language_BG - @string/revanced_audio_default_language_BN - @string/revanced_audio_default_language_CA - @string/revanced_audio_default_language_CS - @string/revanced_audio_default_language_DA - @string/revanced_audio_default_language_DE - @string/revanced_audio_default_language_EL - @string/revanced_audio_default_language_EN - @string/revanced_audio_default_language_ES - @string/revanced_audio_default_language_ET - @string/revanced_audio_default_language_FA - @string/revanced_audio_default_language_FI - @string/revanced_audio_default_language_FR - @string/revanced_audio_default_language_GU - @string/revanced_audio_default_language_HI - @string/revanced_audio_default_language_HR - @string/revanced_audio_default_language_HU - @string/revanced_audio_default_language_ID - @string/revanced_audio_default_language_IT - @string/revanced_audio_default_language_JA - @string/revanced_audio_default_language_KK - @string/revanced_audio_default_language_KO - @string/revanced_audio_default_language_LT - @string/revanced_audio_default_language_LV - @string/revanced_audio_default_language_MK - @string/revanced_audio_default_language_MN - @string/revanced_audio_default_language_MR - @string/revanced_audio_default_language_MS - @string/revanced_audio_default_language_MY - @string/revanced_audio_default_language_NL - @string/revanced_audio_default_language_OR - @string/revanced_audio_default_language_PA - @string/revanced_audio_default_language_PL - @string/revanced_audio_default_language_PT_BR - @string/revanced_audio_default_language_PT_PT - @string/revanced_audio_default_language_RO - @string/revanced_audio_default_language_RU - @string/revanced_audio_default_language_SK - @string/revanced_audio_default_language_SL - @string/revanced_audio_default_language_SR - @string/revanced_audio_default_language_SV - @string/revanced_audio_default_language_SW - @string/revanced_audio_default_language_TA - @string/revanced_audio_default_language_TE - @string/revanced_audio_default_language_TH - @string/revanced_audio_default_language_TR - @string/revanced_audio_default_language_UK - @string/revanced_audio_default_language_UR - @string/revanced_audio_default_language_VI - @string/revanced_audio_default_language_ZH - - - DEFAULT - ORIGINAL - APP_LANGUAGE - AR - AZ - BG - BN - CA - CS - DA - DE - EL - EN - ES - ET - FA - FI - FR - GU - HI - HR - HU - ID - IT - JA - KK - KO - LT - LV - MK - MN - MR - MS - MY - NL - OR - PA - PL - PT_BR - PT_PT - RO - RU - SK - SL - SR - SV - SW - TA - TE - TH - TR - UK - UR - VI - ZH - - diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 2ce8e0c4ed..a099b4fb45 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1226,63 +1226,10 @@ Enabling this can unlock higher video qualities" Haptics are disabled Haptics are enabled - - Default audio stream language - Default - Original video language - App language - Arabic - Azerbaijani - Bulgarian - Bengali - Catalan - Czech - Danish - German - Greek - English - Spanish - Estonian - Persian - Finnish - French - Gujarati - Hindi - Croatian - Hungarian - Indonesian - Italian - Japanese - Kazakh - Korean - Lithuanian - Latvian - Macedonian - Mongolian - Marathi - Malay - Burmese - Dutch - Odia - Punjabi - Polish - Portuguese (Brazil) - Portuguese (Portugal) - Romanian - Russian - Slovak - Slovene - Serbian - Swedish - Swahili - Tamil - Telugu - Thai - Turkish - Ukrainian - Urdu - Vietnamese - Chinese + + Disable forced auto audio tracks + Forced auto audio track are disabled + Forced auto audio tracks are not disabled @@ -1352,6 +1299,61 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi "• Kids videos may not play • Audio track menu is missing • Stable volume is not available" + Default audio stream language + Default + App language + Arabic + Azerbaijani + Bulgarian + Bengali + Catalan + Czech + Danish + German + Greek + English + Spanish + Estonian + Persian + Finnish + French + Gujarati + Hindi + Croatian + Hungarian + Indonesian + Italian + Japanese + Kazakh + Korean + Lithuanian + Latvian + Macedonian + Mongolian + Marathi + Malay + Burmese + Dutch + Odia + Punjabi + Polish + Portuguese (Brazil) + Portuguese (Portugal) + Romanian + Russian + Slovak + Slovene + Serbian + Swedish + Swahili + Tamil + Telugu + Thai + Turkish + Ukrainian + Urdu + Vietnamese + Chinese From 362cc53173d5b978c3b55c6529f4092b599cf92d Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:48:19 +0400 Subject: [PATCH 09/14] fix: Only set language code for iOS --- .../extension/shared/spoof/ClientType.java | 16 ++++++++++++---- .../shared/spoof/requests/PlayerRoutes.java | 4 +++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java index 032d420ec4..b29dce4318 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java @@ -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 - ), + true, + false), // Specific for kids videos. IOS(5, "IOS", @@ -39,7 +39,8 @@ public enum ClientType { // but 17.40 is the last version that supports iOS 13. ? "17.40.5" : "19.47.7", - false + false, + true ); private static boolean forceAVC() { @@ -86,6 +87,11 @@ 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, @@ -93,7 +99,8 @@ private static boolean forceAVC() { String userAgent, @Nullable String androidSdkVersion, String clientVersion, - boolean canLogin) { + boolean canLogin, + boolean useLanguageCode) { this.id = id; this.clientName = clientName; this.deviceModel = deviceModel; @@ -102,5 +109,6 @@ private static boolean forceAVC() { this.androidSdkVersion = androidSdkVersion; this.clientVersion = clientVersion; this.canLogin = canLogin; + this.useLanguageCode = useLanguageCode; } } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java index 9832a08a7f..5da5628e0b 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java @@ -37,7 +37,9 @@ static String createInnertubeBody(ClientType clientType) { JSONObject context = new JSONObject(); JSONObject client = new JSONObject(); - client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1()); + if (clientType.useLanguageCode) { + 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); From 0a9939da2428798523c154d565adc7939dae254d Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 11:11:48 +0400 Subject: [PATCH 10/14] refactor --- .../extension/shared/spoof/AudioStreamLanguage.java | 9 +++------ .../settings/preference/ReVancedPreferenceFragment.java | 2 +- .../src/main/resources/addresources/values/arrays.xml | 2 -- .../src/main/resources/addresources/values/strings.xml | 1 - 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java index bce49c0a05..566b2379f4 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/AudioStreamLanguage.java @@ -4,15 +4,12 @@ public enum AudioStreamLanguage { /** - * Change nothing, same as unpatched. + * YouTube default. + * Can be the original language or can be app language, + * depending on what YouTube decides to pick as the default. */ DEFAULT, - /** - * Current language the app is set to. - */ - APP_LANGUAGE, - // Language codes found in locale_config.xml // Region specific variants of Chinese/English/Spanish/French have been removed. AF, diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 7be29bd3e4..6511fc00ce 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -111,7 +111,7 @@ protected void initialize() { preference = findPreference(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE.key); if (preference instanceof ListPreference languagePreference) { - sortListPreferenceByValues(languagePreference, 2); + sortListPreferenceByValues(languagePreference, 1); } } catch (Exception ex) { Logger.printException(() -> "initialize failure", ex); diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 5ac5a6124d..c600e86b7e 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -13,7 +13,6 @@ @string/revanced_spoof_video_streams_language_DEFAULT - @string/revanced_spoof_video_streams_language_APP_LANGUAGE @string/revanced_spoof_video_streams_language_AR @string/revanced_spoof_video_streams_language_AZ @string/revanced_spoof_video_streams_language_BG @@ -69,7 +68,6 @@ DEFAULT - APP_LANGUAGE AR AZ BG diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index a099b4fb45..8291fed009 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1301,7 +1301,6 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi • Stable volume is not available" Default audio stream language Default - App language Arabic Azerbaijani Bulgarian From 3fe216ce4c6e822e6f07b5237dcc4ecb4b7a3a2d Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 11:12:04 +0400 Subject: [PATCH 11/14] Use default off --- .../java/app/revanced/extension/youtube/settings/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 73179027e3..0c0eaf1522 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -53,7 +53,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 DISABLE_AUTO_AUDIO_TRACKS = new BooleanSetting("revanced_disable_auto_audio_tracks", TRUE); + public static final BooleanSetting DISABLE_AUTO_AUDIO_TRACKS = new BooleanSetting("revanced_disable_auto_audio_tracks", FALSE); // Ads public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE); From 13bac08fa72bb463a2596fcf7b8173784084f4c8 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 11:17:18 +0400 Subject: [PATCH 12/14] comments --- .../patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt index 455b925fda..1029d0e335 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt @@ -82,8 +82,7 @@ val disableAutoAudioTracksPatch = bytecodePatch( }).mutableClass formatStreamModelClass.apply { - // Add a new field to store the override, otherwise it's an - // extension call with regex parsing on every call. + // Add a new field to store the override. val helperFieldName = "isDefaultAudioTrackOverride" fields.add( ImmutableField( From aae72297e7b0a43e69f3ae616b4464987dd19ef1 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:41:26 +0400 Subject: [PATCH 13/14] Adjust settings text --- patches/src/main/resources/addresources/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 8291fed009..bb2534b26b 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1300,7 +1300,7 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi • Audio track menu is missing • Stable volume is not available" Default audio stream language - Default + App language Arabic Azerbaijani Bulgarian From b9a02e6c1af55b95d582ffa1045eb7d947ea0c37 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 15 Dec 2024 16:49:57 +0400 Subject: [PATCH 14/14] Rename patch --- ...TracksPatch.java => ForceOriginalAudioPatch.java} | 4 ++-- .../extension/youtube/settings/Settings.java | 2 +- patches/api/patches.api | 4 ++-- ...udioTracksPatch.kt => ForceOriginalAudioPatch.kt} | 12 ++++++------ .../main/resources/addresources/values/strings.xml | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) rename extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/{DisableAutoAudioTracksPatch.java => ForceOriginalAudioPatch.java} (92%) rename patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/{DisableAutoAudioTracksPatch.kt => ForceOriginalAudioPatch.kt} (94%) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java similarity index 92% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java rename to extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java index 43469fd6b2..4a34eb3cd6 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java @@ -4,7 +4,7 @@ import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") -public class DisableAutoAudioTracksPatch { +public class ForceOriginalAudioPatch { private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original"; @@ -13,7 +13,7 @@ public class DisableAutoAudioTracksPatch { */ public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) { try { - if (!Settings.DISABLE_AUTO_AUDIO_TRACKS.get()) { + if (!Settings.FORCE_ORIGINAL_AUDIO.get()) { return isDefault; } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 0c0eaf1522..eaad85188c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -53,7 +53,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 DISABLE_AUTO_AUDIO_TRACKS = new BooleanSetting("revanced_disable_auto_audio_tracks", FALSE); + public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE); // Ads public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE); diff --git a/patches/api/patches.api b/patches/api/patches.api index 2fc61a12dd..53a61711ca 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1392,8 +1392,8 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt { public static final fun getRollingNumberTextViewAnimationUpdateFingerprint ()Lapp/revanced/patcher/Fingerprint; } -public final class app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatchKt { - public static final fun getDisableAutoAudioTracksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatchKt { + public static final fun getForceOriginalAudioPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt similarity index 94% rename from patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt index 1029d0e335..94a80d908d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/DisableAutoAudioTracksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt @@ -26,12 +26,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter private const val EXTENSION_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/DisableAutoAudioTracksPatch;" + "Lapp/revanced/extension/youtube/patches/ForceOriginalAudioPatch;" @Suppress("unused") -val disableAutoAudioTracksPatch = bytecodePatch( - name = "Disable auto audio tracks", - description = "Adds an option to disable audio tracks from being automatically enabled.", +val forceOriginalAudioPatch = bytecodePatch( + name = "Force original audio", + description = "Adds an option to always use the original audio track.", ) { dependsOn( sharedExtensionPatch, @@ -53,10 +53,10 @@ val disableAutoAudioTracksPatch = bytecodePatch( ) execute { - addResources("youtube", "video.audio.disableAutoAudioTracksPatch") + addResources("youtube", "video.audio.forceOriginalAudioPatch") PreferenceScreen.VIDEO.addPreferences( - SwitchPreference("revanced_disable_auto_audio_tracks") + SwitchPreference("revanced_force_original_audio") ) fun Method.firstFormatStreamingModelCall( diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index bb2534b26b..7f8cab4cf2 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1226,10 +1226,10 @@ Enabling this can unlock higher video qualities" Haptics are disabled Haptics are enabled - - Disable forced auto audio tracks - Forced auto audio track are disabled - Forced auto audio tracks are not disabled + + Forced original audio + Using original audio + Using default audio