From fa04c8eecfbdd0b6ed082b464ca9032536d71762 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:43:04 +0400 Subject: [PATCH 01/11] fix(YouTube Music - Spoof video streams): Fix playback issues when using a cellular network Code adapted from https://github.com/inotia00/revanced-patches/commit/5f35e51a2779f71f27c3f9be62fbe83b7bc9cfe7 --- .../shared/spoof/SpoofVideoStreamsPatch.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) 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 0980f816f..a23814056 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,10 +22,19 @@ public class SpoofVideoStreamsPatch { && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED; /** - * Any unreachable ip address. Used to intentionally fail requests. + * Domain used for internet connectivity verification. + * It has an empty response body and is only used to check for a 204 response code. + *

+ * If an unreachable IP address (127.0.0.1) is used, no response code is provided. + *

+ * YouTube handles unreachable IP addresses without issue. + * YouTube Music has an issue with waiting for the Cronet connect timeout of 30s on mobile networks. + *

+ * Using a VPN or DNS can temporarily resolve this issue, + * But the ideal workaround is to avoid using an unreachable IP address. */ - 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); + private static final String INTERNET_CONNECTION_CHECK_URI_STRING = "https://www.google.com/gen_204"; + private static final Uri INTERNET_CONNECTION_CHECK_URI = Uri.parse(INTERNET_CONNECTION_CHECK_URI_STRING); /** * @return If this patch was included during patching. @@ -53,9 +62,9 @@ public class SpoofVideoStreamsPatch { String path = playerRequestUri.getPath(); if (path != null && path.contains("get_watch")) { - Logger.printDebug(() -> "Blocking 'get_watch' by returning unreachable uri"); + Logger.printDebug(() -> "Blocking 'get_watch' by returning internet connection check uri"); - return UNREACHABLE_HOST_URI; + return INTERNET_CONNECTION_CHECK_URI; } } catch (Exception ex) { Logger.printException(() -> "blockGetWatchRequest failure", ex); @@ -77,9 +86,9 @@ public class SpoofVideoStreamsPatch { String path = originalUri.getPath(); if (path != null && path.contains("initplayback")) { - Logger.printDebug(() -> "Blocking 'initplayback' by clearing query"); + Logger.printDebug(() -> "Blocking 'initplayback' by returning internet connection check uri"); - return originalUri.buildUpon().clearQuery().build().toString(); + return INTERNET_CONNECTION_CHECK_URI_STRING; } } catch (Exception ex) { Logger.printException(() -> "blockInitPlaybackRequest failure", ex); From 3d25da18bcc844277e1b58b6e40a53901ce33313 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 Sep 2025 12:47:02 +0000 Subject: [PATCH 02/11] chore: Release v5.37.1-dev.1 [skip ci] ## [5.37.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.37.1-dev.1) (2025-09-15) ### Bug Fixes * **YouTube Music - Spoof video streams:** Fix playback issues when using a cellular network ([fa04c8e](https://github.com/ReVanced/revanced-patches/commit/fa04c8eecfbdd0b6ed082b464ca9032536d71762)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26dbf50b4..1596cd929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.37.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.37.1-dev.1) (2025-09-15) + + +### Bug Fixes + +* **YouTube Music - Spoof video streams:** Fix playback issues when using a cellular network ([fa04c8e](https://github.com/ReVanced/revanced-patches/commit/fa04c8eecfbdd0b6ed082b464ca9032536d71762)) + # [5.37.0](https://github.com/ReVanced/revanced-patches/compare/v5.36.0...v5.37.0) (2025-09-15) diff --git a/gradle.properties b/gradle.properties index 960166d4e..a422466ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.37.0 +version = 5.37.1-dev.1 From f11d1ef9907082512f139d4ab0e2e9f707de7e48 Mon Sep 17 00:00:00 2001 From: brosssh <44944126+brosssh@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:48:55 +0200 Subject: [PATCH 03/11] fix(Instagram - Hide navigation buttons): Support v397.1.0.52.81 (#5855) --- .../revanced/patches/instagram/hide/navigation/Fingerprints.kt | 2 +- .../patches/instagram/hide/navigation/HideNavigationButtons.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt index 3b401a842..07933f70f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt @@ -23,7 +23,7 @@ internal val tabCreateButtonsLoopEndFingerprint = fingerprint { Opcode.IPUT_OBJECT, // Injection Jump Opcode.ADD_INT_LIT8, //Increase Index - Opcode.GOTO_16 // Jump to loopStart + Opcode.GOTO // Jump to loopStart // LoopEnd ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt index edca83e45..ee68c4fe1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt @@ -15,7 +15,7 @@ val hideNavigationButtonsPatch = bytecodePatch( description = "Hides navigation bar buttons, such as the Reels and Create button.", use = false ) { - compatibleWith("com.instagram.android"("396.0.0.46.242")) + compatibleWith("com.instagram.android"("397.1.0.52.81")) val hideReels by booleanOption( key = "hideReels", From cb6d802de35622e9b67b5cc2785c15224c08a2f5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 Sep 2025 12:52:54 +0000 Subject: [PATCH 04/11] chore: Release v5.37.1-dev.2 [skip ci] ## [5.37.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.1...v5.37.1-dev.2) (2025-09-15) ### Bug Fixes * **Instagram - Hide navigation buttons:** Support v397.1.0.52.81 ([#5855](https://github.com/ReVanced/revanced-patches/issues/5855)) ([f11d1ef](https://github.com/ReVanced/revanced-patches/commit/f11d1ef9907082512f139d4ab0e2e9f707de7e48)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1596cd929..eca82588a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.37.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.1...v5.37.1-dev.2) (2025-09-15) + + +### Bug Fixes + +* **Instagram - Hide navigation buttons:** Support v397.1.0.52.81 ([#5855](https://github.com/ReVanced/revanced-patches/issues/5855)) ([f11d1ef](https://github.com/ReVanced/revanced-patches/commit/f11d1ef9907082512f139d4ab0e2e9f707de7e48)) + ## [5.37.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.37.1-dev.1) (2025-09-15) diff --git a/gradle.properties b/gradle.properties index a422466ba..f988675ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.37.1-dev.1 +version = 5.37.1-dev.2 From abe3943f98fd86dcd74c7e07cf65d3c7fc24fef9 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Mon, 15 Sep 2025 20:58:56 +0400 Subject: [PATCH 05/11] fix(Spoof video streams): Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for `Force original audio` to work with any spoof client (#5861) --- .../patches/spoof/SpoofVideoStreamsPatch.java | 8 +- .../shared/settings/BaseSettings.java | 3 - .../extension/shared/spoof/ClientType.java | 186 ++++++++---------- .../shared/spoof/SpoofVideoStreamsPatch.java | 38 ++-- .../shared/spoof/requests/PlayerRoutes.java | 23 ++- .../spoof/requests/StreamingDataRequest.java | 11 +- .../patches/ForceOriginalAudioPatch.java | 24 ++- .../PlayerFlyoutMenuItemsFilter.java | 4 +- .../patches/spoof/SpoofVideoStreamsPatch.java | 15 +- .../extension/youtube/settings/Settings.java | 3 +- .../ForceOriginalAudioSwitchPreference.java | 36 ---- .../HideAudioFlyoutMenuPreference.java | 4 +- ...oofStreamingDataSideEffectsPreference.java | 22 +-- .../interaction/downloads/DownloadsPatch.kt | 2 +- .../youtube/layout/seekbar/Fingerprints.kt | 3 +- .../shortsautoplay/ShortsAutoplayPatch.kt | 2 +- .../OpenShortsInRegularPlayerPatch.kt | 4 +- .../youtube/layout/theme/Fingerprints.kt | 3 +- .../misc/announcements/AnnouncementsPatch.kt | 4 +- ...ckWatchHistoryDomainNameResolutionPatch.kt | 7 +- .../misc/extension/SharedExtensionPatch.kt | 3 +- .../extension/hooks/ApplicationInitHook.kt | 12 ++ .../misc/navigation/NavigationBarHookPatch.kt | 3 +- .../misc/spoof/SpoofVideoStreamsPatch.kt | 7 +- .../patches/youtube/shared/Fingerprints.kt | 8 +- .../video/audio/ForceOriginalAudioPatch.kt | 12 +- .../resources/addresources/values/arrays.xml | 6 +- .../resources/addresources/values/strings.xml | 23 +-- 28 files changed, 223 insertions(+), 253 deletions(-) delete mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch.java index 5c60437b5..f6d248715 100644 --- a/extensions/music/src/main/java/app/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch.java +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch.java @@ -2,6 +2,9 @@ package app.revanced.extension.music.patches.spoof; import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32; import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48; +import static app.revanced.extension.shared.spoof.ClientType.VISIONOS; + +import java.util.List; import app.revanced.extension.shared.spoof.ClientType; import app.revanced.extension.shared.spoof.requests.StreamingDataRequest; @@ -13,10 +16,11 @@ public class SpoofVideoStreamsPatch { * Injection point. */ public static void setClientOrderToUse() { - ClientType[] availableClients = { + List availableClients = List.of( ANDROID_VR_1_43_32, ANDROID_VR_1_61_48, - }; + VISIONOS + ); StreamingDataRequest.setClientOrderToUse(availableClients, ANDROID_VR_1_43_32); } 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 e2c70f616..2cb08ff90 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 @@ -4,7 +4,6 @@ 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.AudioStreamLanguageOverrideAvailability; -import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability; import app.revanced.extension.shared.spoof.ClientType; @@ -31,8 +30,6 @@ public class BaseSettings { 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", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability()); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS)); - public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true, - "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability()); // Client type must be last spoof setting due to cyclic references. public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_61_48, true, parent(SPOOF_VIDEO_STREAMS)); } 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 cc80cb924..d29b293ff 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 @@ -2,15 +2,19 @@ package app.revanced.extension.shared.spoof; import android.os.Build; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Locale; import java.util.Objects; import app.revanced.extension.shared.Logger; -import app.revanced.extension.shared.settings.BaseSettings; public enum ClientType { + /** + * Video not playable: Kids / Paid / Movie / Private / Age-restricted. + * This client can only be used when logged out. + */ // https://dumps.tadiphone.dev/dumps/oculus/eureka ANDROID_VR_1_61_48( 28, @@ -29,27 +33,30 @@ public enum ClientType { false, "Android VR 1.61" ), - // Chromecast with Google TV 4K. - // https://dumps.tadiphone.dev/dumps/google/kirkwood - ANDROID_UNPLUGGED( - 29, - "ANDROID_UNPLUGGED", - "com.google.android.apps.youtube.unplugged", - "Google", - "Google TV Streamer", - "Android", - "14", - "34", - "UTT3.240625.001.K5", - "132.0.6808.3", - "8.49.0", - true, - true, - "Android TV" + /** + * Uses non adaptive bitrate, which fixes audio stuttering with YT Music. + * Does not use AV1. + */ + ANDROID_VR_1_43_32( + ANDROID_VR_1_61_48.id, + ANDROID_VR_1_61_48.clientName, + Objects.requireNonNull(ANDROID_VR_1_61_48.packageName), + ANDROID_VR_1_61_48.deviceMake, + ANDROID_VR_1_61_48.deviceModel, + ANDROID_VR_1_61_48.osName, + ANDROID_VR_1_61_48.osVersion, + Objects.requireNonNull(ANDROID_VR_1_61_48.androidSdkVersion), + Objects.requireNonNull(ANDROID_VR_1_61_48.buildId), + "107.0.5284.2", + "1.43.32", + ANDROID_VR_1_61_48.requiresAuth, + ANDROID_VR_1_61_48.useAuth, + "Android VR 1.43" ), - // Cannot play livestreams and lacks HDR, but can play videos with music and labeled "for children". - // Google Pixel 9 Pro Fold - // https://dumps.tadiphone.dev/dumps/google/barbet + /** + * Cannot play livestreams and lacks HDR, but can play videos with music and labeled "for children". + * Google Pixel 9 Pro Fold + */ ANDROID_CREATOR( 14, "ANDROID_CREATOR", @@ -66,62 +73,22 @@ public enum ClientType { true, "Android Creator" ), - IOS_UNPLUGGED( - 33, - "IOS_UNPLUGGED", - "com.google.ios.youtubeunplugged", - "Apple", - forceAVC() - // 11 Pro Max (last device with iOS 13) - ? "iPhone12,5" - // 15 Pro Max - : "iPhone16,2", - "iOS", - forceAVC() - // iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1. - ? "13.7.17H35" - : "18.2.22C152", - null, - null, - null, - // Version number should be a valid iOS release. - // https://www.ipa4fun.com/history/152043/ - forceAVC() - // Some newer versions can also force AVC, - // but 6.45 is the last version that supports iOS 13. - ? "6.45" - : "8.49", - true, - true, - forceAVC() - ? "iOS TV Force AVC" - : "iOS TV" - ), /** - * Uses non adaptive bitrate, which fixes audio stuttering with YT Music. - * Uses VP9 and not AV1. + * Internal YT client for an unreleased YT client. May stop working at any time. */ - ANDROID_VR_1_43_32( - ANDROID_VR_1_61_48.id, - ANDROID_VR_1_61_48.clientName, - ANDROID_VR_1_61_48.packageName, - ANDROID_VR_1_61_48.deviceMake, - ANDROID_VR_1_61_48.deviceModel, - ANDROID_VR_1_61_48.osName, - ANDROID_VR_1_61_48.osVersion, - ANDROID_VR_1_61_48.androidSdkVersion, - ANDROID_VR_1_61_48.buildId, - "107.0.5284.2", - "1.43.32", - ANDROID_VR_1_61_48.requiresAuth, - ANDROID_VR_1_61_48.useAuth, - "Android VR 1.43" + VISIONOS(101, + "VISIONOS", + "Apple", + "RealityDevice14,1", + "visionOS", + "1.3.21O771", + "0.1", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15", + false, + false, + "visionOS" ); - private static boolean forceAVC() { - return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get(); - } - /** * YouTube * client type @@ -133,6 +100,7 @@ public enum ClientType { /** * App package name. */ + @Nullable private final String packageName; /** @@ -202,17 +170,20 @@ public enum ClientType { */ public final String friendlyName; + /** + * Android constructor. + */ @SuppressWarnings("ConstantLocale") ClientType(int id, String clientName, - String packageName, + @NonNull String packageName, String deviceMake, String deviceModel, String osName, String osVersion, - @Nullable String androidSdkVersion, - @Nullable String buildId, - @Nullable String cronetVersion, + @NonNull String androidSdkVersion, + @NonNull String buildId, + @NonNull String cronetVersion, String clientVersion, boolean requiresAuth, boolean useAuth, @@ -233,31 +204,44 @@ public enum ClientType { this.friendlyName = friendlyName; Locale defaultLocale = Locale.getDefault(); - if (androidSdkVersion == null) { - // Convert version from '18.2.22C152' into '18_2_22' - String userAgentOsVersion = osVersion - .replaceAll("(\\d+\\.\\d+\\.\\d+).*", "$1") - .replace(".", "_"); - // https://github.com/mitmproxy/mitmproxy/issues/4836 - this.userAgent = String.format("%s/%s (%s; U; CPU iOS %s like Mac OS X; %s)", - packageName, - clientVersion, - deviceModel, - userAgentOsVersion, - defaultLocale - ); - } else { - this.userAgent = String.format("%s/%s (Linux; U; Android %s; %s; %s; Build/%s; Cronet/%s)", - packageName, - clientVersion, - osVersion, - defaultLocale, - deviceModel, - Objects.requireNonNull(buildId), - Objects.requireNonNull(cronetVersion) - ); - } + this.userAgent = String.format("%s/%s (Linux; U; Android %s; %s; %s; Build/%s; Cronet/%s)", + packageName, + clientVersion, + osVersion, + defaultLocale, + deviceModel, + Objects.requireNonNull(buildId), + Objects.requireNonNull(cronetVersion) + ); Logger.printDebug(() -> "userAgent: " + this.userAgent); } + @SuppressWarnings("ConstantLocale") + ClientType(int id, + String clientName, + String deviceMake, + String deviceModel, + String osName, + String osVersion, + String clientVersion, + String userAgent, + boolean requiresAuth, + boolean useAuth, + String friendlyName) { + this.id = id; + this.clientName = clientName; + this.deviceMake = deviceMake; + this.deviceModel = deviceModel; + this.osName = osName; + this.osVersion = osVersion; + this.clientVersion = clientVersion; + this.userAgent = userAgent; + this.requiresAuth = requiresAuth; + this.useAuth = useAuth; + this.friendlyName = friendlyName; + this.packageName = null; + this.androidSdkVersion = null; + this.buildId = null; + this.cronetVersion = null; + } } 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 a23814056..13f6a1d0b 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 @@ -10,6 +10,7 @@ import java.util.Map; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.AppLanguage; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.spoof.requests.StreamingDataRequest; @@ -19,7 +20,10 @@ public class SpoofVideoStreamsPatch { private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get(); private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA - && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED; + && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.VISIONOS; + + @Nullable + private static volatile AppLanguage languageOverride; /** * Domain used for internet connectivity verification. @@ -43,10 +47,21 @@ public class SpoofVideoStreamsPatch { return false; // Modified during patching. } - public static boolean notSpoofingToAndroid() { - return !isPatchIncluded() - || !BaseSettings.SPOOF_VIDEO_STREAMS.get() - || BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED; + public static boolean spoofingToClientWithNoMultiAudioStreams() { + return isPatchIncluded() && BaseSettings.SPOOF_VIDEO_STREAMS.get(); + } + + /** + * @param language Language override for non-authenticated requests. If this is null then + * {@link BaseSettings#SPOOF_VIDEO_STREAMS_LANGUAGE} is used. + */ + public static void setLanguageOverride(@Nullable AppLanguage language) { + languageOverride = language; + } + + @Nullable + public static AppLanguage getLanguageOverride() { + return languageOverride; } /** @@ -261,17 +276,8 @@ public class SpoofVideoStreamsPatch { public static final class AudioStreamLanguageOverrideAvailability implements Setting.Availability { @Override public boolean isAvailable() { - ClientType clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get(); - return BaseSettings.SPOOF_VIDEO_STREAMS.get() - && (clientType == ClientType.ANDROID_VR_1_61_48 || clientType == ClientType.ANDROID_VR_1_43_32); - } - } - - 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_UNPLUGGED; + // Since all current clients are un-authenticated, this works for all spoof clients. + return BaseSettings.SPOOF_VIDEO_STREAMS.get(); } } } 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 6cc3ec1cd..82db445d7 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 @@ -1,5 +1,7 @@ package app.revanced.extension.shared.spoof.requests; +import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32; + import org.json.JSONException; import org.json.JSONObject; @@ -10,8 +12,10 @@ 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.AppLanguage; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.spoof.ClientType; +import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch; final class PlayerRoutes { static final Route.CompiledRoute GET_STREAMING_DATA = new Route( @@ -37,15 +41,16 @@ final class PlayerRoutes { try { JSONObject context = new JSONObject(); - // Can override default language only if no login is used. - // Could use preferred audio for all clients that do not login, - // but if this is a fall over client it will set the language even though - // the audio language is not selectable in the UI. - ClientType userSelectedClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get(); - Locale streamLocale = (userSelectedClient == ClientType.ANDROID_VR_1_61_48 - || userSelectedClient == ClientType.ANDROID_VR_1_43_32) - ? BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getLocale() - : Locale.getDefault(); + AppLanguage language = SpoofVideoStreamsPatch.getLanguageOverride(); + if (language == null || BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ANDROID_VR_1_43_32) { + // Force original audio has not overrode the language. + // Or if YT has fallen over to the very last client (VR 1.43), then always + // use the app language because forcing an audio stream of specific languages + // can sometimes fail so it's better to try and load something rather than nothing. + language = BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get(); + } + //noinspection ExtractMethodRecommender + Locale streamLocale = language.getLocale(); JSONObject client = new JSONObject(); client.put("deviceMake", clientType.deviceMake); diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java index d814ced88..81e96b690 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java @@ -37,10 +37,15 @@ public class StreamingDataRequest { private static volatile ClientType[] clientOrderToUse = ClientType.values(); - public static void setClientOrderToUse(ClientType[] availableClients, ClientType preferredClient) { - Objects.requireNonNull(availableClients); + public static void setClientOrderToUse(List availableClients, ClientType preferredClient) { + Objects.requireNonNull(preferredClient); - clientOrderToUse = new ClientType[availableClients.length]; + int availableClientSize = availableClients.size(); + if (!availableClients.contains(preferredClient)) { + availableClientSize++; + } + + clientOrderToUse = new ClientType[availableClientSize]; clientOrderToUse[0] = preferredClient; int i = 1; diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java index c67a5ffec..02149115c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ForceOriginalAudioPatch.java @@ -1,7 +1,7 @@ package app.revanced.extension.youtube.patches; import app.revanced.extension.shared.Logger; -import app.revanced.extension.shared.settings.Setting; +import app.revanced.extension.shared.settings.AppLanguage; import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch; import app.revanced.extension.youtube.settings.Settings; @@ -11,16 +11,20 @@ public class ForceOriginalAudioPatch { private static final String DEFAULT_AUDIO_TRACKS_SUFFIX = ".4"; /** - * If the conditions to use this patch were present when the app launched. + * Injection point. */ - public static boolean PATCH_AVAILABLE = SpoofVideoStreamsPatch.notSpoofingToAndroid(); - - public static final class ForceOriginalAudioAvailability implements Setting.Availability { - @Override - public boolean isAvailable() { - // Check conditions of launch and now. Otherwise if spoofing is changed - // without a restart the setting will show as available when it's not. - return PATCH_AVAILABLE && SpoofVideoStreamsPatch.notSpoofingToAndroid(); + public static void setPreferredLanguage() { + if (Settings.FORCE_ORIGINAL_AUDIO.get()) { + // None of the current spoof clients support audio track menu, + // And all are un-authenticated and can request any language code + // (authenticated requests ignore the language code and always use the account language). + // To still support force original audio, if it's enabled then pick a language + // that is not auto-dubbed by YouTube: https://support.google.com/youtube/answer/15569972 + // but the language is also supported natively by the Meta Quest device that + // Android VR is spoofing. + AppLanguage override = AppLanguage.SV; + Logger.printDebug(() -> "Setting language override: " + override); + SpoofVideoStreamsPatch.setLanguageOverride(override); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java index 2408ac81c..cbf2930bb 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java @@ -9,13 +9,13 @@ import app.revanced.extension.youtube.shared.ShortsPlayerState; public class PlayerFlyoutMenuItemsFilter extends Filter { public static final class HideAudioFlyoutMenuAvailability implements Setting.Availability { - private static final boolean AVAILABLE_ON_LAUNCH = SpoofVideoStreamsPatch.notSpoofingToAndroid(); + private static final boolean AVAILABLE_ON_LAUNCH = !SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams(); @Override public boolean isAvailable() { // Check conditions of launch and now. Otherwise if spoofing is changed // without a restart the setting will show as available when it's not. - return AVAILABLE_ON_LAUNCH && SpoofVideoStreamsPatch.notSpoofingToAndroid(); + return AVAILABLE_ON_LAUNCH && !SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams(); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java index 23a415708..df228e288 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java @@ -1,9 +1,11 @@ package app.revanced.extension.youtube.patches.spoof; import static app.revanced.extension.shared.spoof.ClientType.ANDROID_CREATOR; -import static app.revanced.extension.shared.spoof.ClientType.ANDROID_UNPLUGGED; +import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32; import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48; -import static app.revanced.extension.shared.spoof.ClientType.IOS_UNPLUGGED; +import static app.revanced.extension.shared.spoof.ClientType.VISIONOS; + +import java.util.List; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.spoof.ClientType; @@ -16,12 +18,13 @@ public class SpoofVideoStreamsPatch { * Injection point. */ public static void setClientOrderToUse() { - ClientType[] availableClients = { + List availableClients = List.of( ANDROID_VR_1_61_48, - ANDROID_UNPLUGGED, ANDROID_CREATOR, - IOS_UNPLUGGED - }; + VISIONOS, + // VR 1.43 must be last as spoof streaming data handles it slightly differently. + ANDROID_VR_1_43_32 + ); StreamingDataRequest.setClientOrderToUse(availableClients, BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get()); 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 2c089bb69..d40879a3c 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 @@ -12,7 +12,6 @@ import static app.revanced.extension.youtube.patches.ChangeHeaderPatch.HeaderLog import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.ChangeStartPageTypeAvailability; import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage; import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode; -import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MINIMAL; @@ -75,7 +74,7 @@ public class Settings extends BaseSettings { "0.25\n0.5\n0.75\n1.0\n1.25\n1.5\n1.75\n2.0\n2.5\n3.0\n4.0\n5.0\n6.0\n7.0\n8.0", true); // Audio - public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new ForceOriginalAudioAvailability()); + public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, true); // Ads public static final BooleanSetting HIDE_CREATOR_STORE_SHELF = new BooleanSetting("revanced_hide_creator_store_shelf", TRUE); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java deleted file mode 100644 index 6a8c3af36..000000000 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.extension.youtube.settings.preference; - -import static app.revanced.extension.shared.StringRef.str; - -import android.content.Context; -import android.preference.SwitchPreference; -import android.util.AttributeSet; - -import app.revanced.extension.youtube.patches.ForceOriginalAudioPatch; - -@SuppressWarnings({"deprecation", "unused"}) -public class ForceOriginalAudioSwitchPreference extends SwitchPreference { - - { - if (!ForceOriginalAudioPatch.PATCH_AVAILABLE) { - // Show why force audio is not available. - String summary = str("revanced_force_original_audio_not_available"); - setSummary(summary); - setSummaryOn(summary); - setSummaryOff(summary); - } - } - - public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - public ForceOriginalAudioSwitchPreference(Context context) { - super(context); - } -} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java index 4d67360a7..c73377fd5 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java @@ -12,8 +12,8 @@ import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch; public class HideAudioFlyoutMenuPreference extends SwitchPreference { { - // Audio menu is not available if spoofing to Android client type. - if (!SpoofVideoStreamsPatch.notSpoofingToAndroid()) { + // Audio menu is not available if spoofing to most client types. + if (SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams()) { String summary = str("revanced_hide_player_flyout_audio_track_not_available"); setSummary(summary); setSummaryOn(summary); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java index 33a69b6b0..07d5c9d6b 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java @@ -78,21 +78,17 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference { Logger.printDebug(() -> "Updating spoof stream side effects preference"); setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get()); - String key = "revanced_spoof_video_streams_about_" + - (clientType == ClientType.IOS_UNPLUGGED - ? "ios_tv" - : "android"); - String title = str(key + "_title"); - String summary = str(key + "_summary"); - - // Android VR supports AV1 but all other clients do not. - if (clientType != ClientType.ANDROID_VR_1_61_48 - && clientType != ClientType.ANDROID_VR_1_43_32) { - summary += '\n' + str("revanced_spoof_video_streams_about_no_av1"); - } - + String title = str("revanced_spoof_video_streams_about_title"); + // Currently only Android VR and VisionOS are supported, and both have the same base side effects. + String summary = str("revanced_spoof_video_streams_about_android_summary"); summary += '\n' + str("revanced_spoof_video_streams_about_kids_videos"); + if (clientType == ClientType.VISIONOS) { + summary = str("revanced_spoof_video_streams_about_experimental") + + '\n' + summary + + '\n' + str("revanced_spoof_video_streams_about_no_av1"); + } + setTitle(title); setSummary(summary); } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt index 82f19f81a..ed2f7f043 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt @@ -89,7 +89,7 @@ val downloadsPatch = bytecodePatch( // Main activity is used to launch downloader intent. mainActivityOnCreateFingerprint.method.addInstruction( - 1, + 0, "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V" ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt index 25d291809..24e062d40 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.layout.seekbar import app.revanced.patcher.fingerprint +import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE import app.revanced.util.containsLiteralInstruction import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -103,7 +104,7 @@ internal val launchScreenLayoutTypeFingerprint = fingerprint { custom { method, _ -> val firstParameter = method.parameterTypes.firstOrNull() // 19.25 - 19.45 - (firstParameter == "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;" + (firstParameter == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE || firstParameter == "Landroid/app/Activity;") // 19.46+ && method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt index 470bdc0b5..bf63a2191 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt @@ -68,7 +68,7 @@ val shortsAutoplayPatch = bytecodePatch( // Main activity is used to check if app is in pip mode. mainActivityOnCreateFingerprint.method.addInstruction( - 1, + 0, "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->setMainActivity(Landroid/app/Activity;)V", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt index 56abd43df..aa9aa1954 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt @@ -90,8 +90,8 @@ val openShortsInRegularPlayerPatch = bytecodePatch( // Activity is used as the context to launch an Intent. mainActivityOnCreateFingerprint.method.addInstruction( - 1, - "invoke-static/range { p0 .. p0 }, ${EXTENSION_CLASS_DESCRIPTOR}->" + + 0, + "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" + "setMainActivity(Landroid/app/Activity;)V", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt index 8864c20c6..583750c06 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.layout.theme import app.revanced.patcher.fingerprint +import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -37,6 +38,6 @@ internal val splashScreenStyleFingerprint = fingerprint { parameters("Landroid/os/Bundle;") literal { SPLASH_SCREEN_STYLE_FEATURE_FLAG } custom { method, classDef -> - method.name == "onCreate" && classDef.endsWith("/MainActivity;") + method.name == "onCreate" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt index 2e0ae6165..5a7d976df 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt @@ -40,9 +40,7 @@ val announcementsPatch = bytecodePatch( ) mainActivityOnCreateFingerprint.method.addInstruction( - // Insert index must be greater than the insert index used by GmsCoreSupport, - // as both patch the same method and GmsCore check should be first. - 1, + 0, "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt index 8b60589ce..f9ee7849b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt @@ -34,12 +34,7 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch( addResources("youtube", "misc.dns.checkWatchHistoryDomainNameResolutionPatch") mainActivityOnCreateFingerprint.method.addInstruction( - // FIXME: Insert index must be greater than the insert index used by GmsCoreSupport, - // as both patch the same method and GmsCoreSupport check should be first, - // but the patch does not depend on GmsCoreSupport, so it should not be possible to enforce this - // unless a third patch is added that this patch and GmsCoreSupport depend on to manage - // the order of the patches. - 1, + 0, "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->checkDnsResolver(Landroid/app/Activity;)V", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/SharedExtensionPatch.kt index 553cc486f..af4b62e4c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/SharedExtensionPatch.kt @@ -3,4 +3,5 @@ package app.revanced.patches.youtube.misc.extension import app.revanced.patches.shared.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.hooks.* -val sharedExtensionPatch = sharedExtensionPatch("youtube", applicationInitHook) +val sharedExtensionPatch = sharedExtensionPatch("youtube", + applicationInitHook, applicationInitOnCrateHook) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt index 6a0e7d1f4..743d1162d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt @@ -1,11 +1,23 @@ package app.revanced.patches.youtube.misc.extension.hooks import app.revanced.patches.shared.misc.extension.extensionHook +import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE /** * Hooks the context when the app is launched as a regular application (and is not an embedded video playback). */ // Extension context is the Activity itself. internal val applicationInitHook = extensionHook { + // Does _not_ resolve to the YouTube main activity. + // Required as some hooked code runs before the main activity is launched. strings("Application creation", "Application.onCreate") } + +internal val applicationInitOnCrateHook = extensionHook { + returns("V") + parameters("Landroid/os/Bundle;") + custom { method, classDef -> + method.name == "onCreate" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE + } +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt index f1ea33327..ee6750c60 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt @@ -127,8 +127,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig // Litho filtering based on navigation tab before the tab is updated. mainActivityOnBackPressedFingerprint.method.addInstruction( 0, - "invoke-static { p0 }, " + - "$EXTENSION_CLASS_DESCRIPTOR->onBackPressed(Landroid/app/Activity;)V", + "invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->onBackPressed(Landroid/app/Activity;)V", ) // Hook the search bar. 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 dbf055299..4a971e079 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 @@ -69,14 +69,13 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch( entryValuesKey = "revanced_language_entry_values", tag = "app.revanced.extension.shared.settings.preference.SortedListPreference" ), - SwitchPreference("revanced_spoof_video_streams_ios_force_avc"), SwitchPreference("revanced_spoof_streaming_data_stats_for_nerds"), - ), - ), + ) + ) ) mainActivityOnCreateFingerprint.method.addInstruction( - 1, // Must use 1 index so context is set by extension patch., + 0, "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setClientOrderToUse()V" ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt index 4a9f3a020..6fc138fc5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt @@ -4,6 +4,8 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +internal const val YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE = "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;" + internal val conversionContextFingerprintToString = fingerprint { parameters() strings( @@ -48,7 +50,7 @@ internal val mainActivityConstructorFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters() custom { _, classDef -> - classDef.endsWith("/MainActivity;") + classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE } } @@ -57,7 +59,7 @@ internal val mainActivityOnBackPressedFingerprint = fingerprint { returns("V") parameters() custom { method, classDef -> - method.name == "onBackPressed" && classDef.endsWith("/MainActivity;") + method.name == "onBackPressed" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE } } @@ -65,7 +67,7 @@ internal val mainActivityOnCreateFingerprint = fingerprint { returns("V") parameters("Landroid/os/Bundle;") custom { method, classDef -> - method.name == "onCreate" && classDef.endsWith("/MainActivity;") + method.name == "onCreate" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt index 8a3ee4e92..b17d1c96c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.video.audio +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -14,6 +15,7 @@ import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch +import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint import app.revanced.util.findMethodFromToString import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.insertLiteralOverride @@ -55,10 +57,12 @@ val forceOriginalAudioPatch = bytecodePatch( addResources("youtube", "video.audio.forceOriginalAudioPatch") PreferenceScreen.VIDEO.addPreferences( - SwitchPreference( - key = "revanced_force_original_audio", - tag = "app.revanced.extension.youtube.settings.preference.ForceOriginalAudioSwitchPreference" - ) + SwitchPreference("revanced_force_original_audio") + ) + + mainActivityOnCreateFingerprint.method.addInstruction( + 0, + "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setPreferredLanguage()V" ) // Disable feature flag that ignores the default track flag diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 197680376..ac8860273 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -125,14 +125,12 @@ - Android TV Android VR - iOS TV + VisionOS - ANDROID_UNPLUGGED ANDROID_VR_1_61_48 - IOS_UNPLUGGED + VISIONOS diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index e1df14c83..a297dd20e 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -765,7 +765,7 @@ If changing this setting does not take effect, try switching to Incognito mode." "Audio track menu is hidden -To show the Audio track menu, change \'Spoof video streams\' to iOS TV" +Audio track menu is not available when \'Spoof video streams\' is enabled" Hide Watch in VR Watch in VR menu is hidden @@ -1613,32 +1613,25 @@ Enabling this can unlock higher video qualities" Spoof video streams Spoof the client video streams to prevent playback issues Spoof video streams - Video streams are spoofed + "Video streams are spoofed + +If you are a YouTube Premium user, this setting may not be required" "Video streams are not spoofed Video playback may not work" Turning off this setting may cause video playback issues. Default client - Force iOS AVC (H.264) - Video codec is forced to AVC (H.264) - Video codec is determined automatically - "Enabling this might improve battery life and fix playback stuttering. - -AVC has a maximum resolution of 1080p, Opus audio codec is not available, and video playback will use more internet data than VP9 or AV1." - iOS spoofing side effects - "• Movies or paid videos may not play -• Stable volume is not available -• Videos end 1 second early" + Spoofing side effects Android spoofing side effects "• Audio track menu is missing -• Stable volume is not available -• Force original audio is not available" +• Stable volume is not available" + • Experimental client and may stop working anytime • No AV1 video codec • Kids videos may not play when logged out or in incognito mode Show in Stats for nerds Client type is shown in Stats for nerds Client is hidden in Stats for nerds - VR default audio stream language + Audio stream language From 1db131e90ed40c6ea638417816a27ff640d51739 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 Sep 2025 17:02:01 +0000 Subject: [PATCH 06/11] chore: Release v5.37.1-dev.3 [skip ci] ## [5.37.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.2...v5.37.1-dev.3) (2025-09-15) ### Bug Fixes * **Spoof video streams:** Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for `Force original audio` to work with any spoof client ([#5861](https://github.com/ReVanced/revanced-patches/issues/5861)) ([abe3943](https://github.com/ReVanced/revanced-patches/commit/abe3943f98fd86dcd74c7e07cf65d3c7fc24fef9)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca82588a..3d1af85da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.37.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.2...v5.37.1-dev.3) (2025-09-15) + + +### Bug Fixes + +* **Spoof video streams:** Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for `Force original audio` to work with any spoof client ([#5861](https://github.com/ReVanced/revanced-patches/issues/5861)) ([abe3943](https://github.com/ReVanced/revanced-patches/commit/abe3943f98fd86dcd74c7e07cf65d3c7fc24fef9)) + ## [5.37.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.1...v5.37.1-dev.2) (2025-09-15) diff --git a/gradle.properties b/gradle.properties index f988675ad..83afc41dd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.37.1-dev.2 +version = 5.37.1-dev.3 From 6b6eea8414432e4287ab6f36389376a5b8f398a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 23:26:07 +0400 Subject: [PATCH 07/11] chore: Sync translations (#5864) --- .../addresources/values-ar-rSA/strings.xml | 27 +++++-------- .../addresources/values-az-rAZ/strings.xml | 27 +++++-------- .../addresources/values-be-rBY/strings.xml | 25 +++++------- .../addresources/values-bg-rBG/strings.xml | 27 +++++-------- .../addresources/values-bn-rBD/strings.xml | 25 +++++------- .../addresources/values-cs-rCZ/strings.xml | 27 +++++-------- .../addresources/values-da-rDK/strings.xml | 25 +++++------- .../addresources/values-de-rDE/strings.xml | 27 +++++-------- .../addresources/values-el-rGR/strings.xml | 23 ++++------- .../addresources/values-es-rES/strings.xml | 39 ++++++++----------- .../addresources/values-et-rEE/strings.xml | 25 +++++------- .../addresources/values-fi-rFI/strings.xml | 18 --------- .../addresources/values-fil-rPH/strings.xml | 23 ++++------- .../addresources/values-fr-rFR/strings.xml | 31 ++++++--------- .../addresources/values-ga-rIE/strings.xml | 27 +++++-------- .../addresources/values-hu-rHU/strings.xml | 27 +++++-------- .../addresources/values-hy-rAM/strings.xml | 27 +++++-------- .../addresources/values-in-rID/strings.xml | 23 ++++------- .../addresources/values-it-rIT/strings.xml | 25 +++++------- .../addresources/values-iw-rIL/strings.xml | 25 +++++------- .../addresources/values-ja-rJP/strings.xml | 23 ++++------- .../addresources/values-ko-rKR/strings.xml | 23 ++++------- .../addresources/values-lt-rLT/strings.xml | 25 +++++------- .../addresources/values-lv-rLV/strings.xml | 27 +++++-------- .../addresources/values-nl-rNL/strings.xml | 27 +++++-------- .../addresources/values-pl-rPL/strings.xml | 27 +++++-------- .../addresources/values-pt-rBR/strings.xml | 27 +++++-------- .../addresources/values-pt-rPT/strings.xml | 25 +++++------- .../addresources/values-ro-rRO/strings.xml | 27 +++++-------- .../addresources/values-ru-rRU/strings.xml | 25 +++++------- .../addresources/values-sk-rSK/strings.xml | 24 +++--------- .../addresources/values-sl-rSI/strings.xml | 26 +++++-------- .../addresources/values-sq-rAL/strings.xml | 27 +++++-------- .../addresources/values-sr-rCS/strings.xml | 27 +++++-------- .../addresources/values-sr-rSP/strings.xml | 27 +++++-------- .../addresources/values-sv-rSE/strings.xml | 23 ++++------- .../addresources/values-th-rTH/strings.xml | 25 +++++------- .../addresources/values-tr-rTR/strings.xml | 23 ++++------- .../addresources/values-uk-rUA/strings.xml | 23 ++++------- .../addresources/values-vi-rVN/strings.xml | 23 ++++------- .../addresources/values-zh-rCN/strings.xml | 27 +++++-------- .../addresources/values-zh-rTW/strings.xml | 18 --------- 42 files changed, 377 insertions(+), 695 deletions(-) diff --git a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml index 91681b4c6..d81498e5f 100644 --- a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml +++ b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" تم إخفاء قائمة المقطع الصوتي يتم عرض قائمة المقطع الصوتي - "تم إخفاء قائمة المقطع الصوتي + "قائمة المسارات الصوتية مخفية -لعرض قائمة المقطع الصوتي، غيّر 'Spoof Video Streams' إلى iOS TV" +قائمة المسارات الصوتية غير متاحة عندما يكون \"تزوير تدفقات الفيديو\" مُمكَّنًا" إخفاء المشاهدة في VR تم إخفاء قائمة المشاهدة في الوضع الافتراضي @@ -1535,32 +1535,25 @@ Second \"item\" text" Spoof Video Streams تزييف تدفقات الفيديو الخاصة بالعميل لمنع حدوث مشكلات أثناء التشغيل Spoof Video Streams - يتم تزييف تدفقات الفيديو + "تدفقات الفيديو مزورة + +إذا كنت مستخدمًا لـ YouTube Premium، فقد لا يكون هذا الإعداد مطلوبًا" "لا يتم تزييف تدفقات الفيديو قد لا يعمل تشغيل الفيديو" إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو. العميل الافتراضي - فرض iOS AVC (H.264) - يتم فرض ترميز فيديو على AVC (H.264) - يتم تحديد ترميز الفيديو تلقائيًا - "قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح تقطيع التشغيل. - -AVC لديه حد أقصى للدقة 1080p، لا يتوفر ترميز الصوت Opus، وسوف يستخدم تشغيل الفيديو بيانات إنترنت أكثر من VP9 أو AV1." - الآثار الجانبية لمحاكاة هوية iOS - "• قد لا يتم تشغيل الأفلام أو الفيديوهات المدفوعة -• مستوى الصوت الثابت غير متوفر -• تنتهي الفيديوهات قبل ب 1 ثانية" + الآثار الجانبية للتزوير الآثار الجانبية لمحاكاة هوية Android - "• قائمة المقطع الصوتي مفقودة -• مستوى الصوت الثابت غير متاح -• فرض الصوت الأصلي غير متوفر" + "• قائمة المسارات الصوتية مفقودة +• مستوى الصوت المستقر غير متاح" + • عميل تجريبي وقد يتوقف عن العمل في أي وقت • لا يوجد ترميز الفيديو AV1 • قد لا يتم تشغيل الفيديوهات المخصصة للأطفال عند تسجيل الخروج أو عند استخدام وضع التصفح المتخفي عرض في إحصاءات تقنية يتم عرض نوع العميل في إحصاءات تقنية تم إخفاء نوع العميل في إحصاءات تقنية - لغة البث الصوتي الافتراضية للواقع الافتراضي VR + لغة بث الصوت diff --git a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml index 5a651318d..e685e6546 100644 --- a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml +++ b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml @@ -700,9 +700,9 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı Səs axını menyusu gizlidir Səs axını menyusu göstərilir - "Audio trek seçimi gizlədilib + "Səs treki menyusu gizlidir -Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iOS TV-yə dəyiş" +\"Video yayımları saxtalaşdır\" aktivləşdikdə səs trek menyusu mövcud deyil " \"VR-da İzləni\" gizlət VR menyusunda izləmə gizlidir @@ -1534,32 +1534,25 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər Video yayımları saxtalaşdır Oynatma problemlərin önləmək üçün qəbuledici video yayımların saxtalaşdır Video yayımları saxtalaşdır - Video yayımları saxtalaşdırılır + "Video yayımları saxtalaşdırılıb + +Əgər YouTube Premium istifadəçisisinizsə, bu tənzimlənmə tələb olunmaya bilər" "Video yayımlar saxtalaşdırılmır Video oynatma işləməyə bilər" Bu seçimi bağlamaq, video oynatma problemlərinə səbəb olar. İlkin qəbuledici - IOS-da AVC (H.264)-ni məcbur et - Video kodlama AVC (H.264)-yə məcbur edilir - Video kodlayıcı avtomatik müəyyən edilir - "Bunu aktivləşdirmə, batareya ömrün yaxşılaşdıra və oynatma qırılmasın düzəldə bilər. - -AVC maksimum 1080p görüntü imkanına malikdir, Opus audio kodlama olmur və video oynatma VP9 və ya AV1-dən daha çox internet məlumatı sərf edəcək." - iOS saxtalaşdırma yan təsirləri - "• Filmlər və ya ödənişli videolar oynadıla bilməz -• Stabil səs səviyyəsi mövcud deyil -• Videolar 1 saniyə tez bitir" + Saxtakarlıq yan təsirləri Android saxtalaşdırma yan təsirləri - "• Səs treki menyusu yoxdur -• Sabit səs səviyyəsi yoxdur -• İlkin səsi məcbur etmə mümkün deyil" + "• Səs treki menyusu əlçatmazdır +• Sabit səs səviyyəsi yoxdur" + • Təcrübi qəbuledici və hər vaxt işləməyi dayandıra bilər • AV1 video kodlayıcı yoxdur • Giriş edilməyəndə və ya gizli rejimdə uşaq videoları oynadıla bilməz İstək üçün Statistikada göstər Qəbuledici növü İstək üçün statistikada göstərilir Qəbuledici nerd üçün Statistikada gizlidir - VR-da ilkin səs yayımı dili + Səs yayım dili diff --git a/patches/src/main/resources/addresources/values-be-rBY/strings.xml b/patches/src/main/resources/addresources/values-be-rBY/strings.xml index 86a34ac66..d7fd26e6b 100644 --- a/patches/src/main/resources/addresources/values-be-rBY/strings.xml +++ b/patches/src/main/resources/addresources/values-be-rBY/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" Меню гукавой дарожкі схавана Адлюструецца меню гукавой дарожкі - "Меню аўдыядарожкі схавана + "Меню гукавой дарожкі схавана -Каб паказаць меню аўдыядарожкі, змяніце \"Падробка відэаструменяў\" на iOS TV" +Меню гукавой дарожкі недаступна, калі ўключана \"Падробка відэаструменяў\"" Схаваць гадзіннік у VR Меню прагляду ў VR схавана @@ -1536,32 +1536,25 @@ Second \"item\" text" Подделывать потоки видео Имитируйте потоки видео клиентов, чтобы предотвратить проблемы с воспроизведением Подделывать потоки видео - Потоки видео подделаны + "Відэаструмені падроблены + +Калі вы карыстаецеся YouTube Premium, гэтая налада можа не спатрэбіцца" "Відэаструм не падроблены Прайграванне відэа можа не працаваць" Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа. Клиент по умолчанию - Вымусіць iOS AVC (H.264) - Відэакaдэк зафіксаваны ў AVC (H.264) - Відэакaдэк вызначаецца аўтаматычна - "Уключэнне гэтага можа палепшыць час аўтаномнай працы і выправіць заіканне прайгравання. - -AVC мае максімальнае дазвол 1080p, аўдыёкадэк Opus недаступны, а прайграванне відэа будзе выкарыстоўваць больш інтэрнэт-даных, чым VP9 або AV1." - Пабочныя эфекты падробкі iOS - "• Фільмы або платныя відэа могуць не прайгравацца -• Стабільная гучнасць недаступная -• Відэа заканчваюцца на 1 секунду раней" + Пабочныя эфекты падробкі Побічныя эфекты падробкі Android "• Меню гукавой дарожкі адсутнічае -• Стабільны гук недаступны -• Прымусовае арыгінальнае аўдыё недаступна" +• Стабільная гучнасць недаступна" + • Эксперыментальны кліент і можа спыніць працу ў любы час • Няма відэакідавання AV1 • Дзіцячыя відэа могуць не прайгравацца ў стане выхаду з акаўнта або ў рэжыме інкогніта Паказаць у статыстыцы для спецыялістаў Тып кліента адлюстроўваецца ў статыстыцы для спецыялістаў Кліент схаваны ў статыстыцы для спецыялістаў - Мова гукавой дарожкі па змаўчанні для VR + Мова аўдыяпатоку diff --git a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml index 0393b8a42..b7bfac19d 100644 --- a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml +++ b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" Менюто за избор на Аудио е скрито Менюто за избор на Аудио се показва - "Менюто за аудио тракове е скрито + "Менюто за аудиозаписи е скрито -За да покажете менюто за аудио тракове, променете \"Подмяна на видео потоци\" на iOS TV" +Менюто за аудиозаписи не е налично, когато „Подменяне на видео потоци“ е активирано" Гледайте във VR Менюто за гледане в VR е скрито @@ -1535,32 +1535,25 @@ Second \"item\" text" Подправяне на видео потоци Подправете клиентските видео потоци, за да предотвратите проблеми с възпроизвеждането Подправяне на видео потоци - Видео потоците са подправени + "Видео потоците са подменени + +Ако сте потребител на YouTube Premium, тази настройка може да не е необходима" "Потоците на видеоклипове не са фалшифицирани Възпроизвеждането на видеоклипове може да не работи" Деактивирането на тази настройка ще доведе до проблеми с възпроизвеждането на видео. Клиент по подразбиране - Принудително използване на AVC (H.264) на iOS - Видео кодекът е принудително зададен на AVC (H.264) - Видео кодекът се определя автоматично - "Включването на това може да подобри живота на батерията и да поправи заекването при възпроизвеждане. - -AVC има максимална резолюция от 1080p, Opus аудио кодек не е наличен и възпроизвеждането на видео ще използва повече интернет данни от VP9 или AV1." - Ефекти на измамата в iOS - "• Филми или платени видеоклипове може да не се възпроизвеждат -• Стабилен звук не е наличен -• Видеоклиповете завършват 1 секунда по-рано" + Странични ефекти от подменянето Strani4ni efekti na fal6ivoto predstavqne na Android - "• Lipsva menju za audio pisti -• Ne e nali4na stabilna glasnost -• Ne e nali4na forsirana originalna audio pista" + "• Липсва менюто за аудиозаписи +• Стабилен звук не е наличен" + • Експериментален клиент и може да спре да работи по всяко време • Без AV1 видео кодек • Детските видеоклипове може да не се възпроизвеждат, когато сте излезли от профила си или в режим \"инкогнито\" Poka6i v Statistiki za nerds Tipът na klienta se poka6va v Statistiki za nerds Klientът e skriт v Statistiki za nerds - Ezik po подразбиране za audio potok v VR + Език на аудио потока diff --git a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml index 9619da2ad..483d3f31e 100644 --- a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml +++ b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml @@ -698,7 +698,7 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ "অডিও ট্র্যাক মেনু লুকানো আছে -অডিও ট্র্যাক মেনু দেখাতে, 'স্পুফ ভিডিও স্ট্রিম' পরিবর্তন করে iOS TV করুন" +\"ভিডিও স্ট্রিম স্পুফ করুন\" সক্ষম করা হলে অডিও ট্র্যাক মেনু উপলব্ধ থাকে না" ভিআর-এ ঘড়ি লুকান ভিআর মেনুতে দেখুন লুকানো আছে @@ -1531,32 +1531,25 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট ভিডিও স্ট্রিমিং স্পুফ করুন প্লেব্যাক সমস্যা প্রতিরোধ করতে ক্লায়েন্ট ভিডিও স্ট্রিম স্পুফ করুন ভিডিও স্ট্রিমিং স্পুফ করুন - ভিডিও স্ট্রিম স্পুফ করা হয়েছে + "ভিডিও স্ট্রিম স্পুফ করা হয়েছে + +আপনি যদি YouTube Premium ব্যবহারকারী হন, তাহলে এই সেটিংটির প্রয়োজন নাও হতে পারে" "ভিডিও স্ট্রিম ভুয়া নয় ভিডিও প্লেব্যাক কাজ নাও করতে পারে" এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে। ডিফল্ট ক্লায়েন্ট - iOS AVC (H.264) বাধ্যতামূলক করুন - ভিডিও কোডেক AVC (H.264) এ বাধ্যতামূলক করা হয়েছে - ভিডিও কোডেক স্বয়ংক্রিয়ভাবে নির্ধারিত হয় - "এটি সক্ষম করলে ব্যাটারি লাইফ উন্নত হতে পারে এবং প্লেব্যাক স্টাটারিং সমস্যা সমাধান হতে পারে। - -AVC-এর সর্বোচ্চ রেজোলিউশন হল 1080p, Opus অডিও কোডেক পাওয়া যায় না এবং VP9 বা AV1-এর তুলনায় ভিডিও প্লেব্যাকে বেশি ইন্টারনেট ডেটা ব্যবহার করা হবে。" - আইওএস স্পুফিংয়ের পার্শ্ব প্রতিক্রিয়া - "• মুভি বা অর্থ প্রদানের ভিডিও চালু নাও হতে পারে -• স্থির ভলিউম পাওয়া যায় না -• ভিডিওগুলি 1 সেকেন্ড আগে শেষ হয়ে যায়" + স্পুফিংয়ের পার্শ্বপ্রতিক্রিয়া Android স্পুফিংয়ের পার্শ্বপ্রতিক্রিয়া - "• অডিও ট্র্যাক মেনু নেই -• স্থির ভলিউম পাওয়া যায় না -• মূল অডিও জোর করে চালু করা যায় না" + "• অডিও ট্র্যাক মেনু অনুপস্থিত +• স্থিতিশীল ভলিউম উপলব্ধ নেই" + • পরীক্ষামূলক ক্লায়েন্ট এবং যেকোনো সময় কাজ করা বন্ধ করতে পারে • কোনো AV1 ভিডিও কোডেক নেই • লগআউট করা হলে বা ছদ্মবেশী মোডে বাচ্চাদের ভিডিও চলতে নাও পারে স্ট্যাটস ফর নার্ডসে দেখান স্ট্যাটস ফর নার্ডসে ক্লায়েন্ট প্রকার দেখানো হবে স্ট্যাটস ফর নার্ডসে ক্লায়েন্ট লুকানো হবে - VR ডিফল্ট অডিও স্ট্রিম ভাষা + অডিও স্ট্রিম ভাষা diff --git a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml index c2b3f63fc..913b4851b 100644 --- a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml +++ b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml @@ -700,9 +700,9 @@ Pokud změna tohoto nastavení nemá žádný účinek, zkuste přepnout do rež Menu Zvuková stopa je skryto Menu Zvuková stopa je zobrazeno - "Nabídka zvukové stopy je skrytá. + "Nabídka zvukové stopy je skrytá -Chcete-li zobrazit nabídku zvukové stopy, změňte možnost „Zfalšovat streamy videa“ na iOS TV" +Nabídka zvukové stopy není dostupná, když je povoleno 'Maskování video streamů'." Skrýt Sledovat ve VR Menu Sledovat ve VR je skryto @@ -1535,32 +1535,25 @@ Povolením této funkce lze odemknout vyšší kvality videa" Napodobovat video streamy Napodobovat klientské video streamy, aby se zabránilo problémům s přehráváním Napodobovat video streamy - Video streamy jsou napodobeny + "Video streamy jsou maskovány + +Pokud jste uživatelem YouTube Premium, toto nastavení nemusí být vyžadováno." "Video streamy nejsou zfalšovány Přehrávání videa nemusí fungovat" Vypnutí tohoto nastavení může způsobit problémy s přehráváním videa. Výchozí klient - Vynucení kodeku iOS AVC (H.264) - Kodek videa je vynucen na AVC (H.264) - Kodek videa je určen automaticky - "Povolení této funkce může zlepšit výdrž baterie a opravit sekání videa. - -AVC má maximální rozlišení 1080p, zvukový kodek Opus není dostupný a přehrávání videa bude používat více dat než VP9 nebo AV1." - iOS spoofing vedlejší účinky - "• Filmy nebo placená videa se nemusí přehrávat -• Stabilní hlasitost není k dispozici -• Videa končí o 1 sekundu dříve" + Vedlejší účinky maskování Vedlejší účinky spoofingu Androidu - "• Chybí nabídka zvukových stop -• Není k dispozici stabilní hlasitost -• Není k dispozici možnost vynucení originálního zvuku" + "• Chybí nabídka zvukové stopy +• Stabilní hlasitost není k dispozici" + • Experimentální klient a může kdykoli přestat fungovat • Žádný video kodek AV1 • Dětská videa se nemusí přehrávat, když jste odhlášení nebo v anonymním režimu Zobrazit ve statistikách pro nadšence Typ klienta se zobrazuje ve statistikách pro nadšence Klient je skrytý ve statistikách pro nadšence - Výchozí jazyk zvukového streamu ve VR + Jazyk zvukového streamu diff --git a/patches/src/main/resources/addresources/values-da-rDK/strings.xml b/patches/src/main/resources/addresources/values-da-rDK/strings.xml index 1911981e9..6c5eb3aca 100644 --- a/patches/src/main/resources/addresources/values-da-rDK/strings.xml +++ b/patches/src/main/resources/addresources/values-da-rDK/strings.xml @@ -700,9 +700,9 @@ Hvis ændring af denne indstilling ikke træder i kraft, kan du prøve at skifte Menuen for lydspor er skjult Menuen Lydspor vises - "Lydspormenuen er skjult + "Lydsporsmenuen er skjult -For at vise lydspormenuen skal du ændre \"Spoof videostream\" til iOS TV" +Lydsporsmenuen er ikke tilgængelig, når 'Spoof videostreams' er aktiveret" Skjul vagt i VR Se i VR-menuen er skjult @@ -1537,30 +1537,25 @@ Aktivering af dette kan låse op for højere videokvalitet" Spoof videostreams Spoof klienten video streams for at forhindre afspilning problemer Spoof videostreams - Video streams er spoofed + "Videostreams er spoofede + +Hvis du er en YouTube Premium-bruger, er denne indstilling muligvis ikke påkrævet" "Videostreams forfalskes ikke Videoafspilning virker muligvis ikke" At slå denne indstilling fra kan forårsage problemer med videoafspilning. Standard klient - Forceer iOS AVC (H.264) - Videokodec er tvunget til AVC (H.264) - Videokodec bestemmes automatisk - "Aktivering af dette kan forbedre batterilevetiden og rette afspilningshakken.\n\nAVC har en maksimal opløsning på 1080p, Opus-lydkodec er ikke tilgængelig, og videoafspilning vil bruge mere internetdata end VP9 eller AV1." - iOS-spoofing kan have følgende bivirkninger - "• Film eller betalte videoer afspilles muligvis ikke -• Stabil lydstyrke er ikke tilgængelig -• Videoer slutter 1 sekund for tidligt" + Bivirkninger ved spoofing Bivirkninger ved Android-spoofing - "• Lydspormenu mangler -• Stabil lydstyrke er ikke tilgængelig -• Gennemtving original lyd er ikke tilgængelig" + "• Lydsporsmenuen mangler +• Stabil lydstyrke er ikke tilgængelig" + • Eksperimentel klient og kan stoppe med at fungere når som helst • Intet AV1-videokodek • Videoer til børn afspilles muligvis ikke, når du er logget ud eller i inkognitotilstand Vis i Statistik for nørder Klienttypen vises i Statistik for nørder Klienten er skjult i Statistik for nørder - VR-standardsprog for lydstrømme + Lydstreamsprog diff --git a/patches/src/main/resources/addresources/values-de-rDE/strings.xml b/patches/src/main/resources/addresources/values-de-rDE/strings.xml index 2fe3648f4..0df4bae10 100644 --- a/patches/src/main/resources/addresources/values-de-rDE/strings.xml +++ b/patches/src/main/resources/addresources/values-de-rDE/strings.xml @@ -695,9 +695,9 @@ Wenn diese Änderung nicht wirksam wird, versuchen Sie, in den Inkognito-Modus z Audiospur-Menü ist ausgeblendet Audiospurmenü wird angezeigt - "Das Audiotrack-Menü ist ausgeblendet. + "Audiotrack-Menü ist ausgeblendet -Um das Audiotrack-Menü anzuzeigen, ändere \"Video-Streams fälschen\" zu iOS TV" +Audiotrack-Menü ist nicht verfügbar, wenn 'Videostreams spoofen' aktiviert ist" Überwachung in VR ausblenden Im VR-Menü beobachten ist ausgeblendet @@ -1530,32 +1530,25 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w Spoof-Video-Streams Spoof der Client-Videostreams um Wiedergabeprobleme zu verhindern Spoof-Video-Streams - Video-Streams sind gefälscht + "Videostreams werden gespooft + +Wenn Sie ein YouTube Premium-Nutzer sind, ist diese Einstellung möglicherweise nicht erforderlich" "Videoströme werden nicht gefälscht Die Videowiedergabe funktioniert möglicherweise nicht" Das Deaktivieren dieser Einstellung kann zu Videowiedergabeproblemen führen. Standard-Client - iOS AVC (H.264) erzwingen - Der Videocodec ist auf AVC (H.264) erzwungen. - Der Videocodec wird automatisch bestimmt. - "Aktivieren Sie dies, um die Akkulaufzeit zu verbessern und Ruckeln bei der Wiedergabe zu beheben. - -AVC hat eine maximale Auflösung von 1080p, Opus-Audiocodec ist nicht verfügbar und die Videowiedergabe verbraucht mehr Internetdaten als VP9 oder AV1." - iOS-Spoofing-Nebenwirkungen - "• Filme oder kostenpflichtige Videos können möglicherweise nicht abgespielt werden -• Eine stabile Lautstärke ist nicht verfügbar -• Videos enden 1 Sekunde zu früh" + Nebenwirkungen des Spoofings Android-Spoofing-Nebenwirkungen - "• Audiospur-Menü fehlt -• Stabile Lautstärke ist nicht verfügbar -• Original-Audio erzwingen ist nicht verfügbar" + "• Audiotrack-Menü fehlt +• Stabile Lautstärke ist nicht verfügbar" + • Experimenteller Client und kann jederzeit aufhören zu funktionieren • Kein AV1-Videocodec • Kinder-Videos werden möglicherweise nicht abgespielt, wenn du abgemeldet bist oder den Inkognito-Modus verwendest. In Statistiken für Nerds anzeigen Der Client-Typ wird in den Statistiken für Nerds angezeigt Der Client wird in den Statistiken für Nerds ausgeblendet - Standard-Audiostreamsprache für VR + Audiodatenstromsprache diff --git a/patches/src/main/resources/addresources/values-el-rGR/strings.xml b/patches/src/main/resources/addresources/values-el-rGR/strings.xml index 6cc1d8625..4b856be61 100644 --- a/patches/src/main/resources/addresources/values-el-rGR/strings.xml +++ b/patches/src/main/resources/addresources/values-el-rGR/strings.xml @@ -704,7 +704,7 @@ Second \"item\" text" "Το μενού «Κομμάτι ήχου» είναι κρυμμένο -Για να εμφανίζεται το μενού κομματιού ήχου, αλλάξτε την «Παραποίηση ροών βίντεο» σε iOS TV" +Το μενού «Κομμάτι ήχου» δεν είναι διαθέσιμο όταν είναι ενεργοποιημένη η «Παραποίηση ροών βίντεο»" Μενού «Προβολή σε VR» Κρυμμένο @@ -1534,32 +1534,25 @@ Second \"item\" text" Παραποίηση ροών βίντεο Παραποίηση ροών βίντεο του προγράμματος πελάτη για την αποφυγή προβλημάτων αναπαραγωγής Παραποίηση ροών βίντεο - Οι ροές βίντεο παραποιούνται + "Οι ροές βίντεο παραποιούνται + +Αν είστε χρήστης YouTube Premium, αυτή η ρύθμιση ενδέχεται να μην απαιτείται" "Οι ροές βίντεο δεν παραποιούνται Η αναπαραγωγή βίντεο ενδέχεται να μην λειτουργεί" Η απενεργοποίηση αυτής της ρύθμισης ενδέχεται να προκαλέσει προβλήματα αναπαραγωγής βίντεο. Προεπιλεγμένο πρόγραμμα πελάτη - Εξαναγκασμός iOS AVC (H.264) - Ο κωδικοποιητής βίντεο έχει οριστεί υποχρεωτικά σε AVC (H.264) - Ο κωδικοποιητής βίντεο ορίζεται αυτόματα - "Η ενεργοποίηση αυτής της λειτουργίας ενδέχεται να βελτιώσει τη διάρκεια ζωής της μπαταρίας και να διορθώσει κολλήματα αναπαραγωγής. - -Ο AVC έχει μέγιστη ανάλυση 1080p, ο κωδικοποιητής ήχου Opus δεν είναι διαθέσιμος και η αναπαραγωγή βίντεο θα χρησιμοποιεί περισσότερα δεδομένα ίντερνετ από τον VP9 ή τον AV1." - Παρενέργειες παραποίησης σε iOS - "• Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται -• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη -• Τα βίντεο τελειώνουν 1 δευτερόλεπτο νωρίτερα" + Παρενέργειες παραποίησης Παρενέργειες παραποίησης σε Android "• Το μενού «Κομμάτι ήχου» λείπει -• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη -• Η λειτουργία «Εξαναγκασμός αρχικού ήχου» δεν είναι διαθέσιμη" +• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη" + • Πειραματικός πελάτης και ενδέχεται να σταματήσει να λειτουργεί ανά πάσα στιγμή • Δεν υπάρχει ο κωδικοποιητής βίντεο AV1 • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεδεμένοι ή σε λειτουργία ανώνυμης περιήγησης Εμφάνιση στο μενού «Στατιστικά για σπασίκλες» Το πρόγραμμα πελάτη εμφανίζεται στο μενού «Στατιστικά για σπασίκλες» Το πρόγραμμα πελάτη δεν εμφανίζεται στο μενού «Στατιστικά για σπασίκλες» - Προεπιλεγμένη γλώσσα ροής ήχου VR + Γλώσσα ροής ήχου diff --git a/patches/src/main/resources/addresources/values-es-rES/strings.xml b/patches/src/main/resources/addresources/values-es-rES/strings.xml index 5544dca79..38a793e02 100644 --- a/patches/src/main/resources/addresources/values-es-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-es-rES/strings.xml @@ -702,7 +702,7 @@ Si cambiar este ajuste no tiene efecto, intenta cambiar al modo incógnito." "El menú de la pista de audio está oculto. -Para mostrar el menú de la pista de audio, cambia \"Suplantar transmisiones de vídeo\" a iOS TV" +El menú de la pista de audio no está disponible cuando \"Falsificar transmisiones de vídeo\" está activado" Ocultar reloj en VR Ver en el menú VR está oculto @@ -1201,7 +1201,7 @@ Diseño para automóviles • El feed está organizado por temas y canales" - Versión de la aplicación Spoof + Versión de la aplicación falseada Versión falseada Versión no falseada "La versión de la aplicación se falsificará a una versión anterior de YouTube. @@ -1209,7 +1209,7 @@ Diseño para automóviles Esto cambiará la apariencia y las características de la aplicación, pero pueden producirse efectos secundarios desconocidos. Si se desactiva posteriormente, se recomienda borrar los datos de la aplicación para evitar errores en la interfaz de usuario." - Versión de aplicación falsa de destino + Versión objetiva de aplicación falsificada 19.35.36 - Restaurar iconos antiguos del reproductor de Shorts 19.01.34 - Restaurar iconos de navegación antiguos @@ -1449,7 +1449,7 @@ Habilitar esto puede desbloquear calidades de vídeo más altas" Usar el idioma de audio original Utilizando audio predeterminado - Para usar esta función, cambia \"Suplantar transmisiones de vídeo\" a iOS TV + Para usar esta función, cambia \"Falsificar transmisiones de vídeo\" a iOS TV @@ -1523,35 +1523,28 @@ Habilitar esto puede desbloquear calidades de vídeo más altas" Slide to seek no está activado - Falsificación del stream de vídeo - Falsifica el stream de vídeo del cliente para evitar problemas de reproducción - Falsificación del stream de vídeo - El stream de vídeo está falsificado + Falsificar transmisiones de vídeo + Falsifica las transmisiones de vídeo del cliente para evitar problemas de reproducción + Falsificar transmisiones de vídeo + "Las transmisiones de vídeo están falsificadas. + +Si eres un usuario de YouTube Premium, esta configuración podría no ser necesaria" "Las transmisiones de vídeo no están falsificadas Es posible que la reproducción de vídeo no funcione" Desactivar esta configuración puede causar problemas de reproducción de vídeo. Cliente por defecto - Forzar iOS AVC (H.264) - El códec de vídeo se fuerza a AVC (H.264) - El códec de vídeo se determina automáticamente - "Habilitar esto puede mejorar la duración de la batería y solucionar el tartamudeo de la reproducción. - -AVC tiene una resolución máxima de 1080p, el códec de audio Opus no está disponible y la reproducción de vídeo utilizará más datos de Internet que VP9 o AV1." - Efectos secundarios de la suplantación de iOS - "• Es posible que las películas o los vídeos pagos no se reproduzcan -• El volumen estable no está disponible -• Los vídeos terminan 1 segundo antes" - Efectos secundarios de la suplantación de Android + Efectos secundarios de la falsificación + Efectos secundarios de la falsificación de Android "• Falta el menú de la pista de audio -• El volumen estable no está disponible -• Forzar el audio original no está disponible" - • No AV1 códec de vídeo +• El volumen estable no está disponible" + • El cliente es experimental y puede dejar de funcionar en cualquier momento + • Sin códec de vídeo AV1 • Es posible que los vídeos infantiles no se reproduzcan cuando se cierra la sesión o se está en modo incógnito Mostrar en Estadísticas para nerds El tipo de cliente se muestra en Estadísticas para nerds El cliente está oculto en Estadísticas para nerds - Idioma de la transmisión de audio por defecto de VR + Idioma de la transmisión de audio diff --git a/patches/src/main/resources/addresources/values-et-rEE/strings.xml b/patches/src/main/resources/addresources/values-et-rEE/strings.xml index a511c3dfc..b9b8232cb 100644 --- a/patches/src/main/resources/addresources/values-et-rEE/strings.xml +++ b/patches/src/main/resources/addresources/values-et-rEE/strings.xml @@ -702,7 +702,7 @@ Kui selle sätte muutmine ei avalda mõju, proovige lülituda Inkognito režiimi "Heliriba menüü on peidetud -Heliriba menüü kuvamiseks muutke valikut „Võltsitud videovoogedastus“ väärtuseks iOS TV" +Heliriba menüü pole saadaval, kui \"Videovoogude võltsimine\" on lubatud" Peida Vaata VR-is Vaata VR-is menüü on peidetud @@ -1535,32 +1535,25 @@ Selle lubamine võib avada kõrgema video kvaliteedi" Võltsitud video voogedastused Võltsitud kliendi video voogedastused, et vältida taasesituse probleeme Võltsitud video voogedastused - Video voogedastused on võltsitud + "Videovood on võltsitud + +Kui olete YouTube Premiumi kasutaja, ei pruugi see säte vajalik olla" "Video vooge ei võltsita Video taasesitus ei pruugi toimida" Selle seade keelamine võib põhjustada videote taasesituse probleeme. Vaikimisi klient - Sunnitud iOS AVC (H.264) kodek - Video kodek on sunnitud AVC (H.264) kodeki - Video kodek määratakse automaatselt - "Funktsiooni sisselülitamine võib parandada aku kestvust ja videotaasesituse katkemist. - -AVC-l on maksimaalne eraldusvõime 1080p, Opus-i heli kodek pole saadaval ning video taasesitus kasutab rohkem internetiandmeid kui VP9 või AV1." - iOS-i videovoogude võltsimine - "• Filmid või tasulised videod ei pruugi taasesitada -• Stabiilne helitugevus pole saadaval -• Videod lõpevad 1 sekund varem" + Võltsimise kõrvalmõjud Androidi pettuse kõrvalmõjud - "• Heliraja menüü puudub -• Stabiilset helitugevust pole saadaval -• Sunnitud originaalheli pole saadaval" + "• Heliriba menüü puudub +• Stabiilne helitugevus pole saadaval" + • Eksperimentaalne klient ja võib igal ajal töötamast lakata • Puuduv AV1 videokoodek • Video lastele ei pruugi taasesitada, kui olete välja logitud või inkognito režiimis Kuva statistikas \"Nerdide jaoks\" Klienditüüp on statistikas \"Nerdide jaoks\" nähtav Klient on statistikas \"Nerdide jaoks\" peidetud - VR vaikeväärtus heli voo keelele + Helivoo keel diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index 52e25fa53..8ec264829 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -697,9 +697,6 @@ Jos tämän asetuksen muuttaminen ei tule voimaan, kokeile vaihtaa Incognito-til Ääniraitavalikko on piilotettu Ääniraitavalikko näytetään - "Ääniraitavalikko on piilotettu - -Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi" Piilota Katso VR-tilassa Katso VR-tilassa -valinta on piilotettu @@ -1532,32 +1529,17 @@ Tämä voi avata korkealaatuisemmat videot" Naamioi videovirrat Naamioi asiakasohjelman videovirrat toisto-ongelmien estämiseksi Naamioi videovirrat - Videovirrat naamioidaan "Videovirtoja ei naamioida Videon toisto ei välttämättä toimi" Tämän asetuksen poistaminen käytöstä voi aiheuttaa ongelmia videotoistossa. Oletusasiakasohjelma - Pakota iOS AVC (H.264) - Videokoodekiksi pakotetaan AVC (H.264) - Videokoodekki määritetään automaattisesti - "Tämän käyttöönotto voi parantaa akun kestoa ja korjata toiston tökkimisen. - -AVC:n maksimiresoluutio on 1080p, Opus-äänikoodekki ei ole käytettävissä, ja videon toisto käyttää enemmän Internet-dataa kuin VP9 tai AV1." - iOS-naamioinnin haittavaikutukset - "• Elokuvat tai maksulliset videot eivät välttämättä toistu -• Tasainen äänenvoimakkuus ei ole käytettävissä -• Videot päättyvät 1 sekuntia etuajassa" Android-naamioinnin haittavaikutukset - "• Ääniraitavalikko puuttuu -• Tasainen äänenvoimakkuus ei ole käytettävissä -• Alkuperäisen äänen pakotus ei ole käytettävissä" • Ei AV1-videokoodekkia • Lasten videot eivät ehkä toistu, kun olet kirjautunut ulos tai incognito-tilassa Näytä teknisissä tiedoissa Asiakastyyppi näytetään teknisissä tiedoissa Asiakastyyppi on piilotettu teknisissä tiedoissa - VR-äänivirran oletuskieli diff --git a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml index 4b1d5311f..6ecd649b2 100644 --- a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml +++ b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml @@ -700,7 +700,7 @@ Tandaan: Ang pagpapagana nito ay nagtatago rin ng mga ad ng video" "Nakatago ang menu ng audio track -Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS TV" +Hindi available ang menu ng audio track kapag naka-enable ang 'Pagpapanggap ng mga video stream'" Itago ang Panoorin sa VR Nakatago ang panonood sa VR menu @@ -1533,32 +1533,25 @@ Ang pagpapagana nito ay maaaring magbukas ng mas mataas na kalidad ng video"Spoof ng mga video stream Spoof ang mga video stream ng client upang maiwasan ang mga problema sa pag-playback Spoof ng mga video stream - Naka-spoof ang mga video stream + "Ang mga video stream ay pinapanggap. + +Kung ikaw ay isang user ng YouTube Premium, maaaring hindi kailangan ang setting na ito" "Ang mga stream ng video ay hindi mapapang-ulol Ang paglalaro ng video ay maaaring hindi gumana" Ang pag-off sa setting na ito ay maaaring magdulot ng mga isyu sa pag-playback ng video. Default na kliyente - Pilitin ang iOS AVC (H.264) - Ang codec ng video ay pinilit sa AVC (H.264) - Ang codec ng video ay awtomatikong natutukoy - "Ang pagpapagana nito ay maaaring mapahaba ang buhay ng baterya at ayusin ang pagkautal ng playback. - -Ang AVC ay may pinakamataas na resolusyon na 1080p, ang codec ng audio ng Opus ay hindi available, at ang playback ng video ay gagamit ng mas maraming data sa internet kaysa sa VP9 o AV1." - Mga epekto ng iOS spoofing - "• Maaaring hindi mai-play ang mga pelikula o binayarang video -• Hindi magagamit ang stable na volume -• Ang mga video ay magtatapos ng 1 segundo nang mas maaga" + Mga epekto ng pagpapanggap Mga side effect ng Android spoofing "• Nawawala ang menu ng audio track -• Hindi magagamit ang stable na volume -• Hindi magagamit ang pagpilit sa orihinal na audio" +• Hindi available ang stable na volume" + • Pang-eksperimentong kliyente at maaaring huminto sa paggana anumang oras • Walang AV1 video codec • Mga video ng mga bata ay maaaring hindi ma-play kapag naka-log out o nasa incognito mode Ipakita sa Mga Istatistika para sa mga nerds Ipinapakita ang uri ng kliyente sa Mga Istatistika para sa mga nerds Nakatago ang kliyente sa Mga Istatistika para sa mga nerds - Wika ng default na audio stream ng VR + Wika ng audio stream diff --git a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml index 1df22a7bb..6c866874f 100644 --- a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml +++ b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml @@ -700,9 +700,9 @@ Si la modification de ce paramètre ne prend pas effet, essayez de passer en mod Le menu Piste audio est masqué Le menu Piste audio est affiché - "Le menu Piste audio est masqué + "Le menu des pistes audio est masqué -Pour afficher le menu Piste audio, définissez \"Falsifier les flux vidéo\" sur iOS TV" +Le menu des pistes audio n'est pas disponible lorsque « Usurper les flux vidéo » est activé" Masquer \"Regarder en RV\" Le menu Regarder en RV est masqué @@ -1077,11 +1077,11 @@ Votre ID d'utilisateur est comme un mot de passe et ne doit jamais être partag Écrans de fin / Crédits Crédits ou moment où apparaissent les écrans de fin YouTube. Pas pour les conclusions contenant des informations. Accroche / Salutations - Présentation de la vidéo actuelle ou d\'une prochaine vidéo par le créateur, salutations et au revoir. N\'inclut pas les sections qui ajoutent du contenu supplémentaire + Présentation de la vidéo actuelle ou d\'une prochaine vidéo par le créateur, salutations et au revoir. N\'inclut pas les sections qui ajoutent du contenu supplémentaire. Aperçu / Résumé Collection de clips qui présentent ce qui va suivre ou ce qui s\'est passé dans la vidéo ou dans d\'autres vidéos d\'une série, où toutes les informations sont répétées ailleurs Digression / Blagues - Digressions ou blagues non nécessaires à la compréhension du contenu principal de la vidéo. Cette catégorie ne devrait pas contenir de segments fournissant du contexte ou des détails secondaires + Digressions ou blagues non nécessaires à la compréhension du contenu principal de la vidéo. N\'inclut pas les sections fournissant du contexte ou des détails secondaires. Musique : Segment non musical Uniquement pour utilisation dans les vidéos musicales. Sections non musicales dans les clips, qui ne sont pas déjà couvertes par une autre catégorie. Passer @@ -1536,32 +1536,25 @@ Activer cette option peut déverrouiller des qualités vidéo supérieures"Falsifier les flux vidéo Falsifiez les flux vidéo client pour prévenir les problèmes de lecture Falsifier les flux vidéo - Les flux vidéo sont falsifiés + "Les flux vidéo sont usurpés + +Si vous êtes un utilisateur YouTube Premium, ce paramètre pourrait ne pas être nécessaire" "Les flux vidéo ne sont pas falsifiés La lecture des vidéos peut ne pas fonctionner" Désactiver ce paramètre peut causer des problèmes de lecture vidéo. Client par défaut - Forcer iOS AVC (H.264) - Le codec vidéo est forcé sur AVC (H.264) - Le codec vidéo est déterminé automatiquement - "Activer cette option pourrait améliorer l'autonomie de la batterie et corriger les saccades lors de la lecture. - -AVC a une résolution maximale de 1080p et ne prend pas en charge le codec audio Opus, et la lecture vidéo utilisera plus de données Internet qu'avec VP9 ou AV1." - Effets secondaires de la falsification iOS - "• La lecture des films ou des vidéos payantes peut ne pas fonctionner -• Volume stable n'est pas disponible -• Les vidéos se terminent 1 seconde trop tôt" + Effets secondaires de l\'usurpation Effets secondaires de la falsification Android - "• Le menu Piste audio est absent -• Volume stable n'est pas disponible -• Forcer l'audio d'origine n'est pas disponible" + "• Le menu des pistes audio est manquant +• Le volume stable n'est pas disponible" + • Client expérimental et peut cesser de fonctionner à tout moment • Codec vidéo AV1 indisponible • La lecture des vidéos pour enfants peut ne pas fonctionner lorsque vous êtes déconnecté ou en mode navigation privée Afficher dans les Statistiques avancées Le type de client est affiché dans les Statistiques avancées Le client est caché dans les Statistiques avancées - Langue par défaut du flux audio en mode RV + Langue du flux audio diff --git a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml index 49ccb7ab1..88ba9d87b 100644 --- a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml +++ b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml @@ -700,9 +700,9 @@ Mura dtagann aon athrú ar an socrú seo, bain triail as mód Incognito a chur a Tá roghchlár rian fuaime i bhfolach Taispeántar roghchlár rian fuaime - "Tá roghchlár na rian fuaime i bhfolach + "Tá roghchlár an rian fuaime i bhfolach -Chun roghchlár na rian fuaime a thaispeáint, athraigh 'Srutháin físeáin bhréige' go iOS TV" +Níl roghchlár an rian fuaime ar fáil nuair atá 'Sruthanna físeáin bhréige' cumasaithe" Folaigh Watch i VR Tá faire i roghchlár VR i bhfolach @@ -1535,32 +1535,25 @@ Is féidir le seo caighdeáin físeáin níos airde a dhíghlasáil" Sruthanna físeán spoof Spoof na sruthanna físeáin cliant chun saincheisteanna athsheinm a chosc Sruthanna físeán spoof - Tá sruthanna físe spoofed + "Tá sruthanna físeáin bréagaithe + +Má tá tú i do úsáideoir YouTube Premium, seans nach mbeidh an socrú seo ag teastáil" "Níl sruthanna físeáin spoofed D'fhéadfadh nach n-oibreoidh athsheinm físeáin" Seans go mbeidh fadhbanna athsheinm físe ag baint leis an socrú seo a mhúchadh. Cliant réamhshocraithe - Féach iOS AVC (H.264) - Fórsaítear códú fhíseán chuig AVC (H.264) - Chinntítear códú fhíseán go huathoibríoch - "D'fhéadfadh a chumasú seo saol na ceallraí a fheabhsú agus stotálú athsaithe a shocrú. - -Tá réiteach uasmhéideach 1080p ag AVC, níl códú fuaime Opus ar fáil, agus bainfear úsáid as tuilleadh sonraí Idirlín le haghaidh athsaithe físeán ná VP9 nó AV1." - Éifeachtaí taobheacha sceimhlitheoireachta iOS - "• D’fhéadfadh sé nach imreodh scannáin nó físeáin íoctha -• Ní bheidh an toirt éagothroime ar fáil -• Críochnaíonn físeáin 1 soicind roimh am" + Fo-iarsmaí bréagaíochta Éifeachtaí taobh Android a mhalartú - "• Tá roghchlár na bhfuaimeanna ar iarraidh -• Níl imfhálú cobhsaí ar fáil -• Níl an fhuaim bhunúsach ar fáil" + "• Tá roghchlár an rian fuaime ar iarraidh +• Níl an toirt chobhsaí ar fáil" + • Cliant turgnamhach é seo agus féadfaidh sé stop a chur ag obair ag am ar bith • Níl aon chóidéir físe AV1 • Videos faoi phaistí uaireanta nach imreoidh nuair a bhíonn tú logáilte amach nó i mod incognito Taispeáin i Staitisticí do nerds Taispeántar cineál an chliaint i Staitisticí do nerds Tá an cliant curtha i bhfolach i Staitisticí do nerds - Teanga an sreafa fuaime réamhshocraithe VR + Teanga an tsrutha fuaime diff --git a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml index 6dc5eb312..cc3b6babb 100644 --- a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml +++ b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml @@ -700,9 +700,9 @@ Ha a beállítás módosítása nem lép életbe, próbáljon meg Inkognitó mó A hangsáv menü el van rejtve A hangsáv menü megjelenik - "Az audiosáv menü rejtett + "Az hangsáv menü elrejtve -Az audiosáv menü megjelenítéséhez módosítsa a \"Videófolyamok hamisítása\" beállítást iOS TV-re" +Az hangsáv menü nem érhető el, ha a \"Videó adatfolyamok hamisítása\" engedélyezve van" \"Megtekintés VR-módban\" elrejtése A megtekintés VR-módban menü el van rejtve @@ -1532,32 +1532,25 @@ Ez a beállítás lehetővé teszi a magasabb videóminőségek feloldását"Hamis videó stream Hamisítsa meg az ügyfél videó streamet a lejátszási problémák elkerülése érdekében Hamis videó stream - A videó stream hamisítva + "A videó adatfolyamok hamisítva vannak + +Ha Ön YouTube Premium felhasználó, ez a beállítás nem feltétlenül szükséges" "A videó streamek nem hamisítva vannak A videólejátszás nem működhet" A beállítás kikapcsolása videolejátszási problémákat okozhat. Alapértelmezett kliens - Az iOS kényyszerített AVC (H.264) videokodeket használ - A videokodek AVC-re kényszerítve (H.264) - A videokodek meghatározása automatikusan történik - "Ennek engedélyezése javíthatja az akkumulátor élettartamát és kijavíthatja a lejátszás akadozását. - -Az AVC maximális felbontása 1080p, az Opus audiokodek nem érhető el, és a videolejátszás több internetes adatot használ, mint a VP9 vagy az AV1." - iOS hamisítási mellékhatások - "• Előfordulhat, hogy a filmeket és a fizetős videókat nem lehet lejátszani -• Nem áll rendelkezésre stabil hangerő -• A videók 1 másodperccel korábban érnek véget" + Hamisítás mellékhatásai Android hamisítási mellékhatások - "• Hiányzik a hangsáv menü -• Nem áll rendelkezésre stabil hangerő -• Az eredeti hang kényszerítése nem érhető el" + "• Az hangsáv menü hiányzik +• Stabil hangerő nem érhető el" + • Kísérleti kliens, és bármikor leállhat • Nincs AV1 videokodek • A gyermekeknek szóló videók nem játszódnak le, ha a felhasználó kijelentkezett, vagy inkognitómódban van. Megjelenítés a Statisztikákban A kliens típusa a Statisztikákban látható A kliens el van rejtve a Statisztikákban - VR alapértelmezett audio adatfolyam nyelve + Hangfolyam nyelve diff --git a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml index 3a28a5b9f..d4d13721e 100644 --- a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml +++ b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml @@ -700,9 +700,9 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Աուդիո ձայնագրման մենյուը թաքցված է Աուդիո ձայնագրման մենյուը երևում է - "Աուդիո ուղու ընտրացանկը թաքնված է: + "Ձայնային ուղու մենյուն թաքնված է -Աուդիո ուղու ընտրացանկը ցուցադրելու համար փոխեք «Կեղծել տեսահոսքերը»-ը iOS TV-ի" +Ձայնային ուղու մենյուն հասանելի չէ, երբ միացված է «Տեսահոսքերը կեղծել» տարբերակը" Դիտել VR-ով թաքցնել VR-ով դիտել մենյուը թաքցված է @@ -1536,32 +1536,25 @@ Mini-player-ը կարող է գրավվել էկրանից դուրս՝ դեպի Հնարավոր է տեսանյութի հոսքերը փոփոխել Փոփոխել տեսանյութի հոսքերը համար խուսափել վերարտադրման հետ կապված պրոբլեմներից Հնարավոր է տեսանյութի հոսքերը փոփոխել - Տեսանյութի հոսքերը փոփոխված են + "Տեսահոսքերը կեղծված են + +Եթե դուք YouTube Premium օգտատեր եք, այս կարգավորումը կարող է անհրաժեշտ չլինել" "Տեսանյութի հոսքերը չեն կեղծվում Տեսանյութի վերարտադրումը կարող է չաշխատել։" Այս կարգավորման անջատումը կարող է առաջացնել տեսանյութի վերարտադրման հետ կապված պրոբլեմներ Դեֆոլտ կլիենտ - iOS-ի համար AVC (H.264) պարտադիր ակտիվացում - Վիդեո կոդեկը պարտադիր կերպով AVC (H.264) է - Վիդեո կոդեկը որոշվում է ավտոմատ կերպով - "Սա ակտիվացնելը կարող է բարելավել մարտկոցի աշխատանքի տևողությունը և վերացնել վերարտադրման խցկումները։ - -AVC-ի առավելագույն թույլտվությունը 1080p է, Opus աուդիո կոդեկը հասանելի չէ, իսկ վիդեոյի վերարտադրումը VP9-ից կամ AV1-ից ավելի շատ ինտերնետ տվյալներ կօգտագործի։" - iOS խաբեության կողմնակի ազդեցություններ - "• Ֆիլմերը կամ վճարովի տեսանյութերը չեն կարող աշխատել -• Հասանելի չէ կայուն ձայնի ծավալը -• Տեսանյութերը վերջանում են 1 վայրկյան վաղ" + Կեղծելու կողմնակի ազդեցություններ Android խաբեության կողմնակի ազդեցություններ - "• Ձայնի գրառման ընտրացանկը բացակայում է -• Ստաբիլ ձայն չկա -• Իրական ձայնի ընտրությունը հասանելի չէ" + "• Ձայնային ուղու մենյուն բացակայում է +• Կայուն ձայնի մակարդակը հասանելի չէ" + • Փորձնական հաճախորդ է և կարող է ցանկացած պահի դադարել աշխատել • Հեռացված բոլոր AV1 վիդեո կոդեկները Երեխաների տեսանյութերը կարող են չհամապատասխանել հետևյալ պահանջներին՝ եթե արտոնագրման խախտումներ կան։ Ցուցադրել վիճակագրության ակնոցներում Հաճախորդի տեսակը ցուցադրվում է վիճակագրության ակնոցներում Հաճախորդը թաքնված է վիճակագրության ակնոցներում - VR-ի համար նախապես ընտրված ձայնի գրառման լեզու + Ձայնային հոսքի լեզուն diff --git a/patches/src/main/resources/addresources/values-in-rID/strings.xml b/patches/src/main/resources/addresources/values-in-rID/strings.xml index 04b5bef2d..097c9c6a5 100644 --- a/patches/src/main/resources/addresources/values-in-rID/strings.xml +++ b/patches/src/main/resources/addresources/values-in-rID/strings.xml @@ -702,7 +702,7 @@ Jika mengubah setelan ini tidak berpengaruh, coba beralih ke mode Penyamaran." "Menu trek audio disembunyikan -Untuk menampilkan menu trek Audio, ubah 'Spoof aliran video' ke iOS TV" +Menu trek audio tidak tersedia saat 'Spoof stream video' diaktifkan" Sembunyikan Tonton di VR Menu tonton di VR disembunyikan @@ -1534,32 +1534,25 @@ Mengaktifkan ini dapat membuka kualitas video yang lebih tinggi" Palsukan aliran video Palsukan klien aliran video untuk mencegah masalah pemutaran Palsukan aliran video - Aliran video dipalsukan + "Stream video ditiru + +Jika Anda adalah pengguna YouTube Premium, setelan ini mungkin tidak diperlukan" "Streaming video tidak dipalsukan Pemutaran video mungkin tidak berfungsi" Mematikan pengaturan ini dapat menyebabkan masalah pemutaran video. Klien bawaan - Paksa iOS AVC (H.264) - Codec video dipaksa menjadi AVC (H.264) - Codec video ditentukan secara otomatis - "Mengaktifkan ini mungkin dapat meningkatkan daya tahan baterai dan memperbaiki masalah pemutaran. - -AVC memiliki resolusi maksimum 1080p, codec audio Opus tidak tersedia, dan pemutaran video akan menggunakan lebih banyak data internet daripada VP9 atau AV1." - Efek samping pemalsuan iOS - "• Film atau video berbayar mungkin tidak dapat diputar -• Volume stabil tidak tersedia -• Video berakhir 1 detik lebih awal" + Efek samping peniruan Efek samping pemalsuan Android "• Menu trek audio tidak ada -• Volume stabil tidak tersedia -• Paksa audio asli tidak tersedia" +• Volume stabil tidak tersedia" + • Klien eksperimental dan dapat berhenti berfungsi kapan saja • Tidak ada codec video AV1 • Video anak-anak mungkin tidak dapat diputar saat keluar atau dalam mode penyamaran Tampilkan di Statistik untuk nerds Jenis klien ditampilkan di Statistik untuk nerds Klien disembunyikan di Statistik untuk nerds - Bahasa aliran audio bawaan VR + Bahasa aliran audio diff --git a/patches/src/main/resources/addresources/values-it-rIT/strings.xml b/patches/src/main/resources/addresources/values-it-rIT/strings.xml index e56aff499..32f9fd2f6 100644 --- a/patches/src/main/resources/addresources/values-it-rIT/strings.xml +++ b/patches/src/main/resources/addresources/values-it-rIT/strings.xml @@ -702,7 +702,7 @@ Se la modifica di questa impostazione non ha effetto, prova a passare alla modal "Il menu della traccia audio è nascosto -Per mostrare il menu della traccia audio, cambia \"Spoof video streams\" in iOS TV" +Il menu della traccia audio non è disponibile quando \"Falsifica flussi video\" è abilitato" Nascondi Guarda in VR Il menu Guarda in VR è nascosto @@ -1534,32 +1534,25 @@ Abilitare questa opzione può sbloccare qualità video più elevate" Simula il client del flusso video Simula il client del flusso video per evitare problemi di riproduzione Simula il client del flusso video - Il client del flusso video è simulato + "I flussi video sono falsificati + +Se sei un utente YouTube Premium, questa impostazione potrebbe non essere necessaria" "I flussi video non sono simulati La riproduzione video potrebbe non funzionare" Disattivando questa impostazione potrebbe causare problemi di riproduzione video. Client predefinito - Forza iOS AVC (H.264) - Il codec video è forzato ad AVC (H.264) - Il codec video è determinato automaticamente - "L'abilitazione di questa opzione potrebbe migliorare la durata della batteria e risolvere i problemi di stuttering durante la riproduzione. - -AVC ha una risoluzione massima di 1080p, il codec audio Opus non è disponibile e la riproduzione video utilizzerà più dati Internet rispetto a VP9 o AV1." - Effetti collaterali simulazione iOS - "• I film o i video a pagamento potrebbero non riprodurre -• Il volume stabile non è disponibile -• I video terminano 1 secondo prima" + Effetti collaterali della falsificazione Effetti collaterali simulazione Android - "• Il menu traccia audio è mancante -• Il volume stabile non è disponibile -• Forza l'audio originale non è disponibile" + "• Il menu della traccia audio è mancante +• Il volume stabile non è disponibile" + • Client sperimentale e potrebbe smettere di funzionare in qualsiasi momento • Nessun codec video AV1 • I video dei bambini potrebbero non essere riprodotti quando si è disconnessi o in modalità di navigazione in incognito Mostra nelle statistiche per nerd Il tipo di client è mostrato nelle statistiche per nerd Il client è nascosto nelle statistiche per nerd - Lingua predefinita del flusso audio VR + Lingua del flusso audio diff --git a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml index 8690287e5..e5e7a4f7b 100644 --- a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml +++ b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml @@ -702,7 +702,7 @@ Second \"item\" text" "תפריט רצועת השמע מוסתר -כדי להציג את תפריט רצועת השמע, שנה את 'זיוף זרמי וידאו' ל-iOS TV" +תפריט רצועת השמע אינו זמין כאשר 'התחזות לזרמי וידאו' מופעלת" הסתר \'צפה ב-VR\' תפריט \'צפה ב-VR\' מוסתר @@ -1537,32 +1537,25 @@ Second \"item\" text" זייף זרמי וידאו זייף זרמי וידאו של לקוח כדי למנוע בעיות הפעלה זייף זרמי וידאו - זרמי וידאו הם מזויפים + "מתבצעת התחזות לזרמי וידאו + +אם אתה משתמש YouTube Premium, ייתכן שהגדרה זו אינה נחוצה" "זרמי וידאו אינם מזויפים ייתכן שהפעלת סרטון לא תעבוד" כיבוי הגדרה זו עלול לגרום לבעיות בהפעלת סרטון. לקוח ברירת מחדל - כפה iOS AVC (H.264) - קודק וידאו נכפה ל-AVC (H.264) - קוד וידאו נקבע באופן אוטומטי - "הפעלת אפשרות זו עשויה לשפר את חיי הסוללה ולתקן גמגום בהפעלה. - -ל-AVC יש רזלוציה מרבית של 1080p, קודק שמע מסוג Opus אינו זמין, והפעלת סרטון תשתמש ביותר נתוני אינטרנט מאשר VP9 או AV1." - תופעות לוואי של זיוף iOS - "• ייתכן שסרטים או סרטונים בתשלום לא יופעלו -• עוצמת קול יציבה אינה זמינה -• סרטונים מסתיימים שנייה 1 מוקדם יותר" + תופעות לוואי של התחזות תופעות לוואי של זיוף Android - "• תפריט רצועת שמע חסר -• עוצמת קול יציבה אינה זמינה -• כפה שמע מקורי אינו זמין" + "• תפריט רצועת השמע חסר +• עוצמת קול יציבה אינה זמינה" + • לקוח ניסיוני ועשוי להפסיק לפעול בכל עת • אין קודק וידאו מסוג AV1 • ייתכן שסרטוני Kids לא יופעלו כשאתה מנותק או במצב פרטי הצג בנתונים לגיקים סוג הלקוח מוצג בנתונים לגיקים הלקוח מוסתר בנתונים לגיקים - שפת זרם שמע ברירת מחדל ב-VR + שפת זרם השמע diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index 6503b1336..5d8d2c236 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -704,7 +704,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に "「音声トラック」は表示されません -「音声トラック」を表示するには、「動画ストリームを偽装」の「デフォルトのクライアント」を iOS TV に変更してください" +「動画ストリームを偽装」が有効になっている場合、「音声トラック」は利用できません" 「VR で見る」を非表示 「VR で見る」は表示されません @@ -1537,32 +1537,25 @@ Automotive レイアウト 動画ストリームを偽装 動画再生の失敗を回避するために、クライアントの動画ストリームを偽装します 動画ストリームを偽装 - 動画ストリームは偽装されます + "動画ストリームは偽装されています + +YouTube Premium ユーザーの場合、この設定は不要な場合があります" "動画ストリームは偽装されません 動画の再生に失敗する可能性があります" この設定をオフにすると、動画の再生に失敗するようになる可能性があります。 デフォルトのクライアント - iOS クライアントで AVC (H.264) を強制的に使用 - ビデオ コーデックは強制的に AVC (H.264) が使用されます - ビデオ コーデックは自動的に決定されます - "この機能を有効にすると、バッテリー寿命が延びたり、動画のカクつきが改善さたりする可能性があります。 - -AVC は、最大解像度が 1080p であり、Opus オーディオ コーデックが利用できず、動画再生時の通信量が VP9 や AV1 より多くなります。" - iOS クライアントの副作用 - "• 映画や有料動画が再生されない可能性がある -•「 一定音量」が利用できない -• 動画が 1 秒早く終了する" + 偽装による副作用 Android クライアントの副作用 "• 「音声トラック」がフライアウト メニューに表示されない -• 「一定音量」が利用できない -• 「オリジナルの音声を強制的に使用」が利用できない" +• 「一定音量」が利用できない" + • 実験的なクライアントであり、いつでも動作を停止する可能性があります • AV1 コーデックが利用できない • ログアウト時またはシークレット モード時に、子ども向け動画が再生されない可能性がある 統計情報に表示する 統計情報に現在のクライアントが表示されます 統計情報に現在のクライアントは表示されません - デフォルトの音声トラック(Android VR) + 音声ストリーム言語 diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index b2adc2a51..cec654327 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -701,7 +701,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 "오디오 트랙 메뉴가 숨겨집니다 -오디오 트랙 메뉴를 표시하려면, '동영상 스트림 변경하기'에서 기본 클라이언트를 iOS TV로 변경하세요" +\"동영상 스트림 변경하기\"가 활성화된 경우 오디오 트랙 메뉴를 사용할 수 없습니다." VR로 보기 메뉴 숨기기 VR로 보기 메뉴가 숨겨집니다 @@ -1542,31 +1542,24 @@ DeArrow에 대해 자세히 알아보려면 여기를 탭하세요" 동영상 스트림 변경하기 클라이언트 동영상 스트림을 변경하여 재생 문제를 방지할 수 있습니다 동영상 스트림 변경하기 - 동영상 스트림을 변경합니다 + "동영상 스트림이 변경되었습니다 + +YouTube Premium 사용자라면 이 설정은 필요하지 않을 수 있습니다." "동영상 스트림을 변경하지 않습니다 동영상 재생 문제가 발생할 수 있습니다" 이 설정을 비활성화하면 동영상 재생 문제가 발생할 수 있습니다. 기본 클라이언트 - iOS AVC (H.264) 강제로 활성화하기 - 동영상 코덱이 AVC (H.264)로 강제로 결정됩니다 - 동영상 코덱이 자동으로 결정됩니다 - "이 설정를 활성화하면 배터리 수명이 향상되고, 동영상 재생 끊김 문제가 해결될 수 있습니다. - -AVC의 최대 화질 값은 1080p이고, OPUS 코덱을 사용불가 및 HDR 동영상을 재생할 수 없으며, 동영상을 재생했을 경우에는 VP9 또는 AV1보다 더 많은 모바일 데이터를 사용되오니 주의하세요." - iOS 변경에 따른 부작용 - "• 영화 또는 유료 동영상이 재생되지 않을 수 있습니다 -• 안정적인 볼륨을 사용할 수 없습니다 -• 동영상이 1초 일찍 종료될 수 있습니다" + 변경에 따른 부작용 Android 변경에 따른 부작용 "• 오디오 트랙 메뉴가 표시되지 않습니다 -• 안정적인 볼륨을 사용할 수 없습니다 -• 원본 오디오 트랙를 강제로 활성화할 수 없습니다" +• 안정적인 볼륨을 사용할 수 없습니다" + • 실험용 클라이언트이며 언제든지 작동이 중단될 수 있습니다. • AV1 코덱이 지원되지 않습니다 • Kids 동영상은 로그인을 하지 않았거나 시크릿 모드에서는 재생되지 않을 수 있습니다 전문 통계에서 표시하기 동영상 스트림을 가져오는 데 사용되는 클라이언트가 전문 통계에서 표시됩니다 동영상 스트림을 가져오는 데 사용되는 클라이언트가 전문 통계에서 표시되지 않습니다 - VR 기본 오디오 스트림 언어 + 오디오 스트림 언어 diff --git a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml index 8f21d9dc9..7f1980edc 100644 --- a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml +++ b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml @@ -700,7 +700,9 @@ Jei pakeitus šį nustatymą neįsigalioja, pabandykite perjungti į inkognito r Garso takelių meniu yra paslėptas Garso takelių meniu yra rodomas - "Garso takelio meniu yra paslėptas.\n\nNorėdami parodyti garso takelio meniu, pakeiskite „Apsimesti vaizdo srautais“ į „iOS TV“" + "Garso takelio meniu paslėptas + +Garso takelio meniu nepasiekiamas, kai įjungta „Klastoti vaizdo srautus“" Slėpti Žiūrėti VR Žiūrėti VR meniu yra paslėptas @@ -1534,32 +1536,25 @@ Gali būti atrakinta aukštesnės vaizdo įrašų kokybės, bet galite patirti v Susifalsifikuoti vaizdo įrašų srautus Susifalsifikuoti kliento vaizdo įrašų srautus, kad būtų išvengta atkūrimo problemų Susifalsifikuoti vaizdo įrašų srautus - Vaizdo įrašų srautai yra susifalsifikuoti + "Vaizdo srautai klastojami + +Jei esate YouTube Premium naudotojas, šis nustatymas gali būti nereikalingas" "Vaizdo įrašų srautai nėra padirbti Vaizdo įrašo atkūrimas gali neveikti" Išjungus šį nustatymą, gali kilti vaizdo įrašų atkūrimo problemų. Numatytasis klientas - Priverstinė iOS AVC (H.264) - Vaizdo kodekas yra priverstinai nustatytas kaip AVC (H.264) - Vaizdo kodekas nustatomas automatiškai - "Įjungus šią funkciją gali pagerėti baterijos veikimo laikas ir nebebus vaizdo strigimo. - -AVC didžiausia skiriamoji geba yra 1080 p, „Opus“ garso kodekas negalimas, o vaizdo įrašo atkūrimas sunaudos daugiau interneto duomenų nei naudojant VP9 arba AV1." - „iOS“ apsimetinėjimo šalutiniai poveikiai - "• Filmai ar mokami vaizdo įrašai gali būti neatkuriami -• Stabilaus garso lygio nėra -• Vaizdo įrašai baigiasi 1 sekunde anksčiau" + Klastojimo šalutiniai efektai Android apsimetinėjimo šalutiniai poveikiai "• Trūksta garso takelio meniu -• Nėra stabilaus garso -• Negalima priverstinai naudoti originalo garso" +• Stabilus garsumas nepasiekiamas" + • Eksperimentinis klientas ir bet kada gali nustoti veikti • Nėra AV1 vaizdo kodeko • Vaikų vaizdo įrašai gali būti neatkuriami, kai atsijungiama arba naudojamas inkognito režimas Rodyti statistinėje informacijoje \"tik profesionalams\" Kliento tipas rodomas statistinėje informacijoje \"tik profesionalams\" Klientas paslėptas statistinėje informacijoje \"tik profesionalams\" - VR numatytoji srautinio garso kalba + Garso srauto kalba diff --git a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml index d5b4469b9..c22e802d9 100644 --- a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml +++ b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml @@ -700,9 +700,9 @@ Ja šī iestatījuma maiņa nestājas spēkā, mēģiniet pārslēgties uz inkog Audio ceļa izvēlne ir paslēpta Audio ceļa izvēlne ir redzama - "Audio celiņu izvēlne ir paslēpta. + "Audio celiņa izvēlne ir paslēpta -Lai parādītu audio celiņu izvēlni, mainiet \"Video straumju viltošana\" uz iOS TV" +Audio celiņa izvēlne nav pieejama, kad ir iespējots \"Viltot video straumes\"" Paslēpt Skatīties VR Skatīties VR izvēlne ir paslēpta @@ -1536,32 +1536,25 @@ Var tikt atbloķētas augstākas video kvalitātes, taču var rasties video atsk Viltot video straumes Viltot klienta video straumes, lai novērstu atskaņošanas problēmas Viltot video straumes - Video straumes ir viltotas + "Video straumes ir viltotas + +Ja esat YouTube Premium lietotājs, šis iestatījums, iespējams, nav nepieciešams" "Video straumes nav viltotas Video atskaņošana var nedarboties" Šī iestatījuma atspējošana var izraisīt video atskaņošanas problēmas. Noklusētā klients - Spēka iOS AVC (H.264) - Video kodeks ir piespiests AVC (H.264) - Video kodeks tiek automātiski noteikts - "Iespējojot to, var uzlabot akumulatora darbības laiku un novērst atskaņošanas aizķeršanos. - -AVC maksimālā izšķirtspēja ir 1080p, Opus audio kodeks nav pieejams, un video atskaņošanā tiks patērēts vairāk interneta datu nekā VP9 vai AV1." - iOS izlikšanās blakusefekti - "• Filmas vai apmaksāti video, iespējams, netiks atskaņoti -• Nav pieejams stabils skaļums -• Video beidzas 1 sekundi par ātru" + Viltotu straumju blakusparādības Android viltus straumēšanas blakus efekti - "• Trūkst audio celiņa izvēlnes -• Nav pieejams stabils skaļums -• Nav pieejama oriģinālā audio piespiešana" + "• Audio celiņa izvēlne trūkst +• Nav pieejams stabils skaļums" + • Eksperimentāls klients un jebkurā brīdī var pārtraukt darbu • Nav pieejams AV1 video kodeks • Bērnu videoklipi var netikt atskaņoti, kad esat izrakstījies vai inkognito režīmā. Rādīt statistiskos datos entuziastiem Klienta tips tiek rādīts statistiskos datos entuziastiem Klients ir paslēpts statistiskos datos entuziastiem - VR noklusējuma audio straumes valoda + Audio straumes valoda diff --git a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml index c76000d69..1d3ff8d7f 100644 --- a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml +++ b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml @@ -700,9 +700,9 @@ Als het wijzigen van deze instelling geen effect heeft, probeer dan over te scha Menu Audiotrack is verborgen Menu Audiotrack wordt weergegeven - "Audiotrackmenu is verborgen + "Audiotracks-menu is verborgen -Om het audiotrackmenu weer te geven, wijzigt u 'Videostreams vervalsen' in iOS TV" +Het audiotracks-menu is niet beschikbaar wanneer 'Videostreams spoofen' is ingeschakeld" Verberg Bekijk in VR Menu Bekijk in VR is verborgen @@ -1533,32 +1533,25 @@ Het inschakelen hiervan kan hogere videokwaliteiten ontgrendelen" Videostreams vervalsen Vervals de client-videostreams om afspeelproblemen te voorkomen Videostreams vervalsen - Videostreams worden vervalst + "Videostreams worden gespooft + +Als je een YouTube Premium-gebruiker bent, is deze instelling mogelijk niet vereist" "Videostreams worden niet gespoofed Video-playback werkt mogelijk niet" Het uitschakelen van deze instelling kan afspeelproblemen veroorzaken. Standaard client - Forceer iOS AVC (H.264) - De videocodec is geforceerd naar AVC (H.264). - De videocodec wordt automatisch bepaald. - "Als u deze functie inschakelt, kan de batterijduur worden verlengd en kan schokkerig afspelen worden verholpen. - -AVC heeft een maximale resolutie van 1080p, de Opus-audiocodec is niet beschikbaar en videoweergave verbruikt meer internetgegevens dan VP9 of AV1." - iOS-spoofingeffects - "• Films of betaalde video's worden mogelijk niet afgespeeld -• Stabiel volume is niet beschikbaar -• Video's eindigen 1 seconde te vroeg" + Spoofing-neveneffecten Bijwerkingen van Android-spoofing - "• Het menu Audiotracks ontbreekt -• Stabiel volume is niet beschikbaar -• Forceer originele audio is niet beschikbaar" + "• Audiotracks-menu ontbreekt +• Stabiel volume is niet beschikbaar" + • Experimentele client en kan elk moment stoppen met werken • Geen AV1-videocodec • \"Kinder\"​-Video’s worden mogelijk niet afgespeeld wanneer u bent uitgelogd of de incognitomodus gebruikt Weergeven in Stats for nerds Het clienttype wordt getoond in Stats for nerds Client is verborgen in Stats for nerds - Standaardtaal van VR-audiostream + Audiostreamtaal diff --git a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml index 20a526292..81c6d0db9 100644 --- a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml +++ b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml @@ -696,9 +696,9 @@ Jeśli zmiana tego ustawienia nie przyniesie efektu, spróbuj przełączyć się Menu ścieżki dźwiękowej jest ukryte Menu ścieżki dźwiękowej jest widoczne - "Menu ścieżki audio jest ukryte + "Menu ścieżek dźwiękowych jest ukryte -Aby pokazać menu ścieżki audio, zmień opcję „Fałszuj strumienie wideo” na iOS TV" +Menu ścieżek dźwiękowych jest niedostępne, gdy włączona jest opcja \"Fałszowanie strumieni wideo\"" Menu oglądania w VR Menu oglądania w VR jest ukryte @@ -1531,32 +1531,25 @@ Włączenie tego może odblokować wyższe jakości wideo" Oszukaj strumienie filmu Oszukuje strumienie filmu klienta, aby zapobiec problemom z odtwarzaniem Oszukaj strumienie filmu - Oszukiwanie strumienia jest włączone + "Strumienie wideo są fałszowane + +Jeśli jesteś użytkownikiem YouTube Premium, to ustawienie może nie być wymagane" "Strumienie wideo nie są sfałszowane Odtwarzanie wideo może nie działać" Wyłączenie tej opcji może spowodować problemy z odtwarzaniem filmów. Domyślny klient - Wymuszaj iOS AVC (H.264) - Kodek wideo jest wymuszany na AVC (H.264) - Kodek wideo jest określany automatycznie - "Włączenie tej opcji może poprawić żywotność baterii i naprawić zacinanie się odtwarzania. - -AVC ma maksymalną rozdzielczość 1080p, kodek audio Opus nie jest dostępny, a odtwarzanie wideo będzie zużywać więcej danych internetowych niż VP9 lub AV1." - Skutki uboczne podszywania się pod iOS - "- Filmy lub płatne wideo mogą nie być odtwarzane -- Stabilna głośność nie jest dostępna -- Filmy kończą się o 1 sekundę za wcześnie" + Skutki uboczne fałszowania Efekty uboczne podszywania się pod Androida - "• Brakuje menu ścieżki audio -• Stabilna głośność jest niedostępna -• Wymuś oryginalny dźwięk jest niedostępny" + "• Brak menu ścieżek dźwiękowych +• Stabilna głośność jest niedostępna" + • Eksperymentalny klient i może przestać działać w każdej chwili • Žádný video kodek AV1 • Filmy dla dzieci mogą nie być odtwarzane po wylogowaniu lub w trybie incognito Pokaż w statystykach dla nerdów Typ klienta jest wyświetlany w Statystykach dla nerdów Klient jest ukryty w statystykach dla nerdów - Język domyślnego strumienia audio VR + Język strumienia audio diff --git a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml index 31f03069d..fe56ef724 100644 --- a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml @@ -700,9 +700,9 @@ Se alterar esta configuração não fizer efeito, tente mudar para o modo anôni Menu faixa de áudio está oculto Menu faixa de áudio não está oculto - "O menu da faixa de áudio está oculto + "Menu de faixas de áudio está oculto -Para exibir o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV" +O menu de faixa de áudio não está disponível quando \"Falsificar streams de vídeo\" está ativado" Ocultar Assistir no VR Menu assistir no VR está oculto @@ -1534,32 +1534,25 @@ Habilitar isso pode desbloquear qualidades de vídeo mais altas" Spoofing do fluxo de vídeo Spoofa o fluxo de vídeo do cliente para evitar problemas de reprodução Spoofing do fluxo de vídeo - Fluxo de vídeo spoofado + "Streams de vídeo são falsificados + +Se você é um usuário do YouTube Premium, esta configuração pode não ser necessária" "Os streams de vídeo não são falsificados A reprodução de vídeo pode não funcionar" Desativar esta configuração pode causar problemas de reprodução de vídeo. Cliente padrão - Forçar iOS AVC (H.264) - O codec de vídeo é forçado para AVC (H.264) - O codec de vídeo é determinado automaticamente - "A ativação desta opção pode aumentar a vida útil da bateria e corrigir problemas de reprodução. - -A AVC tem uma resolução máxima de 1080p, o codec de áudio Opus não está disponível, e a reprodução de vídeo usará mais dados de internet do que VP9 ou AV1." - Efeitos colaterais da falsificação do iOS - "• Filmes ou vídeos pagos podem não ser reproduzidos -• O volume estável não está disponível -• Os vídeos terminam 1 segundo antes" + Efeitos colaterais da falsificação Efeitos colaterais da falsificação do Android - "• Menu de faixa de áudio está faltando -• Volume estável não está disponível -• Forçar áudio original não está disponível" + "• O menu de faixa de áudio está faltando +• Volume estável não está disponível" + • Cliente experimental e pode parar de funcionar a qualquer momento • Sem codec de vídeo AV1 • Vídeos infantis podem não ser reproduzidos quando estiver desconectado ou no modo de navegação anônima Mostrar em Estatísticas para nerds O tipo de cliente é mostrado em Estatísticas para nerds O cliente está oculto em Estatísticas para nerds - Idioma do fluxo de áudio padrão de VR + Idioma do fluxo de áudio diff --git a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml index 376d6c3e9..63356e313 100644 --- a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml @@ -702,7 +702,7 @@ Se alterar esta configuração não fizer efeito, tente alternar para o modo an "O menu da faixa de áudio está oculto -Para mostrar o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV" +O menu da faixa de áudio não está disponível quando 'Falsificar streams de vídeo' está ativado" Esconder relógio no VR Assista no menu VR está escondido @@ -1535,32 +1535,25 @@ Bật tính năng này có thể mở khóa chất lượng video cao hơn"Fluxos de vídeo falsos Disfarçar os fluxos de vídeo do cliente para evitar problemas de reprodução Fluxos de vídeo falsos - Fluxos de vídeo são falsificados + "Streams de vídeo falsificados + +Se você for um usuário do YouTube Premium, esta configuração pode não ser necessária" "Luồng video không bị giả mạo Phát video có thể không hoạt động" Desativar essa configuração pode causar problemas de reprodução de vídeo. Cliente predefinido - Força AVC iOS (H.264) - Codificação de vídeo forçada a AVC (H.264) - Codificação de vídeo é automaticamente determinada - "Ativar pode melhorar bateria e resolver reprodução travando. - -A AVC tem resolução máxima de 1080p, Opus audio codec não está disponível, e reprodução de vídeo usará mais internet que VP9 ou AV1." - Efeitos secundários de falsificação do iOS - "- Os filmes ou vídeos pagos podem não ser reproduzidos -- O volume estável não está disponível -- Os vídeos terminam 1 segundo mais cedo" + Efeitos colaterais da falsificação Efeitos colaterais da falsificação do Android - "- Falta o menu de faixas áudio -- O volume estável não está disponível -- O áudio original forçado não está disponível" + "• O menu da faixa de áudio está faltando +• O volume estável não está disponível" + • Cliente experimental e pode parar de funcionar a qualquer momento • Nenhum codec de vídeo AV1 • Vídeos infantis podem não ser reproduzidos quando desconectado ou no modo anônimo Mostrar em Estatísticas para nerds O tipo de cliente é mostrado em Estatísticas para nerds O cliente está oculto em Estatísticas para nerds - Idioma do fluxo do áudio do VR predefinido + Idioma do fluxo de áudio diff --git a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml index 704c3616c..d276d4ec9 100644 --- a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml +++ b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml @@ -700,9 +700,9 @@ Dacă modificarea acestei setări nu are efect, încercați să comutați la mod Meniul piesei audio este ascuns Meniul piesei audio este afișat - "Meniul pentru pista audio este ascuns + "Meniul piesei audio este ascuns -Pentru a afișa meniul pentru pista audio, schimbați opțiunea „Falsifică fluxurile video” în iOS TV" +Meniul piesei audio nu este disponibil când \"Simulează fluxurile video\" este activat" Ascunde ceas în VR Vizionarea în meniul VR este ascunsă @@ -1534,32 +1534,25 @@ Activarea acestei opțiuni poate debloca calități video mai mari" Spoof video stream-uri Sporirea canalelor video client pentru a preveni problemele de redare Spoof video stream-uri - Fluxurile video sunt falsificate + "Fluxurile video sunt simulate + +Dacă ești utilizator YouTube Premium, această setare ar putea să nu fie necesară" "Fluxurile video nu sunt falsificate Este posibil ca redarea video să nu funcționeze" Dezactivarea acestei setări poate cauza probleme de redare video. Client implicit - Forțarea codecului video AVC (H.264) - Codecul video este forțat la AVC (H.264) - Codecul video este determinat automat - "Activarea acestei opțiuni ar putea îmbunătăți durata de viață a bateriei și remedia întreruperile redării. - -AVC are o rezoluție maximă de 1080p, codecul audio Opus nu este disponibil, iar redarea video va folosi mai multe date de internet decât VP9 sau AV1." - Efecte secundare ale falsificării iOS - "• Este posibil ca filmele sau videoclipurile plătite să nu se redea. -• Volumul stabil nu este disponibil. -• Videoclipurile se termină cu 1 secundă mai devreme." + Efecte secundare ale simulării Efecte secundare spoofing Android - "• Meniul cu piesele audio lipsește -• Volumul stabil nu este disponibil -• Forțarea sunetului original nu este disponibilă" + "• Meniul piesei audio lipsește +• Volumul stabil nu este disponibil" + • Client experimental și se poate opri din funcționare oricând • Fara codec video AV1 • Copiii nu pot urmări videoclipuri atunci când sunt deconectați sau în modul incognito Afișează în Statistici pentru pasionați Tipul clientului este afișat în Statistici pentru pasionați Clientul este ascuns în Statistici pentru pasionați - Limba implicită a fluxului audio VR + Limba fluxului audio diff --git a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml index 716b9a0cf..fec9f75ba 100644 --- a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml +++ b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт Пункт \"Звуковая дорожка\" в выдвижном меню плеера показан - "Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт + "Меню звуковой дорожки скрыто -Для показа пункта \"Звуковая дорожка\" измените клиент \"Подмены видеопотоков\" на iOS TV" +Меню звуковой дорожки недоступно, когда включена функция 'Подмена видеопотоков'" Скрыть пункт \"Смотреть в VR-режиме\" Пункт \"Смотреть в VR-режиме\" в выдвижном меню плеера скрыт @@ -1542,32 +1542,25 @@ Second \"item\" text" Подмена видеопотоков Подмена клиента видеопотоков для предотвращения проблем с воспроизведением видео Подменить видеопотоки - Видеопотоки подменены + "Видеопотоки подменены + +Если вы являетесь пользователем YouTube Premium, эта настройка может не потребоваться" "Видеопотоки не подменены Воспроизведение видео может не работать" Отключение этой настройки может вызвать проблемы с воспроизведением видео Клиент по умолчанию - Принудительно iOS AVC (H.264) - Видеокодек принудительно установлен на AVC (H.264) - Видеокодек определяется автоматически - "Включение данной опции может улучшить время автономной работы и устранить прерывания при воспроизведении. - -Максимальное разрешение видео в формате AVC составляет 1080p. Аудиокодек Opus недоступен. Воспроизведение видео будет потреблять больше интернет трафика, чем VP9 или AV1." - Побочные эффекты подмены на iOS - "• Фильмы и платные видео могут не воспроизводиться -• Стабильный уровень громкости недоступен -• Видео заканчиваются на 1 секунду раньше" + Побочные эффекты подмены Побочные эффекты подмены на Android "• Меню выбора звуковой дорожки отсутствует -• Функция воспроизведения видео с постоянной громкостью недоступна -• Принудительное использование оригинального звука недоступно" +• Функция воспроизведения видео с постоянной громкостью недоступна" + • Экспериментальный клиент и может перестать работать в любое время • Отсутствует видеокодек AV1 • Видео для детей могут не воспроизводиться при выходе из системы или в режиме инкогнито Показать в \"Статистике для сисадминов\" Тип клиента в \"Статистике для сисадминов\" показан Тип клиента в \"Статистике для сисадминов\" скрыт - Язык аудиопотока по умолчанию для VR + Язык аудиопотока diff --git a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml index d92705f40..a5a0fd8e6 100644 --- a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml +++ b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml @@ -698,9 +698,7 @@ Ak zmena tohto nastavenia nemá žiadny účinok, skúste prepnúť do režimu i Ponuka zvukovej stopy je skrytá Zobrazí sa ponuka zvukovej stopy - "Ponuka zvukovej stopy je skrytá - -Ak chcete zobraziť ponuku zvukovej stopy, zmeňte možnosť „Oklamať videostreamy“ na iOS TV" + "Ponuka zvukových stôp je skrytá Ponuka zvukových stôp nie je k dispozícii, keď je povolená možnosť \"Podvrhnúť video streamy\"" Skryť hodinky vo VR Sledovanie v ponuke VR je skryté @@ -1528,32 +1526,22 @@ Povolením tejto možnosti môžete odomknúť vyššie kvality videa" Falošné video strémy Falošné video strémy klienta, aby sa predišlo problémom s prehrávaním Falošné video strémy - Video strémy sú falošné + "Video streamy sú podvrhnuté Ak ste používateľom YouTube Premium, toto nastavenie nemusí byť potrebné" "Video streamy nie sú falošné Prehrávanie videa nemusí fungovať" Vypnutie tohto nastavenia môže spôsobiť problémy s prehrávaním videa. Predvolený klient - Vynútiť iOS AVC (H.264) - Video kodek je vynútený na AVC (H.264) - Video kodek sa určuje automaticky - "Povolenie tejto možnosti môže zlepšiť výdrž batérie a opraviť sekanie prehrávania. - -AVC má maximálne rozlíšenie 1080p, zvukový kodek Opus nie je k dispozícii a prehrávanie videa bude využívať viac internetových dát ako VP9 alebo AV1." - Vedľajšie účinky falošnej polohy iOS - "• Filmy alebo platené videá sa nemusia prehrať -• Stabilná hlasitosť nie je k dispozícii -• Videá sa končia o 1 sekundu skôr" + Vedľajšie účinky podvrhnutia Vedľajšie účinky spoofingu Androidu - "• Chýba ponuka zvukových stôp -• Nie je k dispozícii stabilná hlasitosť -• Výber originálneho zvuku nie je k dispozícii" + "• Ponuka zvukových stôp chýba • Stabilná hlasitosť nie je k dispozícii" + • Experimentálny klient a môže kedykoľvek prestať fungovať • Žiadny video kodek AV1 • Videá pre deti sa nemusia prehrávať, keď ste odhlásení alebo v režime inkognito Zobraziť v štatistike pre expertov Typ klienta sa zobrazuje v štatistikách pre expertov Klient je skrytý v štatistikách pre expertov - Predvolený jazyk zvukovej stopy VR + Jazyk zvukového streamu diff --git a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml index 6ea16d62d..1f2449f6d 100644 --- a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml +++ b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml @@ -700,9 +700,9 @@ Opomba: Omogočanje tega tudi prisilno skrije video oglase" Meni z zvočnim posnetkom je skrit Meni z zvočnim posnetkom je prikazan - "Meni zvočnega posnetka je skrit + "Meni za zvočno skladbo je skrit -Če želite prikazati meni zvočnega posnetka, spremenite možnost »Prikazovalnik video tokov« v iOS TV" +Meni za zvočno skladbo ni na voljo, ko je omogočena možnost \"Ponarejene video tokove\"" Skrij gledanje v VR Meni z gledanjem v VR je skrit @@ -1535,32 +1535,24 @@ Omogočanje tega lahko odklene višje kakovosti videa" Ponarejanje video tokov Ponaredite video tokove odjemalca, da preprečite težave s predvajanjem Ponarejanje video tokov - Video tokovi so ponarejeni + "Video tokovi so ponarejeni +Če ste uporabnik YouTube Premium, ta nastavitev morda ni potrebna" "Videoprenosni tokovi niso posneti Predvajanje videa morda ne bo delovalo" Izklop te nastavitve lahko povzroči težave s predvajanjem videoposnetkov. Privzeti odjemalec - Sile iOS AVC (H.264) - Kodek videa je prisiljen v AVC (H.264) - Kodek videa je določen samodejno - "Omogočanje tega bi lahko izboljšalo življenjsko dobo baterije in odpravilo zatikanje predvajanja. - -AVC ima največjo ločljivost 1080p, avdio kodek Opus ni na voljo, predvajanje videa pa bo porabilo več internetnih podatkov kot VP9 ali AV1." - iOS-ov pojav umetnega predvajanja posnetkov - "• Filmi ali plačani videoposnetki se morda ne bodo predvajali -• Stalna glasnost ni na voljo -• Videi se končajo 1 sekundo prezgodaj" + Stranski učinki ponarejanja Android Stranski učinki spoofing - "• Manjka meni za izbiro zvočnega posnetka -• Stabilna glasnost ni na voljo -• Prisilno izvirno zvočno posnetek ni na voljo" + "• Meni za zvočno skladbo manjka +• Stabilna glasnost ni na voljo" + • Eksperimentalni odjemalec in lahko kadar koli preneha delovati • Brez kodeka videa AV1 • Posnetki za otroke se mogoče ne bodo predvajali, ko ste odjavljeni ali v načinu brez beleženja zgodovine Pokaži v statistiki za piflarje Vrsta odjemalca je prikazana v statistiki za piflarje Odjemalec je skrit v statistiki za piflarje - Privzeti jezik zvočnega posnetka za VR + Jezik zvočnega toka diff --git a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml index d3b99dfd8..a9aada4d0 100644 --- a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml +++ b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml @@ -700,9 +700,9 @@ Nëse ndryshimi i këtij konfigurimi nuk ka efekt, provoni të kaloni në modali Menyja \"Shina e audios\" është e fshehur Menyja \"Shina e audios\" është e dukshme - "Menyja e pistës audio është e fshehur + "Menyja e gjurmës audio është e fshehur -Për të shfaqur menunë e pistës audio, ndryshoni 'Falsifiko transmetimet video' në iOS TV" +Menyja e gjurmës audio nuk është e disponueshme kur \"Falsifikoni transmetimet video\" është e aktivizuar" Fsheh \"Shikoni në VR\" Menyja \"Shikoni në VR\" është e fshehur @@ -1533,32 +1533,25 @@ Aktivizimi i kësaj mund të zhbllokojë cilësi më të larta video" Mashtro rrjedhat e videos Mashtro rrjedhat e videos së klientit për të parandaluar problemet e luajtjes Mashtro rrjedhat e videos - Rrjedhat e videos janë të mashtruara + "Transmetimet video janë falsifikuar + +Nëse jeni përdorues i YouTube Premium, ky cilësim mund të mos jetë i nevojshëm" "Rrjedhat e videove nuk janë spoofed Shikimi i videove mund të mos funksionojë" Çaktivizimi i kësaj cilësimi mund të shkaktojë probleme me luajtjen e videos. Klient i përdoruesit - Forco AVC (H.264) për iOS - Kodiku video është detyruar të jetë AVC (H.264) - Kodiku video është përcaktuar automatikisht - "Aktivizimi i kësaj mund të përmirësojë jetëgjatësinë e baterisë dhe të rregullojë ngecjet gjatë shfaqjes. - -AVC ka një rezolucion maksimal prej 1080p, kodeku audio Opus nuk është i disponueshëm dhe shfaqja e videos do të përdorë më shumë të dhëna interneti sesa VP9 ose AV1." - Efekte anësore të falsifikimit të iOS - "• Filmat ose videot e paguara s'mund të luhen -• Volumi i qëndrueshëm nuk është i disponueshëm -• Videot përfundojnë 1 sekondë më parë" + Efektet anësore të falsifikimit Efekte anësore të spoofinguit të Android - "• Menutë me audiot mungon -• Vellimi i qëndrueshëm nuk është në dispozicion -• Zbatimi i audio origjinalit nuk është në dispozicion" + "• Menyja e gjurmës audio mungon +• Volumi i qëndrueshëm nuk është i disponueshëm" + • Klient eksperimental dhe mund të ndalojë së funksionuari në çdo kohë • Nuk ka codec video AV1 • Video për fëmijë mund të mos luajnë kur jeni jashtë llogarisë ose në modalitetin incognito Shfaqni në Statistikat për nerdës Lloji i klientit shfaqet në Statistikat për nerds Klienti është fshehur në statistikat për nerds - Gjuha e rrjedhës audio VR + Gjuha e transmetimit audio diff --git a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml index 0b6a2d534..601fc2c92 100644 --- a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml @@ -700,9 +700,9 @@ Ako se promena ove opcije ne primeni, pokušajte da pređete u režim bez arhivi Meni „Audio snimak” je skriven Meni „Audio snimak” je prikazan - "Meni „Audio snimak” je skriven + "Meni audio zapisa je skriven -Da biste prikazali meni „Audio snimak”, promenite opciju „Lažirani video strimovi” na iOS TV" +Meni audio zapisa nije dostupan kada je \"Lažiranje video tokova\" omogućeno" Sakrij dugme „Gledaj u VR” Dugme „Gledaj u VR” je skriveno @@ -1534,32 +1534,25 @@ Ako ovo omogućite, mogu biti otključani viši kvaliteti videa" Lažirani video strimovi Lažiranje klijenta video strimova da bi se sprečili problemi sa reprodukcijom Lažirani video strimovi - Video strimovi su lažirani + "Video tokovi su lažirani + +Ako ste YouTube Premium korisnik, ovo podešavanje možda neće biti potrebno" "Video strimovi nisu lažirani Reprodukcija videa možda neće raditi" Isključivanje ove opcije će možda izazvati probleme sa reprodukcijom videa. Podrazumevani klijent - Prisili na AVC (H.264) na iOS-u - Video kodek je prisilno podešen na AVC (H.264) - Video kodek se određuje automatski - "Omogućavanje ovoga može poboljšati trajanje baterije i popraviti zastoje pri reprodukciji. - -AVC ima maksimalnu rezoluciju od 1080p, audio kodek Opus nije dostupan, a reprodukcija videa će koristiti više internet podataka nego VP9 ili AV1." - Neželjeni efekti lažiranja na iOS - "• Filmovi ili plaćeni videi se možda neće puštati -• Ujednačena jačina zvuka nije dostupna -• Videi će se završavati 1 sekundu ranije" + Nuspojave lažiranja Neželjeni efekti lažiranja na Android - "• Meni „Audio snimak” nedostaje -• Ujednačena jačina zvuka nije dostupna -• Opcija „Prisili originalni zvuk” nije dostupna" + "• Meni audio zapisa nedostaje +• Stabilna jačina zvuka nije dostupna" + • Eksperimentalni klijent i može prestati da radi bilo kada • Nema video kodeka AV1 • Videi za decu se možda neće puštati kada ste odjavljeni ili u režimu bez arhiviranja Prikaži u „Statistici za znalce” Tip klijenta je prikazan u „Statistici za znalce” Tip klijenta je skriven u „Statistici za znalce” - Podrazumevani jezik audio strima za VR + Jezik audio toka diff --git a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml index 265ea3fac..f5519c1f6 100644 --- a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" Мени „Аудио снимак” је скривен Мени „Аудио снимак” је приказан - "Мени „Аудио снимак” је скривен + "Мени аудио записа је скривен -Да бисте приказали мени „Аудио снимак”, промените опцију „Лажирани видео стримови” на iOS TV" +Мени аудио записа није доступан када је омогућено „Имитирање видео стримова“" Сакриј дугме „Гледај у ВР” Дугме „Гледај у ВР” је скривено @@ -1537,32 +1537,25 @@ Second \"item\" text" Лажирани видео стримови Лажирање клијента видео стримова да би се спречили проблеми са репродукцијом Лажирани видео стримови - Видео стримови су лажирани + "Видео стримови су имитирани + +Ако сте корисник YouTube Premium-а, ово подешавање можда неће бити потребно" "Видео стримови нису лажирани Репродукција видеа можда неће радити" Искључивање ове опције ће можда изазвати проблеме са репродукцијом видеа. Подразумевани клијент - Присили на AVC (H.264) на iOS-у - Видео кодек је присилно подешен на AVC (H.264) - Видео кодек се одређује аутоматски - "Омогућавање овога може побољшати трајање батерије и поправити застоје при репродукцији. - -AVC има максималну резолуцију од 1080p, аудио кодек Opus није доступан, а репродукција видеа ће користити више интернет података него VP9 или AV1." - Нeжељени ефекти лажирања на iOS - "• Филмови или плаћени видеи се можда неће пуштати -• Уједначена јачина звука није доступна -• Видеи ће се завршавати 1 секунду раније" + Нежељени ефекти имитирања Нежељени ефекти лажирања на Android - "• Мени „Аудио снимак” недостаје -• Уједначена јачина звука није доступна -• Опција „Присили оригинални звук” није доступна" + "• Мени аудио записа недостаје +• Стабилна јачина звука није доступна" + • Експериментални клијент који може престати да ради било када • Нема видео кодека AV1 • Видеи за децу се можда неће пуштати када сте одјављени или у режиму без архивирања Прикажи у „Статистици за зналце” Тип клијента је приказан у „Статистици за зналце” Тип клијента је скривен у „Статистици за зналце” - Подразумевани језик аудио стрима за ВР + Језик аудио стрима diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index c49dcc7a7..06edc868a 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -702,7 +702,7 @@ Om du ändrar den här inställningen utan att det träder i kraft kan du testa "Menyn Ljudspår är dold -För att visa menyn Ljudspår, ändra \"Förfalska videoströmmar\" till iOS TV" +Menyn Ljudspår är inte tillgänglig när \"Förfalska videoströmmar\" är aktiverad" Dölj Titta i VR Menyn Titta i VR är dold @@ -1534,32 +1534,25 @@ Om du aktiverar detta kan högre videokvaliteter låsas upp" Förfalska videoströmmar Förfalska klientens videoströmmar för att förhindra uppspelningsproblem Förfalska videoströmmar - Videoströmmar är förfalskade + "Videoströmmar förfalskas + +Om du är en YouTube Premium-användare kanske den här inställningen inte behövs" "Videoströmmar förfalskas inte Videouppspelning kanske inte fungerar" Om du stänger av den här inställningen kan det leda till problem med videouppspelning. Standardklient - Tvinga iOS AVC (H.264) - Videokodek tvingas till AVC (H.264) - Videokodeken bestäms automatiskt - "Om du aktiverar detta kan det förbättra batteritiden och åtgärda hackig uppspelning. - -AVC har en maximal upplösning på 1080p, Opus-ljudkodek är inte tillgängligt och videouppspelning använder mer internetdata än VP9 eller AV1." - Biverkningar av iOS-förfalskning - "• Filmer eller betalvideor kanske inte spelas upp -• Jämn volym är inte tillgänglig -• Videor slutar 1 sekund för tidigt" + Biverkningar av förfalskning Biverkningar av Android-förfalskning "• Ljudspårsmenyn saknas -• Jämn volym är inte tillgänglig -• Tvinga fram ursprungligt ljud är inte tillgängligt" +• Jämn volym är inte tillgänglig" + • Experimentell klient och kan sluta fungera när som helst • Ingen AV1-videokodek • Videor för barn kanske inte spelas upp när du är utloggad eller i inkognitoläge Visa i Statistik för nördar Klienttypen visas i Statistik för nördar Klienten är dold i Statistik för nördar - Standardspråk för VR-ljudström + Ljudströmmens språk diff --git a/patches/src/main/resources/addresources/values-th-rTH/strings.xml b/patches/src/main/resources/addresources/values-th-rTH/strings.xml index b23f95d0b..c72738914 100644 --- a/patches/src/main/resources/addresources/values-th-rTH/strings.xml +++ b/patches/src/main/resources/addresources/values-th-rTH/strings.xml @@ -698,9 +698,9 @@ Second \"item\" text" เมนูแทร็กเสียงซ่อนอยู่ เมนูแทร็กเสียงแสดงอยู่ - "เมนูแทร็กเสียงถูกซ่อนอยู่ + "เมนูแทร็กเสียงถูกซ่อนไว้ -หากต้องการแสดงเมนูแทร็กเสียง ให้เปลี่ยน 'จำลองสตรีมวิดีโอ' เป็น iOS TV" +เมนูแทร็กเสียงไม่พร้อมใช้งานเมื่อเปิดใช้งาน 'ปลอมแปลงสตรีมวิดีโอ'" ซ่อนดูใน VR เมนูดูใน VR ซ่อนอยู่ @@ -1537,32 +1537,25 @@ User id ของคุณเหมือนกับรหัสผ่าน วิดีโอปลอม ปลอมสตรีมวิดีโอของไคลเอ็นต์เพื่อป้องกันปัญหาการเล่น วิดีโอปลอม - สตรีมวิดีโอถูกปลอมแปลง + "สตรีมวิดีโอถูกปลอมแปลง + +หากคุณเป็นผู้ใช้ YouTube Premium การตั้งค่านี้อาจไม่จำเป็น" "สตรีมวิดีโอไม่ถูกปลอมแปลง การเล่นวิดีโออาจไม่ทํางาน" การปิดการตั้งค่านี้ อาจทำให้เกิดปัญหาในการเล่นวิดีโอ ไคลเอ็นต์เริ่มต้น - บังคับ AVC (H.264) ของ iOS - บังคับตัวแปลงสัญญาณวิดีโอเป็น AVC (H.264) - ตัวแปลงสัญญาณวิดีโอถูกกำหนดโดยอัตโนมัติ - "การเปิดใช้งานฟีเจอร์นี้อาจช่วยยืดอายุแบตเตอรี่และแก้ไขปัญหาการกระตุกของวิดีโอ - -AVC มีความละเอียดสูงสุด 1080p, ตัวแปลงสัญญาณเสียง Opus ไม่พร้อมใช้งาน และการเล่นวิดีโอจะใช้ข้อมูลอินเทอร์เน็ตมากกว่า VP9 หรือ AV1" - ผลข้างเคียงของการสปูฟ iOS - "• ภาพยนตร์หรือวิดีโอแบบเสียเงินอาจไม่สามารถเล่นได้ -• ระดับเสียงที่คงที่จะไม่สามารถใช้งานได้ -• วิดีโอจะจบเร็วขึ้น 1 วินาที" + ผลข้างเคียงของการปลอมแปลง ผลข้างเคียงของการปลอมแปลง Android "• เมนูแทร็กเสียงหายไป -• ปรับระดับเสียงอัตโนมัติใช้งานไม่ได้ -• เปิดเสียงต้นฉบับใช้งานไม่ได้" +• ระดับเสียงคงที่ใช้งานไม่ได้" + • ไคลเอนต์ทดลองและอาจหยุดทำงานได้ตลอดเวลา • ไม่มีตัวแปลงสัญญาณวิดีโอ AV1 • วิดีโอเด็กอาจไม่เล่นเมื่อลงชื่อออกหรืออยู่ในโหมดไม่ระบุตัวตน แสดงในสถิติสำหรับพวกเนิร์ด แสดงชนิดไคลเอ็นต์ในสถิติสำหรับพวกเนิร์ด ซ่อนไคลเอ็นต์ในสถิติสำหรับพวกเนิร์ด - ภาษาของสตรีมเสียงเริ่มต้นของ VR + ภาษาของสตรีมเสียง diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index 4d116be1a..73a7dd6e8 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -702,7 +702,7 @@ Bu ayarı değiştirmek etkili olmazsa, Gizli moda geçmeyi deneyin." "Ses parçası menüsü gizli -Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayarını iOS TV olarak değiştirin" +\"Video akışlarını taklit et\" etkinken ses parçası menüsü kullanılamaz" VR modunda izlemeyi gizle VR modunda izle menüsü gizli @@ -1542,32 +1542,25 @@ Bunu etkinleştirmek daha yüksek video kalitelerini açabilir" Video akışlarını taklit et Oynatma sorunlarını önlemek için istemci video akışlarını taklit et Video akışlarını taklit et - Video akışları taklit edilir + "Video akışları taklit ediliyor. + +YouTube Premium kullanıcısıysanız, bu ayar gerekli olmayabilir" "Video akışları taklit edilmez Video oynatma çalışmayabilir" Bu ayarı devre dışı bırakmak video oynatma sorunlarına yol açabilir. Varsayılan istemci - iOS AVC\'yi (H.264) zorla - Video kodeği AVC\'ye (H.264) zorlandı - Video kodeği otomatik olarak belirlenir - "Bu özelliği etkinleştirmek, pil ömrünü iyileştirebilir ve oynatma takılmalarını düzeltebilir. - -AVC'nin maksimum çözünürlüğü 1080p'dir, Opus ses kodeği kullanılamaz ve video oynatma VP9 veya AV1'den daha fazla internet verisi kullanır." - iOS taklidi yan etkileri - "• Filmler veya ücretli videolar oynatılamayabilir -• Sabit ses özelliği kullanılamaz -• Videolar 1 saniye erken biter" + Taklit yan etkileri Android taklidi yan etkileri "• Ses parçası menüsü eksik -• Sabit ses özelliği kullanılamaz -• Orijinal sesi zorlama kullanılamaz" +• Sabit ses özelliği kullanılamaz" + • Deneysel istemci ve her an çalışmayı durdurabilir • AV1 video kodeği yok • Çocuk videoları oturum açılmadığında veya gizli modda oynatılamayabilir Meraklısı için istatistiklerde göster İstemci tipi meraklısı için istatistiklerde gösterilir İstemci, meraklısı için istatistiklerde gizli - VR varsayılan ses akışı dili + Ses akışı dili diff --git a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml index 2fbb5dbcd..ab2af0b06 100644 --- a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml +++ b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml @@ -702,7 +702,7 @@ Second \"item\" text" "Пункт меню \"Звукова доріжка\" приховано -Для того, щоб пункт меню \"Звукова доріжка\" показувався, змініть клієнт \"Підробки відеопотоків\" на iOS TV" +Пункт меню \"Звукова доріжка\" недоступний, коли увімкнено \"Підробку відеопотоків\"" Приховати \"Дивитись у VR\" Пункт меню \"Дивитись у VR\" приховано @@ -1534,32 +1534,25 @@ Second \"item\" text" Підробка відеопотоків Підробка відеопотоків клієнта для запобігання проблем відтворенням Підробка відеопотоків - Відеопотоки підроблено + "Відеопотоки підроблені + +Якщо ви є користувачем YouTube Premium, це налаштування може не знадобитися" "Відеопотоки не підроблено Відтворення відео може не працювати" Вимкнення цього параметра може спричинити проблеми відтворення відео. Клієнт за замовчуванням - Примусово iOS AVC (H.264) - Відеокодек примусово встановлено на AVC (H.264) - Відеокодек визначається автоматично - "Увімкнення цієї функції може подовжити термін автономної роботи батареї та усунути затримки відтворення. - -AVC має максимальну роздільну здатність 1080p, аудіокодек Opus недоступний, а для відтворення відео використовуватиметься більше Інтернет-даних, ніж VP9 або AV1." - Побічні ефекти підробки iOS - "• Фільми та платні відео можуть не відтворюватися -• Меню стабілізації гучності недоступне -• Відео закінчуються на 1 секунду раніше" + Побічні ефекти підробки Побічні ефекти підробки Android "• Меню звукової доріжки відсутнє -• Меню стабілізації гучності недоступне -• Примусове використання оригінальний звукової доріжки недоступне" +• Меню стабілізації гучності недоступне" + • Експериментальний клієнт, який може припинити роботу в будь-який час • Відсутній відеокодек AV1 • Відео для дітей можуть не відтворюватися, якщо вийти з облікового запису або перейти в анонімний режим Показувати у \"Статистиці для сисадмінів\" Тип клієнта відображається у вікні \"Статистика для сисадмінів\" Тип клієнта приховано у вікні \"Статистика для сисадмінів\" - Звукова доріжка за замовчуванням для VR + Мова звукової доріжки diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index 1f7104a50..e44cc5912 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -702,7 +702,7 @@ Nếu thay đổi cài đặt này không có hiệu lực, hãy thử chuyển "Trình đơn bản âm thanh đã bị ẩn -Để hiển thị bản âm thanh, hãy đổi 'Giả mạo luồng video' thành iOS TV" +Trình đơn bản âm thanh không khả dụng khi tính năng 'Giả mạo luồng video' được bật" Ẩn Xem ở chế độ thực tế ảo Trình đơn xem ở chế độ thực tế ảo đã bị ẩn @@ -1541,32 +1541,25 @@ Bật tính năng này có thể mở khóa chất lượng video cao hơn"Giả mạo luồng video Giả mạo luồng video của thiết bị nhằm ngăn chặn lỗi khi phát Giả mạo luồng video - Luồng video đã được giả mạo + "Luồng video đã được giả mạo + +Nếu bạn là người dùng YouTube Premium, thì cài đặt này có thể không cần thiết" "Luồng video không được giả mạo Có thể gặp lỗi khi phát video" Tắt cài đặt này có thể gây ra lỗi khi phát video. Loại thiết bị mặc định - Bắt buộc iOS AVC (H.264) - Codec video bị buộc phải là AVC (H.264) - Codec video sẽ được xác định tự động - "Bật tuỳ chọn này có thể giúp tiết kiệm pin và khắc phục tình trạng giật lag khi phát video. - -AVC hỗ trợ độ phân giải tối đa là 1080p, codec âm thanh OPUS không khả dụng và phát video sẽ tiêu tốn nhiều dữ liệu di động hơn so với VP9 hoặc AV1." - Hạn chế khi giả mạo iOS - "• Phim hoặc video có trả phí có thể không phát được -• Âm lượng ổn định không khả dụng -• Video kết thúc sớm hơn 1 giây" + Hạn chế khi giả mạo Hạn chế khi giả mạo Android "• Trình đơn bản âm thanh bị thiếu -• Âm lượng ổn định không khả dụng -• Tùy chọn âm thanh gốc không khả dụng" +• Âm lượng ổn định không khả dụng" + • Ứng dụng thử nghiệm và có thể ngừng hoạt động bất cứ lúc nào • Không có codec video AV1 • Video dành cho trẻ em có thể không phát được khi đăng xuất hoặc ở chế độ ẩn danh Hiện trong Thống kê chi tiết Loại máy khách đã được hiển thị trong Thống kê chi tiết Loại thiết bị đã ẩn trong Thống kê chi tiết - Ngôn ngữ âm thanh mặc định (VR) + Ngôn ngữ luồng âm thanh diff --git a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml index c88464b1e..82890158a 100644 --- a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml @@ -700,9 +700,9 @@ Second \"item\" text" 音轨菜单已隐藏 音轨菜单已显示 - "音频轨道菜单已隐藏 + "音轨菜单已隐藏 -要显示音频轨道菜单,请将“欺骗视频流”更改为 iOS TV" +启用“欺骗视频流”时,音轨菜单不可用" 隐藏「在 VR 模式下观看」 在 VR 模式下观看已隐藏 @@ -1540,32 +1540,25 @@ Second \"item\" text" 伪造视频流 伪造客户端视频流以防止播放问题 伪造视频流 - 已伪造视频流 + "视频流已欺骗 + +如果您是 YouTube Premium 用户,此设置可能不需要" "视频流未被欺骗 视频播放可能无法正常工作" 关闭此选项可能会导致视频不能正常播放。 默认客户端 - 强制 iOS 使用 AVC (H.264) - 视频编解码器强制为 AVC (H.264) - 视频编解码器将自动确定 - "启用此选项可能会延长电池寿命并修复播放卡顿。 - -AVC 的最大分辨率为 1080p,Opus 音频编解码器不可用,视频播放将比 VP9 或 AV1 使用更多互联网数据。" - 模拟 iOS 设备可能会导致以下副作用: - "• 电影或付费视频可能无法播放 -• 音量无法稳定 -• 视频会提前 1 秒结束" + 欺骗的副作用 Android 模拟的副作用 - "• 音频轨道菜单缺失 -• 稳定音量不可用 -• 强制原始音频不可用" + "• 音轨菜单缺失 +• 稳定音量不可用" + • 实验性客户端,可能随时停止工作 • 不支持 AV1 视频编解码器 • 注销或使用无痕模式时,儿童视频可能无法播放 显示在 Stats for nerds 中 客户端类型显示在 Stats for nerds 中 客户端隐藏在 Stats for nerds 中 - VR 默认音频流语言 + 音频流语言 diff --git a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml index 960a437de..6f572e553 100644 --- a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml @@ -700,9 +700,6 @@ Second \"item\" text" 已隱藏「音軌」選單 已顯示「音軌」選單 - "已隱藏「音軌」選單 - -如要顯示音軌選單,請將「欺騙視訊串流」變更為 iOS TV" 隱藏「以 VR 模式觀看」 已隱藏「以 VR 模式觀看」 @@ -1545,32 +1542,17 @@ Second \"item\" text" 偽裝影片串流 偽裝用戶端影片串流以避免播放問題 偽裝影片串流 - 已偽裝影片串流 "沒有偽裝影片串流 影片播放可能無法正常運作" 關閉此設定可能會導致影片播放發生問題 預設用戶端 - 強制 iOS AVC (H.264) - 影片解碼器強制為 AVC (H.264) - 自動選擇影片解碼器 - "啟用此功能或許可以提升電池壽命並修正播放不順暢的問題。 - -A​VC 的最高解析度為 1080p,不支援 Opus 音訊解碼器,而且與 VP9 或 AV1 相比,影片播放會使用更多網際網路流量。" - 偽裝 iOS 的副作用 - "• 電影或付費影片可能無法播放 -• 無法使用穩定音量控制 -• 影片提前 1 秒結束" 偽裝 Android 的副作用 - "• 音訊選單遺失 -• 無法使用穩定音量 -• 無法強制使用原始音訊" • 沒有 AV1 影片解碼器 • 在登出或無痕模式下,兒童影片可能無法播放 顯示統計資料 已在統計資料中顯示用戶端類型 已在統計資料中隱藏用戶端類型 - 預設 VR 音訊串流語言 From 1d65887e015a067196f5a84db486fff355c96596 Mon Sep 17 00:00:00 2001 From: brosssh <44944126+brosssh@users.noreply.github.com> Date: Mon, 15 Sep 2025 21:28:01 +0200 Subject: [PATCH 08/11] feat(Instagram): Add `Hide explore feed` patch (#5856) --- patches/api/patches.api | 4 +++ .../instagram/hide/explore/Fingerprints.kt | 9 +++++ .../instagram/hide/explore/HideExploreFeed.kt | 33 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 6d4c6e065..70df3fdcc 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -264,6 +264,10 @@ public final class app/revanced/patches/instagram/ads/HideAdsPatchKt { public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/instagram/hide/explore/HideExploreFeedKt { + public static final fun getHideExportFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/instagram/hide/navigation/HideNavigationButtonsKt { public static final fun getHideNavigationButtonsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt new file mode 100644 index 000000000..63402788b --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt @@ -0,0 +1,9 @@ + +package app.revanced.patches.instagram.hide.explore + +import app.revanced.patcher.fingerprint + +internal val exploreResponseJsonParserFingerprint = fingerprint { + strings("sectional_items", "ExploreTopicalFeedResponse") + custom { method, _ -> method.name == "parseFromJson" } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt new file mode 100644 index 000000000..25ff17907 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt @@ -0,0 +1,33 @@ +package app.revanced.patches.instagram.hide.explore + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Suppress("unused") +val hideExportFeedPatch = bytecodePatch( + name = "Hide explore feed", + description = "Hides posts and reels from the explore/search page.", + use = false +) { + compatibleWith("com.instagram.android") + + execute { + exploreResponseJsonParserFingerprint.method.apply { + val sectionalItemStringIndex = exploreResponseJsonParserFingerprint.stringMatches!!.first().index + val sectionalItemStringRegister = getInstruction(sectionalItemStringIndex).registerA + + /** + * Replacing the JSON key we want to skip with a random string that is not a valid JSON key. + * This way the feeds array will never be populated. + * Received JSON keys that are not handled are simply ignored, so there are no side effects. + */ + replaceInstruction( + sectionalItemStringIndex, + "const-string v$sectionalItemStringRegister, \"BOGUS\"" + ) + } + } +} + From f304c178e2632b3fae35e310df96cfe39ebd7b67 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 Sep 2025 19:30:52 +0000 Subject: [PATCH 09/11] chore: Release v5.38.0-dev.1 [skip ci] # [5.38.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.3...v5.38.0-dev.1) (2025-09-15) ### Features * **Instagram:** Add `Hide explore feed` patch ([#5856](https://github.com/ReVanced/revanced-patches/issues/5856)) ([1d65887](https://github.com/ReVanced/revanced-patches/commit/1d65887e015a067196f5a84db486fff355c96596)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d1af85da..8f7e09b58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.38.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.3...v5.38.0-dev.1) (2025-09-15) + + +### Features + +* **Instagram:** Add `Hide explore feed` patch ([#5856](https://github.com/ReVanced/revanced-patches/issues/5856)) ([1d65887](https://github.com/ReVanced/revanced-patches/commit/1d65887e015a067196f5a84db486fff355c96596)) + ## [5.37.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.2...v5.37.1-dev.3) (2025-09-15) diff --git a/gradle.properties b/gradle.properties index 83afc41dd..46bbfaaa4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.37.1-dev.3 +version = 5.38.0-dev.1 From 5e20bd80f138d7ca94f18857194c46e489c435dc Mon Sep 17 00:00:00 2001 From: MarcaD <152095496+MarcaDian@users.noreply.github.com> Date: Tue, 16 Sep 2025 09:53:49 +0300 Subject: [PATCH 10/11] feat(YouTube Music): Add `Settings` patch (#5838) Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- .../music/patches/HideCategoryBarPatch.java | 14 ++ .../music/patches/HideGetPremiumPatch.java | 14 ++ .../music/patches/HideUpgradeButtonPatch.java | 14 ++ .../music/patches/HideVideoAdsPatch.java | 17 ++ .../music/patches/PermanentRepeatPatch.java | 14 ++ .../music/settings/GoogleApiActivityHook.java | 84 ++++++++ .../extension/music/settings/Settings.java | 21 ++ .../ReVancedPreferenceFragment.java | 38 ++++ .../shared/settings/BaseActivityHook.java | 142 +++++++++++++ .../preference/ClearLogBufferPreference.java | 3 +- .../ExportLogToClipboardPreference.java | 3 +- .../preference/ToolbarPreferenceFragment.java | 150 ++++++++++++++ .../youtube/settings/LicenseActivityHook.java | 188 +++++++++--------- .../ReVancedPreferenceFragment.java | 129 +++--------- patches/api/patches.api | 22 +- .../patches/music/ad/video/HideVideoAds.kt | 32 ++- .../EnableExclusiveAudioPlayback.kt | 7 + .../permanentrepeat/PermanentRepeatPatch.kt | 34 +++- .../layout/compactheader/HideCategoryBar.kt | 32 ++- .../layout/premium/HideGetPremiumPatch.kt | 40 +++- ...ttonPatch.kt => HideUpgradeButtonPatch.kt} | 35 +++- .../BypassCertificateChecksPatch.kt | 7 + .../BackgroundPlaybackPatch.kt | 17 +- .../music/misc/gms/GmsCoreSupportPatch.kt | 26 ++- .../music/misc/settings/Fingerprints.kt | 11 + .../music/misc/settings/SettingsPatch.kt | 176 ++++++++++++++++ ...eoStreams.kt => SpoofVideoStreamsPatch.kt} | 32 ++- .../misc/spoof/SpoofVideoStreamsPatch.kt | 4 +- .../misc/debugging/EnableDebuggingPatch.kt | 11 +- .../youtube/misc/gms/GmsCoreSupportPatch.kt | 14 +- .../youtube/misc/settings/SettingsPatch.kt | 22 +- .../resources/addresources/values/arrays.xml | 6 +- .../resources/addresources/values/strings.xml | 96 ++++++--- .../revanced_music_settings_with_toolbar.xml | 40 ++++ .../settings/music/values/styles.xml | 7 + 35 files changed, 1207 insertions(+), 295 deletions(-) create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/patches/HideCategoryBarPatch.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/patches/HideGetPremiumPatch.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/patches/HideUpgradeButtonPatch.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/patches/HideVideoAdsPatch.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/patches/PermanentRepeatPatch.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/settings/GoogleApiActivityHook.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/settings/Settings.java create mode 100644 extensions/music/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java create mode 100644 extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseActivityHook.java rename extensions/{youtube/src/main/java/app/revanced/extension/youtube => shared/library/src/main/java/app/revanced/extension/shared}/settings/preference/ClearLogBufferPreference.java (88%) rename extensions/{youtube/src/main/java/app/revanced/extension/youtube => shared/library/src/main/java/app/revanced/extension/shared}/settings/preference/ExportLogToClipboardPreference.java (88%) create mode 100644 extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java rename patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/{RemoveUpgradeButtonPatch.kt => HideUpgradeButtonPatch.kt} (70%) create mode 100644 patches/src/main/kotlin/app/revanced/patches/music/misc/settings/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt rename patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/{SpoofVideoStreams.kt => SpoofVideoStreamsPatch.kt} (51%) create mode 100644 patches/src/main/resources/settings/layout/revanced_music_settings_with_toolbar.xml create mode 100644 patches/src/main/resources/settings/music/values/styles.xml diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/HideCategoryBarPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideCategoryBarPatch.java new file mode 100644 index 000000000..f0433ccb1 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideCategoryBarPatch.java @@ -0,0 +1,14 @@ +package app.revanced.extension.music.patches; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class HideCategoryBarPatch { + + /** + * Injection point + */ + public static boolean hideCategoryBar() { + return Settings.HIDE_CATEGORY_BAR.get(); + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/HideGetPremiumPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideGetPremiumPatch.java new file mode 100644 index 000000000..658c0e59a --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideGetPremiumPatch.java @@ -0,0 +1,14 @@ +package app.revanced.extension.music.patches; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class HideGetPremiumPatch { + + /** + * Injection point + */ + public static boolean hideGetPremiumLabel() { + return Settings.HIDE_GET_PREMIUM_LABEL.get(); + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/HideUpgradeButtonPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideUpgradeButtonPatch.java new file mode 100644 index 000000000..8d3e022b1 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideUpgradeButtonPatch.java @@ -0,0 +1,14 @@ +package app.revanced.extension.music.patches; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class HideUpgradeButtonPatch { + + /** + * Injection point + */ + public static boolean hideUpgradeButton() { + return Settings.HIDE_UPGRADE_BUTTON.get(); + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/HideVideoAdsPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideVideoAdsPatch.java new file mode 100644 index 000000000..9c4d51ee3 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/HideVideoAdsPatch.java @@ -0,0 +1,17 @@ +package app.revanced.extension.music.patches; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class HideVideoAdsPatch { + + /** + * Injection point + */ + public static boolean showVideoAds(boolean original) { + if (Settings.HIDE_VIDEO_ADS.get()) { + return false; + } + return original; + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/patches/PermanentRepeatPatch.java b/extensions/music/src/main/java/app/revanced/extension/music/patches/PermanentRepeatPatch.java new file mode 100644 index 000000000..b44b0a3f1 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/patches/PermanentRepeatPatch.java @@ -0,0 +1,14 @@ +package app.revanced.extension.music.patches; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class PermanentRepeatPatch { + + /** + * Injection point + */ + public static boolean permanentRepeat() { + return Settings.PERMANENT_REPEAT.get(); + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/settings/GoogleApiActivityHook.java b/extensions/music/src/main/java/app/revanced/extension/music/settings/GoogleApiActivityHook.java new file mode 100644 index 000000000..8597113c6 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/settings/GoogleApiActivityHook.java @@ -0,0 +1,84 @@ +package app.revanced.extension.music.settings; + +import android.app.Activity; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.preference.PreferenceFragment; +import android.view.View; + +import app.revanced.extension.music.settings.preference.ReVancedPreferenceFragment; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.BaseActivityHook; + +/** + * Hooks GoogleApiActivity to inject a custom ReVancedPreferenceFragment with a toolbar. + */ +public class GoogleApiActivityHook extends BaseActivityHook { + /** + * Injection point + *

+ * Creates an instance of GoogleApiActivityHook for use in static initialization. + */ + @SuppressWarnings("unused") + public static GoogleApiActivityHook createInstance() { + // Must touch the Music settings to ensure the class is loaded and + // the values can be found when setting the UI preferences. + // Logging anything under non debug ensures this is set. + Logger.printInfo(() -> "Permanent repeat enabled: " + Settings.PERMANENT_REPEAT.get()); + + return new GoogleApiActivityHook(); + } + + /** + * Sets the fixed theme for the activity. + */ + @Override + protected void customizeActivityTheme(Activity activity) { + // Override the default YouTube Music theme to increase start padding of list items. + // Custom style located in resources/music/values/style.xml + activity.setTheme(Utils.getResourceIdentifier("Theme.ReVanced.YouTubeMusic.Settings", "style")); + } + + /** + * Returns the resource ID for the YouTube Music settings layout. + */ + @Override + protected int getContentViewResourceId() { + return Utils.getResourceIdentifier("revanced_music_settings_with_toolbar", "layout"); + } + + /** + * Returns the fixed background color for the toolbar. + */ + @Override + protected int getToolbarBackgroundColor() { + return Utils.getResourceColor("ytm_color_black"); + } + + /** + * Returns the navigation icon with a color filter applied. + */ + @Override + protected Drawable getNavigationIcon() { + Drawable navigationIcon = ReVancedPreferenceFragment.getBackButtonDrawable(); + navigationIcon.setColorFilter(Utils.getAppForegroundColor(), PorterDuff.Mode.SRC_IN); + return navigationIcon; + } + + /** + * Returns the click listener that finishes the activity when the navigation icon is clicked. + */ + @Override + protected View.OnClickListener getNavigationClickListener(Activity activity) { + return view -> activity.finish(); + } + + /** + * Creates a new ReVancedPreferenceFragment for the activity. + */ + @Override + protected PreferenceFragment createPreferenceFragment() { + return new ReVancedPreferenceFragment(); + } +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/settings/Settings.java b/extensions/music/src/main/java/app/revanced/extension/music/settings/Settings.java new file mode 100644 index 000000000..394cc7b3e --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/settings/Settings.java @@ -0,0 +1,21 @@ +package app.revanced.extension.music.settings; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + +import app.revanced.extension.shared.settings.BaseSettings; +import app.revanced.extension.shared.settings.BooleanSetting; + +public class Settings extends BaseSettings { + + // Ads + public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_music_hide_video_ads", TRUE, true); + public static final BooleanSetting HIDE_GET_PREMIUM_LABEL = new BooleanSetting("revanced_music_hide_get_premium_label", TRUE, true); + public static final BooleanSetting HIDE_UPGRADE_BUTTON = new BooleanSetting("revanced_music_hide_upgrade_button", TRUE, true); + + // General + public static final BooleanSetting HIDE_CATEGORY_BAR = new BooleanSetting("revanced_music_hide_category_bar", FALSE, true); + + // Player + public static final BooleanSetting PERMANENT_REPEAT = new BooleanSetting("revanced_music_play_permanent_repeat", FALSE, true); +} diff --git a/extensions/music/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java b/extensions/music/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java new file mode 100644 index 000000000..67ca69ba4 --- /dev/null +++ b/extensions/music/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java @@ -0,0 +1,38 @@ +package app.revanced.extension.music.settings.preference; + +import android.widget.Toolbar; + +import app.revanced.extension.music.settings.GoogleApiActivityHook; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment; + +/** + * Preference fragment for ReVanced settings. + */ +@SuppressWarnings({"deprecation", "NewApi"}) +public class ReVancedPreferenceFragment extends ToolbarPreferenceFragment { + + /** + * Initializes the preference fragment. + */ + @Override + protected void initialize() { + super.initialize(); + + try { + Utils.sortPreferenceGroups(getPreferenceScreen()); + setPreferenceScreenToolbar(getPreferenceScreen()); + } catch (Exception ex) { + Logger.printException(() -> "initialize failure", ex); + } + } + + /** + * Sets toolbar for all nested preference screens. + */ + @Override + protected void customizeToolbar(Toolbar toolbar) { + GoogleApiActivityHook.setToolbarLayoutParams(toolbar); + } +} diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseActivityHook.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseActivityHook.java new file mode 100644 index 000000000..a24897ca5 --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseActivityHook.java @@ -0,0 +1,142 @@ +package app.revanced.extension.shared.settings; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.graphics.drawable.Drawable; +import android.preference.PreferenceFragment; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toolbar; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment; + +/** + * Base class for hooking activities to inject a custom PreferenceFragment with a toolbar. + * Provides common logic for initializing the activity and setting up the toolbar. + */ +@SuppressWarnings({"deprecation", "NewApi"}) +public abstract class BaseActivityHook extends Activity { + + /** + * Layout parameters for the toolbar, extracted from the dummy toolbar. + */ + protected static ViewGroup.LayoutParams toolbarLayoutParams; + + /** + * Sets the layout parameters for the toolbar. + */ + public static void setToolbarLayoutParams(Toolbar toolbar) { + if (toolbarLayoutParams != null) { + toolbar.setLayoutParams(toolbarLayoutParams); + } + } + + /** + * Initializes the activity by setting the theme, content view and injecting a PreferenceFragment. + */ + public static void initialize(BaseActivityHook hook, Activity activity) { + try { + hook.customizeActivityTheme(activity); + activity.setContentView(hook.getContentViewResourceId()); + + // Sanity check. + String dataString = activity.getIntent().getDataString(); + if (!"revanced_settings_intent".equals(dataString)) { + Logger.printException(() -> "Unknown intent: " + dataString); + return; + } + + PreferenceFragment fragment = hook.createPreferenceFragment(); + hook.createToolbar(activity, fragment); + + activity.getFragmentManager() + .beginTransaction() + .replace(Utils.getResourceIdentifier("revanced_settings_fragments", "id"), fragment) + .commit(); + } catch (Exception ex) { + Logger.printException(() -> "initialize failure", ex); + } + } + + /** + * Creates and configures a toolbar for the activity, replacing a dummy placeholder. + */ + @SuppressLint("UseCompatLoadingForDrawables") + protected void createToolbar(Activity activity, PreferenceFragment fragment) { + // Replace dummy placeholder toolbar. + // This is required to fix submenu title alignment issue with Android ASOP 15+ + ViewGroup toolBarParent = activity.findViewById( + Utils.getResourceIdentifier("revanced_toolbar_parent", "id")); + ViewGroup dummyToolbar = Utils.getChildViewByResourceName(toolBarParent, "revanced_toolbar"); + toolbarLayoutParams = dummyToolbar.getLayoutParams(); + toolBarParent.removeView(dummyToolbar); + + // Sets appropriate system navigation bar color for the activity. + ToolbarPreferenceFragment.setNavigationBarColor(activity.getWindow()); + + Toolbar toolbar = new Toolbar(toolBarParent.getContext()); + toolbar.setBackgroundColor(getToolbarBackgroundColor()); + toolbar.setNavigationIcon(getNavigationIcon()); + toolbar.setNavigationOnClickListener(getNavigationClickListener(activity)); + toolbar.setTitle(Utils.getResourceIdentifier("revanced_settings_title", "string")); + + final int margin = Utils.dipToPixels(16); + toolbar.setTitleMarginStart(margin); + toolbar.setTitleMarginEnd(margin); + TextView toolbarTextView = Utils.getChildView(toolbar, false, view -> view instanceof TextView); + if (toolbarTextView != null) { + toolbarTextView.setTextColor(Utils.getAppForegroundColor()); + toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); + } + setToolbarLayoutParams(toolbar); + + onPostToolbarSetup(activity, toolbar, fragment); + + toolBarParent.addView(toolbar, 0); + } + + /** + * Customizes the activity's theme. + */ + protected abstract void customizeActivityTheme(Activity activity); + + /** + * Returns the resource ID for the content view layout. + */ + protected abstract int getContentViewResourceId(); + + /** + * Returns the background color for the toolbar. + */ + protected abstract int getToolbarBackgroundColor(); + + /** + * Returns the navigation icon drawable for the toolbar. + */ + protected abstract Drawable getNavigationIcon(); + + /** + * Returns the click listener for the toolbar's navigation icon. + */ + protected abstract View.OnClickListener getNavigationClickListener(Activity activity); + + /** + * Creates the PreferenceFragment to be injected into the activity. + */ + protected PreferenceFragment createPreferenceFragment() { + return new ToolbarPreferenceFragment(); + } + + /** + * Performs additional setup after the toolbar is configured. + * + * @param activity The activity hosting the toolbar. + * @param toolbar The configured toolbar. + * @param fragment The PreferenceFragment associated with the activity. + */ + protected void onPostToolbarSetup(Activity activity, Toolbar toolbar, PreferenceFragment fragment) {} +} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ClearLogBufferPreference.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ClearLogBufferPreference.java similarity index 88% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ClearLogBufferPreference.java rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ClearLogBufferPreference.java index 109c6c8e7..7dbf0dd38 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ClearLogBufferPreference.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ClearLogBufferPreference.java @@ -1,9 +1,8 @@ -package app.revanced.extension.youtube.settings.preference; +package app.revanced.extension.shared.settings.preference; import android.content.Context; import android.util.AttributeSet; import android.preference.Preference; -import app.revanced.extension.shared.settings.preference.LogBufferManager; /** * A custom preference that clears the ReVanced debug log buffer when clicked. diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ExportLogToClipboardPreference.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ExportLogToClipboardPreference.java similarity index 88% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ExportLogToClipboardPreference.java rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ExportLogToClipboardPreference.java index fac1cfa79..57fb12823 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ExportLogToClipboardPreference.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ExportLogToClipboardPreference.java @@ -1,9 +1,8 @@ -package app.revanced.extension.youtube.settings.preference; +package app.revanced.extension.shared.settings.preference; import android.content.Context; import android.util.AttributeSet; import android.preference.Preference; -import app.revanced.extension.shared.settings.preference.LogBufferManager; /** * A custom preference that triggers exporting ReVanced debug logs to the clipboard when clicked. diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java new file mode 100644 index 000000000..05a1fddcc --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java @@ -0,0 +1,150 @@ +package app.revanced.extension.shared.settings.preference; + +import android.annotation.SuppressLint; +import android.app.Dialog; +import android.graphics.Insets; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.preference.Preference; +import android.preference.PreferenceScreen; +import android.util.TypedValue; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowInsets; +import android.widget.TextView; +import android.widget.Toolbar; + +import androidx.annotation.Nullable; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.BaseActivityHook; + +@SuppressWarnings({"deprecation", "NewApi"}) +public class ToolbarPreferenceFragment extends AbstractPreferenceFragment { + /** + * Sets toolbar for all nested preference screens. + */ + protected void setPreferenceScreenToolbar(PreferenceScreen parentScreen) { + for (int i = 0, count = parentScreen.getPreferenceCount(); i < count; i++) { + Preference childPreference = parentScreen.getPreference(i); + if (childPreference instanceof PreferenceScreen) { + // Recursively set sub preferences. + setPreferenceScreenToolbar((PreferenceScreen) childPreference); + + childPreference.setOnPreferenceClickListener( + childScreen -> { + Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog(); + ViewGroup rootView = (ViewGroup) preferenceScreenDialog + .findViewById(android.R.id.content) + .getParent(); + + // Allow package-specific background customization. + customizeDialogBackground(rootView); + + // Fix the system navigation bar color for submenus. + setNavigationBarColor(preferenceScreenDialog.getWindow()); + + // Fix edge-to-edge screen with Android 15 and YT 19.45+ + // https://developer.android.com/develop/ui/views/layout/edge-to-edge#system-bars-insets + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + rootView.setOnApplyWindowInsetsListener((v, insets) -> { + Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars()); + Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars()); + Insets cutoutInsets = insets.getInsets(WindowInsets.Type.displayCutout()); + + // Apply padding for display cutout in landscape. + int leftPadding = cutoutInsets.left; + int rightPadding = cutoutInsets.right; + int topPadding = statusInsets.top; + int bottomPadding = navInsets.bottom; + + v.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); + return insets; + }); + } + + Toolbar toolbar = new Toolbar(childScreen.getContext()); + toolbar.setTitle(childScreen.getTitle()); + toolbar.setNavigationIcon(getBackButtonDrawable()); + toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss()); + + final int margin = Utils.dipToPixels(16); + toolbar.setTitleMargin(margin, 0, margin, 0); + + TextView toolbarTextView = Utils.getChildView(toolbar, + true, TextView.class::isInstance); + if (toolbarTextView != null) { + toolbarTextView.setTextColor(Utils.getAppForegroundColor()); + toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); + } + + // Allow package-specific toolbar customization. + customizeToolbar(toolbar); + + // Allow package-specific post-toolbar setup. + onPostToolbarSetup(toolbar, preferenceScreenDialog); + + rootView.addView(toolbar, 0); + return false; + } + ); + } + } + } + + /** + * Sets the system navigation bar color for the activity. + * Applies the background color obtained from {@link Utils#getAppBackgroundColor()} to the navigation bar. + * For Android 10 (API 29) and above, enforces navigation bar contrast to ensure visibility. + */ + public static void setNavigationBarColor(@Nullable Window window) { + if (window == null) { + Logger.printDebug(() -> "Cannot set navigation bar color, window is null"); + return; + } + + window.setNavigationBarColor(Utils.getAppBackgroundColor()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + window.setNavigationBarContrastEnforced(true); + } + } + + /** + * Returns the drawable for the back button. + */ + @SuppressLint("UseCompatLoadingForDrawables") + public static Drawable getBackButtonDrawable() { + final int backButtonResource = Utils.getResourceIdentifier( + "revanced_settings_toolbar_arrow_left", "drawable"); + Drawable drawable = Utils.getContext().getResources().getDrawable(backButtonResource); + customizeBackButtonDrawable(drawable); + return drawable; + } + + /** + * Customizes the back button drawable. + */ + protected static void customizeBackButtonDrawable(Drawable drawable) { + drawable.setTint(Utils.getAppForegroundColor()); + } + + /** + * Allows subclasses to customize the dialog's root view background. + */ + protected void customizeDialogBackground(ViewGroup rootView) { + rootView.setBackgroundColor(Utils.getAppBackgroundColor()); + } + + /** + * Allows subclasses to customize the toolbar. + */ + protected void customizeToolbar(Toolbar toolbar) { + BaseActivityHook.setToolbarLayoutParams(toolbar); + } + + /** + * Allows subclasses to perform actions after toolbar setup. + */ + protected void onPostToolbarSetup(Toolbar toolbar, Dialog preferenceScreenDialog) {} +} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java index 24d3a4f42..5c4d3ca77 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java @@ -1,50 +1,120 @@ package app.revanced.extension.youtube.settings; -import static app.revanced.extension.shared.Utils.getResourceIdentifier; - import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; +import android.graphics.drawable.Drawable; import android.preference.PreferenceFragment; -import android.util.TypedValue; -import android.view.ViewGroup; -import android.widget.TextView; +import android.view.View; import android.widget.Toolbar; -import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.settings.AppLanguage; +import app.revanced.extension.shared.settings.BaseActivityHook; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.youtube.patches.VersionCheckPatch; import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch; import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment; /** - * Hooks LicenseActivity. - *

- * This class is responsible for injecting our own fragment by replacing the LicenseActivity. + * Hooks LicenseActivity to inject a custom ReVancedPreferenceFragment with a toolbar and search functionality. */ -@SuppressWarnings("unused") -public class LicenseActivityHook extends Activity { +@SuppressWarnings("deprecation") +public class LicenseActivityHook extends BaseActivityHook { private static int currentThemeValueOrdinal = -1; // Must initially be a non-valid enum ordinal value. - private static ViewGroup.LayoutParams toolbarLayoutParams; - + /** + * Controller for managing search view components in the toolbar. + */ @SuppressLint("StaticFieldLeak") public static SearchViewController searchViewController; - public static void setToolbarLayoutParams(Toolbar toolbar) { - if (toolbarLayoutParams != null) { - toolbar.setLayoutParams(toolbarLayoutParams); + /** + * Injection point + *

+ * Creates an instance of LicenseActivityHook for use in static initialization. + */ + @SuppressWarnings("unused") + public static LicenseActivityHook createInstance() { + return new LicenseActivityHook(); + } + + /** + * Customizes the activity theme based on dark/light mode. + */ + @Override + protected void customizeActivityTheme(Activity activity) { + final var theme = Utils.isDarkModeEnabled() + ? "Theme.YouTube.Settings.Dark" + : "Theme.YouTube.Settings"; + activity.setTheme(Utils.getResourceIdentifier(theme, "style")); + } + + /** + * Returns the resource ID for the YouTube settings layout. + */ + @Override + protected int getContentViewResourceId() { + return Utils.getResourceIdentifier("revanced_settings_with_toolbar", "layout"); + } + + /** + * Returns the toolbar background color based on dark/light mode. + */ + @Override + protected int getToolbarBackgroundColor() { + final String colorName = Utils.isDarkModeEnabled() + ? "yt_black3" + : "yt_white1"; + return Utils.getColorFromString(colorName); + } + + /** + * Returns the navigation icon drawable for the toolbar. + */ + @Override + protected Drawable getNavigationIcon() { + return ReVancedPreferenceFragment.getBackButtonDrawable(); + } + + /** + * Returns the click listener for the navigation icon. + */ + @Override + protected View.OnClickListener getNavigationClickListener(Activity activity) { + return null; + } + + /** + * Adds search view components to the toolbar for ReVancedPreferenceFragment. + * + * @param activity The activity hosting the toolbar. + * @param toolbar The configured toolbar. + * @param fragment The PreferenceFragment associated with the activity. + */ + @Override + protected void onPostToolbarSetup(Activity activity, Toolbar toolbar, PreferenceFragment fragment) { + if (fragment instanceof ReVancedPreferenceFragment) { + searchViewController = SearchViewController.addSearchViewComponents( + activity, toolbar, (ReVancedPreferenceFragment) fragment); } } + /** + * Creates a new ReVancedPreferenceFragment for the activity. + */ + @Override + protected PreferenceFragment createPreferenceFragment() { + return new ReVancedPreferenceFragment(); + } + /** * Injection point. * Overrides the ReVanced settings language. */ + @SuppressWarnings("unused") public static Context getAttachBaseContext(Context original) { AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); if (language == AppLanguage.DEFAULT) { @@ -57,6 +127,7 @@ public class LicenseActivityHook extends Activity { /** * Injection point. */ + @SuppressWarnings("unused") public static boolean useCairoSettingsFragment(boolean original) { // Early targets have layout issues and it's better to always force off. if (!VersionCheckPatch.IS_19_34_OR_GREATER) { @@ -80,87 +151,6 @@ public class LicenseActivityHook extends Activity { /** * Injection point. *

- * Hooks LicenseActivity#onCreate in order to inject our own fragment. - */ - public static void initialize(Activity licenseActivity) { - try { - setActivityTheme(licenseActivity); - ReVancedPreferenceFragment.setNavigationBarColor(licenseActivity.getWindow()); - licenseActivity.setContentView(getResourceIdentifier( - "revanced_settings_with_toolbar", "layout")); - - // Sanity check. - String dataString = licenseActivity.getIntent().getDataString(); - if (!"revanced_settings_intent".equals(dataString)) { - Logger.printException(() -> "Unknown intent: " + dataString); - return; - } - - PreferenceFragment fragment = new ReVancedPreferenceFragment(); - createToolbar(licenseActivity, fragment); - - //noinspection deprecation - licenseActivity.getFragmentManager() - .beginTransaction() - .replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment) - .commit(); - } catch (Exception ex) { - Logger.printException(() -> "initialize failure", ex); - } - } - - @SuppressLint("UseCompatLoadingForDrawables") - private static void createToolbar(Activity activity, PreferenceFragment fragment) { - // Replace dummy placeholder toolbar. - // This is required to fix submenu title alignment issue with Android ASOP 15+ - ViewGroup toolBarParent = activity.findViewById( - getResourceIdentifier("revanced_toolbar_parent", "id")); - ViewGroup dummyToolbar = Utils.getChildViewByResourceName(toolBarParent, "revanced_toolbar"); - toolbarLayoutParams = dummyToolbar.getLayoutParams(); - toolBarParent.removeView(dummyToolbar); - - Toolbar toolbar = new Toolbar(toolBarParent.getContext()); - toolbar.setBackgroundColor(getToolbarBackgroundColor()); - toolbar.setNavigationIcon(ReVancedPreferenceFragment.getBackButtonDrawable()); - toolbar.setTitle(getResourceIdentifier("revanced_settings_title", "string")); - - final int margin = Utils.dipToPixels(16); - toolbar.setTitleMarginStart(margin); - toolbar.setTitleMarginEnd(margin); - TextView toolbarTextView = Utils.getChildView(toolbar, false, - view -> view instanceof TextView); - if (toolbarTextView != null) { - toolbarTextView.setTextColor(Utils.getAppForegroundColor()); - toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); - } - setToolbarLayoutParams(toolbar); - - // Add Search bar only for ReVancedPreferenceFragment. - if (fragment instanceof ReVancedPreferenceFragment) { - searchViewController = SearchViewController.addSearchViewComponents(activity, toolbar, (ReVancedPreferenceFragment) fragment); - } - - toolBarParent.addView(toolbar, 0); - } - - public static void setActivityTheme(Activity activity) { - final var theme = Utils.isDarkModeEnabled() - ? "Theme.YouTube.Settings.Dark" - : "Theme.YouTube.Settings"; - activity.setTheme(getResourceIdentifier(theme, "style")); - } - - public static int getToolbarBackgroundColor() { - final String colorName = Utils.isDarkModeEnabled() - ? "yt_black3" - : "yt_white1"; - - return Utils.getColorFromString(colorName); - } - - /** - * Injection point. - * * Updates dark/light mode since YT settings can force light/dark mode * which can differ from the global device settings. */ @@ -173,6 +163,10 @@ public class LicenseActivityHook extends Activity { } } + /** + * Handles configuration changes, such as orientation, to update the search view. + */ + @SuppressWarnings("unused") public static void handleConfigurationChanged(Activity activity, Configuration newConfig) { if (searchViewController != null) { searchViewController.handleOrientationChange(newConfig.orientation); 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 c4cb42313..c96ed26ed 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 @@ -3,11 +3,7 @@ package app.revanced.extension.youtube.settings.preference; import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.Utils.getResourceIdentifier; -import android.annotation.SuppressLint; import android.app.Dialog; -import android.graphics.Insets; -import android.graphics.drawable.Drawable; -import android.os.Build; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceCategory; @@ -17,11 +13,6 @@ import android.preference.SwitchPreference; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; -import android.util.TypedValue; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowInsets; -import android.widget.TextView; import android.widget.Toolbar; import androidx.annotation.CallSuper; @@ -40,16 +31,16 @@ import java.util.regex.Pattern; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.settings.BaseSettings; -import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment; import app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory; +import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment; import app.revanced.extension.youtube.settings.LicenseActivityHook; import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockPreferenceGroup; /** * Preference fragment for ReVanced settings. */ -@SuppressWarnings("deprecation") -public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { +@SuppressWarnings({"deprecation", "NewApi"}) +public class ReVancedPreferenceFragment extends ToolbarPreferenceFragment { /** * The main PreferenceScreen used to display the current set of preferences. @@ -70,31 +61,6 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { */ private final List> allPreferences = new ArrayList<>(); - @SuppressLint("UseCompatLoadingForDrawables") - public static Drawable getBackButtonDrawable() { - final int backButtonResource = getResourceIdentifier("revanced_settings_toolbar_arrow_left", "drawable"); - Drawable drawable = Utils.getContext().getResources().getDrawable(backButtonResource); - drawable.setTint(Utils.getAppForegroundColor()); - return drawable; - } - - /** - * Sets the system navigation bar color for the activity. - * Applies the background color obtained from {@link Utils#getAppBackgroundColor()} to the navigation bar. - * For Android 10 (API 29) and above, enforces navigation bar contrast to ensure visibility. - */ - public static void setNavigationBarColor(@Nullable Window window) { - if (window == null) { - Logger.printDebug(() -> "Cannot set navigation bar color, window is null"); - return; - } - - window.setNavigationBarColor(Utils.getAppBackgroundColor()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - window.setNavigationBarContrastEnforced(true); - } - } - /** * Initializes the preference fragment, copying the original screen to allow full restoration. */ @@ -139,8 +105,28 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { } } + /** + * Sets toolbar for all nested preference screens. + */ + @Override + protected void customizeToolbar(Toolbar toolbar) { + LicenseActivityHook.setToolbarLayoutParams(toolbar); + } + + /** + * Perform actions after toolbar setup. + */ + @Override + protected void onPostToolbarSetup(Toolbar toolbar, Dialog preferenceScreenDialog) { + if (LicenseActivityHook.searchViewController != null + && LicenseActivityHook.searchViewController.isSearchActive()) { + toolbar.post(() -> LicenseActivityHook.searchViewController.closeSearch()); + } + } + /** * Recursively collects all preferences from the screen or group. + * * @param includeDepth Menu depth to start including preferences. * A value of 0 adds all preferences. */ @@ -222,75 +208,6 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { preferenceScreen.addPreference(noResultsPreference); } } - - /** - * Sets toolbar for all nested preference screens. - */ - private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) { - for (int i = 0, count = parentScreen.getPreferenceCount(); i < count; i++) { - Preference childPreference = parentScreen.getPreference(i); - if (childPreference instanceof PreferenceScreen) { - // Recursively set sub preferences. - setPreferenceScreenToolbar((PreferenceScreen) childPreference); - - childPreference.setOnPreferenceClickListener( - childScreen -> { - Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog(); - ViewGroup rootView = (ViewGroup) preferenceScreenDialog - .findViewById(android.R.id.content) - .getParent(); - - // Fix the system navigation bar color for submenus. - setNavigationBarColor(preferenceScreenDialog.getWindow()); - - // Fix edge-to-edge screen with Android 15 and YT 19.45+ - // https://developer.android.com/develop/ui/views/layout/edge-to-edge#system-bars-insets - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - rootView.setOnApplyWindowInsetsListener((v, insets) -> { - Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars()); - Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars()); - Insets cutoutInsets = insets.getInsets(WindowInsets.Type.displayCutout()); - - // Apply padding for display cutout in landscape. - int leftPadding = cutoutInsets.left; - int rightPadding = cutoutInsets.right; - int topPadding = statusInsets.top; - int bottomPadding = navInsets.bottom; - - v.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); - return insets; - }); - } - - Toolbar toolbar = new Toolbar(childScreen.getContext()); - toolbar.setTitle(childScreen.getTitle()); - toolbar.setNavigationIcon(getBackButtonDrawable()); - toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss()); - - final int margin = Utils.dipToPixels(16); - toolbar.setTitleMargin(margin, 0, margin, 0); - - TextView toolbarTextView = Utils.getChildView(toolbar, - true, TextView.class::isInstance); - if (toolbarTextView != null) { - toolbarTextView.setTextColor(Utils.getAppForegroundColor()); - toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); - } - - LicenseActivityHook.setToolbarLayoutParams(toolbar); - - if (LicenseActivityHook.searchViewController != null - && LicenseActivityHook.searchViewController.isSearchActive()) { - toolbar.post(() -> LicenseActivityHook.searchViewController.closeSearch()); - } - - rootView.addView(toolbar, 0); - return false; - } - ); - } - } - } } @SuppressWarnings("deprecation") diff --git a/patches/api/patches.api b/patches/api/patches.api index 70df3fdcc..00b58e88e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -372,8 +372,9 @@ public final class app/revanced/patches/music/layout/premium/HideGetPremiumPatch public static final fun getHideGetPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatchKt { - public static final fun getRemoveUpgradeButtonPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatchKt { + public static final fun getHideUpgradeButton ()Lapp/revanced/patcher/patch/BytecodePatch; + public static final fun getRemoveUpgradeButton ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatchKt { @@ -396,7 +397,21 @@ public final class app/revanced/patches/music/misc/gms/GmsCoreSupportPatchKt { public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/music/misc/spoof/SpoofVideoStreamsKt { +public final class app/revanced/patches/music/misc/settings/PreferenceScreen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen { + public static final field INSTANCE Lapp/revanced/patches/music/misc/settings/PreferenceScreen; + public fun commit (Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference;)V + public final fun getADS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen; + public final fun getGENERAL ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen; + public final fun getMISC ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen; + public final fun getPLAYER ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen; +} + +public final class app/revanced/patches/music/misc/settings/SettingsPatchKt { + public static final fun getSettingsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; + public static final fun newIntent (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent; +} + +public final class app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatchKt { public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -1652,7 +1667,6 @@ public final class app/revanced/patches/youtube/misc/settings/PreferenceScreen : } public final class app/revanced/patches/youtube/misc/settings/SettingsPatchKt { - public static final fun addSettingPreference (Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V public static final fun getSettingsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun newIntent (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent; } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt index 4c89bfb03..fd417bb5d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt @@ -1,13 +1,27 @@ package app.revanced.patches.music.ad.video -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideVideoAdsPatch;" @Suppress("unused") val hideVideoAdsPatch = bytecodePatch( name = "Hide music video ads", - description = "Hides ads that appear while listening to or streaming music videos, podcasts, or songs.", + description = "Adds an option to hide ads that appear while listening to or streaming music videos, podcasts, or songs.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -15,9 +29,21 @@ val hideVideoAdsPatch = bytecodePatch( ) execute { + addResources("music", "ad.video.hideVideoAdsPatch") + + PreferenceScreen.ADS.addPreferences( + SwitchPreference("revanced_music_hide_video_ads"), + ) + navigate(showVideoAdsParentFingerprint.originalMethod) .to(showVideoAdsParentFingerprint.patternMatch!!.startIndex + 1) .stop() - .addInstruction(0, "const/4 p1, 0x0") + .addInstructions( + 0, + """ + invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->showVideoAds(Z)Z + move-result p1 + """ + ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt index 9834f649e..4d598e402 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt @@ -1,6 +1,8 @@ package app.revanced.patches.music.audio.exclusiveaudio import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.settingsPatch import app.revanced.util.returnEarly @Suppress("unused") @@ -8,6 +10,11 @@ val enableExclusiveAudioPlaybackPatch = bytecodePatch( name = "Enable exclusive audio playback", description = "Enables the option to play audio without video.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt index bfcdaba38..559bacc39 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt @@ -4,13 +4,27 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.util.findFreeRegister + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/PermanentRepeatPatch;" @Suppress("unused") val permanentRepeatPatch = bytecodePatch( name = "Permanent repeat", - description = "Permanently remember your repeating preference even if the playlist ends or another track is played.", - use = false, + description = "Adds an option to always repeat even if the playlist ends or another track is played." ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -18,13 +32,27 @@ val permanentRepeatPatch = bytecodePatch( ) execute { + addResources("music", "interaction.permanentrepeat.permanentRepeatPatch") + + PreferenceScreen.PLAYER.addPreferences( + SwitchPreference("revanced_music_play_permanent_repeat"), + ) + val startIndex = repeatTrackFingerprint.patternMatch!!.endIndex val repeatIndex = startIndex + 1 repeatTrackFingerprint.method.apply { + // Start index is at a branch, but the same + // register is clobbered in both branch paths. + val freeRegister = findFreeRegister(startIndex + 1) + addInstructionsWithLabels( startIndex, - "goto :repeat", + """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->permanentRepeat()Z + move-result v$freeRegister + if-nez v$freeRegister, :repeat + """, ExternalLabel("repeat", instructions[repeatIndex]), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt index 78ef86f50..883be02a6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt @@ -1,17 +1,32 @@ package app.revanced.patches.music.layout.compactheader 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.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.findFreeRegister import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideCategoryBarPatch;" + @Suppress("unused") val hideCategoryBar = bytecodePatch( name = "Hide category bar", - description = "Hides the category bar at the top of the homepage.", - use = false, + description = "Adds an option to hide the category bar at the top of the homepage." ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -19,16 +34,27 @@ val hideCategoryBar = bytecodePatch( ) execute { + addResources("music", "layout.compactheader.hideCategoryBar") + + PreferenceScreen.GENERAL.addPreferences( + SwitchPreference("revanced_music_hide_category_bar"), + ) + constructCategoryBarFingerprint.method.apply { val insertIndex = constructCategoryBarFingerprint.patternMatch!!.startIndex val register = getInstruction(insertIndex - 1).registerA val freeRegister = findFreeRegister(insertIndex, register) - addInstructions( + addInstructionsWithLabels( insertIndex, """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->hideCategoryBar()Z + move-result v$freeRegister + if-eqz v$freeRegister, :show const/16 v$freeRegister, 0x8 invoke-virtual { v$register, v$freeRegister }, Landroid/view/View;->setVisibility(I)V + :show + nop """ ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt index 7ba3260ef..beea72673 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt @@ -1,16 +1,31 @@ package app.revanced.patches.music.layout.premium import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -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.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideGetPremiumPatch;" + +@Suppress("unused") val hideGetPremiumPatch = bytecodePatch( - name = "Hide 'Get Music Premium' label", - description = "Hides the \"Get Music Premium\" label from the account menu and settings.", + name = "Hide 'Get Music Premium'", + description = "Adds an option to hide the \"Get Music Premium\" label in the settings and account menu.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -18,6 +33,12 @@ val hideGetPremiumPatch = bytecodePatch( ) execute { + addResources("music", "layout.premium.hideGetPremiumPatch") + + PreferenceScreen.ADS.addPreferences( + SwitchPreference("revanced_music_hide_get_premium_label"), + ) + hideGetPremiumFingerprint.method.apply { val insertIndex = hideGetPremiumFingerprint.patternMatch!!.endIndex @@ -37,12 +58,17 @@ val hideGetPremiumPatch = bytecodePatch( ) } - membershipSettingsFingerprint.method.addInstructions( + membershipSettingsFingerprint.method.addInstructionsWithLabels( 0, """ - const/4 v0, 0x0 - return-object v0 - """, + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->hideGetPremiumLabel()Z + move-result v0 + if-eqz v0, :show + const/4 v0, 0x0 + return-object v0 + :show + nop + """ ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt similarity index 70% rename from patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt index 426ab8046..b54e4f2b6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt @@ -7,17 +7,31 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.newLabel import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.util.getReference import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideUpgradeButtonPatch;" + @Suppress("unused") -val removeUpgradeButtonPatch = bytecodePatch( - name = "Remove upgrade button", - description = "Removes the upgrade tab from the pivot bar.", +val hideUpgradeButton = bytecodePatch( + name = "Hide upgrade button", + description = "Hides the upgrade tab from the pivot bar.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -25,6 +39,15 @@ val removeUpgradeButtonPatch = bytecodePatch( ) execute { + addResources("music", "layout.upgradebutton.hideUpgradeButtonPatch") + + // TODO: Add an extension patch to allow this to be enabled/disabled in app. + if (false) { + PreferenceScreen.ADS.addPreferences( + SwitchPreference("revanced_music_hide_upgrade_button") + ) + } + pivotBarConstructorFingerprint.method.apply { val pivotBarElementFieldReference = getInstruction(pivotBarConstructorFingerprint.patternMatch!!.endIndex - 1) @@ -77,3 +100,9 @@ val removeUpgradeButtonPatch = bytecodePatch( } } } + +@Deprecated("Patch was renamed", ReplaceWith("hideUpgradeButton")) +@Suppress("unused") +val removeUpgradeButton = bytecodePatch{ + dependsOn(hideUpgradeButton) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt index a08e1fceb..70e707fbb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt @@ -1,6 +1,8 @@ package app.revanced.patches.music.misc.androidauto import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.settingsPatch import app.revanced.util.returnEarly @Suppress("unused") @@ -8,6 +10,11 @@ val bypassCertificateChecksPatch = bytecodePatch( name = "Bypass certificate checks", description = "Bypasses certificate checks which prevent YouTube Music from working on Android Auto.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt index ab0fe132d..3d81296a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -1,13 +1,20 @@ package app.revanced.patches.music.misc.backgroundplayback import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.util.returnEarly val backgroundPlaybackPatch = bytecodePatch( name = "Remove background playback restrictions", description = "Removes restrictions on background playback, including playing kids videos in the background.", ) { + dependsOn( + sharedExtensionPatch, + settingsPatch + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" @@ -20,12 +27,6 @@ val backgroundPlaybackPatch = bytecodePatch( "return-void", ) - backgroundPlaybackDisableFingerprint.method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """, - ) + backgroundPlaybackDisableFingerprint.method.returnEarly(true) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt index 0fa223b23..b61258496 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt @@ -1,12 +1,17 @@ package app.revanced.patches.music.misc.gms import app.revanced.patcher.patch.Option +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.music.misc.extension.sharedExtensionPatch import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch import app.revanced.patches.music.misc.spoof.spoofVideoStreamsPatch import app.revanced.patches.shared.castContextFetchFingerprint import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch +import app.revanced.patches.shared.misc.settings.preference.IntentPreference import app.revanced.patches.shared.primeMethodFingerprint @Suppress("unused") @@ -33,4 +38,23 @@ private fun gmsCoreSupportResourcePatch( toPackageName = REVANCED_MUSIC_PACKAGE_NAME, gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption, spoofedPackageSignature = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875", -) + executeBlock = { + addResources("shared", "misc.gms.gmsCoreSupportResourcePatch") + + val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption + + PreferenceScreen.MISC.addPreferences( + IntentPreference( + "microg_settings", + intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") { + "$gmsCoreVendorGroupId.android.gms" + } + ) + ) + } +) { + dependsOn( + addResourcesPatch, + settingsPatch + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/Fingerprints.kt new file mode 100644 index 000000000..580e6e767 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/Fingerprints.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.music.misc.settings + +import app.revanced.patcher.fingerprint + +internal val googleApiActivityFingerprint = fingerprint { + returns("V") + parameters("Landroid/os/Bundle;") + custom { method, classDef -> + classDef.endsWith("GoogleApiActivity;") && method.name == "onCreate" + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt new file mode 100644 index 000000000..09fab446b --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt @@ -0,0 +1,176 @@ +package app.revanced.patches.music.misc.settings + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.resourcePatch +import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.shared.misc.mapping.resourceMappingPatch +import app.revanced.patches.shared.misc.settings.preference.* +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.shared.misc.settings.settingsPatch +import app.revanced.util.* +import com.android.tools.smali.dexlib2.util.MethodUtil + +private const val BASE_ACTIVITY_HOOK_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/shared/settings/BaseActivityHook;" +private const val GOOGLE_API_ACTIVITY_HOOK_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/music/settings/GoogleApiActivityHook;" + +private val preferences = mutableSetOf() + + +private val settingsResourcePatch = resourcePatch { + dependsOn( + resourceMappingPatch, + settingsPatch( + IntentPreference( + titleKey = "revanced_settings_title", + summaryKey = null, + intent = newIntent("revanced_settings_intent"), + ) to "settings_headers", + preferences + ) + ) + + execute { + + // TODO: Remove this when search will be abstract. + copyResources( + "settings", + ResourceGroup( + "layout", + "revanced_music_settings_with_toolbar.xml" + ) + ) + + val targetResource = "values/styles.xml" + inputStreamFromBundledResource( + "settings/music", + targetResource, + )!!.let { inputStream -> + "resources".copyXmlNode( + document(inputStream), + document("res/$targetResource"), + ).close() + } + + // Remove horizontal divider from the settings Preferences. + val styleFile = get("res/values/styles.xml") + styleFile.writeText( + styleFile.readText() + .replace( + "allowDividerAbove\">true", + "allowDividerAbove\">false" + ).replace( + "allowDividerBelow\">true", + "allowDividerBelow\">false" + ) + ) + } +} + +val settingsPatch = bytecodePatch( + description = "Adds settings for ReVanced to YouTube Music.", +) { + dependsOn( + sharedExtensionPatch, + settingsResourcePatch, + addResourcesPatch, + ) + + execute { + addResources("music", "misc.settings.settingsPatch") + addResources("shared", "misc.debugging.enableDebuggingPatch") + + // Should make a separate debugging patch, but for now include it with all installations. + PreferenceScreen.MISC.addPreferences( + PreferenceScreenPreference( + key = "revanced_debug_screen", + sorting = Sorting.UNSORTED, + preferences = setOf( + SwitchPreference("revanced_debug"), + NonInteractivePreference( + "revanced_debug_export_logs_to_clipboard", + tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference", + selectable = true + ), + NonInteractivePreference( + "revanced_debug_logs_clear_buffer", + tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference", + selectable = true + ) + ) + ) + ) + + // Add an "About" preference to the top. + preferences += NonInteractivePreference( + key = "revanced_settings_music_screen_0_about", + summaryKey = null, + tag = "app.revanced.extension.shared.settings.preference.ReVancedAboutPreference", + selectable = true, + ) + + // Modify GoogleApiActivity and remove all existing layout code. + // Must modify an existing activity and cannot add a new activity to the manifest, + // as that fails for root installations. + + googleApiActivityFingerprint.method.addInstructions( + 1, + """ + invoke-static { }, $GOOGLE_API_ACTIVITY_HOOK_CLASS_DESCRIPTOR->createInstance()Lapp/revanced/extension/music/settings/GoogleApiActivityHook; + move-result-object v0 + invoke-static { v0, p0 }, $BASE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->initialize(Lapp/revanced/extension/shared/settings/BaseActivityHook;Landroid/app/Activity;)V + return-void + """ + ) + + // Remove other methods as they will break as the onCreate method is modified above. + googleApiActivityFingerprint.classDef.apply { + methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) } + } + } + + finalize { + PreferenceScreen.close() + } +} + +/** + * Creates an intent to open ReVanced settings. + */ +fun newIntent(settingsName: String) = IntentPreference.Intent( + data = settingsName, + targetClass = "com.google.android.gms.common.api.GoogleApiActivity" +) { + // The package name change has to be reflected in the intent. + setOrGetFallbackPackageName("com.google.android.apps.youtube.music") +} + +object PreferenceScreen : BasePreferenceScreen() { + val ADS = Screen( + "revanced_settings_music_screen_1_ads", + summaryKey = null + ) + val GENERAL = Screen( + "revanced_settings_music_screen_2_general", + summaryKey = null + ) + val PLAYER = Screen( + "revanced_settings_music_screen_3_player", + summaryKey = null + ) + val MISC = Screen( + "revanced_settings_music_screen_4_misc", + summaryKey = null + ) + + override fun commit(screen: PreferenceScreenPreference) { + preferences += screen + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreams.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt similarity index 51% rename from patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreams.kt rename to patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt index e50a70a49..7d1a4c648 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreams.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt @@ -1,12 +1,19 @@ package app.revanced.patches.music.misc.spoof import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.music.misc.extension.sharedExtensionPatch import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch import app.revanced.patches.music.playservice.is_7_33_or_greater import app.revanced.patches.music.playservice.is_8_11_or_greater import app.revanced.patches.music.playservice.is_8_15_or_greater import app.revanced.patches.music.playservice.versionCheckPatch +import app.revanced.patches.shared.misc.settings.preference.ListPreference +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch;" @@ -16,17 +23,36 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch( fixMediaFetchHotConfigAlternativeChanges = { is_8_11_or_greater && !is_8_15_or_greater }, fixParsePlaybackResponseFeatureFlag = { is_7_33_or_greater }, block = { + dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + versionCheckPatch, + userAgentClientSpoofPatch + ) + compatibleWith( "com.google.android.apps.youtube.music"( "7.29.52" ) ) - - dependsOn(sharedExtensionPatch, versionCheckPatch, userAgentClientSpoofPatch) }, executeBlock = { + addResources("shared", "misc.spoof.spoofVideoStreamsPatch") + + PreferenceScreen.MISC.addPreferences( + PreferenceScreenPreference( + key = "revanced_spoof_video_streams_screen", + sorting = PreferenceScreenPreference.Sorting.UNSORTED, + preferences = setOf( + SwitchPreference("revanced_spoof_video_streams"), + ListPreference("revanced_spoof_video_streams_client_type"), + ) + ) + ) + musicActivityOnCreateFingerprint.method.addInstruction( - 1, // Must use 1 index so context is set by extension patch. + 0, "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setClientOrderToUse()V" ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt index 923089d01..26b80a2f9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt @@ -9,8 +9,8 @@ import app.revanced.patcher.patch.BytecodePatchBuilder import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.patch.bytecodePatch 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.music.misc.extension.sharedExtensionPatch import app.revanced.util.findFreeRegister import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference @@ -46,6 +46,8 @@ fun spoofVideoStreamsPatch( dependsOn(addResourcesPatch) execute { + addResources("shared", "misc.fix.playback.spoofVideoStreamsPatch") + // region Enable extension helper method used by other patches patchIncludedExtensionMethodFingerprint.method.returnEarly(true) 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 6d5b70905..ab8c54afb 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 @@ -22,6 +22,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/EnableDebuggingPatch;" +// TODO: Refactor this into a shared patch that can be used by both YT and YT Music. +// Almost all of the feature flag hooks are the same between both apps. val enableDebuggingPatch = bytecodePatch( name = "Enable debugging", description = "Adds options for debugging and exporting ReVanced logs to the clipboard.", @@ -45,6 +47,7 @@ val enableDebuggingPatch = bytecodePatch( ) execute { + addResources("shared", "misc.debugging.enableDebuggingPatch") addResources("youtube", "misc.debugging.enableDebuggingPatch") PreferenceScreen.MISC.addPreferences( @@ -58,13 +61,13 @@ val enableDebuggingPatch = bytecodePatch( SwitchPreference("revanced_debug_toast_on_error"), NonInteractivePreference( "revanced_debug_export_logs_to_clipboard", - tag = "app.revanced.extension.youtube.settings.preference.ExportLogToClipboardPreference", - selectable = true, + tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference", + selectable = true ), NonInteractivePreference( "revanced_debug_logs_clear_buffer", - tag = "app.revanced.extension.youtube.settings.preference.ClearLogBufferPreference", - selectable = true, + tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference", + selectable = true ), ), ), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt index 3c8b238cc..5ffd49cb4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt @@ -53,7 +53,7 @@ private fun gmsCoreSupportResourcePatch( gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption, spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600", executeBlock = { - addResources("youtube", "misc.gms.gmsCoreSupportResourcePatch") + addResources("shared", "misc.gms.gmsCoreSupportResourcePatch") val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption @@ -62,10 +62,14 @@ private fun gmsCoreSupportResourcePatch( "microg_settings", intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") { "$gmsCoreVendorGroupId.android.gms" - }, - ), + } + ) ) - }, + } ) { - dependsOn(settingsPatch, addResourcesPatch, accountCredentialsInvalidTextPatch) + dependsOn( + addResourcesPatch, + settingsPatch, + accountCredentialsInvalidTextPatch + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 672999b6a..a90bb9163 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -29,7 +29,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.util.MethodUtil -private const val EXTENSION_CLASS_DESCRIPTOR = +private const val BASE_ACTIVITY_HOOK_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/shared/settings/BaseActivityHook;" +private const val LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/settings/LicenseActivityHook;" internal var appearanceStringId = -1L @@ -37,10 +39,6 @@ internal var appearanceStringId = -1L private val preferences = mutableSetOf() -fun addSettingPreference(screen: BasePreference) { - preferences += screen -} - private val settingsResourcePatch = resourcePatch { dependsOn( resourceMappingPatch, @@ -225,7 +223,9 @@ val settingsPatch = bytecodePatch( licenseActivityOnCreateFingerprint.method.addInstructions( 1, """ - invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->initialize(Landroid/app/Activity;)V + invoke-static {}, $LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->createInstance()Lapp/revanced/extension/youtube/settings/LicenseActivityHook; + move-result-object v0 + invoke-static { v0, p0 }, $BASE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->initialize(Lapp/revanced/extension/shared/settings/BaseActivityHook;Landroid/app/Activity;)V return-void """ ) @@ -249,7 +249,7 @@ val settingsPatch = bytecodePatch( ).toMutable().apply { addInstructions( """ - invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->getAttachBaseContext(Landroid/content/Context;)Landroid/content/Context; + invoke-static { p1 }, $LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->getAttachBaseContext(Landroid/content/Context;)Landroid/content/Context; move-result-object p1 invoke-super { p0, p1 }, $superclass->attachBaseContext(Landroid/content/Context;)V return-void @@ -294,7 +294,7 @@ val settingsPatch = bytecodePatch( addInstructions( """ invoke-super { p0, p1 }, Landroid/app/Activity;->onConfigurationChanged(Landroid/content/res/Configuration;)V - invoke-static { p0, p1 }, $EXTENSION_CLASS_DESCRIPTOR->handleConfigurationChanged(Landroid/app/Activity;Landroid/content/res/Configuration;)V + invoke-static { p0, p1 }, $LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->handleConfigurationChanged(Landroid/app/Activity;Landroid/content/res/Configuration;)V return-void """ ) @@ -309,15 +309,15 @@ val settingsPatch = bytecodePatch( val register = getInstruction(index).registerA addInstructionsAtControlFlowLabel( index, - "invoke-static { v$register }, ${EXTENSION_CLASS_DESCRIPTOR}->updateLightDarkModeStatus(Ljava/lang/Enum;)V", + "invoke-static { v$register }, ${LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR}->updateLightDarkModeStatus(Ljava/lang/Enum;)V", ) } } - // Add setting to force cairo settings fragment on/off. + // Add setting to force Cairo settings fragment on/off. cairoFragmentConfigFingerprint.method.insertLiteralOverride( CAIRO_CONFIG_LITERAL_VALUE, - "$EXTENSION_CLASS_DESCRIPTOR->useCairoSettingsFragment(Z)Z" + "$LICENSE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->useCairoSettingsFragment(Z)Z" ) } diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index ac8860273..c8796f57d 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -121,18 +121,18 @@ ZH - - Android VR - VisionOS + visionOS ANDROID_VR_1_61_48 VISIONOS + + @string/revanced_swipe_overlay_style_entry_1 diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index a297dd20e..2f4840a5f 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -124,6 +124,8 @@ To translate new languages visit translate.revanced.app" and changes made here must also be made there. --> + GmsCore Settings + Settings for GmsCore MicroG GmsCore is not installed. Install it. Action needed @@ -140,6 +142,37 @@ Disabling battery optimizations for MicroG will not negatively affect battery us Tap the continue button and allow optimization changes." Continue + + Spoof video streams + Spoof the client video streams to prevent playback issues + Spoof video streams + Spoof the client video streams to prevent playback issues + Spoof video streams + "Video streams are spoofed + +If you are a YouTube Premium user, this setting may not be required" + "Video streams are not spoofed + +Playback may not work" + Turning off this setting may cause playback issues. + Default client + + + Debugging + Enable or disable debugging options + Debug logging + Debug logs are enabled + Debug logs are disabled + Export debug logs + Copies ReVanced debug logs to the clipboard + Debug logging is disabled + No logs found + Logs copied + Failed to export logs: %s + Clear debug logs + Clears all stored ReVanced debug logs + Logs cleared + @@ -168,11 +201,6 @@ Tap the continue button and allow optimization changes." Shorts background play is enabled - Debugging - Enable or disable debugging options - Debug logging - Debug logs are enabled - Debug logs are disabled Log protocol buffer Debug logs include proto buffer Debug logs do not include proto buffer @@ -190,15 +218,6 @@ However, enabling this will also log some user data such as your IP address.""Turning off error toasts hides all ReVanced error notifications. You will not be notified of any unexpected events." - Export debug logs - Copies ReVanced debug logs to the clipboard - Debug logging is disabled - No logs found - Logs copied - Failed to export logs: %s - Clear debug logs - Clears all stored ReVanced debug logs - Logs cleared Hide album cards @@ -1493,10 +1512,6 @@ Higher video qualities might be unlocked but you may experience video playback s Enabling this can unlock higher video qualities" Enabling this can cause video playback stuttering, worse battery life, and unknown side effects. - - GmsCore Settings - Settings for GmsCore - Haptic feedback Change haptic feedback @@ -1610,17 +1625,6 @@ Enabling this can unlock higher video qualities" Slide to seek is not enabled - Spoof video streams - Spoof the client video streams to prevent playback issues - Spoof video streams - "Video streams are spoofed - -If you are a YouTube Premium user, this setting may not be required" - "Video streams are not spoofed - -Video playback may not work" - Turning off this setting may cause video playback issues. - Default client Spoofing side effects Android spoofing side effects "• Audio track menu is missing @@ -1634,6 +1638,40 @@ Video playback may not work" Audio stream language + + + About + Ads + General + Player + Miscellaneous + + + Hide video ads + Video ads are hidden + Video ads are shown + + + Enable permanent repeat + Permanent repeat is enabled + Permanent repeat is disabled + + + Hide category bar + Category bar is hidden + Category bar is shown + + + Hide \'Get Music Premium\' label + Label is hidden + Label is shown + + + Hide upgrade button + Button is hidden + Button is shown + + Block audio ads diff --git a/patches/src/main/resources/settings/layout/revanced_music_settings_with_toolbar.xml b/patches/src/main/resources/settings/layout/revanced_music_settings_with_toolbar.xml new file mode 100644 index 000000000..09ce00ad4 --- /dev/null +++ b/patches/src/main/resources/settings/layout/revanced_music_settings_with_toolbar.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/settings/music/values/styles.xml b/patches/src/main/resources/settings/music/values/styles.xml new file mode 100644 index 000000000..4a692559a --- /dev/null +++ b/patches/src/main/resources/settings/music/values/styles.xml @@ -0,0 +1,7 @@ + + + + From 01f7bc9f8dc20de6984e837bc00c4b8b90ecd870 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 16 Sep 2025 06:57:43 +0000 Subject: [PATCH 11/11] chore: Release v5.38.0-dev.2 [skip ci] # [5.38.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.1...v5.38.0-dev.2) (2025-09-16) ### Features * **YouTube Music:** Add `Settings` patch ([#5838](https://github.com/ReVanced/revanced-patches/issues/5838)) ([5e20bd8](https://github.com/ReVanced/revanced-patches/commit/5e20bd80f138d7ca94f18857194c46e489c435dc)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f7e09b58..fefb80382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.38.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.1...v5.38.0-dev.2) (2025-09-16) + + +### Features + +* **YouTube Music:** Add `Settings` patch ([#5838](https://github.com/ReVanced/revanced-patches/issues/5838)) ([5e20bd8](https://github.com/ReVanced/revanced-patches/commit/5e20bd80f138d7ca94f18857194c46e489c435dc)) + # [5.38.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.3...v5.38.0-dev.1) (2025-09-15) diff --git a/gradle.properties b/gradle.properties index 46bbfaaa4..5d4b513c7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.38.0-dev.1 +version = 5.38.0-dev.2