diff --git a/README.md b/README.md index 43951cd52..00d0e4ad8 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,16 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm |:--------:|:--------------:|:-----------------:| | `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 18.29.38 ~ 19.44.39 | | `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 18.29.38 ~ 19.44.39 | +| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 18.29.38 ~ 19.44.39 | | `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 18.29.38 ~ 19.44.39 | +| `Change layout` | Adds an option to change the dp in order to use a tablet or phone layout. | 18.29.38 ~ 19.44.39 | +| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 18.29.38 ~ 19.44.39 | | `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 18.29.38 ~ 19.44.39 | | `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 18.29.38 ~ 19.44.39 | | `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 18.29.38 ~ 19.44.39 | | `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 18.29.38 ~ 19.44.39 | | `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 18.29.38 ~ 19.44.39 | -| `Custom branding name for YouTube` | Renames the YouTube app to the name specified in patch options. | 18.29.38 ~ 19.44.39 | +| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 18.29.38 ~ 19.44.39 | | `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 18.29.38 ~ 19.44.39 | | `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 18.29.38 ~ 19.44.39 | | `Description components` | Adds options to hide and disable description components. | 18.29.38 ~ 19.44.39 | @@ -29,11 +32,9 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 18.29.38 ~ 19.44.39 | | `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 18.29.38 ~ 19.44.39 | | `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 18.29.38 ~ 19.44.39 | -| `Enable OPUS codec` | Adds an options to enable the OPUS audio codec if the player response includes it. | 18.29.38 ~ 19.44.39 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 18.29.38 ~ 19.44.39 | | `Enable debug logging` | Adds an option to enable debug logging. | 18.29.38 ~ 19.44.39 | -| `Enable external browser` | Adds an option to always open links in your browser instead of in the in-app-browser. | 18.29.38 ~ 19.44.39 | | `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 18.29.38 ~ 19.44.39 | -| `Enable open links directly` | Adds an option to skip over redirection URLs in external links. | 18.29.38 ~ 19.44.39 | | `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 18.29.38 ~ 19.44.39 | | `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 18.29.38 ~ 19.44.39 | | `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 18.29.38 ~ 19.44.39 | @@ -49,20 +50,21 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 18.29.38 ~ 19.44.39 | | `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 18.29.38 ~ 19.44.39 | | `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 18.29.38 ~ 19.44.39 | -| `Layout switch` | Adds an option to spoof the dpi in order to use a tablet or phone layout. | 18.29.38 ~ 19.44.39 | | `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 18.29.38 ~ 19.44.39 | | `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 18.29.38 ~ 19.44.39 | | `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 18.29.38 ~ 19.44.39 | +| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 18.29.38 ~ 19.44.39 | | `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 18.29.38 ~ 19.44.39 | | `Player components` | Adds options to hide or change components related to the video player. | 18.29.38 ~ 19.44.39 | | `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 18.29.38 ~ 19.44.39 | | `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 18.29.38 ~ 19.44.39 | | `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 18.29.38 ~ 19.44.39 | | `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 18.29.38 ~ 19.44.39 | -| `Sanitize sharing links` | Adds an option to remove tracking query parameters from URLs when sharing links. | 18.29.38 ~ 19.44.39 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 18.29.38 ~ 19.44.39 | | `Seekbar components` | Adds options to hide or change components related to the seekbar. | 18.29.38 ~ 19.44.39 | | `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 18.29.38 ~ 19.44.39 | | `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 18.29.38 ~ 19.44.39 | +| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 18.29.38 ~ 19.44.39 | | `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 18.29.38 ~ 19.44.39 | | `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 18.29.38 ~ 19.44.39 | | `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 18.29.38 ~ 19.44.39 | @@ -80,47 +82,47 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 7.25.53 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 7.25.53 | -| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 7.25.53 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 7.25.53 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 7.25.53 | -| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 7.25.53 | -| `Custom branding name for YouTube Music` | Renames the YouTube Music app to the name specified in patch options. | 6.20.51 ~ 7.25.53 | -| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 7.25.53 | -| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 7.25.53 | -| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 7.25.53 | -| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 7.25.53 | -| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 7.25.53 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 7.25.53 | -| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 7.25.53 | -| `Enable OPUS codec` | Adds an options to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 7.25.53 | -| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 7.25.53 | -| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 7.25.53 | -| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 7.25.53 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 7.25.53 | -| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 7.25.53 | -| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 7.25.53 | -| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 7.25.53 | -| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 7.25.53 | -| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 7.25.53 | -| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 7.25.53 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 7.25.53 | -| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 7.25.53 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 7.25.53 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 7.25.53 | -| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 7.25.53 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 7.25.53 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 7.25.53 | -| `Sanitize sharing links` | Adds an option to remove tracking query parameters from URLs when sharing links. | 6.20.51 ~ 7.25.53 | -| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 7.25.53 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 7.25.53 | +| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 8.02.53 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 8.02.53 | +| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 8.02.53 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 8.02.53 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 8.02.53 | +| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 8.02.53 | +| `Custom branding name for YouTube Music` | Changes the YouTube Music app name to the name specified in patch options. | 6.20.51 ~ 8.02.53 | +| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 8.02.53 | +| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 8.02.53 | +| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 8.02.53 | +| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 8.02.53 | +| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 8.02.53 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 8.02.53 | +| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 8.02.53 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 8.02.53 | +| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 8.02.53 | +| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 8.02.53 | +| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 8.02.53 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 8.02.53 | +| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 8.02.53 | +| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 8.02.53 | +| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 8.02.53 | +| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 8.02.53 | +| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 8.02.53 | +| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 8.02.53 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 8.02.53 | +| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 8.02.53 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 8.02.53 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 8.02.53 | +| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 8.02.53 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 8.02.53 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 8.02.53 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 6.20.51 ~ 8.02.53 | +| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.02.53 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.02.53 | | `Spoof app version` | Adds options to spoof the YouTube Music client version. This can remove the radio mode restriction in Canadian regions or disable real-time lyrics. | 6.20.51 ~ 7.16.53 | | `Spoof client` | Adds options to spoof the client to allow playback. | 6.20.51 ~ 7.16.53 | -| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 6.20.51 ~ 7.25.53 | -| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 7.25.53 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 7.25.53 | -| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 7.25.53 | +| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 6.20.51 ~ 8.02.53 | +| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.02.53 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.02.53 | +| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 8.02.53 | ### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage) @@ -129,7 +131,7 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| | `Change package name` | Changes the package name for Reddit to the name specified in patch options. | ALL | -| `Custom branding name for Reddit` | Renames the Reddit app to the name specified in patch options. | ALL | +| `Custom branding name for Reddit` | Changes the Reddit app name to the name specified in patch options. | ALL | | `Disable screenshot popup` | Adds an option to disable the popup that appears when taking a screenshot. | ALL | | `Hide Recently Visited shelf` | Adds an option to hide the Recently Visited shelf in the sidebar. | ALL | | `Hide ads` | Adds options to hide ads. | ALL | @@ -139,7 +141,7 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | `Open links externally` | Adds an option to always open links in your browser instead of in the in-app-browser. | ALL | | `Premium icon` | Unlocks premium app icons. | ALL | | `Remove subreddit dialog` | Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically. | ALL | -| `Sanitize sharing links` | Adds an option to remove tracking query parameters from URLs when sharing links. | ALL | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | ALL | | `Settings for Reddit` | Applies mandatory patches to implement ReVanced Extended settings into the application. | ALL | @@ -181,7 +183,8 @@ Example: "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java index 72d3ba3f3..3e0dd7afc 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java @@ -12,6 +12,7 @@ import android.widget.Button; import android.widget.ImageView; import app.revanced.extension.music.settings.Settings; +import app.revanced.extension.shared.utils.ResourceUtils; /** * @noinspection ALL @@ -19,6 +20,18 @@ import app.revanced.extension.music.settings.Settings; @SuppressWarnings("unused") public class GeneralPatch { + // region [Change header] patch + + public static int getHeaderDrawableId(int original) { + final int headerId = ResourceUtils.getDrawableIdentifier("action_bar_logo"); + + return headerId == 0 + ? original + : headerId; + } + + // endregion + // region [Change start page] patch public static String changeStartPage(final String browseId) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java index b6489c720..11bec756e 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java @@ -13,7 +13,9 @@ import app.revanced.extension.music.patches.misc.requests.PipedRequester; import app.revanced.extension.music.settings.Settings; import app.revanced.extension.music.shared.VideoInformation; import app.revanced.extension.music.utils.VideoUtils; +import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") public class AlbumMusicVideoPatch { @@ -98,8 +100,17 @@ public class AlbumMusicVideoPatch { if (request == null) { return; } + // This hook is always called off the main thread, + // but this can later be called for the same video id from the main thread. + // This is not a concern, since the fetch will always be finished + // and never block the main thread. + // But if debugging, then still verify this is the situation. + if (BaseSettings.ENABLE_DEBUG_LOGGING.get() && !request.fetchCompleted() && Utils.isCurrentlyOnMainThread()) { + Logger.printException(() -> "Error: Blocking main thread"); + } String songId = request.getStream(); if (songId == null) { + Logger.printDebug(() -> "Official song not found, videoId: " + videoId); return; } synchronized (lastVideoIds) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PipedRequester.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PipedRequester.java index a846a67c3..88023ee66 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PipedRequester.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PipedRequester.java @@ -12,8 +12,7 @@ import org.json.JSONObject; import java.io.IOException; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; -import java.util.HashMap; -import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -25,38 +24,21 @@ import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; public class PipedRequester { - /** - * How long to keep fetches until they are expired. - */ - private static final long CACHE_RETENTION_TIME_MILLISECONDS = 60 * 1000; // 1 Minute - - private static final long MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000; // 20 seconds + private static final long MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 4 * 1000; // 4 seconds @GuardedBy("itself") - private static final Map cache = new HashMap<>(); + private static final Map cache = new LinkedHashMap<>() { + private static final int NUMBER_OF_LAST_VIDEO_IDS_TO_TRACK = 10; + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > NUMBER_OF_LAST_VIDEO_IDS_TO_TRACK; + } + }; @SuppressLint("ObsoleteSdkInt") public static void fetchRequestIfNeeded(@NonNull String videoId, @NonNull String playlistId, final int playlistIndex) { synchronized (cache) { - final long now = System.currentTimeMillis(); - - if (Utils.isSDKAbove(25)) { - cache.values().removeIf(request -> { - final boolean expired = request.isExpired(now); - if (expired) Logger.printDebug(() -> "Removing expired stream: " + request.videoId); - return expired; - }); - } else { - Iterator> itr = cache.entrySet().iterator(); - while (itr.hasNext()) { - Map.Entry entry = itr.next(); - if (entry.getValue().isExpired(now)) { - Logger.printDebug(() -> "Removing expired fetch: " + entry.getValue().videoId); - itr.remove(); - } - } - } - if (!cache.containsKey(videoId)) { PipedRequester pipedRequester = new PipedRequester(videoId, playlistId, playlistIndex); cache.put(videoId, pipedRequester); @@ -85,7 +67,7 @@ public class PipedRequester { private static JSONObject send(@NonNull String videoId, @NonNull String playlistId, final int playlistIndex) { final long startTime = System.currentTimeMillis(); Logger.printDebug(() -> "Fetching piped instances (videoId: '" + videoId + - "', playlistId: '" + playlistId + "', playlistIndex: '" + playlistIndex + "'"); + "', playlistId: '" + playlistId + "', playlistIndex: '" + playlistIndex + "')"); try { HttpURLConnection connection = PipedRoutes.getPlaylistConnectionFromRoute(playlistId); @@ -121,6 +103,8 @@ public class PipedRequester { if (songId.isEmpty()) { handleConnectionError("Url is empty!"); } else if (!songId.equals(videoId)) { + Logger.printDebug(() -> "Video found (videoId: '" + videoId + + "', songId: '" + songId + "')"); return songId; } } catch (JSONException e) { @@ -145,26 +129,12 @@ public class PipedRequester { /** * Time this instance and the fetch future was created. */ - private final long timeFetched; - private final String videoId; private final Future future; private PipedRequester(@NonNull String videoId, @NonNull String playlistId, final int playlistIndex) { - this.timeFetched = System.currentTimeMillis(); - this.videoId = videoId; this.future = Utils.submitOnBackgroundThread(() -> fetch(videoId, playlistId, playlistIndex)); } - public boolean isExpired(long now) { - final long timeSinceCreation = now - timeFetched; - if (timeSinceCreation > CACHE_RETENTION_TIME_MILLISECONDS) { - return true; - } - - // Only expired if the fetch failed (API null response). - return (fetchCompleted() && getStream() == null); - } - /** * @return if the fetch call has completed. */ diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/navigation/NavigationPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/navigation/NavigationPatch.java index 904aced74..a36ba8fe4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/navigation/NavigationPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/navigation/NavigationPatch.java @@ -1,5 +1,6 @@ package app.revanced.extension.music.patches.navigation; +import static app.revanced.extension.shared.utils.StringRef.str; import static app.revanced.extension.shared.utils.Utils.hideViewUnderCondition; import android.graphics.Color; @@ -11,6 +12,7 @@ import androidx.annotation.NonNull; import app.revanced.extension.music.patches.utils.PatchStatus; import app.revanced.extension.music.settings.Settings; import app.revanced.extension.shared.utils.ResourceUtils; +import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") public class NavigationPatch { @@ -20,10 +22,18 @@ public class NavigationPatch { public static Enum lastPivotTab; - public static int enableBlackNavigationBar() { - return Settings.ENABLE_BLACK_NAVIGATION_BAR.get() - ? Color.BLACK - : colorGrey12; + public static int enableCustomNavigationBarColor() { + try { + if (Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR.get()) { + return Color.parseColor(Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE.get()); + } + } catch (Exception ex) { + Utils.showToastShort(str("revanced_custom_navigation_bar_color_value_invalid_invalid_toast")); + Utils.showToastShort(str("revanced_extended_reset_to_default_toast")); + Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE.resetToDefault(); + } + + return colorGrey12; } public static void hideNavigationLabel(TextView textview) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/utils/DrawableColorPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/utils/DrawableColorPatch.java index beccf6178..18da455ad 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/utils/DrawableColorPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/utils/DrawableColorPatch.java @@ -12,10 +12,10 @@ import app.revanced.extension.shared.utils.ResourceUtils; @SuppressWarnings("unused") public class DrawableColorPatch { - private static final int[] DARK_VALUES = { - -14606047, // comments box background - -16579837, // button container background in album - -16777216, // button container background in playlist + private static final int[] DARK_COLORS = { + 0xFF212121, // comments box background + 0xFF030303, // button container background in album + 0xFF000000, // button container background in playlist }; // background colors @@ -26,10 +26,10 @@ public class DrawableColorPatch { private static final int elementsContainerIdentifier = ResourceUtils.getIdIdentifier("elements_container"); - public static int getLithoColor(int originalValue) { - return ArrayUtils.contains(DARK_VALUES, originalValue) + public static int getLithoColor(int colorValue) { + return ArrayUtils.contains(DARK_COLORS, colorValue) ? blackColor - : originalValue; + : colorValue; } public static void setHeaderGradient(ViewGroup viewGroup) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java index 633d5ddba..43da6f9c4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java @@ -116,8 +116,9 @@ public class Settings extends BaseSettings { PatchStatus.SpoofAppVersionDefaultString(), true); - // PreferenceScreen: Navigation bar - public static final BooleanSetting ENABLE_BLACK_NAVIGATION_BAR = new BooleanSetting("revanced_enable_black_navigation_bar", FALSE); + // PreferenceScreen: Navigation Bar + public static final BooleanSetting ENABLE_CUSTOM_NAVIGATION_BAR_COLOR = new BooleanSetting("revanced_enable_custom_navigation_bar_color", FALSE, true); + public static final StringSetting ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE = new StringSetting("revanced_custom_navigation_bar_color_value", "#000000", true); public static final BooleanSetting HIDE_NAVIGATION_HOME_BUTTON = new BooleanSetting("revanced_hide_navigation_home_button", FALSE, true); public static final BooleanSetting HIDE_NAVIGATION_SAMPLES_BUTTON = new BooleanSetting("revanced_hide_navigation_samples_button", FALSE, true); public static final BooleanSetting HIDE_NAVIGATION_EXPLORE_BUTTON = new BooleanSetting("revanced_hide_navigation_explore_button", FALSE, true); @@ -251,6 +252,7 @@ public class Settings extends BaseSettings { CUSTOM_FILTER_STRINGS.key, CUSTOM_PLAYBACK_SPEEDS.key, DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE.key, + ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE.key, EXTERNAL_DOWNLOADER_PACKAGE_NAME.key, HIDE_ACCOUNT_MENU_FILTER_STRINGS.key, SB_API_URL.key, diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java index 1245e8dce..67c442d04 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java @@ -5,6 +5,7 @@ import static app.revanced.extension.music.settings.Settings.CHANGE_START_PAGE; import static app.revanced.extension.music.settings.Settings.CUSTOM_FILTER_STRINGS; import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYBACK_SPEEDS; import static app.revanced.extension.music.settings.Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE; +import static app.revanced.extension.music.settings.Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE; import static app.revanced.extension.music.settings.Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME; import static app.revanced.extension.music.settings.Settings.HIDE_ACCOUNT_MENU_FILTER_STRINGS; import static app.revanced.extension.music.settings.Settings.OPEN_DEFAULT_APP_SETTINGS; @@ -140,6 +141,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } else if (settings.equals(BYPASS_IMAGE_REGION_RESTRICTIONS_DOMAIN) || settings.equals(CUSTOM_FILTER_STRINGS) || settings.equals(CUSTOM_PLAYBACK_SPEEDS) + || settings.equals(ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE) || settings.equals(HIDE_ACCOUNT_MENU_FILTER_STRINGS) || settings.equals(RETURN_YOUTUBE_USERNAME_YOUTUBE_DATA_API_V3_DEVELOPER_KEY)) { ResettableEditTextPreference.showDialog(mActivity, stringSetting); diff --git a/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java b/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java index aaeb7468d..dc6672633 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java @@ -8,7 +8,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import app.revanced.extension.reddit.settings.Settings; -import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") @@ -31,20 +30,12 @@ public class RemoveSubRedditDialogPatch { clickViewDelayed(cancelButtonView); } - public static void dismissDialogV2(Object object) { - if (!Settings.REMOVE_NOTIFICATION_DIALOG.get()) - return; - - Utils.runOnMainThreadDelayed(() -> { - try { - dismissRedditDialogV2(object); - } catch (Exception ex) { - Logger.printException(() -> "dismissDialogV2 failed", ex); - } - }, 0); + public static boolean spoofHasBeenVisitedStatus(boolean hasBeenVisited) { + return Settings.REMOVE_NSFW_DIALOG.get() || hasBeenVisited; } - private static void dismissRedditDialogV2(Object object) { + public static boolean spoofLoggedInStatus(boolean isLoggedIn) { + return !Settings.REMOVE_NOTIFICATION_DIALOG.get() && isLoggedIn; } private static void clickViewDelayed(View view) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/preference/categories/MiscellaneousPreferenceCategory.java b/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/preference/categories/MiscellaneousPreferenceCategory.java index 5e16cf5b8..aad5d77b0 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/preference/categories/MiscellaneousPreferenceCategory.java +++ b/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/preference/categories/MiscellaneousPreferenceCategory.java @@ -41,7 +41,7 @@ public class MiscellaneousPreferenceCategory extends ConditionalPreferenceCatego addPreference(new TogglePreference( context, "Sanitize sharing links", - "Removes tracking query parameters from URLs when sharing links.", + "Sanitizes sharing links by removing tracking query parameters.", Settings.SANITIZE_URL_QUERY )); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/AppClient.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/AppClient.kt index 0613ec951..9ebc13426 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/AppClient.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/AppClient.kt @@ -289,7 +289,7 @@ object AppClient { /** * Android SDK version, equivalent to [Build.VERSION.SDK] (System property: ro.build.version.sdk) */ - val androidSdkVersion: String = Build.VERSION.SDK, + val androidSdkVersion: String? = null, /** * App version. */ @@ -298,10 +298,6 @@ object AppClient { * GmsCore versionCode. */ val gmscoreVersionCode: String? = null, - /** - * ChipSet. - */ - val chipset: String? = null, /** * If the client can access the API logged in. * If false, 'Authorization' must not be included. @@ -316,6 +312,10 @@ object AppClient { * Whether a poToken is required to get playback for more than 1 minute. */ val requirePoToken: Boolean = false, + /** + * Client name for innertube body. + */ + val clientName: String, /** * Friendly name displayed in stats for nerds. */ @@ -329,9 +329,21 @@ object AppClient { userAgent = USER_AGENT_ANDROID_VR, androidSdkVersion = ANDROID_SDK_VERSION_ANDROID_VR, clientVersion = CLIENT_VERSION_ANDROID_VR, - chipset = CHIPSET_ANDROID_VR, + clientName = "ANDROID_VR", friendlyName = "Android VR" ), + ANDROID_VR_NO_AUTH( + id = 28, + deviceMake = DEVICE_MAKE_ANDROID_VR, + deviceModel = DEVICE_MODEL_ANDROID_VR, + osVersion = OS_VERSION_ANDROID_VR, + userAgent = USER_AGENT_ANDROID_VR, + androidSdkVersion = ANDROID_SDK_VERSION_ANDROID_VR, + clientVersion = CLIENT_VERSION_ANDROID_VR, + supportsCookies = false, + clientName = "ANDROID_VR", + friendlyName = "Android VR No auth" + ), ANDROID_UNPLUGGED( id = 29, deviceMake = DEVICE_MAKE_ANDROID_UNPLUGGED, @@ -341,8 +353,8 @@ object AppClient { androidSdkVersion = ANDROID_SDK_VERSION_ANDROID_UNPLUGGED, clientVersion = CLIENT_VERSION_ANDROID_UNPLUGGED, gmscoreVersionCode = GMS_CORE_VERSION_CODE_ANDROID_UNPLUGGED, - chipset = CHIPSET_ANDROID_UNPLUGGED, requireAuth = true, + clientName = "ANDROID_UNPLUGGED", friendlyName = "Android TV" ), ANDROID_CREATOR( @@ -354,8 +366,8 @@ object AppClient { androidSdkVersion = ANDROID_SDK_VERSION_ANDROID_CREATOR, clientVersion = CLIENT_VERSION_ANDROID_CREATOR, gmscoreVersionCode = GMS_CORE_VERSION_CODE_ANDROID_CREATOR, - chipset = CHIPSET_ANDROID_CREATOR, requireAuth = true, + clientName = "ANDROID_CREATOR", friendlyName = "Android Studio" ), IOS_UNPLUGGED( @@ -367,6 +379,7 @@ object AppClient { userAgent = USER_AGENT_IOS_UNPLUGGED, clientVersion = CLIENT_VERSION_IOS_UNPLUGGED, requireAuth = true, + clientName = "IOS_UNPLUGGED", friendlyName = if (forceAVC()) "iOS TV Force AVC" else @@ -382,6 +395,7 @@ object AppClient { clientVersion = CLIENT_VERSION_IOS, supportsCookies = false, requirePoToken = true, + clientName = "IOS", friendlyName = if (forceAVC()) "iOS Force AVC" else @@ -396,13 +410,11 @@ object AppClient { androidSdkVersion = ANDROID_SDK_VERSION_ANDROID_MUSIC, clientVersion = CLIENT_VERSION_ANDROID_MUSIC, gmscoreVersionCode = GMS_CORE_VERSION_CODE_ANDROID_MUSIC, - chipset = CHIPSET_ANDROID_MUSIC, requireAuth = true, + clientName = "ANDROID_MUSIC", friendlyName = "Android Music" ); - val clientName: String = name - companion object { val CLIENT_ORDER_TO_USE_YOUTUBE: Array = arrayOf( ANDROID_VR, @@ -410,6 +422,7 @@ object AppClient { IOS_UNPLUGGED, ANDROID_CREATOR, IOS, + ANDROID_VR_NO_AUTH, ) internal val CLIENT_ORDER_TO_USE_YOUTUBE_MUSIC: Array = arrayOf( diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spans/Filter.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spans/Filter.java index 566fb96e0..4b81cc66b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spans/Filter.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spans/Filter.java @@ -61,7 +61,7 @@ public abstract class Filter { */ public boolean skip(String conversionContext, SpannableString spannableString, Object span, int start, int end, int flags, boolean isWord, SpanType spanType, StringFilterGroup matchedGroup) { - if (BaseSettings.ENABLE_DEBUG_LOGGING.get()) { + if (BaseSettings.ENABLE_DEBUG_BUFFER_LOGGING.get()) { String filterSimpleName = getClass().getSimpleName(); Logger.printDebug(() -> filterSimpleName + " Removed setSpan: " + spanType.type); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java index 7361c97d5..124790b88 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java @@ -13,8 +13,10 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import app.revanced.extension.shared.patches.client.AppClient.ClientType; import app.revanced.extension.shared.patches.spoof.requests.StreamingDataRequest; import app.revanced.extension.shared.settings.BaseSettings; +import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; @@ -107,16 +109,6 @@ public class SpoofStreamingDataPatch { return SPOOF_STREAMING_DATA; } - /** - * Injection point. - */ - public static Object isSpoofingEnabled(Object original) { - if (!SPOOF_STREAMING_DATA) { - return original; - } - return null; - } - /** * Injection point. * This method is only invoked when playing a livestream on an iOS client. @@ -341,4 +333,12 @@ public class SpoofStreamingDataPatch { return videoFormat; } + + public static final class AudioStreamLanguageOverrideAvailability implements Setting.Availability { + @Override + public boolean isAvailable() { + return BaseSettings.SPOOF_STREAMING_DATA.get() && + BaseSettings.SPOOF_STREAMING_DATA_TYPE.get() == ClientType.ANDROID_VR_NO_AUTH; + } + } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt index ab0e56bc0..5bd228d84 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt @@ -5,6 +5,7 @@ import app.revanced.extension.shared.patches.client.WebClient import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.requests.Route import app.revanced.extension.shared.requests.Route.CompiledRoute +import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils import org.apache.commons.lang3.StringUtils @@ -43,6 +44,14 @@ object PlayerRoutes { "&alt=proto" ).compile() + @JvmField + val GET_VIDEO_DETAILS: CompiledRoute = Route( + Route.Method.POST, + "player" + + "?prettyPrint=false" + + "&fields=videoDetails.channelId" + ).compile() + private const val YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/" /** @@ -77,21 +86,24 @@ object PlayerRoutes { client.put("clientVersion", clientType.clientVersion) client.put("osName", clientType.osName) client.put("osVersion", clientType.osVersion) - if (clientType.osName != "iOS") { + if (clientType.androidSdkVersion != null) { client.put("androidSdkVersion", clientType.androidSdkVersion) if (clientType.gmscoreVersionCode != null) { client.put("gmscoreVersionCode", clientType.gmscoreVersionCode) } - if (clientType.chipset != null) { - client.put("chipset", clientType.chipset) + } + client.put( + "hl", + if (setLocale) { + BaseSettings.SPOOF_STREAMING_DATA_LANGUAGE.get().language + } else { + LOCALE_LANGUAGE } - } - if (setLocale) { - client.put("hl", LOCALE_LANGUAGE) - client.put("gl", LOCALE_COUNTRY) - client.put("timeZone", TIME_ZONE_ID) - client.put("utcOffsetMinutes", "$UTC_OFFSET_MINUTES") - } + ) + client.put("gl", LOCALE_COUNTRY) + client.put("timeZone", TIME_ZONE_ID) + client.put("utcOffsetMinutes", "$UTC_OFFSET_MINUTES") + val context = JSONObject() context.put("client", client) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt index 3eb64af98..bd82b3fee 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt @@ -93,9 +93,14 @@ class StreamingDataRequest private constructor( "X-GOOG-API-FORMAT-VERSION", VISITOR_ID_HEADER ) + private val SPOOF_STREAMING_DATA_TYPE: AppClient.ClientType = + BaseSettings.SPOOF_STREAMING_DATA_TYPE.get() private val CLIENT_ORDER_TO_USE: Array = - availableClientTypes(BaseSettings.SPOOF_STREAMING_DATA_TYPE.get()) + availableClientTypes(SPOOF_STREAMING_DATA_TYPE) + + private val DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH: Boolean = + SPOOF_STREAMING_DATA_TYPE == AppClient.ClientType.ANDROID_VR_NO_AUTH private var lastSpoofedClientType: AppClient.ClientType? = null @@ -177,8 +182,6 @@ class StreamingDataRequest private constructor( connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - val setLocale = - !clientType.supportsCookies || playerHeaders[AUTHORIZATION_HEADER] == null val usePoToken = clientType.requirePoToken && !StringUtils.isAnyEmpty(botGuardPoToken, visitorId) @@ -209,7 +212,7 @@ class StreamingDataRequest private constructor( videoId = videoId, botGuardPoToken = botGuardPoToken, visitorId = visitorId, - setLocale = setLocale + setLocale = DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH, ) Logger.printDebug { "Set poToken (botGuardPoToken):\n$botGuardPoToken" } } else { @@ -217,9 +220,10 @@ class StreamingDataRequest private constructor( createApplicationRequestBody( clientType = clientType, videoId = videoId, - setLocale = setLocale + setLocale = DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH, ) } + connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -275,7 +279,7 @@ class StreamingDataRequest private constructor( } else { BufferedInputStream(connection.inputStream).use { inputStream -> ByteArrayOutputStream().use { stream -> - val buffer = ByteArray(8192) + val buffer = ByteArray(4096) var bytesRead: Int while ((inputStream.read(buffer) .also { bytesRead = it }) >= 0 diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/AppLanguage.java b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/AppLanguage.java new file mode 100644 index 000000000..e6d029a2e --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/AppLanguage.java @@ -0,0 +1,114 @@ +package app.revanced.extension.shared.settings; + +import java.util.Locale; + +public enum AppLanguage { + /** + * The current app language. + */ + DEFAULT, + + // Language codes found in locale_config.xml + // All region specific variants have been removed. + AF, + AM, + AR, + AS, + AZ, + BE, + BG, + BN, + BS, + CA, + CS, + DA, + DE, + EL, + EN, + ES, + ET, + EU, + FA, + FI, + FR, + GL, + GU, + HI, + HE, // App uses obsolete 'IW' and not the modern 'HE' ISO code. + HR, + HU, + HY, + ID, + IS, + IT, + JA, + KA, + KK, + KM, + KN, + KO, + KY, + LO, + LT, + LV, + MK, + ML, + MN, + MR, + MS, + MY, + NE, + NL, + NB, + OR, + PA, + PL, + PT, + RO, + RU, + SI, + SK, + SL, + SQ, + SR, + SV, + SW, + TA, + TE, + TH, + TL, + TR, + UK, + UR, + UZ, + VI, + ZH, + ZU; + + private final String language; + + AppLanguage() { + language = name().toLowerCase(Locale.US); + } + + /** + * @return The 2 letter ISO 639_1 language code. + */ + public String getLanguage() { + // Changing the app language does not force the app to completely restart, + // so the default needs to be the current language and not a static field. + if (this == DEFAULT) { + return Locale.getDefault().getLanguage(); + } + + return language; + } + + public Locale getLocale() { + if (this == DEFAULT) { + return Locale.getDefault(); + } + + return Locale.forLanguageTag(language); + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index c97e3f87c..63c3c5b05 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -6,6 +6,7 @@ import static app.revanced.extension.shared.patches.PatchStatus.HideFullscreenAd import app.revanced.extension.shared.patches.ReturnYouTubeUsernamePatch.DisplayFormat; import app.revanced.extension.shared.patches.client.AppClient.ClientType; +import app.revanced.extension.shared.patches.spoof.SpoofStreamingDataPatch.AudioStreamLanguageOverrideAvailability; /** * Settings shared across multiple apps. @@ -22,6 +23,8 @@ public class BaseSettings { public static final BooleanSetting ENABLE_DEBUG_BUFFER_LOGGING = new BooleanSetting("revanced_enable_debug_buffer_logging", FALSE); public static final BooleanSetting SETTINGS_INITIALIZED = new BooleanSetting("revanced_settings_initialized", FALSE, false, false); + public static final EnumSetting REVANCED_LANGUAGE = new EnumSetting<>("revanced_language", AppLanguage.DEFAULT, true); + /** * These settings are used by YouTube and YouTube Music. */ @@ -37,6 +40,7 @@ public class BaseSettings { public static final StringSetting RETURN_YOUTUBE_USERNAME_YOUTUBE_DATA_API_V3_DEVELOPER_KEY = new StringSetting("revanced_return_youtube_username_youtube_data_api_v3_developer_key", "", true, false); public static final BooleanSetting SPOOF_STREAMING_DATA = new BooleanSetting("revanced_spoof_streaming_data", TRUE, true, "revanced_spoof_streaming_data_user_dialog_message"); + public static final EnumSetting SPOOF_STREAMING_DATA_LANGUAGE = new EnumSetting<>("revanced_spoof_streaming_data_language", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability()); public static final BooleanSetting SPOOF_STREAMING_DATA_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_streaming_data_ios_force_avc", FALSE, true, "revanced_spoof_streaming_data_ios_force_avc_user_dialog_message"); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE); diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java index e1290d73f..5ef12c4a8 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java @@ -43,6 +43,8 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import app.revanced.extension.shared.settings.AppLanguage; +import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BooleanSetting; import kotlin.text.Regex; @@ -280,14 +282,13 @@ public class Utils { } public static Resources getResources() { + if (context != null) { + return context.getResources(); + } Activity mActivity = activityRef.get(); if (mActivity != null) { return mActivity.getResources(); } - Context mContext = getContext(); - if (mContext != null) { - return mContext.getResources(); - } throw new IllegalStateException("Get resources failed"); } @@ -301,7 +302,7 @@ public class Utils { * @param mContext Context to check locale. * @return Context with locale applied. */ - public static Context getLocalizedContextAndSetResources(Context mContext) { + public static Context getLocalizedContext(Context mContext) { Activity mActivity = activityRef.get(); if (mActivity == null) { return mContext; @@ -310,19 +311,15 @@ public class Utils { return null; } - // Locale of MainActivity. - Locale applicationLocale; + AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); + + // Locale of Application. + Locale applicationLocale = language == AppLanguage.DEFAULT + ? mActivity.getResources().getConfiguration().locale + : language.getLocale(); // Locale of Context. - Locale contextLocale; - - if (isSDKAbove(24)) { - applicationLocale = mActivity.getResources().getConfiguration().getLocales().get(0); - contextLocale = mContext.getResources().getConfiguration().getLocales().get(0); - } else { - applicationLocale = mActivity.getResources().getConfiguration().locale; - contextLocale = mContext.getResources().getConfiguration().locale; - } + Locale contextLocale = mContext.getResources().getConfiguration().locale; // If they are identical, no need to override them. if (applicationLocale == contextLocale) { @@ -350,6 +347,14 @@ public class Utils { context = appContext; + AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); + if (language != AppLanguage.DEFAULT) { + // Create a new context with the desired language. + Configuration config = appContext.getResources().getConfiguration(); + config.setLocale(language.getLocale()); + context = appContext.createConfigurationContext(config); + } + // In some apps like TikTok, the Setting classes can load in weird orders due to cyclic class dependencies. // Calling the regular printDebug method here can cause a Settings context null pointer exception, // even though the context is already set before the call. diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/CarouselShelfFilter.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/CarouselShelfFilter.java index d5277448f..ebb05bd72 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/CarouselShelfFilter.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/CarouselShelfFilter.java @@ -20,6 +20,7 @@ public final class CarouselShelfFilter extends Filter { private static final String BROWSE_ID_HOME = "FEwhat_to_watch"; private static final String BROWSE_ID_LIBRARY = "FElibrary"; private static final String BROWSE_ID_MOVIE = "FEstorefront"; + private static final String BROWSE_ID_NEWS = "FEnews_destination"; private static final String BROWSE_ID_NOTIFICATION = "FEactivity"; private static final String BROWSE_ID_NOTIFICATION_INBOX = "FEnotifications_inbox"; private static final String BROWSE_ID_PLAYLIST = "VLPL"; @@ -38,6 +39,7 @@ public final class CarouselShelfFilter extends Filter { BROWSE_ID_COURSES, BROWSE_ID_LIBRARY, BROWSE_ID_MOVIE, + BROWSE_ID_NEWS, BROWSE_ID_NOTIFICATION_INBOX, BROWSE_ID_PREMIUM ); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/FeedComponentsFilter.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/FeedComponentsFilter.java index 68b1b9d1f..707b5511d 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/FeedComponentsFilter.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/FeedComponentsFilter.java @@ -19,12 +19,6 @@ public final class FeedComponentsFilter extends Filter { private static final String INLINE_EXPANSION_PATH = "inline_expansion"; private static final String FEED_VIDEO_PATH = "video_lockup_with_attachment"; - private static final ByteArrayFilterGroup inlineExpansion = - new ByteArrayFilterGroup( - Settings.HIDE_EXPANDABLE_CHIP, - "inline_expansion" - ); - private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup( null, @@ -37,14 +31,11 @@ public final class FeedComponentsFilter extends Filter { "channel_profile" ); private static final StringTrieSearch mixPlaylistsContextExceptions = new StringTrieSearch(); - + private static final StringTrieSearch communityPostsFeedGroupSearch = new StringTrieSearch(); private final StringFilterGroup channelProfile; private final StringFilterGroup communityPosts; private final StringFilterGroup expandableChip; private final ByteArrayFilterGroup visitStoreButton; - private final StringFilterGroup videoLockup; - - private static final StringTrieSearch communityPostsFeedGroupSearch = new StringTrieSearch(); private final StringFilterGroupList communityPostsFeedGroup = new StringFilterGroupList(); @@ -90,18 +81,12 @@ public final class FeedComponentsFilter extends Filter { "cell_button.eml" ); - videoLockup = new StringFilterGroup( - null, - FEED_VIDEO_PATH - ); - addIdentifierCallbacks( chipsShelf, communityPosts, expandableShelf, feedSearchBar, - tasteBuilder, - videoLockup + tasteBuilder ); // Paths. @@ -207,8 +192,7 @@ public final class FeedComponentsFilter extends Filter { notifyMe, playables, subscriptionsChannelBar, - ticketShelf, - videoLockup + ticketShelf ); final StringFilterGroup communityPostsHomeAndRelatedVideos = @@ -259,16 +243,12 @@ public final class FeedComponentsFilter extends Filter { if (!communityPostsFeedGroupSearch.matches(allValue) && Settings.HIDE_COMMUNITY_POSTS_CHANNEL.get()) { return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); } - if (!communityPostsFeedGroup.check(allValue).isFiltered()) { - return false; - } - } else if (matchedGroup == expandableChip) { - if (path.startsWith(FEED_VIDEO_PATH)) { + if (communityPostsFeedGroup.check(allValue).isFiltered()) { return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); } return false; - } else if (matchedGroup == videoLockup) { - if (contentIndex == 0 && path.startsWith("CellType|") && inlineExpansion.check(protobufBufferArray).isFiltered()) { + } else if (matchedGroup == expandableChip) { + if (path.startsWith(FEED_VIDEO_PATH)) { return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); } return false; diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java index cc668821e..52f318f3c 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.Map; import app.revanced.extension.shared.patches.components.ByteArrayFilterGroup; @@ -36,11 +35,12 @@ import app.revanced.extension.youtube.shared.VideoInformation; public final class ReturnYouTubeDislikeFilterPatch extends Filter { /** - * Last unique video id's loaded. Value is ignored and Map is treated as a Set. - * Cannot use {@link LinkedHashSet} because it's missing #removeEldestEntry(). + * Last unique video id's loaded. + * Key is a String represeting the video id. + * Value is a ByteArrayFilterGroup used for performing KMP pattern searching. */ @GuardedBy("itself") - private static final Map lastVideoIds = new LinkedHashMap<>() { + private static final Map lastVideoIds = new LinkedHashMap<>() { /** * Number of video id's to keep track of for searching thru the buffer. * A minimum value of 3 should be sufficient, but check a few more just in case. @@ -101,8 +101,11 @@ public final class ReturnYouTubeDislikeFilterPatch extends Filter { return; } synchronized (lastVideoIds) { - if (lastVideoIds.put(videoId, Boolean.TRUE) == null) { - Logger.printDebug(() -> "New Short video id: " + videoId); + if (!lastVideoIds.containsKey(videoId)) { + Logger.printDebug(() -> "New Shorts video id: " + videoId); + // Put a placeholder first + lastVideoIds.put(videoId, null); + lastVideoIds.put(videoId, new ByteArrayFilterGroup(null, videoId)); } } } catch (Exception ex) { @@ -114,7 +117,12 @@ public final class ReturnYouTubeDislikeFilterPatch extends Filter { * This could use {@link TrieSearch}, but since the patterns are constantly changing * the overhead of updating the Trie might negate the search performance gain. */ - private static boolean byteArrayContainsString(@NonNull byte[] array, @NonNull String text) { + private static boolean byteArrayContainsString(@NonNull byte[] array, @NonNull String text, + @Nullable ByteArrayFilterGroup videoIdFilter) { + // If a video filter is available, check it first. + if (videoIdFilter != null) { + return videoIdFilter.check(array).isFiltered(); + } for (int i = 0, lastArrayStartIndex = array.length - text.length(); i <= lastArrayStartIndex; i++) { boolean found = true; for (int j = 0, textLength = text.length(); j < textLength; j++) { @@ -154,8 +162,10 @@ public final class ReturnYouTubeDislikeFilterPatch extends Filter { @Nullable private String findVideoId(byte[] protobufBufferArray) { synchronized (lastVideoIds) { - for (String videoId : lastVideoIds.keySet()) { - if (byteArrayContainsString(protobufBufferArray, videoId)) { + for (Map.Entry entry : lastVideoIds.entrySet()) { + final String videoId = entry.getKey(); + final ByteArrayFilterGroup videoIdFilter = entry.getValue(); + if (byteArrayContainsString(protobufBufferArray, videoId, videoIdFilter)) { return videoId; } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ShortsCustomActionsFilter.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ShortsCustomActionsFilter.java index bbd515167..dd7c6103b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ShortsCustomActionsFilter.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/ShortsCustomActionsFilter.java @@ -7,7 +7,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.Map; import app.revanced.extension.shared.patches.components.ByteArrayFilterGroup; @@ -30,11 +29,12 @@ public final class ShortsCustomActionsFilter extends Filter { SHORTS_CUSTOM_ACTIONS_FLYOUT_MENU_ENABLED || SHORTS_CUSTOM_ACTIONS_TOOLBAR_ENABLED; /** - * Last unique video id's loaded. Value is ignored and Map is treated as a Set. - * Cannot use {@link LinkedHashSet} because it's missing #removeEldestEntry(). + * Last unique video id's loaded. + * Key is a String represeting the video id. + * Value is a ByteArrayFilterGroup used for performing KMP pattern searching. */ @GuardedBy("itself") - private static final Map lastVideoIds = new LinkedHashMap<>() { + private static final Map lastVideoIds = new LinkedHashMap<>() { /** * Number of video id's to keep track of for searching thru the buffer. * A minimum value of 3 should be sufficient, but check a few more just in case. @@ -117,7 +117,11 @@ public final class ShortsCustomActionsFilter extends Filter { return; } synchronized (lastVideoIds) { - lastVideoIds.putIfAbsent(videoId, Boolean.TRUE); + if (!lastVideoIds.containsKey(videoId)) { + // Put a placeholder first + lastVideoIds.put(videoId, null); + lastVideoIds.put(videoId, new ByteArrayFilterGroup(null, videoId)); + } } } catch (Exception ex) { Logger.printException(() -> "newPlayerResponseVideoId failure", ex); @@ -129,7 +133,12 @@ public final class ShortsCustomActionsFilter extends Filter { * This could use {@link TrieSearch}, but since the patterns are constantly changing * the overhead of updating the Trie might negate the search performance gain. */ - private static boolean byteArrayContainsString(@NonNull byte[] array, @NonNull String text) { + private static boolean byteArrayContainsString(@NonNull byte[] array, @NonNull String text, + @Nullable ByteArrayFilterGroup videoIdFilter) { + // If a video filter is available, check it first. + if (videoIdFilter != null) { + return videoIdFilter.check(array).isFiltered(); + } for (int i = 0, lastArrayStartIndex = array.length - text.length(); i <= lastArrayStartIndex; i++) { boolean found = true; for (int j = 0, textLength = text.length(); j < textLength; j++) { @@ -164,9 +173,12 @@ public final class ShortsCustomActionsFilter extends Filter { private void findVideoId(byte[] protobufBufferArray) { synchronized (lastVideoIds) { - for (String videoId : lastVideoIds.keySet()) { - if (byteArrayContainsString(protobufBufferArray, videoId)) { + for (Map.Entry entry : lastVideoIds.entrySet()) { + final String videoId = entry.getKey(); + final ByteArrayFilterGroup videoIdFilter = entry.getValue(); + if (byteArrayContainsString(protobufBufferArray, videoId, videoIdFilter)) { setShortsVideoId(videoId, false); + return; } } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java index 759397604..7ef55d606 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java @@ -41,9 +41,13 @@ public final class ChangeStartPagePatch { * Channel id, this can be used as a browseId. */ COURSES("UCtFRv9O2AHqOZjjynzrv-xg", TRUE), + FASHION("UCrpQ4p1Ql_hG8rKXIKM1MOQ", TRUE), GAMING("UCOpNcN46UbXVtpKMrmU4Abg", TRUE), LIVE("UC4R8DWoMoI7CAwX8_LjQHig", TRUE), MUSIC("UC-9-kyTW8ZkZNDHQJ6FgpwQ", TRUE), + NEWS("UCYfdidRxbB8Qhf0Nx7ioOYw", TRUE), + PODCASTS("UCNVkxRPqsBNejO6B9thG9Xw", TRUE), + SHOPPING("UCkYQyvc_i9hXEo4xic9Hh2g", TRUE), SPORTS("UCEgdi0XIXXZ-qJOFPf4JSKw", TRUE), /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java index 713b93ed0..db497199e 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java @@ -188,10 +188,6 @@ public class GeneralPatch { return Settings.HIDE_FLOATING_MICROPHONE.get() || original; } - public static boolean hideSnackBar() { - return Settings.HIDE_SNACK_BAR.get(); - } - // endregion // region [Hide navigation bar components] patch diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java new file mode 100644 index 000000000..bce03fedf --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java @@ -0,0 +1,81 @@ +package app.revanced.extension.youtube.patches.general; + +import androidx.annotation.Nullable; + +import java.util.concurrent.atomic.AtomicBoolean; + +import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.youtube.patches.general.requests.VideoDetailsRequest; +import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.utils.VideoUtils; + +@SuppressWarnings("unused") +public final class OpenChannelOfLiveAvatarPatch { + private static final boolean CHANGE_LIVE_RING_CLICK_ACTION = + Settings.CHANGE_LIVE_RING_CLICK_ACTION.get(); + + private static final AtomicBoolean engagementPanelOpen = new AtomicBoolean(false); + private static volatile boolean liveChannelAvatarClicked = false; + private static volatile String videoId = ""; + + public static void showEngagementPanel(@Nullable Object object) { + engagementPanelOpen.set(object != null); + } + + public static void hideEngagementPanel() { + engagementPanelOpen.compareAndSet(true, false); + } + + public static void liveChannelAvatarClicked() { + liveChannelAvatarClicked = true; + } + + public static boolean openChannelOfLiveAvatar() { + try { + if (!CHANGE_LIVE_RING_CLICK_ACTION) { + return false; + } + if (!liveChannelAvatarClicked) { + return false; + } + if (engagementPanelOpen.get()) { + return false; + } + VideoDetailsRequest request = VideoDetailsRequest.getRequestForVideoId(videoId); + if (request != null) { + String channelId = request.getInfo(); + if (channelId != null) { + videoId = ""; + liveChannelAvatarClicked = false; + VideoUtils.openChannel(channelId); + return true; + } + } + } catch (Exception ex) { + Logger.printException(() -> "openChannelOfLiveAvatar failure", ex); + } + return false; + } + + public static void openChannelOfLiveAvatar(String newlyLoadedVideoId) { + try { + if (!CHANGE_LIVE_RING_CLICK_ACTION) { + return; + } + if (!liveChannelAvatarClicked) { + return; + } + if (engagementPanelOpen.get()) { + return; + } + if (newlyLoadedVideoId.isEmpty()) { + return; + } + videoId = newlyLoadedVideoId; + VideoDetailsRequest.fetchRequestIfNeeded(newlyLoadedVideoId); + } catch (Exception ex) { + Logger.printException(() -> "openChannelOfLiveAvatar failure", ex); + } + } + +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SettingsMenuPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SettingsMenuPatch.java index 792fe4635..84d4e6e50 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SettingsMenuPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SettingsMenuPatch.java @@ -22,7 +22,8 @@ public final class SettingsMenuPatch extends BaseSettingsMenuPatch { GENERAL("general_key", Settings.HIDE_SETTINGS_MENU_GENERAL.get()), ACCOUNT("account_switcher_key", Settings.HIDE_SETTINGS_MENU_ACCOUNT.get()), DATA_SAVING("data_saving_settings_key", Settings.HIDE_SETTINGS_MENU_DATA_SAVING.get()), - AUTOPLAY("auto_play_key", Settings.HIDE_SETTINGS_MENU_AUTOPLAY.get()), + AUTOPLAY("auto_play_key", Settings.HIDE_SETTINGS_MENU_AUTOPLAY_PLAYBACK.get()), + PLAYBACK("playback_key", Settings.HIDE_SETTINGS_MENU_AUTOPLAY_PLAYBACK.get()), VIDEO_QUALITY_PREFERENCES("video_quality_settings_key", Settings.HIDE_SETTINGS_MENU_VIDEO_QUALITY_PREFERENCES.get()), POST_PURCHASE("yt_unlimited_post_purchase_key", Settings.HIDE_SETTINGS_MENU_POST_PURCHASE.get()), OFFLINE("offline_key", Settings.HIDE_SETTINGS_MENU_OFFLINE.get()), diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SnackBarPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SnackBarPatch.java new file mode 100644 index 000000000..07c20f03b --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/SnackBarPatch.java @@ -0,0 +1,115 @@ +package app.revanced.extension.youtube.patches.general; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.widget.FrameLayout; + +import java.util.concurrent.atomic.AtomicBoolean; + +import app.revanced.extension.shared.utils.ResourceUtils; +import app.revanced.extension.shared.utils.Utils; +import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.utils.ThemeUtils; + +@SuppressWarnings("unused") +public final class SnackBarPatch { + private static final boolean HIDE_SNACK_BAR = + Settings.HIDE_SNACK_BAR.get(); + private static final boolean HIDE_SERVER_SIDE_SNACK_BAR = + Settings.HIDE_SERVER_SIDE_SNACK_BAR.get(); + private static final boolean CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND = + !HIDE_SNACK_BAR && !HIDE_SERVER_SIDE_SNACK_BAR && Settings.CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND.get(); + private static final boolean INVERT_SNACK_BAR_THEME = + !HIDE_SNACK_BAR && Settings.INVERT_SNACK_BAR_THEME.get(); + private static final boolean INVERT_SERVER_SIDE_SNACK_BAR_THEME = + !HIDE_SERVER_SIDE_SNACK_BAR && INVERT_SNACK_BAR_THEME; + private static final int SNACK_BAR_BLACK_COLOR = 0xFF0F0F0F; + private static final int SNACK_BAR_WHITE_COLOR = 0xFFF1F1F1; + private static final AtomicBoolean lithoSnackBarLoaded = new AtomicBoolean(false); + private static int blackColor = 0; + private static int whiteColor = 0; + + public static boolean hideSnackBar() { + return HIDE_SNACK_BAR; + } + + public static void hideLithoSnackBar(FrameLayout frameLayout) { + if (HIDE_SERVER_SIDE_SNACK_BAR) { + Utils.hideViewByLayoutParams(frameLayout); + } + } + + public static void setLithoSnackBarBackground(View view) { + if (CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND) { + int snackBarRoundedCornersBackgroundIdentifier = + ResourceUtils.getDrawableIdentifier("snackbar_rounded_corners_background"); + Context mContext = invertSnackBarTheme(view.getContext()); + Drawable snackBarRoundedCornersBackground = mContext.getDrawable(snackBarRoundedCornersBackgroundIdentifier); + if (snackBarRoundedCornersBackground != null) { + view.setBackground(snackBarRoundedCornersBackground); + } + } + } + + public static void setLithoSnackBarBackgroundColor(FrameLayout frameLayout, int color) { + if (CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND) { + return; + } + frameLayout.setBackgroundColor(color); + } + + public static Context invertSnackBarTheme(Context mContext) { + if (INVERT_SERVER_SIDE_SNACK_BAR_THEME) { + String styleId = ThemeUtils.isDarkTheme() + ? "Base.Theme.YouTube.Light" + : "Base.Theme.YouTube.Dark"; + int styleIdentifier = ResourceUtils.getStyleIdentifier(styleId); + mContext = new ContextThemeWrapper(mContext, styleIdentifier); + } + + return mContext; + } + + public static Enum invertSnackBarTheme(Enum appTheme, Enum darkTheme) { + if (INVERT_SNACK_BAR_THEME) { + return appTheme == darkTheme + ? null + : darkTheme; + } + + return appTheme; + } + + public static void lithoSnackBarLoaded() { + lithoSnackBarLoaded.compareAndSet(false, true); + } + + public static int getLithoColor(int originalValue) { + if (CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND && + lithoSnackBarLoaded.compareAndSet(true, false)) { + if (originalValue == SNACK_BAR_BLACK_COLOR) { + return INVERT_SERVER_SIDE_SNACK_BAR_THEME + ? getWhiteColor() + : getBlackColor(); + } else if (originalValue == SNACK_BAR_WHITE_COLOR) { + return INVERT_SERVER_SIDE_SNACK_BAR_THEME + ? getBlackColor() + : getWhiteColor(); + } + } + + return originalValue; + } + + private static int getBlackColor() { + if (blackColor == 0) blackColor = ResourceUtils.getColor("revanced_snack_bar_color_dark"); + return blackColor; + } + + private static int getWhiteColor() { + if (whiteColor == 0) whiteColor = ResourceUtils.getColor("revanced_snack_bar_color_light"); + return whiteColor; + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt new file mode 100644 index 000000000..e7eddf002 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt @@ -0,0 +1,144 @@ +package app.revanced.extension.youtube.patches.general.requests + +import android.annotation.SuppressLint +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.WebClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class VideoDetailsRequest private constructor( + private val videoId: String +) { + private val future: Future = Utils.submitOnBackgroundThread { + fetch(videoId) + } + + val info: String? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH, TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getInfo timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getInfo interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getInfo failure" }, + ex + ) + } + + return null + } + + companion object { + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000L // 20 seconds + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + @SuppressLint("ObsoleteSdkInt") + fun fetchRequestIfNeeded(videoId: String) { + cache[videoId] = VideoDetailsRequest(videoId) + } + + @JvmStatic + fun getRequestForVideoId(videoId: String): VideoDetailsRequest? { + synchronized(cache) { + return cache[videoId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private fun sendRequest(videoId: String): JSONObject? { + val startTime = System.currentTimeMillis() + val clientType = WebClient.ClientType.MWEB + val clientTypeName = clientType.name + Logger.printDebug { "Fetching video details request for: $videoId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.GET_VIDEO_DETAILS, + clientType + ) + val requestBody = + PlayerRoutes.createWebInnertubeBody(clientType, videoId) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendRequest failed" }, ex) + } finally { + Logger.printDebug { "video: " + videoId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun parseResponse(videoDetailsJson: JSONObject): String? { + try { + return videoDetailsJson + .getJSONObject("videoDetails") + .getString("channelId") + } catch (e: JSONException) { + Logger.printException( + { "Fetch failed while processing response data for response: $videoDetailsJson" }, + e + ) + } + + return null + } + + private fun fetch(videoId: String): String? { + val videoDetailsJson = sendRequest(videoId) + if (videoDetailsJson != null) { + return parseResponse(videoDetailsJson) + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/ExternalBrowserPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/ExternalBrowserPatch.java deleted file mode 100644 index 794fd93e0..000000000 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/ExternalBrowserPatch.java +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.extension.youtube.patches.misc; - -import app.revanced.extension.youtube.settings.Settings; - -@SuppressWarnings("unused") -public class ExternalBrowserPatch { - - public static String enableExternalBrowser(final String original) { - if (!Settings.ENABLE_EXTERNAL_BROWSER.get()) - return original; - - return ""; - } -} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksDirectlyPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksDirectlyPatch.java index a3e9b9658..e4d466428 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksDirectlyPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksDirectlyPatch.java @@ -10,9 +10,9 @@ import app.revanced.extension.youtube.settings.Settings; public class OpenLinksDirectlyPatch { private static final String YOUTUBE_REDIRECT_PATH = "/redirect"; - public static Uri enableBypassRedirect(String uri) { + public static Uri parseRedirectUri(String uri) { final Uri parsed = Uri.parse(uri); - if (!Settings.ENABLE_OPEN_LINKS_DIRECTLY.get()) + if (!Settings.BYPASS_URL_REDIRECTS.get()) return parsed; if (Objects.equals(parsed.getPath(), YOUTUBE_REDIRECT_PATH)) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksExternallyPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksExternallyPatch.java new file mode 100644 index 000000000..43740adcd --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/OpenLinksExternallyPatch.java @@ -0,0 +1,15 @@ +package app.revanced.extension.youtube.patches.misc; + +import app.revanced.extension.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class OpenLinksExternallyPatch { + + // renamed from 'enableExternalBrowser' + public static String openLinksExternally(final String original) { + if (!Settings.OPEN_LINKS_EXTERNALLY.get()) + return original; + + return ""; + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/ActionButtonsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/ActionButtonsPatch.java new file mode 100644 index 000000000..9cd6f6a0c --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/ActionButtonsPatch.java @@ -0,0 +1,62 @@ +package app.revanced.extension.youtube.patches.player; + +import androidx.annotation.Nullable; + +import java.util.List; + +import app.revanced.extension.shared.settings.BooleanSetting; +import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.VideoInformation; + +@SuppressWarnings("unused") +public class ActionButtonsPatch { + + public enum ActionButton { + INDEX_7(Settings.HIDE_ACTION_BUTTON_INDEX_7, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_7, 7), + INDEX_6(Settings.HIDE_ACTION_BUTTON_INDEX_6, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_6, 6), + INDEX_5(Settings.HIDE_ACTION_BUTTON_INDEX_5, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_5, 5), + INDEX_4(Settings.HIDE_ACTION_BUTTON_INDEX_4, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_4, 4), + INDEX_3(Settings.HIDE_ACTION_BUTTON_INDEX_3, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_3, 3), + INDEX_2(Settings.HIDE_ACTION_BUTTON_INDEX_2, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_2, 2), + INDEX_1(Settings.HIDE_ACTION_BUTTON_INDEX_1, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_1, 1), + INDEX_0(Settings.HIDE_ACTION_BUTTON_INDEX_0, Settings.HIDE_ACTION_BUTTON_INDEX_LIVE_0, 0); + + private final BooleanSetting generalSetting; + private final BooleanSetting liveSetting; + private final int index; + + ActionButton(final BooleanSetting generalSetting, final BooleanSetting liveSetting, final int index) { + this.generalSetting = generalSetting; + this.liveSetting = liveSetting; + this.index = index; + } + } + + private static final String TARGET_COMPONENT_TYPE = "LazilyConvertedElement"; + private static final String VIDEO_ACTION_BAR_PATH_PREFIX = "video_action_bar.eml"; + + public static List hideActionButtonByIndex(@Nullable List list, @Nullable String identifier) { + try { + if (identifier != null && + identifier.startsWith(VIDEO_ACTION_BAR_PATH_PREFIX) && + list != null && + !list.isEmpty() && + list.get(0).toString().equals(TARGET_COMPONENT_TYPE) + ) { + final int size = list.size(); + final boolean isLive = VideoInformation.getLiveStreamState(); + for (ActionButton button : ActionButton.values()) { + if (size > button.index && (isLive ? button.liveSetting.get() : button.generalSetting.get())) { + list.remove(button.index); + } + } + } + } catch (Exception ex) { + Logger.printException(() -> "hideActionButtonByIndex failure", ex); + } + + return list; + } + +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/SeekbarColorPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/SeekbarColorPatch.java index d31788832..256d19902 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/SeekbarColorPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/SeekbarColorPatch.java @@ -27,23 +27,28 @@ public class SeekbarColorPatch { private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000; /** - * Default colors of the gradient seekbar. + * Feed default colors of the gradient seekbar. */ - private static final int[] ORIGINAL_SEEKBAR_GRADIENT_COLORS = {0xFFFF0033, 0xFFFF2791}; + private static final int[] FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS = {0xFFFF0033, 0xFFFF2791}; /** - * Default positions of the gradient seekbar. + * Feed default positions of the gradient seekbar. */ - private static final float[] ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = {0.8f, 1.0f}; + private static final float[] FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = {0.8f, 1.0f}; /** * Default YouTube seekbar color brightness. */ private static final float ORIGINAL_SEEKBAR_COLOR_BRIGHTNESS; + /** + * Empty seekbar gradient, if hide seekbar in feed is enabled. + */ + private static final int[] HIDDEN_SEEKBAR_GRADIENT_COLORS = {0x00000000, 0x00000000}; + /** * If {@link Settings#ENABLE_CUSTOM_SEEKBAR_COLOR} is enabled, - * this is the color value of {@link Settings#ENABLE_CUSTOM_SEEKBAR_COLOR_VALUE}. + * this is the color value of {@link Settings#CUSTOM_SEEKBAR_COLOR_VALUE}. * Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}. */ private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR; @@ -53,6 +58,11 @@ public class SeekbarColorPatch { */ private static final float[] customSeekbarColorHSV = new float[3]; + /** + * Custom seekbar color, used for linear gradient replacements. + */ + private static final int[] customSeekbarColorInt = new int[2]; + static { float[] hsv = new float[3]; Color.colorToHSV(ORIGINAL_SEEKBAR_COLOR, hsv); @@ -61,16 +71,18 @@ public class SeekbarColorPatch { if (CUSTOM_SEEKBAR_COLOR_ENABLED) { loadCustomSeekbarColor(); } + + Arrays.fill(customSeekbarColorInt, seekbarColor); } private static void loadCustomSeekbarColor() { try { - seekbarColor = Color.parseColor(Settings.ENABLE_CUSTOM_SEEKBAR_COLOR_VALUE.get()); + seekbarColor = Color.parseColor(Settings.CUSTOM_SEEKBAR_COLOR_VALUE.get()); Color.colorToHSV(seekbarColor, customSeekbarColorHSV); } catch (Exception ex) { Utils.showToastShort(str("revanced_custom_seekbar_color_value_invalid_invalid_toast")); Utils.showToastShort(str("revanced_extended_reset_to_default_toast")); - Settings.ENABLE_CUSTOM_SEEKBAR_COLOR_VALUE.resetToDefault(); + Settings.CUSTOM_SEEKBAR_COLOR_VALUE.resetToDefault(); loadCustomSeekbarColor(); } } @@ -165,6 +177,33 @@ public class SeekbarColorPatch { return colorValue; } + /** + * Injection point. + */ + public static int[] getLinearGradient(int[] original) { + if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) { + return HIDDEN_SEEKBAR_GRADIENT_COLORS; + } + return CUSTOM_SEEKBAR_COLOR_ENABLED + ? customSeekbarColorInt + : original; + } + + private static String colorArrayToHex(int[] colors) { + final int length = colors.length; + StringBuilder builder = new StringBuilder(length * 10); + builder.append("["); + int i = 0; + for (int color : colors) { + builder.append(String.format("#%X", color)); + if (++i < length) { + builder.append(", "); + } + } + builder.append("]"); + return builder.toString(); + } + /** * Injection point. */ @@ -174,15 +213,15 @@ public class SeekbarColorPatch { if (CUSTOM_SEEKBAR_COLOR_ENABLED || hideSeekbar) { // Most litho usage of linear gradients is hooked here, // so must only change if the values are those for the seekbar. - if (Arrays.equals(ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors) - && Arrays.equals(ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions)) { + if ((Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors) + && Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions))) { Arrays.fill(colors, hideSeekbar ? 0x00000000 : seekbarColor); return; } - Logger.printDebug(() -> "Ignoring gradient colors: " + Arrays.toString(colors) + Logger.printDebug(() -> "Ignoring gradient colors: " + colorArrayToHex(colors) + " positions: " + Arrays.toString(positions)); } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsPatch.java index 9125a2138..b610cad70 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsPatch.java @@ -16,11 +16,14 @@ import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar; import java.lang.ref.WeakReference; +import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.ResourceUtils; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.NavigationBar.NavigationButton; import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.utils.VideoUtils; +import kotlin.Unit; @SuppressWarnings("unused") public class ShortsPatch { @@ -34,7 +37,7 @@ public class ShortsPatch { if (HIDE_SHORTS_NAVIGATION_BAR) { ShortsPlayerState.getOnChange().addObserver((ShortsPlayerState state) -> { setNavigationBarLayoutParams(state); - return null; + return Unit.INSTANCE; }); } final int bottomMargin = validateValue( @@ -60,6 +63,10 @@ public class ShortsPatch { return Settings.DISABLE_RESUMING_SHORTS_PLAYER.get(); } + public static boolean disableResumingStartupShortsPlayer(boolean original) { + return !Settings.DISABLE_RESUMING_SHORTS_PLAYER.get() && original; + } + public static boolean enableShortsTimeStamp(boolean original) { return ENABLE_TIME_STAMP || original; } @@ -211,4 +218,38 @@ public class ShortsPatch { return !Settings.RESTORE_SHORTS_OLD_PLAYER_LAYOUT.get(); } + public static boolean openShortInRegularPlayer(String videoId) { + try { + if (!Settings.OPEN_SHORTS_IN_REGULAR_PLAYER.get()) { + return false; // Default unpatched behavior. + } + + if (videoId.isEmpty()) { + // Shorts was opened using launcher app shortcut. + // + // This check will not detect if the Shorts app shortcut is used + // while the app is running in the background (instead the regular player is opened). + // To detect that the hooked method map parameter can be checked + // if integer key 'com.google.android.apps.youtube.app.endpoint.flags' + // has bitmask 16 set. + // + // This use case seems unlikely if the user has the Shorts + // set to open in the regular player, so it's ignored as + // checking the map makes the patch more complicated. + Logger.printDebug(() -> "Ignoring Short with no videoId"); + return false; + } + + if (NavigationButton.getSelectedNavigationButton() == NavigationButton.SHORTS) { + return false; // Always use Shorts player for the Shorts nav button. + } + + VideoUtils.openVideo(videoId, true); + return true; + } catch (Exception ex) { + Logger.printException(() -> "openShortInRegularPlayer failure", ex); + return false; + } + } + } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/spans/SnackBarFilter.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/spans/SnackBarFilter.java new file mode 100644 index 000000000..4dbed0834 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/spans/SnackBarFilter.java @@ -0,0 +1,62 @@ +package app.revanced.extension.youtube.patches.spans; + +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; + +import app.revanced.extension.shared.patches.spans.Filter; +import app.revanced.extension.shared.patches.spans.SpanType; +import app.revanced.extension.shared.patches.spans.StringFilterGroup; +import app.revanced.extension.shared.utils.ResourceUtils; +import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.utils.ThemeUtils; + +@SuppressWarnings({"unused", "FieldCanBeLocal"}) +public final class SnackBarFilter extends Filter { + private static final boolean HIDE_SNACK_BAR = + Settings.HIDE_SNACK_BAR.get() || Settings.HIDE_SERVER_SIDE_SNACK_BAR.get(); + private static final boolean CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND = + !HIDE_SNACK_BAR && Settings.CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND.get(); + private static final boolean INVERT_SNACK_BAR_THEME = + !HIDE_SNACK_BAR && Settings.INVERT_SNACK_BAR_THEME.get(); + + private final ForegroundColorSpan foregroundColorSpanBlack = + new ForegroundColorSpan(ResourceUtils.getColor("yt_black1")); + private final ForegroundColorSpan foregroundColorSpanWhite = + new ForegroundColorSpan(ResourceUtils.getColor("yt_white1")); + + public SnackBarFilter() { + addCallbacks( + new StringFilterGroup( + Settings.CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND, + "snackbar.eml|" + ) + ); + } + + private ForegroundColorSpan getForegroundColorSpan() { + if (INVERT_SNACK_BAR_THEME) { + return ThemeUtils.isDarkTheme() + ? foregroundColorSpanWhite + : foregroundColorSpanBlack; + } + return ThemeUtils.isDarkTheme() + ? foregroundColorSpanBlack + : foregroundColorSpanWhite; + } + + @Override + public boolean skip(String conversionContext, SpannableString spannableString, Object span, + int start, int end, int flags, boolean isWord, SpanType spanType, StringFilterGroup matchedGroup) { + if (CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND && spanType == SpanType.FOREGROUND_COLOR) { + spannableString.setSpan( + getForegroundColorSpan(), + start, + end, + flags + ); + return super.skip(conversionContext, spannableString, span, start, end, flags, isWord, spanType, matchedGroup); + } + + return false; + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/DrawableColorPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/DrawableColorPatch.java index 772dcd3e6..47f272b93 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/DrawableColorPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/DrawableColorPatch.java @@ -1,34 +1,36 @@ package app.revanced.extension.youtube.patches.utils; +import org.apache.commons.lang3.ArrayUtils; + import app.revanced.extension.shared.utils.ResourceUtils; @SuppressWarnings("unused") public class DrawableColorPatch { - private static final int[] WHITE_VALUES = { - -1, // comments chip background - -394759, // music related results panel background - -83886081 // video chapters list background + private static final int[] DARK_COLORS = { + 0xFF282828, // drawer content view background + 0xFF212121, // comments chip background + 0xFF181818, // music related results panel background + 0xFF0F0F0F, // comments chip background (new layout) + 0xFA212121, // video chapters list background }; - private static final int[] DARK_VALUES = { - -14145496, // drawer content view background - -14606047, // comments chip background - -15198184, // music related results panel background - -15790321, // comments chip background (new layout) - -98492127 // video chapters list background + private static final int[] LIGHT_COLORS = { + -1, // comments chip background + 0xFFF9F9F9, // music related results panel background + 0xFAFFFFFF, // video chapters list background }; // background colors private static int whiteColor = 0; private static int blackColor = 0; - public static int getLithoColor(int originalValue) { - if (anyEquals(originalValue, DARK_VALUES)) { + public static int getLithoColor(int colorValue) { + if (ArrayUtils.contains(DARK_COLORS, colorValue)) { return getBlackColor(); - } else if (anyEquals(originalValue, WHITE_VALUES)) { + } else if (ArrayUtils.contains(LIGHT_COLORS, colorValue)) { return getWhiteColor(); } - return originalValue; + return colorValue; } private static int getBlackColor() { @@ -40,11 +42,6 @@ public class DrawableColorPatch { if (whiteColor == 0) whiteColor = ResourceUtils.getColor("yt_white1"); return whiteColor; } - - private static boolean anyEquals(int value, int... of) { - for (int v : of) if (value == v) return true; - return false; - } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PatchStatus.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PatchStatus.java index 10fefa0e2..6c9ddcbfd 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PatchStatus.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PatchStatus.java @@ -27,6 +27,10 @@ public class PatchStatus { return false; } + public static String SpoofAppVersionDefaultString() { + return "18.17.43"; + } + public static boolean ToolBarComponents() { // Replace this with true if the Toolbar components patch succeeds return false; diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java index d13e2e354..45d84038c 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java @@ -24,7 +24,9 @@ public class VideoQualityPatch { * Injection point. */ public static void newVideoStarted() { - setVideoQuality(0); + VideoInformation.qualityNeedsUpdating = true; + VideoInformation.videoQualities = null; + setVideoQuality(250); } /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt index 9d4f25036..5ceb2615f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt @@ -129,7 +129,11 @@ class MusicRequest private constructor( clientType ) val requestBody = - PlayerRoutes.createApplicationRequestBody(clientType = clientType, videoId = videoId, playlistId = "RD$videoId") + PlayerRoutes.createApplicationRequestBody( + clientType = clientType, + videoId = videoId, + playlistId = "RD$videoId" + ) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -161,7 +165,7 @@ class MusicRequest private constructor( val startTime = System.currentTimeMillis() val clientType = WebClient.ClientType.MWEB val clientTypeName = clientType.name - Logger.printDebug { "Fetching playability request for: $videoId, using client: $clientTypeName" } + Logger.printDebug { "Fetching microformat request for: $videoId, using client: $clientTypeName" } try { val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( @@ -226,9 +230,14 @@ class MusicRequest private constructor( .getJSONObject("watchEndpoint") val playerParams: String? = watchEndpointJsonObject?.getString("playerParams") - return playerParams != null && VideoInformation.isMixPlaylistsOpenedByUser(playerParams) + return playerParams != null && VideoInformation.isMixPlaylistsOpenedByUser( + playerParams + ) } catch (e: JSONException) { - Logger.printException ({ "Fetch failed while processing Application response data for response: $playlistJson" }, e) + Logger.printException( + { "Fetch failed while processing Application response data for response: $playlistJson" }, + e + ) } return false @@ -242,7 +251,10 @@ class MusicRequest private constructor( .getString("category") .equals("Music") } catch (e: JSONException) { - Logger.printException ({ "Fetch failed while processing Web response data for response: $microFormatJson" }, e) + Logger.printException( + { "Fetch failed while processing Web response data for response: $microFormatJson" }, + e + ) } return false diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index d1762467b..ff4bcb090 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -87,13 +87,12 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_MOVIE_SHELF = new BooleanSetting("revanced_hide_movie_shelf", FALSE); public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", FALSE); public static final BooleanSetting HIDE_PLAYABLES = new BooleanSetting("revanced_hide_playables", TRUE); - public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true); public static final BooleanSetting HIDE_FEED_SEARCH_BAR = new BooleanSetting("revanced_hide_feed_search_bar", FALSE); - public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE); + public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true); public static final BooleanSetting HIDE_SUBSCRIPTIONS_CAROUSEL = new BooleanSetting("revanced_hide_subscriptions_carousel", FALSE, true); + public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE); public static final BooleanSetting HIDE_TICKET_SHELF = new BooleanSetting("revanced_hide_ticket_shelf", TRUE); - // PreferenceScreen: Feed - Category bar public static final BooleanSetting HIDE_CATEGORY_BAR_IN_FEED = new BooleanSetting("revanced_hide_category_bar_in_feed", FALSE, true); public static final BooleanSetting HIDE_CATEGORY_BAR_IN_SEARCH = new BooleanSetting("revanced_hide_category_bar_in_search", FALSE, true); @@ -152,12 +151,12 @@ public class Settings extends BaseSettings { public static final BooleanSetting ENABLE_GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_enable_gradient_loading_screen", FALSE, true); public static final BooleanSetting HIDE_FLOATING_MICROPHONE = new BooleanSetting("revanced_hide_floating_microphone", TRUE, true); public static final BooleanSetting HIDE_GRAY_SEPARATOR = new BooleanSetting("revanced_hide_gray_separator", TRUE); - public static final BooleanSetting HIDE_SNACK_BAR = new BooleanSetting("revanced_hide_snack_bar", FALSE); public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE); public static final EnumSetting CHANGE_LAYOUT = new EnumSetting<>("revanced_change_layout", FormFactor.ORIGINAL, true); + public static final BooleanSetting CHANGE_LIVE_RING_CLICK_ACTION = new BooleanSetting("revanced_change_live_ring_click_action", FALSE, true); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", false, true, "revanced_spoof_app_version_user_dialog_message"); - public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "18.17.43", true, parent(SPOOF_APP_VERSION)); + public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", PatchStatus.SpoofAppVersionDefaultString(), true, parent(SPOOF_APP_VERSION)); // PreferenceScreen: General - Account menu public static final BooleanSetting HIDE_ACCOUNT_MENU = new BooleanSetting("revanced_hide_account_menu", FALSE); @@ -181,7 +180,7 @@ public class Settings extends BaseSettings { public static final IntegerSetting MINIPLAYER_WIDTH_DIP = new IntegerSetting("revanced_miniplayer_width_dip", 192, true, MINIPLAYER_ANY_MODERN); public static final IntegerSetting MINIPLAYER_OPACITY = new IntegerSetting("revanced_miniplayer_opacity", 100, true, MINIPLAYER_TYPE.availability(MODERN_1)); - // PreferenceScreen: General - Navigation bar + // PreferenceScreen: General - Navigation Bar public static final BooleanSetting ENABLE_NARROW_NAVIGATION_BUTTONS = new BooleanSetting("revanced_enable_narrow_navigation_buttons", FALSE, true); public static final BooleanSetting HIDE_NAVIGATION_CREATE_BUTTON = new BooleanSetting("revanced_hide_navigation_create_button", TRUE, true); public static final BooleanSetting HIDE_NAVIGATION_HOME_BUTTON = new BooleanSetting("revanced_hide_navigation_home_button", FALSE, true); @@ -209,7 +208,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_SETTINGS_MENU_GENERAL = new BooleanSetting("revanced_hide_settings_menu_general", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_ACCOUNT = new BooleanSetting("revanced_hide_settings_menu_account", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_DATA_SAVING = new BooleanSetting("revanced_hide_settings_menu_data_saving", FALSE, true); - public static final BooleanSetting HIDE_SETTINGS_MENU_AUTOPLAY = new BooleanSetting("revanced_hide_settings_menu_auto_play", FALSE, true); + public static final BooleanSetting HIDE_SETTINGS_MENU_AUTOPLAY_PLAYBACK = new BooleanSetting("revanced_hide_settings_menu_autoplay_playback", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_VIDEO_QUALITY_PREFERENCES = new BooleanSetting("revanced_hide_settings_menu_video_quality", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_OFFLINE = new BooleanSetting("revanced_hide_settings_menu_offline", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_WATCH_ON_TV = new BooleanSetting("revanced_hide_settings_menu_pair_with_tv", FALSE, true); @@ -231,11 +230,17 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_SETTINGS_MENU_POST_PURCHASE = new BooleanSetting("revanced_hide_settings_menu_post_purchase", FALSE, true); public static final BooleanSetting HIDE_SETTINGS_MENU_THIRD_PARTY = new BooleanSetting("revanced_hide_settings_menu_third_party", FALSE, true); + // PreferenceScreen: General - Snack bar + public static final BooleanSetting HIDE_SNACK_BAR = new BooleanSetting("revanced_hide_snack_bar", FALSE, true); + public static final BooleanSetting HIDE_SERVER_SIDE_SNACK_BAR = new BooleanSetting("revanced_hide_server_side_snack_bar", FALSE, true); + public static final BooleanSetting CHANGE_SERVER_SIDE_SNACK_BAR_BACKGROUND = new BooleanSetting("revanced_change_server_side_snack_bar_background", FALSE, true, "revanced_change_server_side_snack_bar_background_user_dialog_message"); + public static final BooleanSetting INVERT_SNACK_BAR_THEME = new BooleanSetting("revanced_invert_snack_bar_theme", FALSE, true); + // PreferenceScreen: General - Toolbar public static final BooleanSetting CHANGE_YOUTUBE_HEADER = new BooleanSetting("revanced_change_youtube_header", TRUE, true); public static final BooleanSetting ENABLE_WIDE_SEARCH_BAR = new BooleanSetting("revanced_enable_wide_search_bar", FALSE, true); public static final BooleanSetting ENABLE_WIDE_SEARCH_BAR_WITH_HEADER = new BooleanSetting("revanced_enable_wide_search_bar_with_header", TRUE, true); - public static final BooleanSetting ENABLE_WIDE_SEARCH_BAR_IN_YOU_TAB = new BooleanSetting("revanced_enable_wide_search_bar_in_you_tab", FALSE, true); + public static final BooleanSetting ENABLE_WIDE_SEARCH_BAR_IN_YOU_TAB = new BooleanSetting("revanced_enable_wide_search_bar_in_you_tab", FALSE, true, "revanced_enable_wide_search_bar_in_you_tab_user_dialog_message"); public static final BooleanSetting HIDE_TOOLBAR_CAST_BUTTON = new BooleanSetting("revanced_hide_toolbar_cast_button", TRUE, true); public static final BooleanSetting HIDE_TOOLBAR_CREATE_BUTTON = new BooleanSetting("revanced_hide_toolbar_create_button", FALSE, true); public static final BooleanSetting HIDE_TOOLBAR_NOTIFICATION_BUTTON = new BooleanSetting("revanced_hide_toolbar_notification_button", FALSE, true); @@ -284,6 +289,23 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_SHOP_BUTTON = new BooleanSetting("revanced_hide_shop_button", FALSE); public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_0 = new BooleanSetting("revanced_hide_action_button_index_0", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_1 = new BooleanSetting("revanced_hide_action_button_index_1", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_2 = new BooleanSetting("revanced_hide_action_button_index_2", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_3 = new BooleanSetting("revanced_hide_action_button_index_3", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_4 = new BooleanSetting("revanced_hide_action_button_index_4", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_5 = new BooleanSetting("revanced_hide_action_button_index_5", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_6 = new BooleanSetting("revanced_hide_action_button_index_6", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_7 = new BooleanSetting("revanced_hide_action_button_index_7", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_0 = new BooleanSetting("revanced_hide_action_button_index_live_0", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_1 = new BooleanSetting("revanced_hide_action_button_index_live_1", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_2 = new BooleanSetting("revanced_hide_action_button_index_live_2", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_3 = new BooleanSetting("revanced_hide_action_button_index_live_3", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_4 = new BooleanSetting("revanced_hide_action_button_index_live_4", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_5 = new BooleanSetting("revanced_hide_action_button_index_live_5", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_6 = new BooleanSetting("revanced_hide_action_button_index_live_6", FALSE); + public static final BooleanSetting HIDE_ACTION_BUTTON_INDEX_LIVE_7 = new BooleanSetting("revanced_hide_action_button_index_live_7", FALSE); + // PreferenceScreen: Player - Ambient mode public static final BooleanSetting BYPASS_AMBIENT_MODE_RESTRICTIONS = new BooleanSetting("revanced_bypass_ambient_mode_restrictions", FALSE); public static final BooleanSetting DISABLE_AMBIENT_MODE = new BooleanSetting("revanced_disable_ambient_mode", FALSE, true); @@ -394,7 +416,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting REPLACE_TIME_STAMP_ACTION = new BooleanSetting("revanced_replace_time_stamp_action", TRUE, true, parent(APPEND_TIME_STAMP_INFORMATION)); public static final BooleanSetting DISABLE_SEEKBAR_CHAPTERS = new BooleanSetting("revanced_disable_seekbar_chapters", FALSE, true); public static final BooleanSetting ENABLE_CUSTOM_SEEKBAR_COLOR = new BooleanSetting("revanced_enable_custom_seekbar_color", FALSE, true); - public static final StringSetting ENABLE_CUSTOM_SEEKBAR_COLOR_VALUE = new StringSetting("revanced_custom_seekbar_color_value", "#FF0033", true, parent(ENABLE_CUSTOM_SEEKBAR_COLOR)); + public static final StringSetting CUSTOM_SEEKBAR_COLOR_VALUE = new StringSetting("revanced_custom_seekbar_color_value", "#FF0033", true, parent(ENABLE_CUSTOM_SEEKBAR_COLOR)); public static final BooleanSetting ENABLE_SEEKBAR_TAPPING = new BooleanSetting("revanced_enable_seekbar_tapping", TRUE); public static final BooleanSetting HIDE_SEEKBAR_CHAPTER_LABEL = new BooleanSetting("revanced_hide_seekbar_chapter_label", FALSE, true); public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true); @@ -432,6 +454,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_SHORTS_SHELF_HISTORY = new BooleanSetting("revanced_hide_shorts_shelf_history", TRUE); public static final EnumSetting CHANGE_SHORTS_BACKGROUND_REPEAT_STATE = new EnumSetting<>("revanced_change_shorts_background_repeat_state", ShortsLoopBehavior.UNKNOWN); public static final EnumSetting CHANGE_SHORTS_REPEAT_STATE = new EnumSetting<>("revanced_change_shorts_repeat_state", ShortsLoopBehavior.UNKNOWN); + public static final BooleanSetting OPEN_SHORTS_IN_REGULAR_PLAYER = new BooleanSetting("revanced_open_shorts_in_regular_player", FALSE); // PreferenceScreen: Shorts - Shorts player components public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE); @@ -550,8 +573,8 @@ public class Settings extends BaseSettings { // PreferenceScreen: Miscellaneous - public static final BooleanSetting ENABLE_EXTERNAL_BROWSER = new BooleanSetting("revanced_enable_external_browser", TRUE, true); - public static final BooleanSetting ENABLE_OPEN_LINKS_DIRECTLY = new BooleanSetting("revanced_enable_open_links_directly", TRUE); + public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); + public static final BooleanSetting OPEN_LINKS_EXTERNALLY = new BooleanSetting("revanced_open_links_externally", TRUE, true); // Experimental Flags public static final BooleanSetting CHANGE_SHARE_SHEET = new BooleanSetting("revanced_change_share_sheet", FALSE, true); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/VideoInformation.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/VideoInformation.java index 06217d432..be7a14684 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/VideoInformation.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/VideoInformation.java @@ -69,9 +69,9 @@ public final class VideoInformation { * The available qualities of the current video in human readable form: [1080, 720, 480] */ @Nullable - private static List videoQualities; + public static volatile List videoQualities; - private static boolean qualityNeedsUpdating; + public static volatile boolean qualityNeedsUpdating; /** * Injection point. diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java index bccbbd3e6..8eed690d5 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java @@ -23,6 +23,7 @@ import app.revanced.extension.youtube.patches.player.PlayerPatch; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment; +import kotlin.Unit; @SuppressWarnings("unused") public class SponsorBlockViewController { @@ -44,7 +45,7 @@ public class SponsorBlockViewController { static { PlayerType.getOnChange().addObserver((PlayerType type) -> { playerTypeChanged(type); - return null; + return Unit.INSTANCE; }); defaultBottomMargin = getDimension("brand_interaction_default_bottom_margin"); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/controller/ScreenBrightnessController.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/controller/ScreenBrightnessController.kt index abf0d0db8..dfdc1b13e 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/controller/ScreenBrightnessController.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/controller/ScreenBrightnessController.kt @@ -59,7 +59,7 @@ class ScreenBrightnessController( */ private var rawScreenBrightness: Float get() = host.window.attributes.screenBrightness - private set(value) { + set(value) { val attr = host.window.attributes attr.screenBrightness = value host.window.attributes = attr diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index 0a5eb34e6..cf55b9b11 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -29,12 +29,17 @@ import app.revanced.extension.youtube.shared.VideoInformation; @SuppressWarnings("unused") public class VideoUtils extends IntentUtils { + private static final String CHANNEL_URL = "https://www.youtube.com/channel/"; private static final String PLAYLIST_URL = "https://www.youtube.com/playlist?list="; private static final String VIDEO_URL = "https://youtu.be/"; private static final String VIDEO_SCHEME_INTENT_FORMAT = "vnd.youtube://%s?start=%d"; private static final String VIDEO_SCHEME_LINK_FORMAT = "https://youtu.be/%s?t=%d"; private static final AtomicBoolean isExternalDownloaderLaunched = new AtomicBoolean(false); + private static String getChannelUrl(String channelId) { + return CHANNEL_URL + channelId; + } + private static String getPlaylistUrl(String playlistId) { return PLAYLIST_URL + playlistId; } @@ -119,6 +124,10 @@ public class VideoUtils extends IntentUtils { } } + public static void openChannel(@NonNull String channelId) { + launchView(getChannelUrl(channelId), getContext().getPackageName()); + } + public static void openVideo() { openVideo(VideoInformation.getVideoId()); } diff --git a/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java b/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java index 14d19be64..64b06fcab 100644 --- a/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java +++ b/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java @@ -44,7 +44,7 @@ public class VideoQualitySettingsActivity extends Activity { @Override protected void attachBaseContext(Context base) { - super.attachBaseContext(Utils.getLocalizedContextAndSetResources(base)); + super.attachBaseContext(Utils.getLocalizedContext(base)); } @Override diff --git a/gradle.properties b/gradle.properties index 70d42e4e1..c22c51760 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.2.2 +version = 5.3.1 diff --git a/patches.json b/patches.json index 611167a51..36c4d06e0 100644 --- a/patches.json +++ b/patches.json @@ -57,7 +57,28 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" + ] + }, + "options": [] + }, + { + "name": "Bypass URL redirects", + "description": "Adds an option to bypass URL redirects and open the original URL directly.", + "use": true, + "dependencies": [ + "Settings for YouTube" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "18.29.38", + "18.33.40", + "18.38.44", + "18.48.39", + "19.05.36", + "19.16.39", + "19.44.39" ] }, "options": [] @@ -77,7 +98,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -115,7 +137,51 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" + ] + }, + "options": [] + }, + { + "name": "Change layout", + "description": "Adds an option to change the dp in order to use a tablet or phone layout.", + "use": true, + "dependencies": [ + "Settings for YouTube" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "18.29.38", + "18.33.40", + "18.38.44", + "18.48.39", + "19.05.36", + "19.16.39", + "19.44.39" + ] + }, + "options": [] + }, + { + "name": "Change live ring click action", + "description": "Adds an option to open the channel instead of the live stream when clicking on the live ring.", + "use": true, + "dependencies": [ + "Settings for YouTube", + "ResourcePatch", + "BytecodePatch", + "BytecodePatch" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "18.29.38", + "18.33.40", + "18.38.44", + "18.48.39", + "19.05.36", + "19.16.39", + "19.44.39" ] }, "options": [] @@ -180,7 +246,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -221,7 +288,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -376,7 +444,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -418,7 +487,7 @@ }, { "name": "Custom branding name for Reddit", - "description": "Renames the Reddit app to the name specified in patch options.", + "description": "Changes the Reddit app name to the name specified in patch options.", "use": false, "dependencies": [], "compatiblePackages": { @@ -441,7 +510,7 @@ }, { "name": "Custom branding name for YouTube", - "description": "Renames the YouTube app to the name specified in patch options.", + "description": "Changes the YouTube app name to the name specified in patch options.", "use": true, "dependencies": [ "Settings for YouTube" @@ -476,7 +545,7 @@ }, { "name": "Custom branding name for YouTube Music", - "description": "Renames the YouTube Music app to the name specified in patch options.", + "description": "Changes the YouTube Music app name to the name specified in patch options.", "use": true, "dependencies": [ "Settings for YouTube Music" @@ -488,7 +557,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -599,7 +669,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -630,7 +701,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -701,7 +773,8 @@ "com.google.android.apps.youtube.music": [ "7.06.54", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -721,7 +794,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -751,7 +825,8 @@ "description": "Adds an option to disable redirection to the next track when clicking the Dislike button.", "use": true, "dependencies": [ - "Settings for YouTube Music" + "Settings for YouTube Music", + "ResourcePatch" ], "compatiblePackages": { "com.google.android.apps.youtube.music": [ @@ -760,7 +835,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -800,7 +876,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -862,7 +939,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -872,7 +950,8 @@ "description": "Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched.", "use": true, "dependencies": [ - "Settings for YouTube" + "Settings for YouTube", + "ResourcePatch" ], "compatiblePackages": { "com.google.android.youtube": [ @@ -922,7 +1001,7 @@ }, { "name": "Enable OPUS codec", - "description": "Adds an options to enable the OPUS audio codec if the player response includes it.", + "description": "Adds an option to enable the OPUS audio codec if the player response includes it.", "use": true, "dependencies": [ "BytecodePatch", @@ -935,14 +1014,15 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] }, { "name": "Enable OPUS codec", - "description": "Adds an options to enable the OPUS audio codec if the player response includes it.", + "description": "Adds an option to enable the OPUS audio codec if the player response includes it.", "use": true, "dependencies": [ "BytecodePatch", @@ -975,7 +1055,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1000,27 +1081,6 @@ }, "options": [] }, - { - "name": "Enable external browser", - "description": "Adds an option to always open links in your browser instead of in the in-app-browser.", - "use": true, - "dependencies": [ - "BytecodePatch", - "Settings for YouTube" - ], - "compatiblePackages": { - "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", - "19.05.36", - "19.16.39", - "19.44.39" - ] - }, - "options": [] - }, { "name": "Enable gradient loading screen", "description": "Adds an option to enable the gradient loading screen.", @@ -1056,27 +1116,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" - ] - }, - "options": [] - }, - { - "name": "Enable open links directly", - "description": "Adds an option to skip over redirection URLs in external links.", - "use": true, - "dependencies": [ - "Settings for YouTube" - ], - "compatiblePackages": { - "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", - "19.05.36", - "19.16.39", - "19.44.39" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1102,7 +1143,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1169,7 +1211,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -1332,7 +1375,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1355,7 +1399,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1366,6 +1411,7 @@ "use": true, "dependencies": [ "Settings for YouTube", + "BytecodePatch", "BytecodePatch" ], "compatiblePackages": { @@ -1379,7 +1425,17 @@ "19.44.39" ] }, - "options": [] + "options": [ + { + "key": "hideActionButtonByIndex", + "title": "Hide action buttons by index", + "description": "Add an option to hide action buttons by index.\n\nThis setting is still experimental, so use it only for debugging purposes.", + "required": true, + "type": "kotlin.Boolean", + "default": false, + "values": null + } + ] }, { "name": "Hide ads", @@ -1399,7 +1455,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1476,7 +1533,9 @@ "BytecodePatch", "ResourcePatch", "Settings for YouTube", - "BytecodePatch" + "BytecodePatch", + "BytecodePatch", + "ResourcePatch" ], "compatiblePackages": { "com.google.android.youtube": [ @@ -1530,7 +1589,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1587,7 +1647,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1652,7 +1713,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1769,26 +1831,6 @@ }, "options": [] }, - { - "name": "Layout switch", - "description": "Adds an option to spoof the dpi in order to use a tablet or phone layout.", - "use": true, - "dependencies": [ - "Settings for YouTube" - ], - "compatiblePackages": { - "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", - "19.05.36", - "19.16.39", - "19.44.39" - ] - }, - "options": [] - }, { "name": "MaterialYou", "description": "Applies the MaterialYou theme for Android 12+ devices.", @@ -1848,7 +1890,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -1903,6 +1946,27 @@ }, "options": [] }, + { + "name": "Open links externally", + "description": "Adds an option to always open links in your browser instead of the in-app browser.", + "use": true, + "dependencies": [ + "BytecodePatch", + "Settings for YouTube" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "18.29.38", + "18.33.40", + "18.38.44", + "18.48.39", + "19.05.36", + "19.16.39", + "19.44.39" + ] + }, + "options": [] + }, { "name": "Overlay buttons", "description": "Adds options to display useful overlay buttons in the video player.", @@ -1913,8 +1977,7 @@ "BytecodePatch", "ResourcePatch", "ResourcePatch", - "Settings for YouTube", - "ResourcePatch" + "Settings for YouTube" ], "compatiblePackages": { "com.google.android.youtube": [ @@ -1944,20 +2007,20 @@ { "key": "bottomMargin", "title": "Bottom margin", - "description": "The bottom margin for the overlay buttons and timestamp. Supports from YouTube 18.29.38 to YouTube 19.16.39.", + "description": "The bottom margin for the overlay buttons and timestamp.", "required": true, "type": "kotlin.String", "default": "2.5dip", "values": { "Default": "2.5dip", - "None": "0.0dip", + "Minimum": "0.1dip", "Wider": "5.0dip" } }, { "key": "widerButtonsSpace", "title": "Wider between-buttons space", - "description": "Prevent adjacent button presses by increasing the horizontal spacing between buttons. Supports from YouTube 18.29.38 to YouTube 19.16.39.", + "description": "Prevent adjacent button presses by increasing the horizontal spacing between buttons.", "required": true, "type": "kotlin.Boolean", "default": false, @@ -1993,7 +2056,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2011,7 +2075,8 @@ "ResourcePatch", "BytecodePatch", "BytecodePatch", - "BytecodePatch" + "BytecodePatch", + "ResourcePatch" ], "compatiblePackages": { "com.google.android.youtube": [ @@ -2050,7 +2115,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2103,7 +2169,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2143,7 +2210,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2163,7 +2231,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2208,7 +2277,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2236,7 +2306,7 @@ }, { "name": "Sanitize sharing links", - "description": "Adds an option to remove tracking query parameters from URLs when sharing links.", + "description": "Adds an option to sanitize sharing links by removing tracking query parameters.", "use": true, "dependencies": [ "BytecodePatch", @@ -2249,14 +2319,15 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] }, { "name": "Sanitize sharing links", - "description": "Adds an option to remove tracking query parameters from URLs when sharing links.", + "description": "Adds an option to sanitize sharing links by removing tracking query parameters.", "use": true, "dependencies": [ "Settings for Reddit" @@ -2268,7 +2339,7 @@ }, { "name": "Sanitize sharing links", - "description": "Adds an option to remove tracking query parameters from URLs when sharing links.", + "description": "Adds an option to sanitize sharing links by removing tracking query parameters.", "use": true, "dependencies": [ "BytecodePatch", @@ -2416,7 +2487,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -2445,6 +2517,8 @@ "BytecodePatch", "BytecodePatch", "BytecodePatch", + "BytecodePatch", + "BytecodePatch", "ResourcePatch", "BytecodePatch", "ResourcePatch", @@ -2463,6 +2537,88 @@ }, "options": [] }, + { + "name": "Snack bar components", + "description": "Adds options to hide or change components related to the snack bar.", + "use": true, + "dependencies": [ + "Settings for YouTube", + "BytecodePatch" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "18.29.38", + "18.33.40", + "18.38.44", + "18.48.39", + "19.05.36", + "19.16.39", + "19.44.39" + ] + }, + "options": [ + { + "key": "cornerRadius", + "title": "Corner radius", + "description": "Specify a corner radius for the snack bar.", + "required": true, + "type": "kotlin.String", + "default": "8.0dip", + "values": null + }, + { + "key": "darkThemeBackgroundColor", + "title": "Dark theme background color", + "description": "Specify a background color for the snack bar. You can specify hex color (#AARRGGBB) or color resource reference.", + "required": true, + "type": "kotlin.String", + "default": "@color/yt_black3", + "values": { + "YouTube Dark": "@color/yt_black3", + "Amoled Black": "@android:color/black", + "Catppuccin (Mocha)": "#FF181825", + "Dark Pink": "#FF290025", + "Dark Blue": "#FF001029", + "Dark Green": "#FF002905", + "Dark Yellow": "#FF282900", + "Dark Orange": "#FF291800", + "Dark Red": "#FF290000" + } + }, + { + "key": "lightThemeBackgroundColor", + "title": "Light theme background color", + "description": "Specify a background color for the snack bar. You can specify hex color (#AARRGGBB) or color resource reference.", + "required": true, + "type": "kotlin.String", + "default": "@color/yt_white3", + "values": { + "YouTube Light": "@color/yt_white3", + "White": "@android:color/white", + "Catppuccin (Latte)": "#FFE6E9EF", + "Light Pink": "#FFFCCFF3", + "Light Blue": "#FFD1E0FF", + "Light Green": "#FFCCFFCC", + "Light Yellow": "#FFFDFFCC", + "Light Orange": "#FFFFE6CC", + "Light Red": "#FFFFD6D6" + } + }, + { + "key": "strokeColor", + "title": "Stroke color", + "description": "Specify a stroke color for the snack bar. You can specify hex color.", + "required": true, + "type": "kotlin.String", + "default": "", + "values": { + "None": "", + "Blue": "?attr/ytThemedBlue", + "Chip": "?attr/ytChipBackground" + } + } + ] + }, { "name": "SponsorBlock", "description": "Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections.", @@ -2478,7 +2634,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2594,7 +2751,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2669,7 +2827,7 @@ "key": "darkThemeBackgroundColor", "title": "Dark theme background color", "description": "Can be a hex color (#AARRGGBB) or a color resource reference.", - "required": false, + "required": true, "type": "kotlin.String", "default": "@android:color/black", "values": { @@ -2688,7 +2846,7 @@ "key": "lightThemeBackgroundColor", "title": "Light theme background color", "description": "Can be a hex color (#AARRGGBB) or a color resource reference.", - "required": false, + "required": true, "type": "kotlin.String", "default": "@android:color/white", "values": { @@ -2790,7 +2948,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ @@ -2839,7 +2998,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [] @@ -2933,7 +3093,8 @@ "6.42.55", "6.51.53", "7.16.53", - "7.25.53" + "7.25.53", + "8.02.53" ] }, "options": [ diff --git a/patches/api/patches.api b/patches/api/patches.api index 1e7634a06..cec332225 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -48,6 +48,8 @@ public final class app/revanced/patches/music/general/oldstylelibraryshelf/OldSt public final class app/revanced/patches/music/general/redirection/DislikeRedirectionPatchKt { public static final fun getDislikeRedirectionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; + public static final fun getOnClickReference ()Ljava/lang/String; + public static final fun setOnClickReference (Ljava/lang/String;)V } public final class app/revanced/patches/music/general/spoofappversion/SpoofAppVersionPatchKt { @@ -58,6 +60,10 @@ public final class app/revanced/patches/music/general/startpage/ChangeStartPageP public static final fun getChangeStartPagePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/music/general/startpage/FingerprintsKt { + public static final field DEFAULT_BROWSE_ID Ljava/lang/String; +} + public final class app/revanced/patches/music/layout/branding/icon/CustomBrandingIconPatchKt { public static final fun getCustomBrandingIconPatch ()Lapp/revanced/patcher/patch/ResourcePatch; } @@ -201,6 +207,8 @@ public final class app/revanced/patches/music/utils/playservice/VersionCheckPatc public static final fun is_7_20_or_greater ()Z public static final fun is_7_23_or_greater ()Z public static final fun is_7_25_or_greater ()Z + public static final fun is_7_27_or_greater ()Z + public static final fun is_7_29_or_greater ()Z } public final class app/revanced/patches/music/utils/resourceid/SharedResourceIdPatchKt { @@ -339,8 +347,9 @@ public final class app/revanced/patches/reddit/layout/screenshotpopup/Screenshot } public final class app/revanced/patches/reddit/layout/subredditdialog/FingerprintsKt { - public static final fun indexOfDismissScreenInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)I + public static final fun indexOfHasBeenVisitedInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)I public static final fun indexOfSetBackgroundTintListInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)I + public static final fun listOfIsLoggedInInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/util/List; } public final class app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatchKt { @@ -386,6 +395,7 @@ public final class app/revanced/patches/reddit/utils/settings/SettingsPatchKt { public static final fun getSettingsPatch ()Lapp/revanced/patcher/patch/ResourcePatch; public static final fun is_2024_26_or_greater ()Z public static final fun is_2024_41_or_greater ()Z + public static final fun is_2025_01_or_greater ()Z } public final class app/revanced/patches/shared/FingerprintsKt { @@ -615,6 +625,10 @@ public final class app/revanced/patches/youtube/general/layoutswitch/LayoutSwitc public static final fun getLayoutSwitchPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatchKt { + public static final fun getOpenChannelOfLiveAvatarPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/general/loadingscreen/GradientLoadingScreenPatchKt { public static final fun getGradientLoadingScreenPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -631,6 +645,10 @@ public final class app/revanced/patches/youtube/general/navigation/NavigationBar public static final fun getNavigationBarComponentsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatchKt { + public static final fun getSnackBarComponentsPatch ()Lapp/revanced/patcher/patch/ResourcePatch; +} + public final class app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatchKt { public static final fun getSplashAnimationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -712,12 +730,12 @@ public final class app/revanced/patches/youtube/misc/debugging/DebuggingPatchKt public static final fun getDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatchKt { - public static final fun getOpenLinksExternallyPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/youtube/misc/openlinks/directly/OpenLinksDirectlyPatchKt { + public static final fun getOpenLinksDirectlyPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatchKt { - public static final fun getOpenLinksDirectlyPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/youtube/misc/openlinks/externally/OpenLinksExternallyPatchKt { + public static final fun getOpenLinksExternallyPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/youtube/misc/quic/QUICProtocolPatchKt { @@ -817,6 +835,10 @@ public final class app/revanced/patches/youtube/utils/controlsoverlay/ControlsOv public static final fun getControlsOverlayConfigPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatchKt { + public static final fun getEngagementPanelHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/utils/extension/SharedExtensionPatchKt { public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -952,6 +974,8 @@ public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPa public static final fun is_19_43_or_greater ()Z public static final fun is_19_44_or_greater ()Z public static final fun is_19_46_or_greater ()Z + public static final fun is_19_49_or_greater ()Z + public static final fun is_20_02_or_greater ()Z } public final class app/revanced/patches/youtube/utils/recyclerview/RecyclerViewTreeObserverPatchKt { @@ -994,6 +1018,7 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public static final fun getDrawerResults ()J public static final fun getEasySeekEduContainer ()J public static final fun getEditSettingsAction ()J + public static final fun getElementsImage ()J public static final fun getEmojiPickerIcon ()J public static final fun getEndScreenElementLayoutCircle ()J public static final fun getEndScreenElementLayoutIcon ()J @@ -1010,6 +1035,7 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public static final fun getImageOnlyTab ()J public static final fun getInlineTimeBarColorizedBarPlayedColorDark ()J public static final fun getInlineTimeBarPlayedNotHighlightedColor ()J + public static final fun getInsetElementsWrapper ()J public static final fun getInsetOverlayViewLayout ()J public static final fun getInterstitialsContainer ()J public static final fun getMenuItemView ()J @@ -1072,6 +1098,7 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public static final fun getYtOutlineXWhite ()J public static final fun getYtPremiumWordMarkHeader ()J public static final fun getYtWordMarkHeader ()J + public static final fun getYtYoutubeMagenta ()J } public final class app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatchKt { @@ -1121,6 +1148,14 @@ public final class app/revanced/patches/youtube/video/playback/VideoPlaybackPatc public static final fun getVideoPlaybackPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/video/playbackstart/FingerprintsKt { + public static final field PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR Ljava/lang/String; +} + +public final class app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatchKt { + public static final fun getPlaybackStartDescriptorPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public abstract class app/revanced/patches/youtube/video/playerresponse/Hook { public synthetic fun (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun toString ()Ljava/lang/String; diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt index a39582645..34ca7563a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt @@ -9,6 +9,8 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA import app.revanced.patches.music.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.patch.PatchList.DISABLE_DISLIKE_REDIRECTION import app.revanced.patches.music.utils.pendingIntentReceiverFingerprint +import app.revanced.patches.music.utils.playservice.is_7_29_or_greater +import app.revanced.patches.music.utils.playservice.versionCheckPatch import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.addSwitchPreference @@ -23,7 +25,8 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.Reference + +var onClickReference = "" @Suppress("unused") val dislikeRedirectionPatch = bytecodePatch( @@ -32,11 +35,12 @@ val dislikeRedirectionPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn(settingsPatch) + dependsOn( + settingsPatch, + versionCheckPatch, + ) execute { - lateinit var onClickReference: Reference - pendingIntentReceiverFingerprint.methodOrThrow().apply { val startIndex = indexOfFirstStringInstructionOrThrow("YTM Dislike") val onClickRelayIndex = @@ -49,27 +53,35 @@ val dislikeRedirectionPatch = bytecodePatch( val onClickMethod = getWalkerMethod(onClickMethodIndex) onClickMethod.apply { - val onClickIndex = indexOfFirstInstructionOrThrow { - val reference = - ((this as? ReferenceInstruction)?.reference as? MethodReference) + val relativeIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_VIRTUAL && + getReference() + ?.parameterTypes + ?.contains("Ljava/util/Map;") == true + } + val onClickIndex = indexOfFirstInstructionOrThrow(relativeIndex) { + val reference = getReference() opcode == Opcode.INVOKE_INTERFACE && reference?.returnType == "V" && reference.parameterTypes.size == 1 } onClickReference = - getInstruction(onClickIndex).reference + getInstruction(onClickIndex).reference.toString() disableDislikeRedirection(onClickIndex) } } } - dislikeButtonOnClickListenerFingerprint.methodOrThrow().apply { - val onClickIndex = indexOfFirstInstructionOrThrow { - getReference()?.toString() == onClickReference.toString() - } - disableDislikeRedirection(onClickIndex) + if (is_7_29_or_greater) { + dislikeButtonOnClickListenerAlternativeFingerprint + .methodOrThrow() + .disableDislikeRedirection() + } else { + dislikeButtonOnClickListenerFingerprint + .methodOrThrow() + .disableDislikeRedirection() } addSwitchPreference( @@ -83,7 +95,15 @@ val dislikeRedirectionPatch = bytecodePatch( } } -private fun MutableMethod.disableDislikeRedirection(onClickIndex: Int) { +private fun MutableMethod.disableDislikeRedirection(startIndex: Int = 0) { + val onClickIndex = + if (startIndex == 0) { + indexOfFirstInstructionOrThrow { + getReference()?.toString() == onClickReference + } + } else { + startIndex + } val targetIndex = indexOfFirstInstructionReversedOrThrow(onClickIndex, Opcode.IF_EQZ) val insertRegister = getInstruction(targetIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/Fingerprints.kt index 527af433a..38f3d17e8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/Fingerprints.kt @@ -4,6 +4,8 @@ import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference internal val dislikeButtonOnClickListenerFingerprint = legacyFingerprint( name = "dislikeButtonOnClickListenerFingerprint", @@ -18,3 +20,31 @@ internal val dislikeButtonOnClickListenerFingerprint = legacyFingerprint( } ) +/** + * YouTube Music 7.27.52 ~ + * TODO: Make this fingerprint more concise + */ +internal val dislikeButtonOnClickListenerAlternativeFingerprint = legacyFingerprint( + name = "dislikeButtonOnClickListenerAlternativeFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Ljava/util/Map;"), + customFingerprint = custom@{ method, classDef -> + if (classDef.fields.count() != 7) { + return@custom false + } + if (classDef.methods.count() != 5) { + return@custom false + } + val implementation = method.implementation + ?: return@custom false + val instructions = implementation.instructions + val instructionCount = instructions.count() + if (instructionCount < 50) { + return@custom false + } + + ((instructions.elementAt(0) as? ReferenceInstruction)?.reference as? FieldReference)?.name == "likeEndpoint" + } +) + diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt index ac6fb70e0..d9d81d9e0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt @@ -2,7 +2,6 @@ package app.revanced.patches.music.general.startpage import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR @@ -11,8 +10,13 @@ import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.settingsPatch -import app.revanced.util.fingerprint.matchOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference @Suppress("unused") val changeStartPagePatch = bytecodePatch( @@ -25,20 +29,20 @@ val changeStartPagePatch = bytecodePatch( execute { - coldStartUpFingerprint.matchOrThrow().let { - it.method.apply { - val targetIndex = it.patternMatch!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$targetRegister - return-object v$targetRegister - """ - ) - removeInstruction(targetIndex) + coldStartUpFingerprint.methodOrThrow().apply { + val defaultBrowseIdIndex = indexOfFirstStringInstructionOrThrow(DEFAULT_BROWSE_ID) + val browseIdIndex = indexOfFirstInstructionReversedOrThrow(defaultBrowseIdIndex) { + opcode == Opcode.IGET_OBJECT && + getReference()?.type == "Ljava/lang/String;" } + val browseIdRegister = getInstruction(browseIdIndex).registerA + + addInstructions( + browseIdIndex + 1, """ + invoke-static {v$browseIdRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$browseIdRegister + """ + ) } addPreferenceWithIntent( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt index 613adde88..9da6c2b7e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt @@ -5,16 +5,17 @@ import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +const val DEFAULT_BROWSE_ID = "FEmusic_home" + internal val coldStartUpFingerprint = legacyFingerprint( name = "coldStartUpFingerprint", returnType = "Ljava/lang/String;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), opcodes = listOf( - Opcode.GOTO, Opcode.CONST_STRING, Opcode.RETURN_OBJECT ), - strings = listOf("FEmusic_library_sideloaded_tracks", "FEmusic_home") + strings = listOf("FEmusic_library_sideloaded_tracks", DEFAULT_BROWSE_ID) ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt index 8143cfddd..e580af2b5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt @@ -4,8 +4,10 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.patch.PatchList.CUSTOM_HEADER_FOR_YOUTUBE_MUSIC import app.revanced.patches.music.utils.playservice.is_7_06_or_greater +import app.revanced.patches.music.utils.playservice.is_7_27_or_greater import app.revanced.patches.music.utils.playservice.versionCheckPatch import app.revanced.patches.music.utils.resourceid.actionBarLogo import app.revanced.patches.music.utils.resourceid.actionBarLogoRingo2 @@ -15,14 +17,17 @@ import app.revanced.patches.music.utils.resourceid.ytmLogoRingo2 import app.revanced.patches.music.utils.settings.ResourceUtils.getIconType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.settingsPatch +import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.ResourceGroup import app.revanced.util.Utils.printWarn import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.copyFile import app.revanced.util.copyResources +import app.revanced.util.doRecursively import app.revanced.util.replaceLiteralInstructionCall import app.revanced.util.underBarOrThrow import app.revanced.util.valueOrThrow +import org.w3c.dom.Element private const val DEFAULT_HEADER_KEY = "Custom branding icon" private const val DEFAULT_HEADER_VALUE = "custom_branding_icon" @@ -125,11 +130,26 @@ private val changeHeaderBytecodePatch = bytecodePatch( return@execute } - listOf( - actionBarLogoRingo2 to actionBarLogo, - ytmLogoRingo2 to ytmLogo, - ).forEach { (originalResource, replacementResource) -> - replaceLiteralInstructionCall(originalResource, replacementResource) + if (actionBarLogoRingo2 == -1L || ytmLogoRingo2 == -1L) { + printWarn("Target resource not found!") + return@execute + } + + if (is_7_27_or_greater) { + replaceLiteralInstructionCall( + actionBarLogoRingo2, + """ + invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $GENERAL_CLASS_DESCRIPTOR->getHeaderDrawableId(I)I + move-result v$REGISTER_TEMPLATE_REPLACEMENT + """ + ) + } else { + listOf( + actionBarLogoRingo2 to actionBarLogo, + ytmLogoRingo2 to ytmLogo, + ).forEach { (originalResource, replacementResource) -> + replaceLiteralInstructionCall(originalResource, replacementResource) + } } } } @@ -186,6 +206,21 @@ val changeHeaderPatch = resourcePatch( printWarn(warnings) } + if (is_7_27_or_greater) { + document("res/layout/signin_fragment.xml").use { document -> + document.doRecursively node@{ node -> + if (node !is Element) return@node + + if (node.attributes.getNamedItem("android:id")?.nodeValue == "@id/logo") { + node.getAttributeNode("android:src") + ?.let { attribute -> + attribute.textContent = "@drawable/ytm_logo" + } + } + } + } + } + updatePatchStatus(CUSTOM_HEADER_FOR_YOUTUBE_MUSIC) } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt index 52f0bf163..7700b9b4f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt @@ -22,7 +22,9 @@ internal val audioVideoSwitchToggleConstructorFingerprint = legacyFingerprint( internal fun indexOfAudioVideoSwitchSetOnClickListenerInstruction(method: Method) = method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() == "Lcom/google/android/apps/youtube/music/player/AudioVideoSwitcherToggleView;->setOnClickListener(Landroid/view/View${'$'}OnClickListener;)V" + getReference() + ?.toString() + ?.endsWith("/AudioVideoSwitcherToggleView;->setOnClickListener(Landroid/view/View${'$'}OnClickListener;)V") == true } internal val snackBarParentFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt index ed45770dc..3ce8e4b7c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt @@ -40,6 +40,7 @@ val cairoSplashAnimationPatch = bytecodePatch( "7.06.54", "7.16.53", "7.25.53", + "8.02.53", ), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt index 55adfbadf..265ee72d4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt @@ -14,6 +14,7 @@ import app.revanced.patches.music.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.text1 import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus +import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.addSwitchPreference import app.revanced.patches.music.utils.settings.settingsPatch import app.revanced.util.fingerprint.matchOrThrow @@ -62,7 +63,7 @@ val navigationBarComponentsPatch = bytecodePatch( execute { /** - * Enable black navigation bar + * Enable custom navigation bar color */ tabLayoutFingerprint.methodOrThrow().apply { val constIndex = indexOfFirstLiteralInstructionOrThrow(colorGrey) @@ -74,7 +75,7 @@ val navigationBarComponentsPatch = bytecodePatch( addInstructions( insertIndex, """ - invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I + invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableCustomNavigationBarColor()I move-result v$insertRegister """ ) @@ -129,8 +130,13 @@ val navigationBarComponentsPatch = bytecodePatch( addSwitchPreference( CategoryType.NAVIGATION, - "revanced_enable_black_navigation_bar", - "true" + "revanced_enable_custom_navigation_bar_color", + "false" + ) + addPreferenceWithIntent( + CategoryType.NAVIGATION, + "revanced_custom_navigation_bar_color_value", + "revanced_enable_custom_navigation_bar_color" ) addSwitchPreference( CategoryType.NAVIGATION, diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt index bf5204063..b1c99a5f6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt @@ -23,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference const val AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY = - "Lcom/google/android/apps/youtube/music/player/AudioVideoSwitcherToggleView;->setVisibility(I)V" + "/AudioVideoSwitcherToggleView;->setVisibility(I)V" internal val audioVideoSwitchToggleFingerprint = legacyFingerprint( name = "audioVideoSwitchToggleFingerprint", @@ -33,7 +33,9 @@ internal val audioVideoSwitchToggleFingerprint = legacyFingerprint( customFingerprint = { method, _ -> method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() == AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY + getReference() + ?.toString() + ?.endsWith(AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY) == true } >= 0 } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index bba1dbab8..6f49240a4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -799,7 +799,7 @@ val playerComponentsPatch = bytecodePatch( val reference = (instruction as? ReferenceInstruction)?.reference instruction.opcode == Opcode.INVOKE_VIRTUAL && reference is MethodReference && - reference.toString() == AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY + reference.toString().endsWith(AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY) } .map { (index, _) -> index } .reversed() @@ -995,7 +995,7 @@ val playerComponentsPatch = bytecodePatch( val reference = getReference() opcode == Opcode.INVOKE_INTERFACE && reference?.returnType == "Z" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } + 1 val targetRegister = getInstruction(targetIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt index b964b90bb..f7d70c001 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt @@ -14,7 +14,8 @@ internal object Constants { "6.42.55", // This is the latest version that supports Android 7.0 "6.51.53", // This is the latest version of YouTube Music 6.xx.xx "7.16.53", // This is the latest version that supports the 'Spoof app version' patch. - "7.25.53", // This is the latest version supported by the RVX patch. + "7.25.53", // This is the last supported version for 2024. + "8.02.53", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt index c14acd990..bb89a82b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt @@ -31,7 +31,7 @@ internal enum class PatchList( ), CUSTOM_BRANDING_NAME_FOR_YOUTUBE_MUSIC( "Custom branding name for YouTube Music", - "Renames the YouTube Music app to the name specified in patch options." + "Changes the YouTube Music app name to the name specified in patch options." ), CUSTOM_HEADER_FOR_YOUTUBE_MUSIC( "Custom header for YouTube Music", @@ -63,7 +63,7 @@ internal enum class PatchList( ), ENABLE_OPUS_CODEC( "Enable OPUS codec", - "Adds an options to enable the OPUS audio codec if the player response includes it." + "Adds an option to enable the OPUS audio codec if the player response includes it." ), ENABLE_DEBUG_LOGGING( "Enable debug logging", @@ -135,7 +135,7 @@ internal enum class PatchList( ), SANITIZE_SHARING_LINKS( "Sanitize sharing links", - "Adds an option to remove tracking query parameters from URLs when sharing links." + "Adds an option to sanitize sharing links by removing tracking query parameters." ), SETTINGS_FOR_YOUTUBE_MUSIC( "Settings for YouTube Music", diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt index 6344ff17a..9e4c07482 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt @@ -27,6 +27,10 @@ var is_7_23_or_greater = false private set var is_7_25_or_greater = false private set +var is_7_27_or_greater = false + private set +var is_7_29_or_greater = false + private set val versionCheckPatch = resourcePatch( description = "versionCheckPatch", @@ -53,5 +57,7 @@ val versionCheckPatch = resourcePatch( is_7_20_or_greater = 243899000 <= playStoreServicesVersion is_7_23_or_greater = 244199000 <= playStoreServicesVersion is_7_25_or_greater = 244399000 <= playStoreServicesVersion + is_7_27_or_greater = 244515000 <= playStoreServicesVersion + is_7_29_or_greater = 244799000 <= playStoreServicesVersion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt index 0edb35019..58cd49634 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt @@ -1,26 +1,33 @@ package app.revanced.patches.music.utils.videotype import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val videoTypeFingerprint = legacyFingerprint( name = "videoTypeFingerprint", returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.SGET_OBJECT - ) + customFingerprint = { method, _ -> + indexOfGetEnumInstruction(method) >= 0 + } ) +internal fun indexOfGetEnumInstruction(method: Method) = + method.indexOfFirstInstruction { + val reference = getReference() + opcode == Opcode.INVOKE_STATIC && + reference?.name == "a" && + reference.parameterTypes.firstOrNull() == "I" && + reference.definingClass == reference.returnType + } + internal val videoTypeParentFingerprint = legacyFingerprint( name = "videoTypeParentFingerprint", returnType = "Z", diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt index 587048a3d..bc0ec4167 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt @@ -4,8 +4,14 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.music.utils.extension.Constants.UTILS_PATH -import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "$UTILS_PATH/VideoTypeHookPatch;" @@ -17,22 +23,27 @@ val videoTypeHookPatch = bytecodePatch( execute { - videoTypeFingerprint.matchOrThrow(videoTypeParentFingerprint).let { - it.method.apply { - val insertIndex = it.patternMatch!!.startIndex + 3 - val referenceIndex = insertIndex + 1 - val referenceInstruction = - getInstruction(referenceIndex).reference - - addInstructionsWithLabels( - insertIndex, """ - if-nez p0, :dismiss - sget-object p0, $referenceInstruction - :dismiss - invoke-static {p0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoType(Ljava/lang/Enum;)V - """ - ) + videoTypeFingerprint.methodOrThrow(videoTypeParentFingerprint).apply { + val getEnumIndex = indexOfGetEnumInstruction(this) + val enumClass = (getInstruction(getEnumIndex).reference as MethodReference).definingClass + val referenceIndex = indexOfFirstInstructionOrThrow(getEnumIndex) { + opcode == Opcode.SGET_OBJECT && + getReference()?.type == enumClass } + val referenceInstruction = + getInstruction(referenceIndex).reference + + val insertIndex = indexOfFirstInstructionOrThrow(getEnumIndex, Opcode.IF_NEZ) + val insertRegister = getInstruction(insertIndex).registerA + + addInstructionsWithLabels( + insertIndex, """ + if-nez v$insertRegister, :dismiss + sget-object v$insertRegister, $referenceInstruction + :dismiss + invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->setVideoType(Ljava/lang/Enum;)V + """ + ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt index d6a110041..d27eb8784 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt @@ -26,12 +26,6 @@ internal val videoIdFingerprint = legacyFingerprint( returnType = "V", parameters = listOf("L", "Ljava/lang/String;"), accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - ), strings = listOf("Null initialPlayabilityStatus") ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt index e4901ea36..275e96b4c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt @@ -191,7 +191,12 @@ val videoInformationPatch = bytecodePatch( */ videoIdFingerprint.matchOrThrow().let { it.method.apply { - val playerResponseModelIndex = it.patternMatch!!.startIndex + val playerResponseModelIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + (opcode == Opcode.INVOKE_INTERFACE_RANGE || opcode == Opcode.INVOKE_INTERFACE) && + reference?.returnType == "Ljava/lang/String;" && + reference.parameterTypes.isEmpty() + } PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR = getInstruction(playerResponseModelIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt index 0564715e1..450ce37ea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt @@ -2,9 +2,19 @@ package app.revanced.patches.music.video.playerresponse import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or +import app.revanced.util.parametersEqual import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +private val PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST = listOf( + "Ljava/lang/String;", // VideoId. + "[B", + "Ljava/lang/String;", // Player parameters proto buffer. + "Ljava/lang/String;", // PlaylistId. + "I", // PlaylistIndex. + "I" +) + /** * For targets 7.03 and later. */ @@ -12,23 +22,21 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint( name = "playerParameterBuilderFingerprint", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "L", - parameters = listOf( - "Ljava/lang/String;", // VideoId. - "[B", - "Ljava/lang/String;", // Player parameters proto buffer. - "Ljava/lang/String;", // PlaylistId. - "I", // PlaylistIndex. - "I", - "L", - "Ljava/util/Set;", - "Ljava/lang/String;", - "Ljava/lang/String;", - "L", - "Z", - "Z", - "Z", // Appears to indicate if the video id is being opened or is currently playing. - ), - strings = listOf("psps") + strings = listOf("psps"), + customFingerprint = custom@{ method, _ -> + val parameterTypes = method.parameterTypes + val parameterSize = parameterTypes.size + if (parameterSize < 13) { + return@custom false + } + + val startsWithMethodParameterList = parameterTypes.slice(0..5) + + parametersEqual( + PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST, + startsWithMethodParameterList + ) + } ) /** diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt index f8ab5cc7b..cae1dc6d8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt @@ -3,11 +3,11 @@ package app.revanced.patches.reddit.layout.subredditdialog import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.indexOfFirstInstructionReversed import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val frequentUpdatesSheetScreenFingerprint = legacyFingerprint( @@ -26,38 +26,49 @@ internal val frequentUpdatesSheetScreenFingerprint = legacyFingerprint( } ) -internal val frequentUpdatesSheetV2ScreenFingerprint = legacyFingerprint( - name = "frequentUpdatesSheetV2ScreenFingerprint", - returnType = "V", +internal val frequentUpdatesHandlerFingerprint = legacyFingerprint( + name = "frequentUpdatesHandlerFingerprint", + returnType = "Ljava/lang/Object;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, strings = listOf("subreddit_name"), customFingerprint = { method, classDef -> - classDef.type == "Lcom/reddit/screens/pager/v2/FrequentUpdatesSheetV2Screen;" + classDef.type.startsWith("Lcom/reddit/screens/pager/FrequentUpdatesHandler${'$'}handleFrequentUpdates${'$'}") && + method.name == "invokeSuspend" && + listOfIsLoggedInInstruction(method).isNotEmpty() } ) -internal val frequentUpdatesSheetV2ScreenInvokeFingerprint = legacyFingerprint( - name = "frequentUpdatesSheetV2ScreenInvokeFingerprint", - returnType = "V", +fun listOfIsLoggedInInstruction(method: Method) = + method.implementation?.instructions + ?.withIndex() + ?.filter { (_, instruction) -> + val reference = (instruction as? ReferenceInstruction)?.reference + instruction.opcode == Opcode.INVOKE_INTERFACE && + reference is MethodReference && + reference.name == "isLoggedIn" && + reference.returnType == "Z" + } + ?.map { (index, _) -> index } + ?.reversed() + ?: emptyList() + +internal val nsfwAlertEmitFingerprint = legacyFingerprint( + name = "nsfwAlertEmitFingerprint", + returnType = "Ljava/lang/Object;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID, - ), - customFingerprint = { method, classDef -> - classDef.type.startsWith("Lcom/reddit/screens/pager/v2/FrequentUpdatesSheetV2Screen${'$'}SheetContent${'$'}") && - method.name == "invoke" && - indexOfDismissScreenInstruction(method) >= 0 + strings = listOf("reddit://reddit/r/", "nsfwAlertDelegate"), + customFingerprint = { method, _ -> + method.name == "emit" && + indexOfHasBeenVisitedInstruction(method) >= 0 } ) -fun indexOfDismissScreenInstruction(method: Method) = - method.indexOfFirstInstructionReversed { +fun indexOfHasBeenVisitedInstruction(method: Method) = + method.indexOfFirstInstruction { val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && - reference?.returnType == "V" && - reference.parameterTypes.isEmpty() + reference?.name == "getHasBeenVisited" && + reference.returnType == "Z" } internal val redditAlertDialogsFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt index bed1778a3..25a3db115 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -3,15 +3,14 @@ package app.revanced.patches.reddit.layout.subredditdialog import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.REMOVE_SUBREDDIT_DIALOG import app.revanced.patches.reddit.utils.settings.is_2024_41_or_greater +import app.revanced.patches.reddit.utils.settings.is_2025_01_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -19,7 +18,6 @@ import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = @@ -36,6 +34,25 @@ val subRedditDialogPatch = bytecodePatch( execute { + if (is_2024_41_or_greater) { + frequentUpdatesHandlerFingerprint + .methodOrThrow() + .apply { + listOfIsLoggedInInstruction(this) + .forEach { index -> + val register = getInstruction(index + 1).registerA + + addInstructions( + index + 2, """ + invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->spoofLoggedInStatus(Z)Z + move-result v$register + """ + ) + } + } + } + + // Not used in latest Reddit client. frequentUpdatesSheetScreenFingerprint.methodOrThrow().apply { val index = indexOfFirstInstructionReversedOrThrow(Opcode.RETURN_OBJECT) val register = @@ -43,42 +60,27 @@ val subRedditDialogPatch = bytecodePatch( addInstruction( index, - "invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->onDialogCreated(Landroid/view/View;)V" + "invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialog(Landroid/view/View;)V" ) } - if (is_2024_41_or_greater) { - val dismissReference = with (frequentUpdatesSheetV2ScreenInvokeFingerprint.methodOrThrow()) { - val index = indexOfDismissScreenInstruction(this) - getInstruction(index).reference as MethodReference + if (is_2025_01_or_greater) { + nsfwAlertEmitFingerprint.methodOrThrow().apply { + val hasBeenVisitedIndex = indexOfHasBeenVisitedInstruction(this) + val hasBeenVisitedRegister = + getInstruction(hasBeenVisitedIndex + 1).registerA + + addInstructions( + hasBeenVisitedIndex + 2, """ + invoke-static {v$hasBeenVisitedRegister}, $EXTENSION_CLASS_DESCRIPTOR->spoofHasBeenVisitedStatus(Z)Z + move-result v$hasBeenVisitedRegister + """ + ) } - - findMethodOrThrow(EXTENSION_CLASS_DESCRIPTOR) { - name == "dismissRedditDialogV2" - }.addInstructions( - 0, """ - check-cast p0, ${dismissReference.definingClass} - invoke-virtual {p0}, $dismissReference - """ - ) - - frequentUpdatesSheetV2ScreenFingerprint - .methodOrThrow() - .apply { - val targetIndex = implementation!!.instructions.lastIndex - - addInstructions( - targetIndex + 1, """ - invoke-static {p0}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialogV2(Ljava/lang/Object;)V - return-void - """ - ) - removeInstruction(targetIndex) - } } // Not used in latest Reddit client. - redditAlertDialogsFingerprint.second.methodOrNull?.apply { + redditAlertDialogsFingerprint.methodOrThrow().apply { val backgroundTintIndex = indexOfSetBackgroundTintListInstruction(this) val insertIndex = indexOfFirstInstructionOrThrow(backgroundTintIndex) { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/patch/PatchList.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/patch/PatchList.kt index 434e5321f..98a0e3fae 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/patch/PatchList.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/patch/PatchList.kt @@ -11,7 +11,7 @@ internal enum class PatchList( ), CUSTOM_BRANDING_NAME_FOR_REDDIT( "Custom branding name for Reddit", - "Renames the Reddit app to the name specified in patch options." + "Changes the Reddit app name to the name specified in patch options." ), DISABLE_SCREENSHOT_POPUP( "Disable screenshot popup", @@ -55,7 +55,7 @@ internal enum class PatchList( ), SANITIZE_SHARING_LINKS( "Sanitize sharing links", - "Adds an option to remove tracking query parameters from URLs when sharing links." + "Adds an option to sanitize sharing links by removing tracking query parameters." ), SETTINGS_FOR_REDDIT( "Settings for Reddit", diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt index f5910d0cf..ae28725f9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt @@ -37,6 +37,8 @@ var is_2024_26_or_greater = false private set var is_2024_41_or_greater = false private set +var is_2025_01_or_greater = false + private set private val settingsBytecodePatch = bytecodePatch( description = "settingsBytecodePatch" @@ -58,7 +60,8 @@ private val settingsBytecodePatch = bytecodePatch( .replace(".", "").toInt() is_2024_26_or_greater = 2024260 <= versionNumber - is_2024_41_or_greater = 2024100 <= versionNumber + is_2024_41_or_greater = 2024410 <= versionNumber + is_2025_01_or_greater = 2025010 <= versionNumber } /** diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/drawable/DrawableColorHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/drawable/DrawableColorHookPatch.kt index 89d8c816a..6afc0f311 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/drawable/DrawableColorHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/drawable/DrawableColorHookPatch.kt @@ -30,13 +30,15 @@ val drawableColorHookPatch = bytecodePatch( } internal fun addDrawableColorHook( - methodDescriptor: String + methodDescriptor: String, + highPriority: Boolean = false ) { insertMethod.addInstructions( - insertIndex + offset, """ - invoke-static {v$insertRegister}, $methodDescriptor - move-result v$insertRegister - """ + if (highPriority) insertIndex else insertIndex + offset, + """ + invoke-static {v$insertRegister}, $methodDescriptor + move-result v$insertRegister + """ ) offset += 2 } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt index 9c673e4c9..92d885399 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt @@ -389,6 +389,9 @@ private object Constants { // misc "com.google.android.gms.clearcut.service.START", + "com.google.android.gms.common.telemetry.service.START", + "com.google.android.gms.gmscompliance.service.START", + "com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE", "com.google.android.gms.languageprofile.service.START", "com.google.android.gms.measurement.START", "com.google.android.gms.pseudonymous.service.START", diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt index af61831fd..d517732b1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt @@ -16,6 +16,7 @@ import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstStringInstruction import app.revanced.util.indexOfFirstStringInstructionOrThrow import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags @@ -27,6 +28,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.TypeReference import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.util.MethodUtil @@ -42,6 +44,8 @@ private var filterCount = 0 internal lateinit var addLithoFilter: (String) -> Unit private set +internal var emptyComponentLabel = "" + val lithoFilterPatch = bytecodePatch( description = "lithoFilterPatch", ) { @@ -73,6 +77,8 @@ val lithoFilterPatch = bytecodePatch( return-object v0 """ + emptyComponentLabel = label + Pair(this, label) } } @@ -121,17 +127,25 @@ val lithoFilterPatch = bytecodePatch( val stringBuilderRegister = getInstruction(stringBuilderIndex).registerA - val emptyStringIndex = indexOfFirstStringInstructionOrThrow("") + val emptyStringIndex = indexOfFirstStringInstruction("") + val relativeIndex = if (emptyStringIndex > -1) { + emptyStringIndex + } else { + val separatorIndex = indexOfFirstStringInstructionOrThrow("|") + indexOfFirstInstructionOrThrow(separatorIndex) { + opcode == Opcode.NEW_INSTANCE && + getReference()?.type == "Ljava/lang/StringBuilder;" + } + } + val identifierRegister = getInstruction( - indexOfFirstInstructionReversedOrThrow(emptyStringIndex) { + indexOfFirstInstructionReversedOrThrow(relativeIndex) { opcode == Opcode.IPUT_OBJECT && getReference()?.type == "Ljava/lang/String;" } ).registerA val objectRegister = getInstruction( - indexOfFirstInstructionOrThrow(emptyStringIndex) { - opcode == Opcode.INVOKE_VIRTUAL - } + indexOfFirstInstructionOrThrow(relativeIndex, Opcode.INVOKE_VIRTUAL) ).registerC val insertIndex = stringBuilderIndex + 1 diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/BaseSpoofStreamingDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/BaseSpoofStreamingDataPatch.kt index 5ba50bab4..451a17c12 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/BaseSpoofStreamingDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/BaseSpoofStreamingDataPatch.kt @@ -14,14 +14,11 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import app.revanced.patches.shared.extension.Constants.SPOOF_PATH import app.revanced.patches.shared.formatStreamModelConstructorFingerprint import app.revanced.util.findInstructionIndicesReversedOrThrow -import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.definingClassOrThrow import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow -import app.revanced.util.fingerprint.mutableClassOrThrow import app.revanced.util.getReference -import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -370,35 +367,4 @@ fun baseSpoofStreamingDataPatch( executeBlock() } - - finalize { - gmsServiceBrokerFingerprint.methodOrThrow() - .addInstructionsWithLabels( - 0, """ - invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z - move-result v0 - if-eqz v0, :ignore - return-void - :ignore - nop - """ - ) - - gmsServiceBrokerExceptionFingerprint.matchOrThrow().let { - val walkerIndex = it.patternMatch!!.startIndex - val walkerMethod = it.getWalkerMethod(walkerIndex) - - walkerMethod.apply { - val insertIndex = indexOfFirstInstructionOrThrow(Opcode.CHECK_CAST) - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex + 1, """ - invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled(Ljava/lang/Object;)Ljava/lang/Object; - move-result-object v$insertRegister - """ - ) - } - } - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/Fingerprints.kt index 8be26a661..79e334099 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/spoof/streamingdata/Fingerprints.kt @@ -198,20 +198,4 @@ internal val hlsCurrentTimeFingerprint = legacyFingerprint( literals = listOf(HLS_CURRENT_TIME_FEATURE_FLAG), ) -internal val gmsServiceBrokerFingerprint = legacyFingerprint( - name = "gmsServiceBrokerFingerprint", - returnType = "V", - strings = listOf("mServiceBroker is null, client disconnected") -) - -internal val gmsServiceBrokerExceptionFingerprint = legacyFingerprint( - name = "gmsServiceBrokerExceptionFingerprint", - returnType = "V", - parameters = listOf("Ljava/lang/Exception;"), - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ), - strings = listOf("Exception must not be null") -) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/textcomponent/TextComponentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/textcomponent/TextComponentPatch.kt index 6b04a1689..93347f20a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/textcomponent/TextComponentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/textcomponent/TextComponentPatch.kt @@ -16,6 +16,7 @@ import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference @@ -40,11 +41,11 @@ val textComponentPatch = bytecodePatch( spannedIndex = indexOfSpannableStringInstruction(this) spannedRegister = getInstruction(spannedIndex).registerC spannedContextRegister = - getInstruction(0).registerA + getInstruction(spannedIndex + 1).registerA replaceInstruction( spannedIndex, - "nop" + "move-object/from16 v$spannedContextRegister, p0" ) addInstruction( ++spannedIndex, diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt index 3c9dc5ee8..f7f3b8b97 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt @@ -49,6 +49,7 @@ fun ResourcePatchContext.baseTranslationsPatch( sourceDirectory: String, ) { val resourceDirectory = get("res") + val isYouTube = sourceDirectory == "youtube" // Check if the custom translation path is valid. customTranslations?.takeIf { it.isNotEmpty() }?.let { customLang -> @@ -90,10 +91,10 @@ fun ResourcePatchContext.baseTranslationsPatch( // Filter the app languages to include both versions of locales (with and without 'r', en-rGB and en-GB) // and also handle locales with "b+" prefix - val filteredAppLanguages = selectedStringResourcesArray.flatMap { language -> - setOf(language, language.replace("-r", "-"), - language.replace("b+", "").replace("+", "-")) - }.toTypedArray() + var filteredAppLanguages = (selectedStringResourcesArray + arrayOf("en")) + .map { language -> + language.replace("-r", "-").replace("b+", "").replace("+", "-") + }.toHashSet().toTypedArray() // Remove unselected app languages from UI document("res/xml/locales_config.xml").use { document -> @@ -102,7 +103,7 @@ fun ResourcePatchContext.baseTranslationsPatch( document.doRecursively { node -> if (node is Element && node.tagName == "locale") { node.getAttributeNode("android:name")?.let { attribute -> - if (attribute.textContent != "en" && attribute.textContent !in filteredAppLanguages) { + if (attribute.textContent !in filteredAppLanguages) { nodesToRemove.add(node) } } @@ -114,6 +115,45 @@ fun ResourcePatchContext.baseTranslationsPatch( node.parentNode?.removeChild(node) } } + + if (!isYouTube) return + + filteredAppLanguages = filteredAppLanguages.map { language -> + language.subSequence(0,2).toString().uppercase() + }.toHashSet().toTypedArray() + + // Remove unselected app languages from RVX Settings + setOf( + "revanced_language_entries", + "revanced_language_entry_values", + ).forEach { attributeName -> + document("res/values/arrays.xml").use { document -> + with(document) { + val nodesToRemove = mutableListOf() + + val resourcesNode = getElementsByTagName("resources").item(0) as Element + for (i in 0 until resourcesNode.childNodes.length) { + val node = resourcesNode.childNodes.item(i) as? Element ?: continue + + if (node.getAttribute("name") == attributeName) { + for (j in 0 until node.childNodes.length) { + val item = node.childNodes.item(j) as? Element ?: continue + val text = item.textContent + val length = text.length + if (!text.endsWith("DEFAULT") && text.subSequence(length - 2, length) !in filteredAppLanguages) { + nodesToRemove.add(item) + } + } + } + } + + // Remove the collected nodes (avoids NullPointerException) + for (n in nodesToRemove) { + n.parentNode?.removeChild(n) + } + } + } + } } /** diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt index fa99e6c4b..d4054ad43 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt @@ -7,13 +7,14 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.litho.addLithoFilter +import app.revanced.patches.shared.litho.emptyComponentLabel import app.revanced.patches.shared.mainactivity.onCreateMethod import app.revanced.patches.youtube.utils.bottomsheet.bottomSheetHookPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.engagementPanelBuilderFingerprint +import app.revanced.patches.youtube.utils.engagement.engagementPanelHookPatch +import app.revanced.patches.youtube.utils.engagement.hookEngagementPanelState import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.extension.Constants.FEED_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.FEED_PATH @@ -21,6 +22,9 @@ import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch import app.revanced.patches.youtube.utils.navigation.navigationBarHookPatch import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_FEED_COMPONENTS import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch +import app.revanced.patches.youtube.utils.playservice.is_19_46_or_greater +import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater +import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.bar import app.revanced.patches.youtube.utils.resourceid.captionToggleContainer import app.revanced.patches.youtube.utils.resourceid.channelListSubMenu @@ -37,19 +41,16 @@ import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.mutableClassOrThrow import app.revanced.util.getReference import app.revanced.util.getWalkerMethod -import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.StringReference -import com.android.tools.smali.dexlib2.util.MethodUtil private const val CAROUSEL_SHELF_FILTER_CLASS_DESCRIPTOR = "$COMPONENTS_PATH/CarouselShelfFilter;" @@ -78,6 +79,8 @@ val feedComponentsPatch = bytecodePatch( sharedResourceIdPatch, settingsPatch, bottomSheetHookPatch, + engagementPanelHookPatch, + versionCheckPatch, ) execute { @@ -171,38 +174,6 @@ val feedComponentsPatch = bytecodePatch( // region patch for hide relative video - fun Method.indexOfEngagementPanelBuilderInstruction(targetMethod: MutableMethod) = - indexOfFirstInstruction { - opcode == Opcode.INVOKE_DIRECT && - MethodUtil.methodSignaturesMatch( - targetMethod, - getReference()!! - ) - } - - engagementPanelBuilderFingerprint.matchOrThrow().let { - it.classDef.methods.filter { method -> - method.indexOfEngagementPanelBuilderInstruction(it.method) >= 0 - }.forEach { method -> - method.apply { - val index = indexOfEngagementPanelBuilderInstruction(it.method) - val register = getInstruction(index + 1).registerA - - addInstruction( - index + 2, - "invoke-static {v$register}, " + - "$RELATED_VIDEO_CLASS_DESCRIPTOR->showEngagementPanel(Ljava/lang/Object;)V" - ) - } - } - } - - engagementPanelUpdateFingerprint.methodOrThrow(engagementPanelBuilderFingerprint) - .addInstruction( - 0, - "invoke-static {}, $RELATED_VIDEO_CLASS_DESCRIPTOR->hideEngagementPanel()V" - ) - linearLayoutManagerItemCountsFingerprint.matchOrThrow().let { val methodWalker = it.getWalkerMethod(it.patternMatch!!.endIndex) @@ -219,23 +190,28 @@ val feedComponentsPatch = bytecodePatch( } } + hookEngagementPanelState(RELATED_VIDEO_CLASS_DESCRIPTOR) + // endregion // region patch for hide subscriptions channel section for tablet - arrayOf( - channelListSubMenuTabletFingerprint, - channelListSubMenuTabletSyntheticFingerprint - ).forEach { fingerprint -> - fingerprint.methodOrThrow().apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $FEED_CLASS_DESCRIPTOR->hideSubscriptionsChannelSection()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) + // Integrated as a litho component since YouTube 20.02. + if (!is_20_02_or_greater) { + arrayOf( + channelListSubMenuTabletFingerprint, + channelListSubMenuTabletSyntheticFingerprint + ).forEach { fingerprint -> + fingerprint.methodOrThrow().apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $FEED_CLASS_DESCRIPTOR->hideSubscriptionsChannelSection()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } } } @@ -287,30 +263,42 @@ val feedComponentsPatch = bytecodePatch( it.method.apply { val freeRegister = implementation!!.registerCount - parameters.size - 2 val insertIndex = indexOfFirstInstructionOrThrow { - val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference) + val reference = getReference() reference?.parameterTypes?.size == 1 && reference.parameterTypes.first() == "[B" && reference.returnType.startsWith("L") } - val objectIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT) - val objectRegister = getInstruction(objectIndex).registerA + if (is_19_46_or_greater) { + val objectIndex = indexOfFirstInstructionReversedOrThrow(insertIndex, Opcode.IGET_OBJECT) + val objectRegister = getInstruction(objectIndex).registerA - val jumpIndex = it.patternMatch!!.startIndex + addInstructionsWithLabels( + insertIndex, """ + invoke-static {v$objectRegister, p3}, $FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z + move-result v$freeRegister + if-eqz v$freeRegister, :ignore + """ + emptyComponentLabel, + ExternalLabel("ignore", getInstruction(insertIndex)) + ) + } else { + val objectIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT) + val objectRegister = getInstruction(objectIndex).registerA + val jumpIndex = it.patternMatch!!.startIndex - addInstructionsWithLabels( - insertIndex, """ - invoke-static {v$objectRegister, v$freeRegister}, $FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z - move-result v$freeRegister - if-nez v$freeRegister, :filter - """, ExternalLabel("filter", getInstruction(jumpIndex)) - ) - - addInstruction( - 0, - "move-object/from16 v$freeRegister, p3" - ) + addInstructionsWithLabels( + insertIndex, """ + invoke-static {v$objectRegister, v$freeRegister}, $FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z + move-result v$freeRegister + if-nez v$freeRegister, :filter + """, ExternalLabel("filter", getInstruction(jumpIndex)) + ) + addInstruction( + 0, + "move-object/from16 v$freeRegister, p3" + ) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/Fingerprints.kt index f1e655d25..9ee3d8d9d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/Fingerprints.kt @@ -11,12 +11,9 @@ import app.revanced.patches.youtube.utils.resourceid.filterBarHeight import app.revanced.patches.youtube.utils.resourceid.horizontalCardList import app.revanced.patches.youtube.utils.resourceid.relatedChipCloudMargin import app.revanced.util.fingerprint.legacyFingerprint -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val breakingNewsFingerprint = legacyFingerprint( name = "breakingNewsFingerprint", @@ -103,19 +100,6 @@ internal val elementParserParentFingerprint = legacyFingerprint( strings = listOf("Element tree missing id in debug mode.") ) -internal val engagementPanelUpdateFingerprint = legacyFingerprint( - name = "engagementPanelUpdateFingerprint", - returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, - parameters = listOf("L", "Z"), - customFingerprint = { method, _ -> - method.indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL && - getReference().toString() == "Ljava/util/ArrayDeque;->pop()Ljava/lang/Object;" - } >= 0 - } -) - internal val filterBarHeightFingerprint = legacyFingerprint( name = "filterBarHeightFingerprint", returnType = "V", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt index 0acbf1fa6..e9e4a2e29 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt @@ -69,16 +69,6 @@ internal val appBlockingCheckResultToStringFingerprint = legacyFingerprint( strings = listOf("AppBlockingCheckResult{intent=") ) -internal val bottomUiContainerFingerprint = legacyFingerprint( - name = "bottomUiContainerFingerprint", - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L", "L"), - customFingerprint = { method, _ -> - method.definingClass.endsWith("/BottomUiContainer;") - } -) - internal val floatingMicrophoneFingerprint = legacyFingerprint( name = "floatingMicrophoneFingerprint", returnType = "V", @@ -87,7 +77,6 @@ internal val floatingMicrophoneFingerprint = legacyFingerprint( opcodes = listOf( Opcode.IGET_BOOLEAN, Opcode.IF_EQZ, - Opcode.RETURN_VOID ), literals = listOf(fab), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt index 05b29167a..7782e7741 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt @@ -2,12 +2,10 @@ package app.revanced.patches.youtube.general.components 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.removeInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.litho.addLithoFilter import app.revanced.patches.shared.litho.lithoFilterPatch import app.revanced.patches.shared.settingmenu.settingsMenuPatch @@ -20,6 +18,7 @@ import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_LAYOUT_COMPONENTS import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.accountSwitcherAccessibility +import app.revanced.patches.youtube.utils.resourceid.fab import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch @@ -154,18 +153,17 @@ val layoutComponentsPatch = bytecodePatch( // region patch for hide floating microphone - floatingMicrophoneFingerprint.matchOrThrow().let { - it.method.apply { - val insertIndex = it.patternMatch!!.startIndex - val register = getInstruction(insertIndex).registerA + floatingMicrophoneFingerprint.methodOrThrow().apply { + val literalIndex = indexOfFirstLiteralInstructionOrThrow(fab) + val booleanIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.IGET_BOOLEAN) + val insertRegister = getInstruction(booleanIndex).registerA - addInstructions( - insertIndex + 1, """ - invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingMicrophone(Z)Z - move-result v$register - """ - ) - } + addInstructions( + booleanIndex + 1, """ + invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingMicrophone(Z)Z + move-result v$insertRegister + """ + ) } // endregion @@ -215,21 +213,6 @@ val layoutComponentsPatch = bytecodePatch( // endregion - // region patch for hide snack bar - - bottomUiContainerFingerprint.methodOrThrow().apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideSnackBar()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - - // endregion - // region patch for hide tooltip content tooltipContentFullscreenFingerprint.methodOrThrow().apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt index ec4891efa..26ec6af6d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt @@ -6,7 +6,7 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.shared.createPlayerRequestBodyWithModelFingerprint import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH -import app.revanced.patches.youtube.utils.patch.PatchList.LAYOUT_SWITCH +import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LAYOUT import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.util.fingerprint.definingClassOrThrow @@ -24,8 +24,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR = @Suppress("unused") val layoutSwitchPatch = bytecodePatch( - LAYOUT_SWITCH.title, - LAYOUT_SWITCH.summary, + CHANGE_LAYOUT.title, + CHANGE_LAYOUT.summary, ) { compatibleWith(COMPATIBLE_PACKAGE) @@ -71,9 +71,9 @@ val layoutSwitchPatch = bytecodePatch( arrayOf( "PREFERENCE_SCREEN: GENERAL", "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS", - "SETTINGS: LAYOUT_SWITCH" + "SETTINGS: CHANGE_LAYOUT" ), - LAYOUT_SWITCH + CHANGE_LAYOUT ) // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt new file mode 100644 index 000000000..873ef9df8 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt @@ -0,0 +1,42 @@ +package app.revanced.patches.youtube.general.livering + +import app.revanced.patches.youtube.utils.resourceid.elementsImage +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal val elementsImageFingerprint = legacyFingerprint( + name = "elementsImageFingerprint", + returnType = "Landroid/view/View;", + accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, + parameters = listOf("Landroid/view/View;"), + literals = listOf(elementsImage), +) + +internal val clientSettingEndpointFingerprint = legacyFingerprint( + name = "clientSettingEndpointFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Ljava/util/Map;"), + strings = listOf( + "force_fullscreen", + "PLAYBACK_START_DESCRIPTOR_MUTATOR", + "VideoPresenterConstants.VIDEO_THUMBNAIL_BITMAP_KEY" + ), + customFingerprint = { method, _ -> + indexOfPlaybackStartDescriptorInstruction(method) >= 0 + } +) + +internal fun indexOfPlaybackStartDescriptorInstruction(method: Method) = + method.indexOfFirstInstruction { + val reference = getReference() + opcode == Opcode.INVOKE_VIRTUAL && + reference?.returnType == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" && + reference.parameterTypes.isEmpty() + } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt new file mode 100644 index 000000000..7f7798982 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt @@ -0,0 +1,95 @@ +package app.revanced.patches.youtube.general.livering + +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.patch.bytecodePatch +import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.engagement.engagementPanelHookPatch +import app.revanced.patches.youtube.utils.engagement.hookEngagementPanelState +import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH +import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LIVE_RING_CLICK_ACTION +import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch +import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference +import app.revanced.patches.youtube.utils.settings.settingsPatch +import app.revanced.patches.youtube.video.playbackstart.playbackStartDescriptorPatch +import app.revanced.patches.youtube.video.playbackstart.playbackStartVideoIdReference +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +private const val EXTENSION_CLASS_DESCRIPTOR = + "$GENERAL_PATH/OpenChannelOfLiveAvatarPatch;" + +@Suppress("unused") +val openChannelOfLiveAvatarPatch = bytecodePatch( + CHANGE_LIVE_RING_CLICK_ACTION.title, + CHANGE_LIVE_RING_CLICK_ACTION.summary, +) { + compatibleWith(COMPATIBLE_PACKAGE) + + dependsOn( + settingsPatch, + sharedResourceIdPatch, + playbackStartDescriptorPatch, + engagementPanelHookPatch, + ) + + execute { + + elementsImageFingerprint.methodOrThrow().addInstruction( + 0, + "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->liveChannelAvatarClicked()V" + ) + + hookEngagementPanelState(EXTENSION_CLASS_DESCRIPTOR) + + clientSettingEndpointFingerprint.methodOrThrow().apply { + val eqzIndex = indexOfFirstInstructionReversedOrThrow(Opcode.IF_EQZ) + var freeIndex = indexOfFirstInstructionReversedOrThrow(eqzIndex, Opcode.NEW_INSTANCE) + var freeRegister = getInstruction(freeIndex).registerA + + addInstructionsWithLabels( + eqzIndex, """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->openChannelOfLiveAvatar()Z + move-result v$freeRegister + if-eqz v$freeRegister, :ignore + return-void + :ignore + nop + """ + ) + + val playbackStartIndex = indexOfPlaybackStartDescriptorInstruction(this) + 1 + val playbackStartRegister = getInstruction(playbackStartIndex).registerA + + freeIndex = indexOfFirstInstructionOrThrow(playbackStartIndex, Opcode.CONST_STRING) + freeRegister = getInstruction(freeIndex).registerA + + addInstructions( + playbackStartIndex + 1, """ + invoke-virtual { v$playbackStartRegister }, $playbackStartVideoIdReference + move-result-object v$freeRegister + invoke-static { v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->openChannelOfLiveAvatar(Ljava/lang/String;)V + """ + ) + } + + // region add settings + + addPreference( + arrayOf( + "PREFERENCE_SCREEN: GENERAL", + "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS", + "SETTINGS: CHANGE_LIVE_RING_CLICK_ACTION" + ), + CHANGE_LIVE_RING_CLICK_ACTION + ) + + // endregion + + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/miniplayer/MiniplayerPatch.kt index cfe0b936c..0c9882607 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/miniplayer/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/miniplayer/MiniplayerPatch.kt @@ -281,7 +281,7 @@ val miniplayerPatch = bytecodePatch( "$EXTENSION_CLASS_DESCRIPTOR->setRoundedCorners(Z)Z" ) - settingArray += "SETTINGS: MINIPLAYER_ROUNDED_CONERS" + settingArray += "SETTINGS: MINIPLAYER_ROUNDED_CORNERS" } if (is_19_43_or_greater) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/Fingerprints.kt new file mode 100644 index 000000000..dfa3a62d7 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/Fingerprints.kt @@ -0,0 +1,68 @@ +package app.revanced.patches.youtube.general.snackbar + +import app.revanced.patches.youtube.utils.resourceid.insetElementsWrapper +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversed +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +private const val BOTTOM_UI_CONTAINER_CLASS_DESCRIPTOR = + "Lcom/google/android/apps/youtube/app/common/ui/bottomui/BottomUiContainer;" + +internal val bottomUiContainerFingerprint = legacyFingerprint( + name = "bottomUiContainerFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "L"), + customFingerprint = { _, classDef -> + classDef.type == BOTTOM_UI_CONTAINER_CLASS_DESCRIPTOR + } +) + +internal val bottomUiContainerPreFingerprint = legacyFingerprint( + name = "bottomUiContainerPreFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "L", "L"), + opcodes = listOf( + Opcode.IF_NEZ, + Opcode.INVOKE_VIRTUAL, + Opcode.RETURN_VOID + ), + customFingerprint = { _, classDef -> + classDef.type == BOTTOM_UI_CONTAINER_CLASS_DESCRIPTOR + } +) + +internal val bottomUiContainerThemeFingerprint = legacyFingerprint( + name = "bottomUiContainerThemeFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(BOTTOM_UI_CONTAINER_CLASS_DESCRIPTOR), + opcodes = listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IF_NE, + Opcode.CONST, + ), +) + +internal val lithoSnackBarFingerprint = legacyFingerprint( + name = "lithoSnackBarFingerprint", + returnType = "Landroid/view/View;", + literals = listOf(insetElementsWrapper), + customFingerprint = { method, _ -> + indexOfBackGroundColor(method) >= 0 + } +) + +internal fun indexOfBackGroundColor(method: Method) = + method.indexOfFirstInstructionReversed { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setBackgroundColor" + } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt new file mode 100644 index 000000000..5175a04ec --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt @@ -0,0 +1,342 @@ +package app.revanced.patches.youtube.general.snackbar + +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.patcher.patch.resourcePatch +import app.revanced.patcher.patch.stringOption +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.drawable.addDrawableColorHook +import app.revanced.patches.shared.drawable.drawableColorHookPatch +import app.revanced.patches.shared.spans.addSpanFilter +import app.revanced.patches.shared.spans.inclusiveSpanPatch +import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH +import app.revanced.patches.youtube.utils.extension.Constants.SPANS_PATH +import app.revanced.patches.youtube.utils.patch.PatchList.SNACK_BAR_COMPONENTS +import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch +import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference +import app.revanced.patches.youtube.utils.settings.settingsPatch +import app.revanced.util.findElementByAttributeValueOrThrow +import app.revanced.util.findMethodOrThrow +import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getNode +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.valueOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import org.w3c.dom.Element + +private const val EXTENSION_CLASS_DESCRIPTOR = + "$GENERAL_PATH/SnackBarPatch;" +private const val FILTER_CLASS_DESCRIPTOR = + "$SPANS_PATH/SnackBarFilter;" + +private val snackBarComponentsBytecodePatch = bytecodePatch( + description = "snackBarComponentsBytecodePatch" +) { + dependsOn( + settingsPatch, + sharedResourceIdPatch, + drawableColorHookPatch, + inclusiveSpanPatch, + ) + + execute { + bottomUiContainerFingerprint.methodOrThrow().apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->hideSnackBar()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + + bottomUiContainerPreFingerprint.matchOrThrow().let { + it.method.apply { + val insertIndex = it.patternMatch!!.startIndex + 1 + + addInstruction( + insertIndex, + "invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->lithoSnackBarLoaded()V" + ) + } + } + + bottomUiContainerThemeFingerprint.matchOrThrow().let { + it.method.apply { + val startIndex = it.patternMatch!!.startIndex + val appThemeIndex = startIndex + 1 + val darkThemeIndex = startIndex + 2 + val insertIndex = startIndex + 3 + + val appThemeRegister = + getInstruction(appThemeIndex).registerA + val darkThemeRegister = + getInstruction(darkThemeIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$appThemeRegister, v$darkThemeRegister}, $EXTENSION_CLASS_DESCRIPTOR->invertSnackBarTheme(Ljava/lang/Enum;Ljava/lang/Enum;)Ljava/lang/Enum; + move-result-object v$appThemeRegister + """ + ) + } + } + + fun MutableMethod.setBackground(index: Int, register: Int) = + addInstruction( + index, + "invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->setLithoSnackBarBackground(Landroid/view/View;)V" + ) + + lithoSnackBarFingerprint.methodOrThrow().apply { + val backGroundColorIndex = indexOfBackGroundColor(this) + val viewRegister = + getInstruction(backGroundColorIndex).registerC + val colorRegister = + getInstruction(backGroundColorIndex).registerD + + replaceInstruction( + backGroundColorIndex, + "invoke-static {v$viewRegister, v$colorRegister}, $EXTENSION_CLASS_DESCRIPTOR->" + + "setLithoSnackBarBackgroundColor(Landroid/widget/FrameLayout;I)V" + ) + setBackground(backGroundColorIndex + 2, viewRegister) + + implementation!!.instructions + .withIndex() + .filter { (_, instruction) -> + instruction.opcode == Opcode.CHECK_CAST && + (instruction as? ReferenceInstruction)?.reference?.toString() == "Landroid/widget/FrameLayout;" + } + .map { (index, _) -> index } + .reversed() + .forEach { index -> + val register = + getInstruction(index).registerA + + setBackground(index + 1, register) + } + + findMethodOrThrow(definingClass).apply { + val contextIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.IPUT_OBJECT && + getReference()?.type == "Landroid/content/Context;" + } + val contextRegister = + getInstruction(contextIndex).registerA + + addInstructions( + contextIndex, """ + invoke-static {v$contextRegister}, $EXTENSION_CLASS_DESCRIPTOR->invertSnackBarTheme(Landroid/content/Context;)Landroid/content/Context; + move-result-object v$contextRegister + """ + ) + + val viewIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.IPUT_OBJECT && + getReference()?.type == "Landroid/widget/FrameLayout;" + } + val viewRegister = + getInstruction(viewIndex).registerA + + addInstructions( + viewIndex, + "invoke-static {v$viewRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideLithoSnackBar(Landroid/widget/FrameLayout;)V" + ) + } + } + + addDrawableColorHook("$EXTENSION_CLASS_DESCRIPTOR->getLithoColor(I)I", true) + addSpanFilter(FILTER_CLASS_DESCRIPTOR) + } +} + +@Suppress("unused") +val snackBarComponentsPatch = resourcePatch( + SNACK_BAR_COMPONENTS.title, + SNACK_BAR_COMPONENTS.summary, +) { + compatibleWith(COMPATIBLE_PACKAGE) + + dependsOn( + settingsPatch, + snackBarComponentsBytecodePatch, + ) + + val ytBackgroundColorDark = "@color/yt_black3" + val ytBackgroundColorLight = "@color/yt_white3" + + val availableDarkTheme = mapOf( + "YouTube Dark" to ytBackgroundColorDark, + "Amoled Black" to "@android:color/black", + "Catppuccin (Mocha)" to "#FF181825", + "Dark Pink" to "#FF290025", + "Dark Blue" to "#FF001029", + "Dark Green" to "#FF002905", + "Dark Yellow" to "#FF282900", + "Dark Orange" to "#FF291800", + "Dark Red" to "#FF290000", + ) + + val availableLightTheme = mapOf( + "YouTube Light" to ytBackgroundColorLight, + "White" to "@android:color/white", + "Catppuccin (Latte)" to "#FFE6E9EF", + "Light Pink" to "#FFFCCFF3", + "Light Blue" to "#FFD1E0FF", + "Light Green" to "#FFCCFFCC", + "Light Yellow" to "#FFFDFFCC", + "Light Orange" to "#FFFFE6CC", + "Light Red" to "#FFFFD6D6", + ) + + val cornerRadiusOption = stringOption( + key = "cornerRadius", + default = "8.0dip", + title = "Corner radius", + description = "Specify a corner radius for the snack bar.", + required = true, + ) + + val darkThemeBackgroundColor = stringOption( + key = "darkThemeBackgroundColor", + default = ytBackgroundColorDark, + values = availableDarkTheme, + title = "Dark theme background color", + description = "Specify a background color for the snack bar. You can specify hex color (#AARRGGBB) or color resource reference.", + required = true, + ) + + val lightThemeBackgroundColor = stringOption( + key = "lightThemeBackgroundColor", + default = ytBackgroundColorLight, + values = availableLightTheme, + title = "Light theme background color", + description = "Specify a background color for the snack bar. You can specify hex color (#AARRGGBB) or color resource reference.", + required = true, + ) + + val strokeColorOption = stringOption( + key = "strokeColor", + default = "", + values = mapOf( + "None" to "", + "Blue" to "?attr/ytThemedBlue", + "Chip" to "?attr/ytChipBackground" + ), + title = "Stroke color", + description = "Specify a stroke color for the snack bar. You can specify hex color.", + required = true, + ) + + execute { + + // Check patch options first. + val cornerRadius = cornerRadiusOption + .valueOrThrow() + val darkThemeColor = darkThemeBackgroundColor + .valueOrThrow() + val lightThemeColor = lightThemeBackgroundColor + .valueOrThrow() + val strokeColor = strokeColorOption + .valueOrThrow() + + val snackBarColorAttr = "snackBarColor" + val snackBarColorAttrReference = "?attr/$snackBarColorAttr" + val snackBarColorDark = "revanced_snack_bar_color_dark" + val snackBarColorDarkReference = "@color/$snackBarColorDark" + val snackBarColorLight = "revanced_snack_bar_color_light" + val snackBarColorLightReference = "@color/$snackBarColorLight" + + document("res/values/colors.xml").use { document -> + mapOf( + snackBarColorDark to darkThemeColor, + snackBarColorLight to lightThemeColor, + ).forEach { (k, v) -> + val colorElement = document.createElement("color") + + colorElement.setAttribute("name", k) + colorElement.textContent = v + + document.getElementsByTagName("resources").item(0) + .appendChild(colorElement) + } + } + + document("res/values/attrs.xml").use { document -> + (document.getElementsByTagName("resources").item(0) as Element).appendChild( + document.createElement("attr").apply { + setAttribute("format", "reference|color") + setAttribute("name", snackBarColorAttr) + } + ) + } + + document("res/values/styles.xml").use { document -> + mapOf( + "Base.Theme.YouTube.Dark" to snackBarColorLightReference, + "Base.Theme.YouTube.Light" to snackBarColorDarkReference, + ).forEach { (styleName, colorName) -> + val snackBarColorNode = document.createElement("item") + snackBarColorNode.setAttribute("name", snackBarColorAttr) + snackBarColorNode.appendChild(document.createTextNode(colorName)) + + document.childNodes.findElementByAttributeValueOrThrow( + "name", + styleName, + ).appendChild(snackBarColorNode) + } + } + + document("res/drawable/snackbar_rounded_corners_background.xml").use { document -> + document.getNode("corners").apply { + arrayOf( + "android:bottomLeftRadius", + "android:bottomRightRadius", + "android:topLeftRadius", + "android:topRightRadius", + ).forEach { + attributes.getNamedItem(it).nodeValue = cornerRadius + } + } + document.getNode("solid").apply { + attributes.getNamedItem("android:color").nodeValue = snackBarColorAttrReference + } + if (!strokeColor.isEmpty()) { + (document.getElementsByTagName("shape").item(0) as Element).appendChild( + document.createElement("stroke").apply { + setAttribute("android:width", "1.0dip") + setAttribute("android:color", strokeColor) + } + ) + } + } + + // region add settings + + addPreference( + arrayOf( + "PREFERENCE_SCREEN: GENERAL", + "SETTINGS: SNACK_BAR_COMPONENTS" + ), + SNACK_BAR_COMPONENTS + ) + + // endregion + + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt index c942b4489..5177e36c7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt @@ -2,12 +2,14 @@ package app.revanced.patches.youtube.general.spoofappversion 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.patcher.patch.resourcePatch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.spoof.appversion.baseSpoofAppVersionPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.extension.Constants.PATCH_STATUS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.fix.cairo.cairoFragmentPatch import app.revanced.patches.youtube.utils.indexOfGetDrawableInstruction import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_APP_VERSION @@ -23,6 +25,7 @@ import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.patches.youtube.utils.toolBarButtonFingerprint import app.revanced.util.appendAppVersion +import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -69,6 +72,13 @@ private val spoofAppVersionBytecodePatch = bytecodePatch( """, ExternalLabel("ignore", getInstruction(jumpIndex)) ) } + + findMethodOrThrow(PATCH_STATUS_CLASS_DESCRIPTOR) { + name == "SpoofAppVersionDefaultString" + }.replaceInstruction( + 0, + "const-string v0, \"18.38.45\"" + ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt index 46233d174..2d50bbb25 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt @@ -15,6 +15,7 @@ import app.revanced.patches.youtube.utils.castbutton.hookToolBarCastButton import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.patch.PatchList.TOOLBAR_COMPONENTS +import app.revanced.patches.youtube.utils.playservice.is_19_46_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.actionBarRingoBackground import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch @@ -265,7 +266,11 @@ val toolBarComponentsPatch = bytecodePatch( // region patch for hide search term thumbnail createSearchSuggestionsFingerprint.methodOrThrow().apply { - val relativeIndex = indexOfFirstLiteralInstructionOrThrow(40L) + val literal = if (is_19_46_or_greater) + 32L + else + 40L + val relativeIndex = indexOfFirstLiteralInstructionOrThrow(literal) val replaceIndex = indexOfFirstInstructionReversedOrThrow(relativeIndex) { opcode == Opcode.INVOKE_VIRTUAL && getReference()?.toString() == "Landroid/widget/ImageView;->setVisibility(I)V" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt index d95f7c786..a27467bcd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt @@ -27,7 +27,7 @@ val sharedThemePatch = resourcePatch( document(attrsResourceFile).use { document -> (document.getElementsByTagName("resources").item(0) as Element).appendChild( document.createElement("attr").apply { - setAttribute("format", "reference") + setAttribute("format", "reference|color") setAttribute("name", SPLASH_SCREEN_COLOR_NAME) } ) @@ -49,7 +49,7 @@ val sharedThemePatch = resourcePatch( setAttribute( "name", when (pathIndex) { - 0 -> "splashScreenColor" + 0 -> SPLASH_SCREEN_COLOR_NAME 1 -> "android:windowSplashScreenBackground" else -> "null" } @@ -59,8 +59,10 @@ val sharedThemePatch = resourcePatch( document.createTextNode( when (pathIndex) { 0 -> when (nodeAttributeName) { - "Base.Theme.YouTube.Launcher.Dark" -> "@color/yt_black1" - "Base.Theme.YouTube.Launcher.Light" -> "@color/yt_white1" + "Base.Theme.YouTube.Launcher.Dark", + "Base.Theme.YouTube.Launcher.Cairo.Dark" -> "@color/yt_black1" + "Base.Theme.YouTube.Launcher.Light", + "Base.Theme.YouTube.Launcher.Cairo.Light" -> "@color/yt_white1" else -> "null" } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt index bb94e8a30..8a75f139d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt @@ -54,6 +54,7 @@ val themePatch = resourcePatch( values = availableDarkTheme, title = "Dark theme background color", description = "Can be a hex color (#AARRGGBB) or a color resource reference.", + required = true, ) val lightThemeBackgroundColor = stringOption( @@ -62,6 +63,7 @@ val themePatch = resourcePatch( values = availableLightTheme, title = "Light theme background color", description = "Can be a hex color (#AARRGGBB) or a color resource reference.", + required = true, ) execute { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/Fingerprints.kt similarity index 96% rename from patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/Fingerprints.kt rename to patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/Fingerprints.kt index 1b33eeab6..82a750711 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/Fingerprints.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.openlinksdirectly +package app.revanced.patches.youtube.misc.openlinks.directly import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/OpenLinksDirectlyPatch.kt similarity index 82% rename from patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/OpenLinksDirectlyPatch.kt index 61ffa6c1d..bd111ce99 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/directly/OpenLinksDirectlyPatch.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.youtube.misc.openlinksdirectly +package app.revanced.patches.youtube.misc.openlinks.directly import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.patch.PatchList.ENABLE_OPEN_LINKS_DIRECTLY +import app.revanced.patches.youtube.utils.patch.PatchList.BYPASS_URL_REDIRECTS import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.util.fingerprint.methodOrThrow @@ -17,8 +17,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Suppress("unused") val openLinksDirectlyPatch = bytecodePatch( - ENABLE_OPEN_LINKS_DIRECTLY.title, - ENABLE_OPEN_LINKS_DIRECTLY.summary, + BYPASS_URL_REDIRECTS.title, + BYPASS_URL_REDIRECTS.summary, ) { compatibleWith(COMPATIBLE_PACKAGE) @@ -40,7 +40,7 @@ val openLinksDirectlyPatch = bytecodePatch( replaceInstruction( insertIndex, - "invoke-static {v$insertRegister}, $MISC_PATH/OpenLinksDirectlyPatch;->enableBypassRedirect(Ljava/lang/String;)Landroid/net/Uri;" + "invoke-static {v$insertRegister}, $MISC_PATH/OpenLinksDirectlyPatch;->parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;" ) } } @@ -49,9 +49,9 @@ val openLinksDirectlyPatch = bytecodePatch( addPreference( arrayOf( - "SETTINGS: ENABLE_OPEN_LINKS_DIRECTLY" + "SETTINGS: BYPASS_URL_REDIRECTS" ), - ENABLE_OPEN_LINKS_DIRECTLY + BYPASS_URL_REDIRECTS ) // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/externally/OpenLinksExternallyPatch.kt similarity index 81% rename from patches/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/externally/OpenLinksExternallyPatch.kt index 020594c8a..4a7d1cd9a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/openlinks/externally/OpenLinksExternallyPatch.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.youtube.misc.externalbrowser +package app.revanced.patches.youtube.misc.openlinks.externally import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.shared.transformation.transformInstructionsPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.patch.PatchList.ENABLE_EXTERNAL_BROWSER +import app.revanced.patches.youtube.utils.patch.PatchList.OPEN_LINKS_EXTERNALLY import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -14,8 +14,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference @Suppress("unused") val openLinksExternallyPatch = bytecodePatch( - ENABLE_EXTERNAL_BROWSER.title, - ENABLE_EXTERNAL_BROWSER.summary, + OPEN_LINKS_EXTERNALLY.title, + OPEN_LINKS_EXTERNALLY.summary, ) { compatibleWith(COMPATIBLE_PACKAGE) @@ -36,7 +36,7 @@ val openLinksExternallyPatch = bytecodePatch( mutableMethod.addInstructions( intentStringIndex + 1, """ - invoke-static {v$register}, $MISC_PATH/ExternalBrowserPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$register}, $MISC_PATH/OpenLinksExternallyPatch;->openLinksExternally(Ljava/lang/String;)Ljava/lang/String; move-result-object v$register """, ) @@ -51,9 +51,9 @@ val openLinksExternallyPatch = bytecodePatch( addPreference( arrayOf( - "SETTINGS: ENABLE_EXTERNAL_BROWSER" + "SETTINGS: OPEN_LINKS_EXTERNALLY" ), - ENABLE_EXTERNAL_BROWSER + OPEN_LINKS_EXTERNALLY ) // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt index 91f46f888..d1d695fdd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt @@ -1,16 +1,37 @@ package app.revanced.patches.youtube.player.action +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.booleanOption import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.shared.litho.addLithoFilter +import app.revanced.patches.shared.litho.emptyComponentsFingerprint import app.revanced.patches.shared.litho.lithoFilterPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_PATH import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_ACTION_BUTTONS import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch +import app.revanced.patches.youtube.video.information.videoInformationPatch +import app.revanced.util.Utils.trimIndentMultiline +import app.revanced.util.addInstructionsAtControlFlowLabel +import app.revanced.util.findMethodOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference private const val FILTER_CLASS_DESCRIPTOR = "$COMPONENTS_PATH/ActionButtonsFilter;" +private const val ACTION_BUTTONS_CLASS_DESCRIPTOR = + "$PLAYER_PATH/ActionButtonsPatch;" @Suppress("unused") val actionButtonsPatch = bytecodePatch( @@ -22,18 +43,73 @@ val actionButtonsPatch = bytecodePatch( dependsOn( settingsPatch, lithoFilterPatch, + videoInformationPatch, + ) + + val hideActionButtonByIndex by booleanOption( + key = "hideActionButtonByIndex", + default = false, + title = "Hide action buttons by index", + description = """ + Add an option to hide action buttons by index. + + This setting is still experimental, so use it only for debugging purposes. + """.trimIndentMultiline(), + required = true ) execute { addLithoFilter(FILTER_CLASS_DESCRIPTOR) + var settingArray = arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: HIDE_ACTION_BUTTONS" + ) + + if (hideActionButtonByIndex == true) { + componentListFingerprint.methodOrThrow(emptyComponentsFingerprint).apply { + val conversionContextToStringMethod = + findMethodOrThrow(parameters[1].type) { + name == "toString" + } + val identifierReference = with (conversionContextToStringMethod) { + val identifierStringIndex = + indexOfFirstStringInstructionOrThrow(", identifierProperty=") + val identifierStringAppendIndex = + indexOfFirstInstructionOrThrow(identifierStringIndex, Opcode.INVOKE_VIRTUAL) + val identifierStringAppendIndexRegister = getInstruction(identifierStringAppendIndex).registerD + val identifierAppendIndex = + indexOfFirstInstructionOrThrow(identifierStringAppendIndex + 1, Opcode.INVOKE_VIRTUAL) + val identifierRegister = getInstruction(identifierAppendIndex).registerD + val identifierIndex = indexOfFirstInstructionReversedOrThrow(identifierAppendIndex) { + opcode == Opcode.IGET_OBJECT && + getReference()?.type == "Ljava/lang/String;" && + (this as? TwoRegisterInstruction)?.registerA == identifierRegister + } + getInstruction(identifierIndex).reference + } + + val listIndex = implementation!!.instructions.lastIndex + val listRegister = getInstruction(listIndex).registerA + val identifierRegister = listRegister + 1 + + addInstructionsAtControlFlowLabel( + listIndex, """ + move-object/from16 v$identifierRegister, p2 + iget-object v$identifierRegister, v$identifierRegister, $identifierReference + invoke-static {v$listRegister, v$identifierRegister}, $ACTION_BUTTONS_CLASS_DESCRIPTOR->hideActionButtonByIndex(Ljava/util/List;Ljava/lang/String;)Ljava/util/List; + move-result-object v$listRegister + """ + ) + + settingArray += "SETTINGS: HIDE_BUTTONS_BY_INDEX" + } + } + // region add settings addPreference( - arrayOf( - "PREFERENCE_SCREEN: PLAYER", - "SETTINGS: HIDE_ACTION_BUTTONS" - ), + settingArray, HIDE_ACTION_BUTTONS ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/Fingerprints.kt new file mode 100644 index 000000000..a3735638f --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/Fingerprints.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.youtube.player.action + +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal val componentListFingerprint = legacyFingerprint( + name = "componentListFingerprint", + returnType = "Ljava/util/List;", + accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_STATIC && + getReference()?.name == "nCopies" + } >= 0 + } +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index 3934b2277..029818d01 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -23,6 +23,8 @@ import app.revanced.patches.youtube.utils.extension.Constants.SPANS_PATH import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.suggestedVideoEndScreenPatch import app.revanced.patches.youtube.utils.patch.PatchList.PLAYER_COMPONENTS import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch +import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater +import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.darkBackground import app.revanced.patches.youtube.utils.resourceid.fadeDurationFast import app.revanced.patches.youtube.utils.resourceid.scrimOverlay @@ -278,9 +280,15 @@ val playerComponentsPatch = bytecodePatch( speedOverlayPatch, suggestedVideoEndScreenPatch, videoInformationPatch, + versionCheckPatch, ) execute { + var settingArray = arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: PLAYER_COMPONENTS" + ) + fun MutableMethod.getAllLiteralComponent( startIndex: Int, endIndex: Int @@ -563,30 +571,34 @@ val playerComponentsPatch = bytecodePatch( ) } - youtubeControlsOverlayFingerprint.methodOrThrow().apply { - val insertIndex = - indexOfFirstLiteralInstructionOrThrow(seekUndoEduOverlayStub) - val insertRegister = getInstruction(insertIndex).registerA + if (!is_20_02_or_greater) { + youtubeControlsOverlayFingerprint.methodOrThrow().apply { + val insertIndex = + indexOfFirstLiteralInstructionOrThrow(seekUndoEduOverlayStub) + val insertRegister = getInstruction(insertIndex).registerA - val onClickListenerIndex = indexOfFirstInstructionOrThrow(insertIndex) { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.name == "setOnClickListener" - } - val constComponent = getFirstLiteralComponent(insertIndex, onClickListenerIndex - 1) + val onClickListenerIndex = indexOfFirstInstructionOrThrow(insertIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setOnClickListener" + } + val constComponent = getFirstLiteralComponent(insertIndex, onClickListenerIndex - 1) - if (constComponent.isNotEmpty()) { - addInstruction( - onClickListenerIndex + 2, - constComponent + if (constComponent.isNotEmpty()) { + addInstruction( + onClickListenerIndex + 2, + constComponent + ) + } + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekUndoMessage()Z + move-result v$insertRegister + if-nez v$insertRegister, :default + """, ExternalLabel("default", getInstruction(onClickListenerIndex + 1)) ) + + settingArray += "SETTINGS: HIDE_SEEK_UNDO_MESSAGE" } - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekUndoMessage()Z - move-result v$insertRegister - if-nez v$insertRegister, :default - """, ExternalLabel("default", getInstruction(onClickListenerIndex + 1)) - ) } // endregion @@ -652,10 +664,7 @@ val playerComponentsPatch = bytecodePatch( // region add settings addPreference( - arrayOf( - "PREFERENCE_SCREEN: PLAYER", - "SETTINGS: PLAYER_COMPONENTS" - ), + settingArray, PLAYER_COMPONENTS ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt index 82fd8fd5f..135a3a021 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt @@ -16,17 +16,17 @@ internal val engagementPanelTitleFingerprint = legacyFingerprint( } ) +internal val engagementPanelTitleParentFingerprint = legacyFingerprint( + name = "engagementPanelTitleParentFingerprint", + strings = listOf("[EngagementPanelTitleHeader] Cannot remove action buttons from header as the child count is out of sync. Buttons to remove exceed current header child count.") +) + internal fun indexOfContentDescriptionInstruction(method: Method) = method.indexOfFirstInstructionReversed { opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setContentDescription" } -internal val engagementPanelTitleParentFingerprint = legacyFingerprint( - name = "engagementPanelTitleParentFingerprint", - strings = listOf("[EngagementPanelTitleHeader] Cannot remove action buttons from header as the child count is out of sync. Buttons to remove exceed current header child count.") -) - /** * This fingerprint is compatible with YouTube v18.35.xx~ * Nonetheless, the patch works in YouTube v19.02.xx~ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt index f65a4b917..bda5fdde7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt @@ -7,6 +7,7 @@ import app.revanced.patches.youtube.utils.resourceid.quickActionsElementContaine import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.util.MethodUtil internal val broadcastReceiverFingerprint = legacyFingerprint( name = "broadcastReceiverFingerprint", @@ -45,12 +46,15 @@ internal val playerTitleViewFingerprint = legacyFingerprint( literals = listOf(playerVideoTitleView), ) -internal val quickActionsElementFingerprint = legacyFingerprint( - name = "quickActionsElementFingerprint", +internal val quickActionsElementSyntheticFingerprint = legacyFingerprint( + name = "quickActionsElementSyntheticFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Landroid/view/View;"), literals = listOf(quickActionsElementContainer), + customFingerprint = { _, classDef -> + AccessFlags.SYNTHETIC.isSet(classDef.accessFlags) + } ) internal val relatedEndScreenResultsFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt index 21f315edc..2a56b37c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt @@ -19,6 +19,7 @@ import app.revanced.patches.youtube.utils.extension.Constants.PATCH_STATUS_CLASS import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_PATH import app.revanced.patches.youtube.utils.fullscreen.fullscreenButtonHookPatch +import app.revanced.patches.youtube.utils.indexOfFocusableInTouchModeInstruction import app.revanced.patches.youtube.utils.layoutConstructorFingerprint import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch import app.revanced.patches.youtube.utils.patch.PatchList.FULLSCREEN_COMPONENTS @@ -101,7 +102,6 @@ val fullscreenComponentsPatch = bytecodePatch( "invoke-static {v$targetRegister}, " + "$PLAYER_CLASS_DESCRIPTOR->disableEngagementPanels(Landroidx/coordinatorlayout/widget/CoordinatorLayout;)V" ) - } playerTitleViewFingerprint.methodOrThrow().apply { @@ -190,7 +190,7 @@ val fullscreenComponentsPatch = bytecodePatch( // region patch for quick actions - quickActionsElementFingerprint.methodOrThrow().apply { + quickActionsElementSyntheticFingerprint.methodOrThrow().apply { val containerCalls = implementation!!.instructions.withIndex() .filter { instruction -> (instruction.value as? WideLiteralInstruction)?.wideLiteral == quickActionsElementContainer @@ -219,11 +219,13 @@ val fullscreenComponentsPatch = bytecodePatch( // region patch for compact control overlay youtubeControlsOverlayFingerprint.methodOrThrow().apply { - val targetIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.name == "setFocusableInTouchMode" + val targetIndex = indexOfFocusableInTouchModeInstruction(this) + val walkerIndex = indexOfFirstInstructionOrThrow(targetIndex) { + val reference = getReference() + opcode == Opcode.INVOKE_STATIC && + reference?.returnType == "Z" && + reference.parameterTypes.size == 1 } - val walkerIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.INVOKE_STATIC) val walkerMethod = getWalkerMethod(walkerIndex) walkerMethod.apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt index 3c07be84b..67ce333ab 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt @@ -15,8 +15,6 @@ import app.revanced.patches.youtube.utils.patch.PatchList.OVERLAY_BUTTONS import app.revanced.patches.youtube.utils.pip.pipStateHookPatch import app.revanced.patches.youtube.utils.playercontrols.hookBottomControlButton import app.revanced.patches.youtube.utils.playercontrols.playerControlsPatch -import app.revanced.patches.youtube.utils.playservice.is_19_17_or_greater -import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch @@ -58,7 +56,7 @@ private val overlayButtonsBytecodePatch = bytecodePatch( } } -private const val MARGIN_NONE = "0.0dip" +private const val MARGIN_MINIMUM = "0.1dip" private const val MARGIN_DEFAULT = "2.5dip" private const val MARGIN_WIDER = "5.0dip" @@ -78,7 +76,6 @@ val overlayButtonsPatch = resourcePatch( playerControlsPatch, sharedResourceIdPatch, settingsPatch, - versionCheckPatch, ) val iconTypeOption = stringOption( @@ -99,11 +96,11 @@ val overlayButtonsPatch = resourcePatch( default = MARGIN_DEFAULT, values = mapOf( "Default" to MARGIN_DEFAULT, - "None" to MARGIN_NONE, + "Minimum" to MARGIN_MINIMUM, "Wider" to MARGIN_WIDER, ), title = "Bottom margin", - description = "The bottom margin for the overlay buttons and timestamp. Supports from YouTube 18.29.38 to YouTube 19.16.39.", + description = "The bottom margin for the overlay buttons and timestamp.", required = true ) @@ -111,7 +108,7 @@ val overlayButtonsPatch = resourcePatch( key = "widerButtonsSpace", default = false, title = "Wider between-buttons space", - description = "Prevent adjacent button presses by increasing the horizontal spacing between buttons. Supports from YouTube 18.29.38 to YouTube 19.16.39.", + description = "Prevent adjacent button presses by increasing the horizontal spacing between buttons.", required = true ) @@ -132,15 +129,18 @@ val overlayButtonsPatch = resourcePatch( var marginBottom = bottomMarginOption .lowerCaseOrThrow() - if (marginBottom != MARGIN_DEFAULT && is_19_17_or_greater) { - printWarn("\"Bottom margin\" is not supported in this version. Use YouTube 19.16.39 or earlier.") + try { + val marginBottomFloat = marginBottom.split("dip")[0].toFloat() + if (marginBottomFloat <= 0f) { + printWarn("Patch option \"Bottom margin\" must be greater than 0, fallback to minimum.") + marginBottom = MARGIN_MINIMUM + } + } catch (_: Exception) { + printWarn("Patch option \"Bottom margin\" failed validation, fallback to default.") marginBottom = MARGIN_DEFAULT } - if (widerButtonsSpace == true && is_19_17_or_greater) { - printWarn("\"Wider between-buttons space\" is not supported in this version. Use YouTube 19.16.39 or earlier.") - } - val useWiderButtonsSpace = widerButtonsSpace == true && !is_19_17_or_greater + val useWiderButtonsSpace = widerButtonsSpace == true // Inject hooks for overlay buttons. setOf( @@ -196,10 +196,13 @@ val overlayButtonsPatch = resourcePatch( "yt_fill_arrow_repeat_white_24.png", "yt_outline_arrow_repeat_1_white_24.png", "yt_outline_arrow_shuffle_1_white_24.png", + "yt_outline_arrow_shuffle_black_24.png", + "yt_outline_list_play_arrow_black_24.png", + "yt_outline_list_play_arrow_white_24.png", "yt_outline_screen_full_exit_white_24.png", - "yt_outline_screen_full_white_24.png", "yt_outline_screen_full_vd_theme_24.png", - "yt_outline_screen_vertical_vd_theme_24.png" + "yt_outline_screen_full_white_24.png", + "yt_outline_screen_vertical_vd_theme_24.png", ), ResourceGroup( "drawable", @@ -215,15 +218,11 @@ val overlayButtonsPatch = resourcePatch( "android.support.constraint.ConstraintLayout" ) - var xmlFiles = arrayOf( - "youtube_controls_bottom_ui_container.xml" - ) - if (!is_19_17_or_greater) { - xmlFiles += "youtube_controls_fullscreen_button.xml" - xmlFiles += "youtube_controls_cf_fullscreen_button.xml" - } - - xmlFiles.forEach { xmlFile -> + arrayOf( + "youtube_controls_bottom_ui_container.xml", + "youtube_controls_fullscreen_button.xml", + "youtube_controls_cf_fullscreen_button.xml" + ).forEach { xmlFile -> val targetXml = get("res").resolve("layout").resolve(xmlFile) if (targetXml.exists()) { document("res/layout/$xmlFile").use { document -> @@ -238,6 +237,13 @@ val overlayButtonsPatch = resourcePatch( } } + node.getAttributeNode("yt:layout_constraintBottom_toTopOf") + ?.let { attribute -> + if (attribute.textContent == "@id/quick_actions_container") { + attribute.textContent = "@+id/bottom_margin" + } + } + val (id, height, width) = Triple( node.getAttribute("android:id"), node.getAttribute("android:layout_height"), @@ -248,11 +254,7 @@ val overlayButtonsPatch = resourcePatch( width != "0.0dip", ) - val isButton = if (is_19_17_or_greater) - // Note: Do not modify fullscreen button and multiview button - id.endsWith("_button") && id != "@id/multiview_button" - else - id.endsWith("_button") || id == "@id/youtube_controls_fullscreen_button_stub" + val isButton = id.endsWith("_button") && id != "@id/multiview_button" || id == "@id/youtube_controls_fullscreen_button_stub" // Adjust TimeBar and Chapter bottom padding val timBarItem = mutableMapOf( @@ -266,7 +268,6 @@ val overlayButtonsPatch = resourcePatch( "48.0dip" if (isButton) { - node.setAttribute("android:layout_marginBottom", marginBottom) node.setAttribute("android:paddingLeft", "0.0dip") node.setAttribute("android:paddingRight", "0.0dip") node.setAttribute("android:paddingBottom", "22.0dip") @@ -275,14 +276,15 @@ val overlayButtonsPatch = resourcePatch( node.setAttribute("android:layout_width", layoutHeightWidth) } } else if (timBarItem.containsKey(id)) { - node.setAttribute("android:layout_marginBottom", marginBottom) if (!useWiderButtonsSpace) { node.setAttribute("android:paddingBottom", timBarItem.getValue(id)) } } - if (!is_19_17_or_greater && id.equals("@id/youtube_controls_fullscreen_button_stub")) { - node.setAttribute("android:layout_width", layoutHeightWidth) + if (id.equals("@+id/bottom_margin")) { + node.setAttribute("android:layout_height", marginBottom) + } else if (id.equals("@id/time_bar_reference_view")) { + node.setAttribute("yt:layout_constraintBottom_toTopOf", "@id/quick_actions_container") } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt index d59944886..d6ce2d8e3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.player.seekbar import app.revanced.patches.youtube.utils.resourceid.reelTimeBarPlayedColor +import app.revanced.patches.youtube.utils.resourceid.ytYoutubeMagenta import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or @@ -22,6 +23,35 @@ internal val lithoLinearGradientFingerprint = legacyFingerprint( returnType = "Landroid/graphics/LinearGradient;", parameters = listOf("F", "F", "F", "F", "[I", "[F") ) + +/** + * YouTube 19.25 - 19.47 + */ +internal val playerLinearGradientLegacyFingerprint = legacyFingerprint( + name = "playerLinearGradientLegacyFingerprint", + returnType = "V", + opcodes = listOf( + Opcode.FILLED_NEW_ARRAY, + Opcode.MOVE_RESULT_OBJECT + ), + literals = listOf(ytYoutubeMagenta), +) + +/** + * YouTube 19.49+ + */ +internal val playerLinearGradientFingerprint = legacyFingerprint( + name = "playerLinearGradientFingerprint", + returnType = "Landroid/graphics/LinearGradient;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("I", "I", "I", "I", "Landroid/content/Context;", "I"), + opcodes = listOf( + Opcode.FILLED_NEW_ARRAY, + Opcode.MOVE_RESULT_OBJECT + ), + literals = listOf(ytYoutubeMagenta), +) + internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L internal val launchScreenLayoutTypeFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt index f3f587372..fe14c9d11 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt @@ -25,6 +25,7 @@ import app.revanced.patches.youtube.utils.playerButtonsVisibilityFingerprint import app.revanced.patches.youtube.utils.playerSeekbarColorFingerprint import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_46_or_greater +import app.revanced.patches.youtube.utils.playservice.is_19_49_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarColorizedBarPlayedColorDark import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarPlayedNotHighlightedColor @@ -253,16 +254,35 @@ val seekbarComponentsPatch = bytecodePatch( addDrawableColorHook("$EXTENSION_SEEKBAR_COLOR_CLASS_DESCRIPTOR->getLithoColor(I)I") if (is_19_25_or_greater) { - playerSeekbarGradientConfigFingerprint.injectLiteralInstructionBooleanCall( - PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG, - "$EXTENSION_SEEKBAR_COLOR_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z" - ) - lithoLinearGradientFingerprint.methodOrThrow().addInstruction( 0, "invoke-static/range { p4 .. p5 }, $EXTENSION_SEEKBAR_COLOR_CLASS_DESCRIPTOR->setLinearGradient([I[F)V" ) + if (!is_19_49_or_greater) { + playerLinearGradientLegacyFingerprint.matchOrThrow().let { + it.method.apply { + val index = it.patternMatch!!.endIndex + val register = getInstruction(index).registerA + + addInstructions( + index + 1, + """ + invoke-static { v$register }, $EXTENSION_SEEKBAR_COLOR_CLASS_DESCRIPTOR->getLinearGradient([I)[I + move-result-object v$register + """ + ) + } + } + } else { + // TODO: add 19.49 support + playerSeekbarGradientConfigFingerprint.injectLiteralInstructionBooleanCall( + PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG, + "$EXTENSION_SEEKBAR_COLOR_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z" + ) + } + + if (!restoreOldSplashAnimationIncluded) { // Don't use the lotte splash screen layout if using custom seekbar. arrayOf( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt index 3ebc3e3db..573c63f4a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt @@ -21,6 +21,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import kotlin.collections.listOf internal val bottomSheetMenuListBuilderFingerprint = legacyFingerprint( name = "bottomSheetMenuListBuilderFingerprint", @@ -187,3 +188,40 @@ internal val shortsFullscreenFeatureFingerprint = legacyFingerprint( literals = listOf(FULLSCREEN_FEATURE_FLAG), ) +// Pre 19.25 +internal val shortsPlaybackIntentLegacyFingerprint = legacyFingerprint( + name = "shortsPlaybackIntentLegacyFingerprint", + returnType = "V", + parameters = listOf( + "L", + "Ljava/util/Map;", + "J", + "Ljava/lang/String;", + "Z", + "Ljava/util/Map;" + ), + strings = listOf( + // None of these strings are unique. + "com.google.android.apps.youtube.app.endpoint.flags", + "ReelWatchFragmentArgs", + "reels_fragment_descriptor" + ) +) + +internal val shortsPlaybackIntentFingerprint = legacyFingerprint( + name = "shortsPlaybackIntentFingerprint", + accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, + returnType = "V", + parameters = listOf( + "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", + "Ljava/util/Map;", + "J", + "Ljava/lang/String;" + ), + strings = listOf( + // None of these strings are unique. + "com.google.android.apps.youtube.app.endpoint.flags", + "ReelWatchFragmentArgs", + "reels_fragment_descriptor" + ) +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index 76363b6df..8d7b386d4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -62,6 +62,9 @@ import app.revanced.patches.youtube.utils.toolbar.hookToolBar import app.revanced.patches.youtube.utils.toolbar.toolBarHookPatch import app.revanced.patches.youtube.video.information.hookShortsVideoInformation import app.revanced.patches.youtube.video.information.videoInformationPatch +import app.revanced.patches.youtube.video.playbackstart.PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.video.playbackstart.playbackStartDescriptorPatch +import app.revanced.patches.youtube.video.playbackstart.playbackStartVideoIdReference import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId import app.revanced.patches.youtube.video.videoid.videoIdPatch import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT @@ -569,6 +572,8 @@ val shortsComponentPatch = bytecodePatch( shortsToolBarPatch, lithoFilterPatch, + navigationBarHookPatch, + playbackStartDescriptorPatch, playerTypeHookPatch, sharedResourceIdPatch, textComponentPatch, @@ -874,6 +879,45 @@ val shortsComponentPatch = bytecodePatch( // endregion + // region patch for open Shorts in regular player + + fun extensionInstructions(playbackStartRegister: Int, freeRegister: Int) = + """ + invoke-virtual { v$playbackStartRegister }, $playbackStartVideoIdReference + move-result-object v$freeRegister + invoke-static { v$freeRegister }, $SHORTS_CLASS_DESCRIPTOR->openShortInRegularPlayer(Ljava/lang/String;)Z + move-result v$freeRegister + if-eqz v$freeRegister, :disabled + return-void + :disabled + nop + """ + + if (is_19_25_or_greater) { + shortsPlaybackIntentFingerprint.methodOrThrow().addInstructionsWithLabels( + 0, + """ + move-object/from16 v0, p1 + ${extensionInstructions(0, 1)} + """ + ) + } else { + shortsPlaybackIntentLegacyFingerprint.methodOrThrow().apply { + val index = indexOfFirstInstructionOrThrow { + getReference()?.returnType == PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR + } + val freeRegister = getInstruction(index).registerC + val playbackStartRegister = getInstruction(index + 1).registerA + + addInstructionsWithLabels( + index + 2, + extensionInstructions(playbackStartRegister, freeRegister) + ) + } + } + + // endregion + addLithoFilter(BUTTON_FILTER_CLASS_DESCRIPTOR) addLithoFilter(SHELF_FILTER_CLASS_DESCRIPTOR) addLithoFilter(RETURN_YOUTUBE_CHANNEL_NAME_FILTER_CLASS_DESCRIPTOR) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/Fingerprints.kt index 1ce5d5dde..a8408ede6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/Fingerprints.kt @@ -10,7 +10,7 @@ import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference /** - * This fingerprint is compatible with all YouTube versions after v18.15.40. + * YouTube v18.15.40 ~ YouTube 19.46.42 */ internal val userWasInShortsABConfigFingerprint = legacyFingerprint( name = "userWasInShortsABConfigFingerprint", @@ -27,10 +27,35 @@ internal fun indexOfOptionalInstruction(method: Method) = getReference().toString() == "Lj${'$'}/util/Optional;->of(Ljava/lang/Object;)Lj${'$'}/util/Optional;" } +/** + * YouTube 19.47.53 ~ + */ +internal val userWasInShortsABConfigAlternativeFingerprint = legacyFingerprint( + name = "userWasInShortsABConfigAlternativeFingerprint", + returnType = "V", + parameters = listOf("I"), + opcodes = listOf(Opcode.OR_INT_LIT8), + strings = listOf("alias", "null"), +) + +/** + * ~ YouTube 19.50.42 + */ internal val userWasInShortsFingerprint = legacyFingerprint( name = "userWasInShortsFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Ljava/lang/Object;"), strings = listOf("Failed to read user_was_in_shorts proto after successful warmup") +) + +/** + * YouTube 20.02.08 ~ + */ +internal val userWasInShortsAlternativeFingerprint = legacyFingerprint( + name = "userWasInShortsAlternativeFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Ljava/lang/Object;"), + strings = listOf("userIsInShorts: ") ) \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt index ea7fe70ea..bfbc72f85 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt @@ -1,20 +1,28 @@ package app.revanced.patches.youtube.shorts.startupshortsreset +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.removeInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.SHORTS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.patch.PatchList.DISABLE_RESUMING_SHORTS_ON_STARTUP +import app.revanced.patches.youtube.utils.playservice.is_19_46_or_greater +import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater +import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch +import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -27,12 +35,14 @@ val resumingShortsOnStartupPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn(settingsPatch) + dependsOn( + settingsPatch, + versionCheckPatch, + ) execute { - userWasInShortsABConfigFingerprint.methodOrThrow().apply { - val startIndex = indexOfOptionalInstruction(this) + fun MutableMethod.hookUserWasInShortsABConfig(startIndex: Int) { val walkerIndex = implementation!!.instructions.let { val subListIndex = it.subList(startIndex, startIndex + 20).indexOfFirst { instruction -> @@ -64,29 +74,65 @@ val resumingShortsOnStartupPatch = bytecodePatch( } } - userWasInShortsFingerprint.methodOrThrow().apply { - val listenableInstructionIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_INTERFACE && - getReference()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" && - getReference()?.name == "isDone" + if (is_19_46_or_greater) { + userWasInShortsABConfigAlternativeFingerprint.methodOrThrow().apply { + val stringIndex = indexOfFirstStringInstructionOrThrow("null") + val startIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.OR_INT_LIT8) + hookUserWasInShortsABConfig(startIndex) } - val originalInstructionRegister = - getInstruction(listenableInstructionIndex).registerC - val freeRegister = - getInstruction(listenableInstructionIndex + 1).registerA + } else { + userWasInShortsABConfigFingerprint.methodOrThrow().apply { + val startIndex = indexOfOptionalInstruction(this) + hookUserWasInShortsABConfig(startIndex) + } + } - addInstructionsWithLabels( - listenableInstructionIndex + 1, - """ - invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z - move-result v$freeRegister - if-eqz v$freeRegister, :show - return-void - :show - invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z + if (is_20_02_or_greater) { + userWasInShortsAlternativeFingerprint.matchOrThrow().let { + it.method.apply { + val stringIndex = it.stringMatches!!.first().index + val booleanValueIndex = indexOfFirstInstructionReversedOrThrow(stringIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "booleanValue" + } + val booleanValueRegister = + getInstruction(booleanValueIndex + 1).registerA + + addInstructions( + booleanValueIndex + 2, """ + invoke-static {v$booleanValueRegister}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z + move-result v$booleanValueRegister + """ + ) + } + } + } else { + userWasInShortsFingerprint.methodOrThrow().apply { + val listenableInstructionIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + opcode == Opcode.INVOKE_INTERFACE && + reference?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" && + reference.name == "isDone" + } + val originalInstructionRegister = + getInstruction(listenableInstructionIndex).registerC + val freeRegister = + getInstruction(listenableInstructionIndex + 1).registerA + + addInstructionsWithLabels( + listenableInstructionIndex + 1, """ - ) - removeInstruction(listenableInstructionIndex) + invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z + move-result v$freeRegister + if-eqz v$freeRegister, :show + return-void + :show + invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z + """ + ) + removeInstruction(listenableInstructionIndex) + } + } // region add settings diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt index d55486456..89aa98555 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt @@ -27,14 +27,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val bottomSheetMenuItemBuilderFingerprint = legacyFingerprint( name = "bottomSheetMenuItemBuilderFingerprint", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "L", parameters = listOf("L"), opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT + Opcode.IGET, + Opcode.AND_INT_LIT16, + Opcode.IF_EQZ, ), strings = listOf("Text missing for BottomSheetMenuItem."), customFingerprint = { method, _ -> @@ -251,9 +249,19 @@ internal val youtubeControlsOverlayFingerprint = legacyFingerprint( fadeDurationFast, insetOverlayViewLayout, scrimOverlay, - seekUndoEduOverlayStub + // Removed in YouTube 20.02.38+ + // seekUndoEduOverlayStub ), + customFingerprint = { method, _ -> + indexOfFocusableInTouchModeInstruction(method) >= 0 + } ) +internal fun indexOfFocusableInTouchModeInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setFocusableInTouchMode" + } + const val PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR = "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt new file mode 100644 index 000000000..e8607bd69 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt @@ -0,0 +1,67 @@ +package app.revanced.patches.youtube.utils.engagement + +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.youtube.utils.engagementPanelBuilderFingerprint +import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch +import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversed +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +private lateinit var hideEngagementPanelMethod: MutableMethod +private var showEngagementPanelMethods = mutableListOf() + +val engagementPanelHookPatch = bytecodePatch( + description = "engagementPanelHookPatch" +) { + dependsOn(sharedResourceIdPatch) + + execute { + engagementPanelBuilderFingerprint.matchOrThrow().let { + it.classDef.methods.filter { method -> + method.indexOfEngagementPanelBuilderInstruction(it.method) >= 0 + }.forEach { method -> + showEngagementPanelMethods.add(method) + } + } + + hideEngagementPanelMethod = + engagementPanelUpdateFingerprint.methodOrThrow(engagementPanelBuilderFingerprint) + } +} + +private fun Method.indexOfEngagementPanelBuilderInstruction(targetMethod: MutableMethod) = + indexOfFirstInstructionReversed { + opcode == Opcode.INVOKE_DIRECT && + MethodUtil.methodSignaturesMatch( + targetMethod, + getReference()!! + ) + } + +internal fun hookEngagementPanelState(classDescriptor: String) { + showEngagementPanelMethods.forEach { method -> + method.apply { + val index = indexOfEngagementPanelBuilderInstruction(this) + val register = getInstruction(index + 1).registerA + + addInstruction( + index + 2, + "invoke-static {v$register}, $classDescriptor->showEngagementPanel(Ljava/lang/Object;)V" + ) + } + } + + hideEngagementPanelMethod.addInstruction( + 0, + "invoke-static {}, $classDescriptor->hideEngagementPanel()V" + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/Fingerprints .kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/Fingerprints .kt new file mode 100644 index 000000000..855f89fd8 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/Fingerprints .kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.utils.engagement + +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal val engagementPanelUpdateFingerprint = legacyFingerprint( + name = "engagementPanelUpdateFingerprint", + returnType = "V", + accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, + parameters = listOf("L", "Z"), + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference().toString() == "Ljava/util/ArrayDeque;->pop()Ljava/lang/Object;" + } >= 0 + } +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt index a6ead82f6..7dcb6f3bf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt @@ -98,19 +98,25 @@ val cairoFragmentPatch = bytecodePatch( settingsFragmentSyntheticFingerprint.methodOrThrow().apply { val literalIndex = indexOfFirstLiteralInstructionOrThrow(settingsFragmentCairo) - val fragmentStyleIndex = indexOfFirstInstructionOrThrow(literalIndex) { + val fragmentStylePrimaryIndex = indexOfFirstInstructionOrThrow(literalIndex) { val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL_RANGE && reference?.returnType == "V" && reference.parameterTypes.firstOrNull() == "Ljava/lang/String;" } - val fragmentStyleMethod = getWalkerMethod(fragmentStyleIndex) + val fragmentStyleSecondaryIndex = indexOfFirstInstructionOrThrow(literalIndex) { + val reference = getReference() + opcode == Opcode.INVOKE_VIRTUAL && + reference?.returnType == "V" && + reference.parameterTypes == listOf("Ljava/util/List;", "Landroidx/preference/Preference;") + } arrayOf( // Load cairo fragment xml. this, // Set style to cairo preference. - fragmentStyleMethod + getWalkerMethod(fragmentStylePrimaryIndex), + getWalkerMethod(fragmentStyleSecondaryIndex) ).forEach { method -> method.disableCairoFragmentConfig() } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt index 489b38a11..b40668b3f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt @@ -7,56 +7,91 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.utils.extension.Constants.EXTENSION_PATH import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch +import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater +import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.util.addStaticFieldToExtension import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference +import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.TypeReference +import kotlin.collections.mutableListOf private const val EXTENSION_VIDEO_UTILS_CLASS_DESCRIPTOR = "$EXTENSION_PATH/utils/VideoUtils;" -internal lateinit var enterFullscreenMethod: MutableMethod +internal var enterFullscreenMethods = mutableListOf() val fullscreenButtonHookPatch = bytecodePatch( description = "fullscreenButtonHookPatch" ) { - dependsOn(sharedExtensionPatch) + dependsOn( + sharedExtensionPatch, + versionCheckPatch, + ) execute { - val (referenceClass, fullscreenActionClass) = with( - nextGenWatchLayoutFullscreenModeFingerprint.methodOrThrow() - ) { - val targetIndex = indexOfFirstInstructionReversedOrThrow { - opcode == Opcode.INVOKE_DIRECT && - getReference()?.parameterTypes?.size == 2 - } - val targetReference = - getInstruction(targetIndex).reference as MethodReference + fun getParameters(): Pair { + nextGenWatchLayoutFullscreenModeFingerprint.methodOrThrow().apply { + val methodIndex = indexOfFirstInstructionReversedOrThrow { + opcode == Opcode.INVOKE_DIRECT && + getReference()?.parameterTypes?.size == 2 + } + val fieldIndex = + indexOfFirstInstructionReversedOrThrow(methodIndex, Opcode.IGET_OBJECT) + val fullscreenActionClass = + (getInstruction(fieldIndex).reference as FieldReference).type - Pair(targetReference.definingClass, targetReference.parameterTypes[1].toString()) + if (is_20_02_or_greater) { + val setAnimatorListenerIndex = + indexOfFirstInstructionOrThrow(methodIndex, Opcode.INVOKE_VIRTUAL) + getWalkerMethod(setAnimatorListenerIndex).apply { + val addListenerIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "addListener" + } + val animatorListenerAdapterClass = getInstruction( + indexOfFirstInstructionReversedOrThrow(addListenerIndex, Opcode.NEW_INSTANCE) + ).reference.toString() + return Pair( + findMethodOrThrow(animatorListenerAdapterClass) { parameters.isEmpty() }, + fullscreenActionClass + ) + } + } else { + val animatorListenerClass = + (getInstruction(methodIndex).reference as MethodReference).definingClass + return Pair( + findMethodOrThrow(animatorListenerClass) { parameters == listOf("I") }, + fullscreenActionClass + ) + } + } } + val (animatorListenerMethod, fullscreenActionClass) = getParameters() + val (enterFullscreenReference, exitFullscreenReference, opcodeName) = - with(findMethodOrThrow(referenceClass) { parameters == listOf("I") }) { + with(animatorListenerMethod) { val enterFullscreenIndex = indexOfFirstInstructionOrThrow { val reference = getReference() reference?.returnType == "V" && reference.definingClass == fullscreenActionClass && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } val exitFullscreenIndex = indexOfFirstInstructionReversedOrThrow { val reference = getReference() reference?.returnType == "V" && reference.definingClass == fullscreenActionClass && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } val enterFullscreenReference = @@ -68,18 +103,28 @@ val fullscreenButtonHookPatch = bytecodePatch( val enterFullscreenClass = (enterFullscreenReference as MethodReference).definingClass - enterFullscreenMethod = if (opcode == Opcode.INVOKE_INTERFACE) { - classes.find { classDef -> classDef.interfaces.contains(enterFullscreenClass) } - ?.let { classDef -> + if (opcode == Opcode.INVOKE_INTERFACE) { + classes.forEach { classDef -> + if (enterFullscreenMethods.size >= 2) + return@forEach + if (!classDef.interfaces.contains(enterFullscreenClass)) + return@forEach + + val enterFullscreenMethod = proxy(classDef) .mutableClass .methods .find { method -> method.name == enterFullscreenReference.name } - } ?: throw PatchException("No matching classes: $enterFullscreenClass") - } else { - findMethodOrThrow(enterFullscreenClass) { - name == enterFullscreenReference.name + ?: throw PatchException("No matching classes: $enterFullscreenClass") + + enterFullscreenMethods.add(enterFullscreenMethod) } + } else { + val enterFullscreenMethod = + findMethodOrThrow(enterFullscreenClass) { + name == enterFullscreenReference.name + } + enterFullscreenMethods.add(enterFullscreenMethod) } Triple( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt index f7e622b80..41a56de93 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt @@ -17,6 +17,18 @@ internal enum class PatchList( "Bypass image region restrictions", "Adds an option to use a different host for static images, so that images blocked in some countries can be received." ), + BYPASS_URL_REDIRECTS( + "Bypass URL redirects", + "Adds an option to bypass URL redirects and open the original URL directly." + ), + CHANGE_LAYOUT( + "Change layout", + "Adds an option to change the dp in order to use a tablet or phone layout." + ), + CHANGE_LIVE_RING_CLICK_ACTION( + "Change live ring click action", + "Adds an option to open the channel instead of the live stream when clicking on the live ring." + ), CHANGE_PLAYER_FLYOUT_MENU_TOGGLES( "Change player flyout menu toggles", "Adds an option to use text toggles instead of switch toggles within the additional settings menu." @@ -39,7 +51,7 @@ internal enum class PatchList( ), CUSTOM_BRANDING_NAME_FOR_YOUTUBE( "Custom branding name for YouTube", - "Renames the YouTube app to the name specified in patch options." + "Changes the YouTube app name to the name specified in patch options." ), CUSTOM_DOUBLE_TAP_LENGTH( "Custom double tap length", @@ -79,24 +91,16 @@ internal enum class PatchList( ), ENABLE_OPUS_CODEC( "Enable OPUS codec", - "Adds an options to enable the OPUS audio codec if the player response includes it." + "Adds an option to enable the OPUS audio codec if the player response includes it." ), ENABLE_DEBUG_LOGGING( "Enable debug logging", "Adds an option to enable debug logging." ), - ENABLE_EXTERNAL_BROWSER( - "Enable external browser", - "Adds an option to always open links in your browser instead of in the in-app-browser." - ), ENABLE_GRADIENT_LOADING_SCREEN( "Enable gradient loading screen", "Adds an option to enable the gradient loading screen." ), - ENABLE_OPEN_LINKS_DIRECTLY( - "Enable open links directly", - "Adds an option to skip over redirection URLs in external links." - ), FORCE_HIDE_PLAYER_BUTTONS_BACKGROUND( "Force hide player buttons background", "Removes, at compile time, the dark background surrounding the video player controls." @@ -157,10 +161,6 @@ internal enum class PatchList( "Hook download actions", "Adds support to download videos with an external downloader app using the in-app download button." ), - LAYOUT_SWITCH( - "Layout switch", - "Adds an option to spoof the dpi in order to use a tablet or phone layout." - ), MATERIALYOU( "MaterialYou", "Applies the MaterialYou theme for Android 12+ devices." @@ -173,6 +173,10 @@ internal enum class PatchList( "Navigation bar components", "Adds options to hide or change components related to the navigation bar." ), + OPEN_LINKS_EXTERNALLY( + "Open links externally", + "Adds an option to always open links in your browser instead of the in-app browser." + ), OVERLAY_BUTTONS( "Overlay buttons", "Adds options to display useful overlay buttons in the video player." @@ -199,7 +203,7 @@ internal enum class PatchList( ), SANITIZE_SHARING_LINKS( "Sanitize sharing links", - "Adds an option to remove tracking query parameters from URLs when sharing links." + "Adds an option to sanitize sharing links by removing tracking query parameters." ), SEEKBAR_COMPONENTS( "Seekbar components", @@ -213,6 +217,10 @@ internal enum class PatchList( "Shorts components", "Adds options to hide or change components related to YouTube Shorts." ), + SNACK_BAR_COMPONENTS( + "Snack bar components", + "Adds options to hide or change components related to the snack bar." + ), SPONSORBLOCK( "SponsorBlock", "Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content." diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt index e0e54f204..5dbf43ec9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt @@ -9,7 +9,7 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch -import app.revanced.patches.youtube.utils.fullscreen.enterFullscreenMethod +import app.revanced.patches.youtube.utils.fullscreen.enterFullscreenMethods import app.revanced.patches.youtube.utils.fullscreen.fullscreenButtonHookPatch import app.revanced.patches.youtube.utils.playerButtonsResourcesFingerprint import app.revanced.patches.youtube.utils.playerButtonsVisibilityFingerprint @@ -122,10 +122,12 @@ private val playerControlsBytecodePatch = bytecodePatch( // Reproduced only in RVX if (is_19_23_or_greater) { - enterFullscreenMethod.addInstruction( - 0, - "invoke-static {}, $EXTENSION_PLAYER_CONTROLS_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediately()V" - ) + enterFullscreenMethods.forEach { method -> + method.addInstruction( + 0, + "invoke-static {}, $EXTENSION_PLAYER_CONTROLS_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediately()V" + ) + } } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index f7cdcea1f..d05423dea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -51,6 +51,10 @@ var is_19_44_or_greater = false private set var is_19_46_or_greater = false private set +var is_19_49_or_greater = false + private set +var is_20_02_or_greater = false + private set val versionCheckPatch = resourcePatch( description = "versionCheckPatch", @@ -89,5 +93,7 @@ val versionCheckPatch = resourcePatch( is_19_43_or_greater = 244405000 <= playStoreServicesVersion is_19_44_or_greater = 244505000 <= playStoreServicesVersion is_19_46_or_greater = 244705000 <= playStoreServicesVersion + is_19_49_or_greater = 245005000 <= playStoreServicesVersion + is_20_02_or_greater = 250299000 <= playStoreServicesVersion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index 64a23bfc0..bf423d64a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -83,6 +83,8 @@ var easySeekEduContainer = -1L private set var editSettingsAction = -1L private set +var elementsImage = -1L + private set var endScreenElementLayoutCircle = -1L private set var endScreenElementLayoutIcon = -1L @@ -119,6 +121,8 @@ var insetOverlayViewLayout = -1L private set var interstitialsContainer = -1L private set +var insetElementsWrapper = -1L + private set var menuItemView = -1L private set var metaPanel = -1L @@ -239,7 +243,8 @@ var ytPremiumWordMarkHeader = -1L private set var ytWordMarkHeader = -1L private set - +var ytYoutubeMagenta = -1L + private set internal val sharedResourceIdPatch = resourcePatch( description = "sharedResourceIdPatch" @@ -383,6 +388,10 @@ internal val sharedResourceIdPatch = resourcePatch( STRING, "edit_settings_action" ] + elementsImage = resourceMappings[ + ID, + "elements_image" + ] endScreenElementLayoutCircle = resourceMappings[ LAYOUT, "endscreen_element_layout_circle" @@ -455,6 +464,10 @@ internal val sharedResourceIdPatch = resourcePatch( ID, "interstitials_container" ] + insetElementsWrapper = resourceMappings[ + LAYOUT, + "inset_elements_wrapper" + ] menuItemView = resourceMappings[ ID, "menu_item_view" @@ -695,5 +708,9 @@ internal val sharedResourceIdPatch = resourcePatch( ATTR, "ytWordmarkHeader" ] + ytYoutubeMagenta = resourceMappings[ + COLOR, + "yt_youtube_magenta", + ] } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/Fingerprints.kt index 79bdce50a..b43b9f9eb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/Fingerprints.kt @@ -2,11 +2,9 @@ package app.revanced.patches.youtube.utils.settings import app.revanced.patches.youtube.utils.resourceid.appearance import app.revanced.util.fingerprint.legacyFingerprint -import com.android.tools.smali.dexlib2.Opcode internal val themeSetterSystemFingerprint = legacyFingerprint( name = "themeSetterSystemFingerprint", returnType = "L", - opcodes = listOf(Opcode.RETURN_OBJECT), literals = listOf(appearance), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt index 82cf48b41..5a0854b44 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt @@ -1,12 +1,9 @@ package app.revanced.patches.youtube.utils.settings -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.extension.Constants.EXTENSION_UTILS_CLASS_DESCRIPTOR import app.revanced.patches.shared.extension.Constants.EXTENSION_UTILS_PATH import app.revanced.patches.shared.mainactivity.injectConstructorMethodCall @@ -23,11 +20,14 @@ import app.revanced.patches.youtube.utils.patch.PatchList.SETTINGS_FOR_YOUTUBE import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.util.ResourceGroup +import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.copyResources import app.revanced.util.copyXmlNode -import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.findInstructionIndicesReversedOrThrow +import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.removeStringsElements import app.revanced.util.valueOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import org.w3c.dom.Element import java.nio.file.Files @@ -50,23 +50,16 @@ private val settingsBytecodePatch = bytecodePatch( ) execute { - fun MutableMethod.injectCall(index: Int) { - val register = getInstruction(index).registerA - - addInstructions( - index + 1, """ - invoke-static {v$register}, $EXTENSION_THEME_METHOD_DESCRIPTOR - return-object v$register - """ - ) - removeInstruction(index) - } // apply the current theme of the settings page - themeSetterSystemFingerprint.matchOrThrow().let { - it.method.apply { - injectCall(implementation!!.instructions.size - 1) - injectCall(it.patternMatch!!.startIndex) + themeSetterSystemFingerprint.methodOrThrow().apply { + findInstructionIndicesReversedOrThrow(Opcode.RETURN_OBJECT).forEach { index -> + val register = getInstruction(index).registerA + + addInstructionsAtControlFlowLabel( + index, + "invoke-static { v$register }, $EXTENSION_THEME_METHOD_DESCRIPTOR" + ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index 288fc190c..fa9d1075c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -249,11 +249,13 @@ val videoInformationPatch = bytecodePatch( ) val literalIndex = indexOfFirstLiteralInstructionOrThrow(45368273L) - val walkerIndex = - indexOfFirstInstructionReversedOrThrow( - literalIndex, - Opcode.INVOKE_VIRTUAL_RANGE - ) + val walkerIndex = indexOfFirstInstructionReversedOrThrow(literalIndex) { + val reference = getReference() + (opcode == Opcode.INVOKE_VIRTUAL || opcode == Opcode.INVOKE_VIRTUAL_RANGE) && + reference?.definingClass == definingClass && + reference.parameterTypes.isEmpty() && + reference.returnType == "V" + } videoEndMethod = getWalkerMethod(walkerIndex) } @@ -419,7 +421,10 @@ val videoInformationPatch = bytecodePatch( # Get the container class field. iget-object v0, v2, $setPlaybackSpeedContainerClassFieldReference - + + # For some reason, in YouTube 19.44.39 this value is sometimes null. + if-eqz v0, :ignore + # Get the field from its class. iget-object v1, v0, $setPlaybackSpeedClassFieldReference diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/Fingerprints.kt new file mode 100644 index 000000000..c196c1f44 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/Fingerprints.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.youtube.video.playbackstart + +import app.revanced.util.fingerprint.legacyFingerprint + +const val PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR = + "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" + +/** + * Purpose of this method is not clear, and it's only used to identify + * the obfuscated name of the videoId() method in PlaybackStartDescriptor. + */ +internal val playbackStartFeatureFlagFingerprint = legacyFingerprint( + name = "playbackStartFeatureFlagFingerprint", + returnType = "Z", + parameters = listOf(PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR), + literals = listOf(45380134L) +) + + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt new file mode 100644 index 000000000..c2dbc260a --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt @@ -0,0 +1,33 @@ +package app.revanced.patches.youtube.video.playbackstart + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.Reference + +internal lateinit var playbackStartVideoIdReference: Reference + +val playbackStartDescriptorPatch = bytecodePatch( + description = "playbackStartDescriptorPatch" +) { + dependsOn(sharedResourceIdPatch) + + execute { + // Find the obfuscated method name for PlaybackStartDescriptor.videoId() + playbackStartFeatureFlagFingerprint.methodOrThrow().apply { + val stringMethodIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.definingClass == PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR + && reference.returnType == "Ljava/lang/String;" + } + + playbackStartVideoIdReference = getInstruction(stringMethodIndex).reference + } + } +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt index 02e4b048f..822f8e6aa 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt @@ -13,20 +13,12 @@ private val PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST = listOf( "I", "I" ) -private val PLAYER_PARAMETER_ENDS_WITH_PARAMETER_LIST = listOf( - "Ljava/util/Set;", - "Ljava/lang/String;", - "Ljava/lang/String;", - "L", - "Z", // Appears to indicate if the video id is being opened or is currently playing. - "Z", - "Z" -) internal val playerParameterBuilderFingerprint = legacyFingerprint( name = "playerParameterBuilderFingerprint", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "L", + strings = listOf("psps"), // 19.22 and earlier parameters are: // "Ljava/lang/String;", // VideoId. // "[B", @@ -60,20 +52,41 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint( customFingerprint = custom@{ method, _ -> val parameterTypes = method.parameterTypes val parameterSize = parameterTypes.size - if (parameterSize != 13 && parameterSize != 14) { + if (parameterSize < 13) { return@custom false } val startsWithMethodParameterList = parameterTypes.slice(0..5) - val endsWithMethodParameterList = parameterTypes.slice(parameterSize - 7..Hides the Terms of Service container. - - Action Bar + + Action bar Hide Like and Dislike buttons Hides the Like and Dislike buttons. It does not work in the old player layout. @@ -65,19 +65,19 @@ Limitations: Hide general ads Hides general ads. Hide media ads - Hides ads before playing media. + Hides the ads that play during media playback. Hide paid promotion label Hides the paid promotion label. Hide premium promotion popups - Hides premium promotion popups. + Hides the premium promotion popups. Hide premium renewal banner Hides the premium renewal banner. Hide promotion alert banner Hides the promotion alert banner. - - Flyout Menu + + Flyout menu Add Trim silence switch "Adds a Trim silence switch to the playback speed flyout menu. @@ -196,11 +196,14 @@ This does not bypass the age restriction. It just accepts it automatically."7.16.53 - Restore old action bar - - Navigation Bar + + Navigation bar - Enable black navigation bar - Sets the navigation bar color to black. + Enable custom navigation bar color + Sets the navigation bar color. + Custom navigation bar color value + Type the hex code of the navigation bar color. + Invalid navigation bar color value. Hide Home button Hides the Home button. Hide Samples button @@ -214,7 +217,7 @@ This does not bypass the age restriction. It just accepts it automatically."Hide navigation bar Hides the navigation bar. Hide navigation labels - Hides the label below each navigation buttons. + Hides the label below each navigation button. @@ -225,7 +228,7 @@ This does not bypass the age restriction. It just accepts it automatically."Add miniplayer previous button Adds a previous track button to the miniplayer. Change miniplayer color - Changes the miniplayer color to that of fullscreen player. + Changes the miniplayer color to match the fullscreen player. Change player background color Changes the player background color to black. Disable miniplayer gesture @@ -286,11 +289,11 @@ Some features may not work properly in the old player layout." Remember playback speed changes Remembers the last playback speed selected. Show a toast - Show a toast when changing the default playback speed. + Shows a toast when changing the default playback speed. Remember video quality changes Remembers the last video quality selected. Show a toast - Show a toast when changing the default video quality. + Shows a toast when changing the default video quality. Custom speeds must be less than %sx. Invalid custom playback speeds. Changing default speed to %s. @@ -340,7 +343,7 @@ Some features may not work properly in the old player layout." The daily quota for API keys on the free plan is 10,000, and 1 quota is used to replace a handle with a username for 1 comment. -Click to see how to issue a API key." +Click to see how to issue an API key." Issue YouTube Data API v3 developer key 1. Go to <a href=%1$s>Create a new project</a>.<br>2. Click the <b>CREATE</b> button.<br>3. Go to <a href=%2$s>YouTube Data API v3</a>.<br>4. Click the <b>ENABLE</b> button.<br>5. Click the <b>CREATE CREDENTIALS</b> button.<br>6. Select the <b>Public data</b> option.<br>7. Click the <b>NEXT</b> button.<br>8. Copy the API key.<br><br>※ API key should never be shared with others, so it is not included in Import / Export settings. @@ -349,7 +352,7 @@ Click to see how to issue a API key." SponsorBlock Enable SponsorBlock - SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos. + SponsorBlock is a crowdsourced system for skipping annoying parts of YouTube videos. Show a toast if API is unavailable Shows a toast if the SponsorBlock API is unavailable. Show a toast when skipping automatically @@ -413,7 +416,7 @@ Click to see how to issue a API key." Miscellaneous Import / Export settings - Import or export settings. + Import / Export RVX Music settings. Export settings to file Import settings from file @@ -430,9 +433,9 @@ Click to see how to issue a API key." Settings copied to clipboard. Bypass image region restrictions - Replaces the domain that is blocked in some regions so that playlist thumbnails, channel avatars, etc. can be received. + Bypasses the domain that is blocked in some regions so that playlist thumbnails, channel avatars, etc. can be received. Change share sheet - Change from in-app share sheet to system share sheet. + Changes the in-app share sheet to system share sheet. Disable Cairo splash animation Disables Cairo splash animation when the app starts up. Disable DRC audio @@ -453,13 +456,13 @@ Find the official song if a music video is detected playing from an album. Enable debug buffer logging Includes the buffer in the debug log. Enable OPUS codec - "Enable the OPUS codec if the player response includes the OPUS codec. + "Enables the OPUS codec if the player response includes it. Info: • Latest YouTube Music clients use the OPUS audio codec by default. • This is only valid for users spoofing with very old clients." Sanitize sharing links - Removes tracking query parameters from URLs when sharing links. + Sanitizes sharing links by removing tracking query parameters. Spoof client "Spoof the client to prevent playback issues. @@ -484,10 +487,10 @@ Info: Android Music Open default app settings - To open YouTube Music links in RVX Music, enable \'Open supported links\' and enable the supported web addresses. + To open YouTube Music links in RVX Music, enable Open supported links and enable all the Supported web addresses. Open GmsCore settings - Opens GmsCore settings. Then enable cloud messaging to receive notifications. + To receive notifications in RVX Music, enable Cloud Messaging. GmsCore is not installed. Install it. Action needed "GmsCore does not have permission to run in the background. @@ -503,3 +506,4 @@ Disabling battery optimizations for GmsCore will not negatively affect battery u Tap the continue button and allow optimization changes." Continue + diff --git a/patches/src/main/resources/music/translations/bg-rBG/strings.xml b/patches/src/main/resources/music/translations/bg-rBG/strings.xml index 0ede7da4a..f341cc8f3 100644 --- a/patches/src/main/resources/music/translations/bg-rBG/strings.xml +++ b/patches/src/main/resources/music/translations/bg-rBG/strings.xml @@ -17,7 +17,7 @@ Скрива имейл/@ник в менюто за промяна на акаунта. Скриване на информацията за поверителност Скриване на подробностите за поверителност / правила и условия. - + Лента с действия Скриване на бутоните за харесване и нехаресване Скрива бутоните „Харесвам“ и „Не харесвам“. Не работи в стария интерфейс на плейъра. @@ -59,7 +59,7 @@ Скрива изскачащи реклами Premium. Скриване на банера за подновяване на Premium Скриване на банера за подновяване на Premium. - + Падащо меню Добавете опция „Скриване на мълчанията“ "Добавя „Скриване на мълчанията“ към падащото меню „Скорост на възпроизвеждане“. @@ -169,10 +169,8 @@ Задайте желаната фалшива версия на приложението. 4.27.53 - Деактивира радио режима в регионите на Канада 6.11.52 -Изключва речта в реално време - + Лента за навигация - Включване на черна навигационна лента - Задава цвета на лентата за навигация на черен. Скриване на бутон за Начало Скрива бутона \"Начало\". Скриване на бутона \"навигация\" diff --git a/patches/src/main/resources/music/translations/bn/strings.xml b/patches/src/main/resources/music/translations/bn/strings.xml index 092ad74e4..b1eebe132 100644 --- a/patches/src/main/resources/music/translations/bn/strings.xml +++ b/patches/src/main/resources/music/translations/bn/strings.xml @@ -11,14 +11,14 @@ অ্যাকাউন্ট পরিবর্তনের হ্যান্ডল লুকায়। নীতিমালা কন্টেইনার লুকান সার্ভিস কন্টেইনারের নীতিমালা লুকায়। - + বাহিরের ডাউনলোডারের প্যাকেজ নাম আপনার ইনস্টল করা বাইরের ডাউনলোডার অ্যাপের প্যাকেজ নাম, যেমন NewPipe বা Seal %s ইনস্টল করা হয়নি। অনুগ্রপূর্বক এটি ইনস্টল করুন। সঙ্গীতের বিজ্ঞাপন লুকান ট্র্যাক চালু হওয়ার আগে বিজ্ঞাপনগুলি লুকান। - + কম্প্যাক্ট ডায়ালগ সক্রিয় করুন স্বয়ংক্রিয় ক্যাপশন বন্ধ করুন @@ -39,9 +39,7 @@ বিভাগ বার লুকান প্রধান পাতার উপর থেকে বিভাগ বার লুকান। অ্যাপ সংস্করণ স্পুফ করুন - - কালো নেভিগেশন বার সক্রিয় করুন - নেভিগেমন বার এর রং কালো করে। + নেভিগেশন বার লুকান নেভিগেশন বার লুকায়। নেভিগেশন বারের লেবেল লুকান diff --git a/patches/src/main/resources/music/translations/cs-rCZ/strings.xml b/patches/src/main/resources/music/translations/cs-rCZ/strings.xml index c4663088b..1a93c5201 100644 --- a/patches/src/main/resources/music/translations/cs-rCZ/strings.xml +++ b/patches/src/main/resources/music/translations/cs-rCZ/strings.xml @@ -11,14 +11,14 @@ Skrýt nabídku účtu Skryje prvky nabídky účtu pomocí vlastního filtru. Filtr nabídky účtu - + Název balíčku pro externí stahování Název balíčku externí nainstalované aplikace na stahování, jako jsou např. NewPipe nebo Seal %s není instalován. Prosím, nainstalujte jej. Skrýt hudební reklamy Skryje reklamy před přehráváním hudby. - + Povolit kompaktní dialogové okno Zakázat vynucené automatické titulky @@ -38,9 +38,7 @@ Skrýt lištu s kategoriemi Skryje lištu s hudebními kategoriemi z horní části domovské obrazovky. Zfalšovat verzi aplikace - - Povolit černou navigační lištu - Nastaví barvu navigačního panelu na černou. + Skrýt popisky navigačního panelu Skrýt popisky v navigačním panelu. diff --git a/patches/src/main/resources/music/translations/el-rGR/strings.xml b/patches/src/main/resources/music/translations/el-rGR/strings.xml index 3471ce0d4..82d2aab64 100644 --- a/patches/src/main/resources/music/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/music/translations/el-rGR/strings.xml @@ -18,7 +18,7 @@ Απόκρυψη του ψευδώνυμου στην εναλλαγή λογαριασμού. Απόκρυψη στοιχείων απορρήτου & όρων Απόκρυψη των στοιχείων απορρήτου / όρων και προϋποθέσεων. - + Γραμμή ενεργειών Απόκρυψη κουμπιών «Μου αρέσει» και «Δεν μου αρέσει» Απόκρυψη των κουμπιών «Μου αρέσει» και «Δεν μου αρέσει». Δεν λειτουργεί στην παλιά εμφάνιση της οθόνης αναπαραγωγής. @@ -56,7 +56,7 @@ Απόκρυψη γενικών διαφημίσεων Απόκρυψη των γενικών διαφημίσεων. Απόκρυψη διαφημίσεων μουσικής - Απόκρυψη διαφημίσεων πριν την αναπαραγωγή κομματιού. + Απόκρυψη διαφημίσεων που αναπαράγονται κατά την αναπαραγωγή πολυμέσων. Απόκρυψη ετικέτας προώθησης επί πληρωμή Απόκρυψη της ετικέτας προώθησης επί πληρωμή. Απόκρυψη παραθύρων προώθησης Premium @@ -65,7 +65,7 @@ Απόκρυψη του διαφημιστικού ανανέωσης YT Premium. Απόκρυψη ετικετών προειδοποίησης προώθησης Απόκρυψη των ετικετών προειδοποίησης προώθησης. - + Αναδυόμενο μενού ρυθμίσεων Ενεργοποίηση περικοπής σίγασης "Ενεργοποίηση της λειτουργίας «Περικοπή σίγασης» στο αναδυόμενο μενού αλλαγής ταχύτητας αναπαραγωγής. @@ -179,10 +179,13 @@ 4.27.53 - Απενεργοποίηση λειτουργίας ραδιοφώνου σε περιοχές του Καναδά 6.11.52 - Απενεργοποίηση στίχων σε πραγματικό χρόνο 7.16.53 - Επαναφορά παλιάς γραμμής ενεργειών - + Γραμμή πλοήγησης - Μαύρη γραμμής πλοήγησης - Ορισμός του χρώματος της γραμμής πλοήγησης σε μαύρο. + Προσαρμοσμένο χρώμα γραμμής πλοήγησης + Ορισμός του χρώματος της γραμμής πλοήγησης. + Τιμή χρώματος γραμμής πλοήγησης + Πληκτρολογήστε τον κωδικό hex του χρώματος της γραμμής πλοήγησης. + Μη έγκυρη τιμή χρώματος γραμμής πλοήγησης. Απόκρυψη κουμπιού «Αρχική» Απόκρυψη της καρτέλας «Αρχική». Απόκρυψη κουμπιού «Δείγματα» @@ -368,7 +371,7 @@ Διάφορα Εισαγωγή / Εξαγωγή - Εισαγωγή ή εξαγωγή των ρυθμίσεών σας. + Εισαγωγή ή εξαγωγή των ρυθμίσεών RVX σας. Εξαγωγή ρυθμίσεων σε αρχείο Εισαγωγή ρυθμίσεων από αρχείο Εισαγωγή / Εξαγωγή ρυθμίσεων ως κείμενο @@ -384,7 +387,7 @@ Παράκαμψη μπλοκαρίσματος φόρτωσης εικόνων Αντικατάσταση του domain για την φόρτωση εικόνων όπου είναι μπλοκαρισμένες σε ορισμένες περιοχές ώστε να μπορούν να ληφθούν μικρογραφίες βίντεο, εικόνες δημοσιεύσεων, κλπ. Αλλαγή μενού κοινοποίησης - Αλλαγή του μενού κοινοποίησης σε αυτό του συστήματος σας αντί του YouTube Music. + Αλλαγή του μενού κοινοποίησης σε αυτό του συστήματος σας αντί αυτού της εφαρμογής. Απενεργοποίηση εφέ εκκίνησης θέματος Cairo Απενεργοποίηση των εφέ θέματος Cairo κατά την εκκίνηση της εφαρμογής. Απενεργοποίηση ήχου DRC @@ -407,7 +410,7 @@ Ενεργοποίηση κωδικοποιητή opus "Ενεργοποίηση του κωδικοποιητή OPUS αν η ανταπόκριση του προγράμματος αναπαραγωγής τον περιλαμβάνει. -Πληροφορία: Οι τελευταίες εκδόσεις Android χρησιμοποιούν τον κωδικοποιητή opus από προεπιλογή, οπότε αυτή η ρύθμιση ισχύει μόνο για χρήστες που χρησιμοποιούν τη λειτουργία παραποίησης έκδοσης εφαρμογής, σε πολύ παλιές εκδόσεις." +Οι τελευταίες εκδόσεις Android χρησιμοποιούν τον κωδικοποιητή opus από προεπιλογή, οπότε αυτή η ρύθμιση ισχύει μόνο για χρήστες που χρησιμοποιούν τη λειτουργία παραποίησης έκδοσης εφαρμογής, σε πολύ παλιές εκδόσεις." Καθαρισμός συνδέσμων κοινοποίησης Αφαίρεση των παραμέτρων παρακολούθησης από τις διευθύνσεις URL κατά την κοινοποίηση συνδέσμων. Παραποίηση προγράμματος πελάτη @@ -433,8 +436,8 @@ Android Music Άνοιγμα ρυθμίσεων προεπιλεγμένων εφαρμογών Για να ανοίγουν οι συνδέσμοι YouTube Music στο RVX Music, ενεργοποιήστε το «Άνοιγμα υποστηριζόμενων συνδέσμων» και τις υποστηριζόμενες διευθύνσεις ιστού. - Άνοιγμα του MicroG GmsCore - Ενεργοποιήστε τις ρυθμίσεις cloud messaging για να λαμβάνετε ειδοποιήσεις. + Άνοιγμα ρυθμίσεων του MicroG GmsCore + Για να λαμβάνετε ειδοποιήσεις στο RVX Music, ενεργοποιήστε τις ρυθμίσεις Cloud Messaging. Το MicroG GmsCore δεν είναι εγκατεστημένο. Εγκαταστήστε το. Απαιτείται ενέργεια "Το MicroG GmsCore δεν έχει άδεια να τρέχει στο παρασκήνιο. diff --git a/patches/src/main/resources/music/translations/es-rES/strings.xml b/patches/src/main/resources/music/translations/es-rES/strings.xml index c7c2bda18..39bc4d864 100644 --- a/patches/src/main/resources/music/translations/es-rES/strings.xml +++ b/patches/src/main/resources/music/translations/es-rES/strings.xml @@ -18,7 +18,7 @@ Oculta el asa en el conmutador de cuenta. Ocultar contenedor de términos Oculta los términos del contenedor de servicio. - + Barra de Acción Ocultar botones Me gusta y No me gusta Oculta los botones \"Me gusta\" y \"no me gusta\". No funciona en el diseño del reproductor antiguo. @@ -62,7 +62,7 @@ Descarga %2$s desde el sitio web." Oculta banner de renovación premium. Ocultar banner de alerta de promoción Oculta el banner de alerta de promoción. - + Menú desplegable Añadir interruptor para recortar silencios "Añade un interruptor para recortar silencios en el menú desplegable de velocidad de reproducción. @@ -176,10 +176,8 @@ Esto no evita la restricción de edad. Solo la acepta automáticamente."4.27.53 - Desactivar el modo radio en las regiones canadienses 6.11.52 - Desactivar letras en tiempo real 7.16.53 - Restaurar la antigua barra de acción - + Barra de navegación - Activar barra de navegación negra - Establece el color de la barra de navegación en negro. Ocultar botón de Inicio Oculta el botón de Inicio. Ocultar botón de Samples diff --git a/patches/src/main/resources/music/translations/fr-rFR/strings.xml b/patches/src/main/resources/music/translations/fr-rFR/strings.xml index a107379a8..5ed471cd8 100644 --- a/patches/src/main/resources/music/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/music/translations/fr-rFR/strings.xml @@ -18,7 +18,7 @@ Masque l\'identifiant dans le menu \"compte\". Masquer le conteneur de termes Masque le conteneur des conditions d\'utilisation. - + Barre d\'action Masquer les boutons \"J\'aime\" et \"Je n\'aime pas\" Masque les boutons \"J\'aime\" et \"Je n\'aime pas\". Ne fonctionne pas sur l\'ancienne interface du lecteur. @@ -62,7 +62,7 @@ Veuillez télécharger %2$s à partir du site web." Masque la bannière \"Renouveler votre abonnement Premium\". Masquer la bannière d\'alerte de promotion Masque la bannière d\'alerte de promotion. - + Menu déroulant Ajouter une option \"Masquer les silences\" "Ajoute \"Masquer les silences\" dans le menu \"Vitesse de lecture\" du menu déroulant. @@ -174,10 +174,8 @@ Cela ne contourne pas la restriction d'âge, mais le confirme automatiquement."< 4.27.53 - Désactive le mode radio dans les régions canadiennes 6.11.52 - Désactive les paroles en temps réel 7.16.53 - Restaurer l\'ancienne barre d\'action - + Barre de navigation - Activer la barre de navigation en noir - Modifie la couleur de la barre de navigation en noir. Masquer le bouton \"Accueil\" Masque le bouton \"Accueil\". Masquer le bouton \"Samples\" diff --git a/patches/src/main/resources/music/translations/hu-rHU/strings.xml b/patches/src/main/resources/music/translations/hu-rHU/strings.xml index 38aecea44..47f00b78d 100644 --- a/patches/src/main/resources/music/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/music/translations/hu-rHU/strings.xml @@ -18,7 +18,7 @@ Elrejti a felhasználónevedet a fiók menüben. Feltételek rész elrejtése Elrejti a Szolgáltatási feltételeket a fiókmenüben. - + Műveletsáv A tetszik és nem tetszik gombok elrejtése Elrejti a tetszik és nem tetszik gombokat. Nem működik a régi lejátszóval. @@ -53,16 +53,16 @@ Töltsd le a(z) %2$s weboldalról." Általános hirdetések elrejtése Elrejti az általános hirdetéseket. Zenei hirdetések elrejtése - Elrejti a hirdetéseket a zene lejátszása előtt. + Elrejti a hirdetéseket a zene lejátszása közben. Fizetett promóció címke elrejtése Elrejti a promóció címkét. Felugró prémium hírdetések elrejtése - Elrejti a felugró prémium hírdetéseket. + Elrejti a prémium promóciós felugró ablakokat. Prémium megújítás szalaghírdetés elrejtése Elrejti a prémium megújítás szalaghírdetést. Promóciós figyelmeztető banner elrejtése Promóciós figyelmeztető banner elrejtése. - + Felugró menü Csend kivágás kapcsoló hozzáadása "A 'Csend kivágás' kapcsoló hozzáadása a lejátszási sebesség felugró menühöz. @@ -128,7 +128,7 @@ Korlátozások: Nem tetszik átirányítás letiltása Letiltja az átirányítást a következő számra, amikor rányomsz a nem tetszik gombra. Kényszerített automatikus feliratok letiltása - Letiltja a feliratokat, hogy ne jelenjenek meg automatikusan. + Letiltja az automatikus feliratok bekapcsolását. Fekvő mód engedélyezése Engedélyezi a fekvő módot, amikor elforgatod a telefonodat. Egyéni szűrők engedélyezése @@ -161,8 +161,8 @@ Korlátozások: Elrejti a Kattints a frissítéshez gombot. Hangkeresés gomb elrejtése Elrejti a hang keresés gombot a kereső sávban. - Visszaállítja a régi stílusú könyvtár polcot - Visszaállítja a régi megjelenését a könyvtár oldalnak. (Kísérleti) + Régi Könyvtár lap visszaállítása + Visszaállítja a Könyvtár lap régi stílusát. (Kísérleti) Nézői döntés menü eltávolítása "Eltávolítja a nézői döntés menüt. Ez nem kerüli meg a korhatárkorlátozást. Csak automatikusan elfogadja azt." @@ -176,10 +176,13 @@ Ez nem kerüli meg a korhatárkorlátozást. Csak automatikusan elfogadja azt."< 4.27.53 - Letiltja a rádió módot Kanada területén 6.11.52 - Letiltja a valós idejű dalszövegeket 7.16.53 - Régi menüsor visszaállítása - + Navigációs sor - Fekete navigációs sor engedélyezése - A navigációs sor színét átállítja feketére. + Egyéni navigációs sáv szín engedélyezése + Beállítja a navigációs sáv színét. + Egyéni navigációs sáv szín értéke + Írd be a navigációs sáv színének hexakódját. + Érvénytelen navigációs sáv színérték. Kezdőlap gomb elrejtése Elrejti a kezdőlap gombot. Minták gomb elrejtése @@ -200,40 +203,40 @@ Ez nem kerüli meg a korhatárkorlátozást. Csak automatikusan elfogadja azt."< Engedélyezi a következő szám gombot a minilejátszónál. Minilejátszó előző gomb engedélyezése Engedélyezi a előző szám gombot a minilejátszónál. - Megegyező színű lejátszó bekapcsolása - Egyező színe lesz a kis lejátszónak, mint a teljes képernyősnek. - Fekete hátterű lejátszó engedélyezése + Minialejátszó színének módosítása + A minialejátszó színét a teljes képernyős lejátszó színéhez igazítja. + A lejátszó háttérszínének módosítása Megváltoztatja a lejátszó háttér színét feketére. Minilejátszó gesztus letiltása - Kikapcsolja a zeneszámok váltását a minialejátszóban. + Letiltja a zeneszámok váltását a minilejátszóban. Lejtászó gesztus letiltása - Kikapcsolja a zeneszámok váltását a lejátszóban. - Mini lejátszó kényszerítése - A lejátszó akkor is minimalizálva marad, amikor egy másik zeneszámot játszanak le. + Letiltja a zeneszámok váltását a lejátszóban. + Minilejátszó kényszerítése + A lejátszó akkor is minimalizálva marad, amikor új zeneszámra vált. Minilejátszó elhagyása egy húzással Lehetővé teszi a minialejátszó elhagyását lefelé húzással. Zen mód bekapcsolása - Megváltoztatja a lejátszó hátterét világos szürkére a szem megóvására. + Világosszürke színt használ a lejátszó hátteréhez, hogy csökkentse a szem megerőltetését. Zen mód engedélyezése podcastekben - A zen mód a podcasteknél is működni fog. + Zen mód engedélyezése a podcastokban. Csatorna irányelveinek elrejtése Elrejti a csatorna irányelveit a komment szekció tetején. Dupla koppintás átfedés elrejtése Elrejti dupla koppintáskor megjelenő sötét átfedést. - Elrejti az időbélyeget és az emoji gombokat - Elrejti az időbélyeget és az emotikon gombokat hozzászólás gépelése közben. + Emoji és időbélyeg gombok elrejtése + Elrejti az emoji és az időbélyeg gombokat a hozzászólás beírásakor. Teljes képernyős megosztás gomb elrejtése Elrejti a megosztás gombot a teljes képernyős lejátszóban. Hang/Videó gomb elrejtése - Elrejti a hang/videó gombot a lejátszóban. + Elrejti a Hang / Videó gombot a lejátszóban. Isméltés állapotának megjegyzése Emlékezik az ismétlés állapotára. Keverés állapotának megjegyzése Emlékezik az keverés állapotára. Régi komment felugró menü visszaállítása - Visszaállítja a régi felugró menü a régi kinézetére. + Visszaállítja a megjegyzések felugró paneljeit a régi megjelenésére. Régi lejátszó kinézet visszaállítása - Visszaállítja a lejátszó hátterét a régi kinézetére. + Visszaállítja a lejátszó hátterét a régi stílusára. Régi lejátszó kinézet visszaállítása "Visszaállítja a lejátszó elrendezését a régi stílusra. Előfordulhat, hogy egyes funkciók nem működnek megfelelően a régi lejátszó elrendezésben." @@ -256,11 +259,11 @@ Előfordulhat, hogy egyes funkciók nem működnek megfelelően a régi lejátsz Lejátszási sebesség módosításainak megjegyzése Megjegyzi az utoljára kiválasztott lejátszási sebességet. Mutass egy felugró értesítést - Értesíts, ha változik a lejátszás sebessége. + Az alapértelmezett lejátszási sebesség megváltoztatásakor egy értesítés jelenjen meg. Videó minőség megjegyzése Megjegyezi a legutolsó videó minőséget, amit kiválasztottál. Mutass egy felugró értesítést - Értesíts ha meg változik a lejátszás minőségének beállítása. + Értesítés jelenjen meg az alapértelmezett videóminőség megváltoztatásakor. Az egyéni sebességnek kisebbnek kell lennie, mint %sx. Érvénytelen egyedi lejátszási sebesség. Megváltoztatva az alap sebességet %s-re. @@ -299,17 +302,17 @@ Előfordulhat, hogy egyes funkciók nem működnek megfelelően a régi lejátsz YouTube Data API kulcs A fejlesztői kulcs a YouTube Data API v3 használatához. A YouTube Data API-kulcsról - "YouTube Data API v3 fejlesztői kulcsra van szükség az azonosítók felhasználónevekre való cseréjéhez. + "A YouTube Data API v3 fejlesztői kulcsra van szükség ahhoz, hogy a azonosítókat felhasználónevekkel lehessen helyettesíteni. -Az ingyenes csomagban az API-kulcsok napi kvótája 10 000, és 1 kvótával 1 megjegyzéshez egy azonosító felhasználónévre cserélhető. +Az API-kulcsok napi kvótája az ingyenes csomagban 10 000, és 1 kvóta 1 kommenthez tartozó azonosító felhasználónévvel való helyettesítésére szolgál. -Kattints ide az API-kulcs megszerzéséhez." +Kattintson ide az API-kulcs kiadásának megtekintéséhez." YouTube Data API v3 fejlesztői kulcs megszerzése 1. Nyisd meg az <a href=%1$s>Új projekt létrehozását</a>.<br>2. Kattints a <b>LÉTREHOZÁS</b> gombra.<br>3. Lépj a <a href=%2$s>YouTube Data API v3</a> oldalára.<br>4. Kattints az <b>Engedélyezés</b> gombra.<br>5. Kattints a <b>HITELEZÉSI ADATOK LÉTREHOZÁSA</b> gombot.<br>6. Válaszd ki a <b>Nyilvános adatok</b> lehetőség.<br>7. Kattints a <b>KÖVETKEZŐ</b> gombra.<br>8. Másold ki az API-kulcsot.<br><br>※ Az API-kulcsot soha nem szabad megosztani másokkal, így az nem szerepel az importálási/exportálási beállításokban. Szponzor Blokk SzponsorBlokk engedélyezése - A SzponsorBlokk egy közösségi rendszer a YouTube videók zavaró részeinek átugrására. + A SponsorBlock egy közösségi rendszer a YouTube-videók idegesítő részeinek kihagyására. Üzenet megjelenítése, ha az API nem elérhető Üzenetet ír ki, ha a SponsorBlock API nem érhető el. Üzenet megjelenítése automatikus ugráskor @@ -365,7 +368,7 @@ Kattints ide az API-kulcs megszerzéséhez." Egyéb Beállítások Importálása / Exportálása - Beállítások importálása vagy exportálása. + RVX Music beállítások importálása / exportálása. Beállítások exportálása egy fájlba Beállítások importálása fájlból Beállítások import- / exportálása szövegként @@ -379,9 +382,9 @@ Kattints ide az API-kulcs megszerzéséhez." Visszaállítás A beállítások vágólapra másolva. Területi kép-korlátozások megkerülése - Helyettesíti az egyes régiókban blokkolt tartományt, így a lejátszási lista miniatűrjei, csatorna avatarok stb. fogadhatóak. + Helyettesíti az egyes régiókban blokkolt domaint, így a lejátszási lista miniatűrjei, csatorna avatarok stb. fogadhatóak. Megosztási lap megváltoztatása - Váltás az alkalmazáson belüli megosztási lapról a rendszer megosztási lapjára. + Az alkalmazáson belüli megosztási lapot a rendszer megosztási lapjára változtatja. Betöltési animáció kikapcsolása Letiltja a betöltési animációt amikor az app indul. DRC hang letiltása @@ -402,13 +405,13 @@ Piped instance használatban van, és előfordulhat, hogy az API egyes régiókb Hibakeresési puffer naplózásának engedélyezése Beleírja a puffert a hibakeresési naplóba. Opus codec engedélyezése - "Az opus audio codec engedélyezése az mp4a audio codec helyett. + "Engedélyezi az OPUS codec-et, ha a lejátszó válasza tartalmazza azt. -Info: -• A legújabb Android-kliensek alapértelmezés szerint az opus audio codec-et használják. -• Ez csak a nagyon régi klienseket használó felhasználókra érvényes." +Információk: +• A legújabb YouTube Music kliensek alapértelmezés szerint az OPUS audio codec-et használják. +• Ez csak a nagyon régi kliensekre hamisító felhasználókra érvényes." Megosztási linkek tisztítása - Linkek megosztásakor eltávolítja a nyomkövetési paramétereket az URL-ekből. + A megosztási linkeket a nyomkövető lekérdezési paraméterek eltávolításával tisztítja. Kliens hamisítása "Az kliens meghamisítása a lejátszási problémák megelőzése érdekében. @@ -431,7 +434,7 @@ Info: Android VR Android Music Alapértelmezett program beállítások megnyitása - A YouTube Music linkek megnyitásához az RVX Musicban engedélyezze a \'Támogatott linkek megnyitása\' opciót, és engedélyezze a támogatott webcímeket. + A YouTube Music linkek megnyitásához az RVX Musicban engedélyezze a Támogatott linkek megnyitása és az összes Támogatott webcím engedélyezése opciót. GmsCore megnyitása Értesítések fogadásához engedélyezd a felhő alapú üzenetküldést. A GmsCore nincs telepítve. Telepítsd. diff --git a/patches/src/main/resources/music/translations/id-rID/strings.xml b/patches/src/main/resources/music/translations/id-rID/strings.xml index c97aa1954..905c3a3e7 100644 --- a/patches/src/main/resources/music/translations/id-rID/strings.xml +++ b/patches/src/main/resources/music/translations/id-rID/strings.xml @@ -17,7 +17,7 @@ Menyembunyikan handle di menu akun. Sembunyikan kontainer ketentuan Menyembunyikan kontainer ketentuan layanan. - + Bilah Tindakan Sembunyikan tombol Like dan Dislike Menyembunyikan tombol Like dan Dislike. Itu tidak akan bekerja di layout player lama. @@ -59,7 +59,7 @@ Download %2$s dari website." Menyembunyikan popup promosi premium. Sembunyikan banner pembaruan premium Menyembunyikan banner pembaruan premium. - + Menu flyout Tambah switch Trim silence "Menambahkan tombol Trim silence ke menu flyout playback speed. @@ -170,10 +170,8 @@ This does not bypass the age restriction. It just accepts it automatically."Pilih target pemalsuan versi aplikasi. 4.27.53 - Nonaktifkan mode radio di wilayah Kanada 6.11.52 - Matikan Lirik real-time - + Bilah Navigasi - Aktifkan bilah navigasi hitam - Mengatur warna bilah navigasi menjadi hitam. Hide Home button Hides the Home button. Hide Samples button diff --git a/patches/src/main/resources/music/translations/in/strings.xml b/patches/src/main/resources/music/translations/in/strings.xml index c97aa1954..905c3a3e7 100644 --- a/patches/src/main/resources/music/translations/in/strings.xml +++ b/patches/src/main/resources/music/translations/in/strings.xml @@ -17,7 +17,7 @@ Menyembunyikan handle di menu akun. Sembunyikan kontainer ketentuan Menyembunyikan kontainer ketentuan layanan. - + Bilah Tindakan Sembunyikan tombol Like dan Dislike Menyembunyikan tombol Like dan Dislike. Itu tidak akan bekerja di layout player lama. @@ -59,7 +59,7 @@ Download %2$s dari website." Menyembunyikan popup promosi premium. Sembunyikan banner pembaruan premium Menyembunyikan banner pembaruan premium. - + Menu flyout Tambah switch Trim silence "Menambahkan tombol Trim silence ke menu flyout playback speed. @@ -170,10 +170,8 @@ This does not bypass the age restriction. It just accepts it automatically."Pilih target pemalsuan versi aplikasi. 4.27.53 - Nonaktifkan mode radio di wilayah Kanada 6.11.52 - Matikan Lirik real-time - + Bilah Navigasi - Aktifkan bilah navigasi hitam - Mengatur warna bilah navigasi menjadi hitam. Hide Home button Hides the Home button. Hide Samples button diff --git a/patches/src/main/resources/music/translations/it-rIT/strings.xml b/patches/src/main/resources/music/translations/it-rIT/strings.xml index 5598e8c74..25486a5c0 100644 --- a/patches/src/main/resources/music/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/music/translations/it-rIT/strings.xml @@ -17,13 +17,13 @@ Nascondi l\'intestazione Nascondi contenitore termini Nasconde il contenitore dei termini di servizio. - + Nome del pacchetto downloader esterno Nome del pacchetto dell\'app downloader esterna installata, come NewPipe o Seal. %s non è installato. Installalo. Nascondi le pubblicità musicali - + Abilita dialogo compatto Disabilita i sottotitoli automatici forzati @@ -41,9 +41,7 @@ Nascondi il bottone cast Nascondo il pulsante cast nella parte superiore della homepage e in cima al riproduttore. Versione dell\'app falsificata - - Abilita la barra di navigazione nera - Imposta il colore della barra di navigazione su nero. + Nascondi etichetta di navigazione Abilita l\'abbinamento di colore dei Riproduttori diff --git a/patches/src/main/resources/music/translations/ja-rJP/strings.xml b/patches/src/main/resources/music/translations/ja-rJP/strings.xml index ef08c06e4..a132811e2 100644 --- a/patches/src/main/resources/music/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/music/translations/ja-rJP/strings.xml @@ -18,7 +18,7 @@ アカウントスイッチャーでハンドルを非表示にします。 利用規約を非表示 利用規約コンテナーを非表示にします。 - + アクションバー 評価ボタンを非表示 高評価ボタンや低評価ボタンを非表示にします。古いプレイヤーのレイアウトでは動作しません。 @@ -62,7 +62,7 @@ プレミアム更新バナーを非表示にします。 プロモーションバナーを非表示 プロモーションバナーを非表示にします。 - + フライアウトメニュー 「無音トリム」を有効化 "再生スピードのフライアウトメニューで「無音トリム」スイッチを有効にする。 @@ -176,10 +176,13 @@ 4.27.53 - カナダの地域でラジオモードを無効化 6.11.52 - リアルタイムの歌詞を無効化 7.16.53 - 古いアクションバーを復元 - + ナビゲーションバー - 黒いナビゲーションバーを有効化 - ナビゲーションバーの色を黒に設定します。 + カスタムナビゲーションバーの色を有効にする + ナビゲーションバーの色を設定します。 + ナビゲーションバーの色の値 + ナビゲーションバーの色の16進数コードを入力します。 + ナビゲーションバーの色が無効です。 ホームボタンを非表示 ホームボタンを非表示にします。 サンプルボタンを非表示 diff --git a/patches/src/main/resources/music/translations/ko-rKR/strings.xml b/patches/src/main/resources/music/translations/ko-rKR/strings.xml index beb91d9bb..f0d1f6fc1 100644 --- a/patches/src/main/resources/music/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/music/translations/ko-rKR/strings.xml @@ -18,7 +18,7 @@ 계정 메뉴에서 핸들(@사용자 아이디)을 숨깁니다. 서비스 약관 컨테이너 제거 서비스 약관 컨테이너를 숨깁니다. - + 액션바 좋아요 & 싫어요 버튼 제거 좋아요 & 싫어요 버튼을 숨깁니다. \n이전 플레이어 레이아웃에서는 작동하지 않습니다. @@ -56,16 +56,16 @@ 일반 레이아웃 광고 제거 일반 레이아웃 광고를 숨깁니다. 음악 광고 제거 - 음악을 재생하기 전 광고를 숨깁니다. + 음악을 재생하는 동안에 광고를 숨깁니다. 유료 광고 포함 라벨 제거 유료 광고 포함 라벨을 숨깁니다. - YouTube Premium 팝업 광고 제거 - YouTube Premium 팝업 광고를 숨깁니다. - YouTube Premium 갱신 배너 제거 - YouTube Premium 갱신 배너를 숨깁니다. + YT Premium 프로모션 팝업 제거 + YT Premium 프로모션 팝업을 숨깁니다. + YT Premium 갱신 배너 제거 + YT Premium 갱신 배너를 숨깁니다. 프로모션 알림 배너 제거 프로모션 알림 배너를 숨깁니다. - + 메뉴 구성요소 무음 건너뛰기 스위치 추가 "재생 속도 메뉴 구성요소에 '무음 건너뛰기' 스위치를 추가합니다. @@ -180,10 +180,13 @@ 4.27.53 - 캐나다 지역에서 뮤직 스테이션 모드를 비활성화합니다. 6.11.52 - 실시간 가사를 비활성화합니다. 7.16.53 - 이전 액션바로 복원합니다. - + 하단바 - 검정 하단바 활성화 - 하단바 색상을 검정으로 설정합니다. + 사용자 정의 하단바 색상 활성화 + 사용자 정의 하단바 색상을 활성화합니다. + 사용자 정의 하단바 색상 + 하단바 색상의 헥스 코드를 입력하세요. + 잘못된 하단바 색상 값입니다. 홈 버튼 제거 홈 버튼을 숨깁니다. 샘플 버튼 제거 @@ -309,7 +312,7 @@ API Key를 발급받는 방법을 보려면 여기를 누르세요." YouTube Data API v3 Developer Key 발급 - 1. <a href=%1$s>새 프로젝트 만들기</a> 로 이동합니다.<br>2. <b>만들기</b> 버튼을 터치합니다.<br>3. <a href=%2$s>YouTube Data API v3</a> 로 이동합니다.<br>4. <b>사용</b> 버튼을 터치합니다.<br>5. <b>사용자 인증 정보 만들기</b> 버튼을 터치합니다.<br>6. <b>공개 데이터</b> 옵션을 선택합니다.<br>7. <b>다음</b> 버튼을 터치합니다.<br>8. API Key를 복사합니다.<br><br>※ API Key는 다른 사람과 공유해서는 안 되므로 가져오기 / 내보내기 설정에 포함되지 않습니다. + 1. <a href=%1$s>새 프로젝트 만들기</a> 로 이동합니다.<br>2. <b>만들기</b> 버튼을 누릅니다.<br>3. <a href=%2$s>YouTube Data API v3</a> 로 이동합니다.<br>4. <b>사용</b> 버튼을 누릅니다.<br>5. <b>사용자 인증 정보 만들기</b> 버튼을 누릅니다.<br>6. <b>공개 데이터</b> 옵션을 선택합니다.<br>7. <b>다음</b> 버튼을 누릅니다.<br>8. API Key를 복사합니다.<br><br>※ API Key는 다른 사람과 공유해서는 안 되므로 가져오기 / 내보내기 설정에 포함되지 않습니다. SponsorBlock SponsorBlock 활성화 diff --git a/patches/src/main/resources/music/translations/nl-rNL/strings.xml b/patches/src/main/resources/music/translations/nl-rNL/strings.xml index 8b2b54610..0bc35e554 100644 --- a/patches/src/main/resources/music/translations/nl-rNL/strings.xml +++ b/patches/src/main/resources/music/translations/nl-rNL/strings.xml @@ -17,7 +17,7 @@ Verbergt de handgreep in de account wijziger. Container van termen verbergen Verbergt de gebruikersvoorwaarden in het accountmenu. - + Actie bar Verberg de like- en dislike-knoppen Verbergt de knoppen \'Vind ik leuk\' en \'Niet leuk\'. Het werkt niet in de oude spelerindeling. @@ -59,7 +59,7 @@ Verbergt pop-ups van premiumpromoties. Banner voor premiumverlenging verbergen Verbergt de banner voor premiumverlenging. - + Flyout-menu Voeg een trimstilteschakelaar toe "Voegt de schakelaar 'Trim stilte' toe aan het vervolgmenu voor afspeelsnelheid. @@ -120,10 +120,8 @@ Bekende problemen: Selecteer het doel van de spoof app versie 4.27.53 - Radio modus uitschakelen in Canadese regio\'s 6.11.52 - Realtime songteksten uitschakelen - + Navigatiebalk - Activeer zwarte navigatie balk - Zet de navigatie balk kleur naar zwart. Home-knop verbergen Verbergt de homeknop. Knop Monsters verbergen diff --git a/patches/src/main/resources/music/translations/pl-rPL/strings.xml b/patches/src/main/resources/music/translations/pl-rPL/strings.xml index e4434b1d9..f8c99af58 100644 --- a/patches/src/main/resources/music/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/music/translations/pl-rPL/strings.xml @@ -18,7 +18,7 @@ Ukrywa nicki w przełączniku kont. Ukryj kontener warunków usług Ukrywa kontener warunków usług z menu konta. - + Pasek akcji Ukryj przyciski łapki w górę i dół Ukrywa przyciski łapki w górę i dół. Nie będzie działać na starym układzie odtwarzacza. @@ -56,7 +56,7 @@ Ograniczenie: Ukryj ogólne reklamy Ukrywa ogólne reklamy. Ukryj reklamy multimedialne - Ukrywa reklamy przed odtworzeniem multimediów. + Ukrywa reklamy w trakcie odtwarzania multimediów. Ukryj etykiety oznaczające płatne promocje Ukrywa etykiety oznaczające płatne promocje. Ukryj wyskakujące okienka promocyjne Premium @@ -65,7 +65,7 @@ Ograniczenie: Ukrywa baner odnawiania Premium. Ukryj banery z alertami promocyjnymi Ukrywa banery z alertami promocyjnymi. - + Menu ustawień utworu Włącz przełącznik do pomijania ciszy "Dodaje przycisk pomijania ciszy do menu od prędkości odtwarzania. @@ -179,10 +179,13 @@ Nie pomija to ograniczeń wiekowych, lecz akceptuje je automatycznie." 4.27.53 - Wyłącza tryb radia w rejonach kanadyjskich 6.11.52 - Wyłącza teksty w czasie rzeczywistym 7.16.53 - Przywraca stary pasek akcji - + Pasek nawigacji - Włącz czarny pasek nawigacji - Ustawia kolor paska nawigacji na czarny. + Włącz niestandardowy kolor paska nawigacji + Ustawia kolor paska nawigacji. + Niestandardowy kolor paska nawigacji + Wpisz kod hex koloru paska nawigacji. + Nieprawidłowa wartość koloru paska nawigacji. Ukryj przycisk do strony głównej Ukrywa przycisk do strony głównej. Ukryj przycisk od sampli @@ -368,7 +371,7 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Pozostałe Importuj/Eksportuj ustawienia - Zaimportuj lub wyeksportuj ustawienia + Zaimportuj / wyeksportuj ustawienia RVX Music Wyeksportuj ustawienia do pliku Zaimportuj ustawienia z pliku Zaimportuj/Wyeksportuj ustawienia jako tekst @@ -435,9 +438,9 @@ Informacje: Android VR Android Music Otwórz systemowe ustawienia aplikacji - Aby otwierać linki YouTube Music w RVX Music, przejdź do opcji obsługiwanych linków w ustawieniach i włącz obsługiwane adresy internetowe dla RVX. + Aby otwierać linki YouTube Music w RVX Music, przejdź do opcji obsługiwanych linków w ustawieniach i włącz obsługiwane adresy internetowe dla RVX Music. Otwórz ustawienia GmsCore - Otwiera ustawienia GmsCore. Następnie włącz cloud messaging, by otrzymywać powiadomienia. + Aby otrzymywać powiadomienia w RVX Music, włącz Cloud Messaging. GmsCore nie jest zainstalowany. Zainstaluj go. Wymagane działanie "GmsCore nie ma uprawnień do działania w tle. diff --git a/patches/src/main/resources/music/translations/pt-rBR/strings.xml b/patches/src/main/resources/music/translations/pt-rBR/strings.xml index b80929fde..d46b912e1 100644 --- a/patches/src/main/resources/music/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/music/translations/pt-rBR/strings.xml @@ -18,7 +18,7 @@ Oculta o identificador no menu da conta. Ocultar contêiner de termos Oculta o contêiner dos Termos de Serviço. - + Barra de ação Ocultar botões de Like e Deslike Oculta os botões de Like e Deslike. Não funciona no antigo layout do reprodutor. @@ -56,16 +56,16 @@ Limitações: Ocultar anúncios gerais Oculta anúncios gerais. Ocultar anúncios de mídia - Oculta os anúncios antes de reproduzir mídia. + Oculta os anúncios reproduzidos durante a reprodução de mídia. Ocultar rótulo de promoção paga Oculta o rótulo de promoção paga. Ocultar pop-ups de promoção premium - Oculta pop-ups de promoção premium. + Oculta os pop-ups de promoção premium. Ocultar banner de renovação premium Oculta o banner de renovação premium. Ocultar banner de alerta de promoção Oculta o banner de alerta de promoção. - + Menu flutuante Adicionar alternador para Cortar silêncio "Adiciona a opção Cortar silêncio ao menu flutuante de velocidade de reprodução. @@ -165,7 +165,7 @@ Limitações: Ocultar botão de pesquisa por voz Oculta o botão de pesquisa por voz na barra de pesquisa. Restaurar a aba antiga da Biblioteca - Retorna a aba da Biblioteca para o estilo antigo. (Experimental) + Restaura a aba da Biblioteca para o estilo antigo. (Experimental) Remover o diálogo discricionário do visualizador "Remover o diálogo discricionário de visualização. Isso não ignora a restrição de idade, apenas aceita isso automaticamente." @@ -179,10 +179,13 @@ Isso não ignora a restrição de idade, apenas aceita isso automaticamente."4.27.53 - Desativar modo de Rádio em regiões Canadenses 6.11.52 - Desativar letras em tempo real 7.16.53 - Restaurar barra de ação antiga - + Barra de Navegação - Ativar barra de navegação preta - Define a cor da barra de navegação para preto. + Ativar cor personalizada da barra de navegação + Define a cor da barra de navegação. + Valor da cor da barra de navegação personalizada + Digite o código hexadecimal da cor da barra de navegação. + Valor da cor da barra de navegação inválido. Ocultar botão Início Oculta o botão de Início. Ocultar botão Descobertas @@ -196,49 +199,49 @@ Isso não ignora a restrição de idade, apenas aceita isso automaticamente."Ocultar barra de navegação Oculta a barra de navegação. Ocultar rótulos de navegação - Oculta rótulos abaixo dos botões de navegação. + Oculta o rótulo abaixo de cada botão de navegação. Reprodutor Adicionar o botão próximo no mini reprodutor Adiciona o botão próximo no mini reprodutor. Adicionar o botão anterior no mini reprodutor Adiciona o botão anterior no mini reprodutor. - Alterar cor do miniplayer - Corresponde à cor do mini reprodutor para o reprodutor em tela cheia. - Ativar fundo do reprodutor preto + Alterar cor do mini reprodutor + Altera a cor do mini reprodutor para a cor do reprodutor em tela cheia. + Alterar cor de fundo do reprodutor Altera a cor de fundo do reprodutor para preto. Desativar gesto do mini reprodutor - Desativar deslize para alterar faixas no mini reprodutor. + Desativa a função de deslizar para alterar faixa no mini reprodutor. Desativar gesto do reprodutor - Desativar deslize para alterar faixas no reprodutor. - Ativar reprodutor minimizado forçado - Mantém o reprodutor minimizado mesmo quando outra faixa é reproduzida. + Desativa a função de deslizar para alterar faixa no reprodutor. + Ativar mini reprodutor forçado + Ativa o mini reprodutor forçado ao alternar para uma nova faixa. Ativar deslizar para dispensar o mini reprodutor Permite deslizar para baixo para dispensar o mini reprodutor. Ativar modo Calmo - Altera a cor de fundo do reprodutor para cinza claro para reduzir o cansaço visual. + Ativa uma cor cinza claro para o fundo do reprodutor para reduzir o cansaço visual. Ativar o modo Calmo em podcasts - Também ativa o modo Calmo para podcasts. + Ativa o modo Calmo em podcasts. Ocultar diretrizes do canal Oculta as diretrizes do canal na parte superior da seção de comentários. Ocultar filtro de sobreposição de toque duplo Oculta a sobreposição escura que aparece quando um duplo toque para procurar. - Ocultar botões de marcação de tempo e emoji - Oculta os botões de marcação de tempo e emoji ao escrever comentários. + Ocultar botões de emoji e marcação de tempo + Oculta os botões de emoji e marcação de tempo ao escrever comentários. Ocultar botão Compartilhar em tela cheia Oculta o botão Compartilhar no reprodutor de tela cheia. - Ocultar alternador de Áudio / Vídeo - Oculta o alternador de Áudio / Vídeo no reprodutor. + Ocultar alternador de Música / Vídeo + Oculta o alternador de Música / Vídeo no reprodutor. Lembrar estado de repetição Lembra o estado da alternância de repetição. Lembrar estado do modo aleatório Lembre o estado da alternância do modo aleatório. - Restaurar antigo painel popup de comentários - Retorna os painéis popup de comentários ao estilo antigo. + Restaurar antigo painel pop-up de comentários + Restaura os painéis pop-up de comentários ao estilo antigo. Restaurar antigo fundo do reprodutor - Retorna o fundo do reprodutor para o estilo antigo. + Restaura o fundo do reprodutor para o estilo antigo. Restaurar antigo layout do reprodutor - "Retorna o layout do reprodutor ao estilo antigo. + "Restaura o layout do reprodutor ao estilo antigo. Alguns recursos podem não funcionar corretamente no layout antigo do reprodutor." Menu de configurações @@ -259,11 +262,11 @@ Alguns recursos podem não funcionar corretamente no layout antigo do reprodutor Lembrar mudança na velocidade de reprodução Lembra a última velocidade de reprodução selecionada. Exibir uma notificação flutuante - Exibir uma notificação flutuante quando alterar a velocidade padrão de reprodução. + Exibe uma notificação flutuante quando alterar a velocidade padrão de reprodução. Lembrar mudança na qualidade do vídeo Lembra a última qualidade de vídeo selecionada. Exibir uma notificação flutuante - Exibir uma notificação flutuante quando alterar a qualidade padrão do vídeo. + Exibe uma notificação flutuante quando alterar a qualidade padrão do vídeo. Velocidades personalizadas devem ser menores que %sx. Velocidades de reprodução personalizadas inválidas. Alterando a velocidade padrão para %s. @@ -368,7 +371,7 @@ Clique para ver como emitir uma chave de API." Diversos Importar / Exportar configurações - Importar ou exportar as configurações como texto. + Importar / Exportar configurações do RVX Music. Exportar configurações para um arquivo Importar configurações de um arquivo Importar / Exportar as configurações como texto @@ -382,9 +385,9 @@ Clique para ver como emitir uma chave de API." Reiniciar Configurações copiadas para área de transferência. Ignorar restrições de imagem por região - Substitui o domínio que está bloqueado em algumas regiões para que miniaturas para playlists, avatares de canais, etc. possam ser recebidos. + Ignora o domínio que está bloqueado em algumas regiões para que miniaturas para playlists, avatares de canais, etc. possam ser recebidos. Alterar menu de compartilhamento - Alterar o menu de compartilhamento do app para o meno de compartilhamento do sistema. + Altera o menu de compartilhamento do app para o meno de compartilhamento do sistema. Desativar a animação inicial do Cairo Desabilita a animação inicial do Cairo quando o aplicativo é iniciado. Desativar áudio DRC @@ -398,20 +401,20 @@ Encontre a música oficial se um videoclipe for detectado tocando de um álbum. Tipo de redirecionamento Especifica como redirecionar para a música oficial. Redirecionar - Tocar alternador de Áudio / Vídeo - Tocar e segurar alternador de Áudio / Vídeo + Tocar alternador de Música / Vídeo + Tocar e segurar alternador de Música / Vídeo Ativar o relatório de depuração Imprime o relatório de depuração Ativar o registro de depuração do buffer Inclui o buffer no log de depuração. Ativar codec OPUS - "Ative o codec OPUS se a resposta do reprodutor incluir o codec OPUS. + "Ativa o codec OPUS se a resposta do reprodutor o incluir. Informações: • Os clientes mais recentes do YouTube Music usam o codec de áudio OPUS por padrão. • Isto só é válido para usuários que falsificam com clientes muito antigos." Limpar links compartilhados - Remove os parâmetros de consulta de rastreamento das URLs ao compartilhar os links. + Limpa links de compartilhamento removendo parâmetros de consulta de rastreamento. Falsificar cliente "Falsificar o cliente para evitar problemas de reprodução. @@ -434,9 +437,9 @@ Informações: Android VR Android Music Abrir configurações padrão do aplicativo - Para abrir os links de música do YouTube no RVX Music, ative \'Abrir links suportados\' e ative os endereços web suportados. - Abrir GmsCore - Ative as mensagens na nuvem para receber notificações. + Para abrir links do YouTube Music no RVX Music, ative Abrir links suportados e ative todos os endereços da web suportados. + Abrir configurações do GmsCore + Para receber notificações no RVX Music, ative as mensagens na nuvem. O GmsCore não está instalado. Instale-o. Ação necessária "O GmsCore não tem permissão para executar em segundo plano. diff --git a/patches/src/main/resources/music/translations/ro-rRO/strings.xml b/patches/src/main/resources/music/translations/ro-rRO/strings.xml index bd4ff81cd..ce5df7023 100644 --- a/patches/src/main/resources/music/translations/ro-rRO/strings.xml +++ b/patches/src/main/resources/music/translations/ro-rRO/strings.xml @@ -11,14 +11,14 @@ Ascunde mânerul în comutatorul de conturi. Ascunde containerul termenilor Ascunde containerul termenilor și condițiilor de utilizare. - + Numele pachetului de descărcare extern Numele pachetului al aplicației externe de descărcare instalate, cum ar fi NewPipe sau YTDLnis. %s nu este instalat. Vă rugăm să-l instalaţi. Ascunde reclamele muzicale Ascunde reclamele înainte de a reda o piesă. - + Activare dialog compact "Activați dialogul compact pe telefon. @@ -46,9 +46,7 @@ Probleme cunoscute: Ascunde butonul de istoric Ascunde butonul de istoric în bara de instrumente. 4.27.53 - Dezactivare mod radio în regiunile canadiene - - Activare bară neagră de navigare - Setează culoarea barei de navigare la negru. + Ascunde bara de navigare Ascunde bara de navigare. Ascunde eticheta de navigare diff --git a/patches/src/main/resources/music/translations/ru-rRU/strings.xml b/patches/src/main/resources/music/translations/ru-rRU/strings.xml index 17ddf4c16..5ffe9ad7a 100644 --- a/patches/src/main/resources/music/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/music/translations/ru-rRU/strings.xml @@ -18,7 +18,7 @@ Скрывает электронную почту / @ник в меню смены аккаунтов. Скрыть \"Конфиденциальность • Условия\" Скрывает пункт \"Конфиденциальность • Условия\". - + Панель действий Скрыть кнопки \"Нравится\" и \"Не нравится\" Скрывает кнопки \"Нравится\" и \"Не нравится\". Не работает в старом интерфейсе проигрывателя. @@ -62,7 +62,7 @@ Скрывает баннер продления Premium. Скрыть баннер с уведомлением о промо акции Скрывает баннер с уведомлением о промо акции. - + Выдвижное меню Включить обрезание тишины "Включает переключатель \"Обрезать тишину\" во всплывающем меню скорости воспроизведения. @@ -176,10 +176,13 @@ 4.27.53 - Отключить режим радиостанции в канадских регионах 6.11.52 - Отключить динамические текста 7.16.53 - Восстановить старую панель действий - + Панель навигации - Чёрная панель навигации - Устанавливает чёрный цвет панели навигации. + Включить пользовательский цвет панели навигации + Устанавливает цвет для панели навигации. + Значение пользовательского цвета панели навигации + Введите hex код цвета панели навигации. + Неверное значение цвета панели навигации. Скрыть кнопку \"Главная\" Скрывает кнопку \"Главная\". Скрыть кнопку \"Семплы\" diff --git a/patches/src/main/resources/music/translations/tr-rTR/strings.xml b/patches/src/main/resources/music/translations/tr-rTR/strings.xml index cc9361e78..3ee2cee43 100644 --- a/patches/src/main/resources/music/translations/tr-rTR/strings.xml +++ b/patches/src/main/resources/music/translations/tr-rTR/strings.xml @@ -18,7 +18,7 @@ Hesap menüsündeki etiketi gizler. Terimler kapsayıcısını gizle Hizmet Şartları kapsayıcısını gizler. - + Görev Çubuğu \"Beğen\" ve \"Beğenme\" butonlarını gizle Beğenme ve beğenmeme düğmelerini gizler. Eski oynatıcı arayüzünde çalışmayabilir. @@ -65,7 +65,7 @@ Sınırlamalar: Premium yenileme başlığını gizler. Promosyon uyarı başlığını gizle Promosyon uyarı başlığını gizler. - + Açılır menü Kırpma sessizliğini etkinleştir "Oynatma hızı açılır menüsüne 'Sessizliği kırp' geçişini etkinleştirir. @@ -177,10 +177,8 @@ Bilinen sorunlar: 4.27.53 - Kanada bölgelerinde radyo modunu devre dışı bırakın 6.11.52 - Gerçek zamanlı şarkı sözlerini devre dışı bırak 7.16.53 - Eski eylem çubuğunu geri yükle - + Gezinti çubuğu - Siyah gezinme çubuğunu etkinleştir - Gezinme çubuğunun rengini siyah yapar. Ana sayfa düğmesini gizle Ev düğmesini gizler. Örnekler düğmesini gizle diff --git a/patches/src/main/resources/music/translations/uk-rUA/strings.xml b/patches/src/main/resources/music/translations/uk-rUA/strings.xml index fa14ec34c..3cb5e92ef 100644 --- a/patches/src/main/resources/music/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/music/translations/uk-rUA/strings.xml @@ -18,7 +18,7 @@ Приховує електронну пошту / @нік у меню облікових записів. Приховати \"Конфіденційність • Умови використання\" Приховує контейнер \"Конфіденційність • Умови використання\". - + Панель дій Приховати \"Подобається\" і \"Не подобається\" Приховує кнопки \"Подобається\" та \"Не подобається\". Це не працює в старому інтерфейсі плеєра. @@ -56,16 +56,16 @@ Приховати загальну рекламу Приховує загальну рекламу. Приховати медіарекламу - Приховує рекламу перед відтворенням медіа. + Приховує рекламу, яка з\'являється під час відтворення медіа. Приховати \"Містить пряму рекламу\" Приховує мітку \"Містить пряму рекламу\". Приховати спливаючу рекламу Premium - Приховує спливаючі вікна реклами підписки Music Premium. + Приховує спливаючі вікна реклами підписки. Приховати банер поновлення Premium Приховує банер поновлення підписки Music Premium. Приховати рекламні сповіщення Приховує банер рекламних сповіщень. - + Спливаюче меню Додати перемикач \"Пропуск тиші\" "Додає перемикач \"Пропуск тиші\" у спливаючому меню швидкості відео. @@ -92,7 +92,7 @@ Приховати \"Перейти до випуску\" Приховати \"Перейти до подкасту\" Приховати \"Довідка й відгуки\" - Приховати \"Закріпити у швидкому виборі\" + Приховати \"Закріпити в розділі Швидкий набір\" Приховати \"Відтворити наступним\" Приховати \"Якість\" Приховати \"Вилучити з бібліотеки\" @@ -107,7 +107,7 @@ Приховати \"Увімкнути Радіо\" Приховати \"Статистика для досвідчених користувачів\" Приховати \"Підписатися / Скасувати підписку\" - Приховати \"Відкріпити зі швидкого вибору\" + Приховати \"Відкріпити від розділу Швидкий набір\" Приховати \"Переглянути авторів пісні\" Продовжити перегляд Продовжує відео з поточного моменту під час переходу на YouTube. @@ -131,7 +131,7 @@ Вимкнути перенаправлення при \"Не подобається\" Вимикає перенаправлення на наступний трек при натисканні на кнопку \"Не подобається\". Вимкнути примусові авто субтитри - Вимикає автоматичне ввімкнення субтитрів. + Вимикає примусове ввімкнення автоматичних субтитрів. Увімкнути ландшафтний режим Вмикає ландшафтний режим під час повороту екрана на телефонах. Увімкнути користувацький фільтр @@ -165,7 +165,7 @@ Приховати кнопку голосового пошуку Приховує кнопку голосового пошуку у панелі пошуку. Відновити старий стиль вкладки \"Бібліотека\" - Повертає старий стиль вкладки \"Бібліотека\". (Експериментальна опція) + Відновлює старий стиль вкладки \"Бібліотека\". (Експериментальна опція) Вилучити діалог про небажаний контент "Вилучає діалог про небажаний контент. Це не обходить вікові обмеження. Просто приймає їх автоматично." @@ -179,10 +179,13 @@ 4.27.53 - Вимкнення режиму радіо в канадських регіонах 6.11.52 - Вимкнення динамічних текстів (караоке) 7.16.53 - Відновлення старої панелі дій - + Панель навігації - Увімкнути чорну панель навігації - Встановлює чорний колір для панелі навігації. + Увімкнути користувацький колір панелі навігації + Встановлює колір для панелі навігації. + Значення користувацького кольору панелі навігації + Введіть hex код кольору панелі навігації. + Недійсне значення кольору панелі навігації. Приховати \"Головна\" Приховує кнопку \"Головна\" на панелі навігації. Приховати \"Семпли\" @@ -196,35 +199,35 @@ Приховати панель навігації Приховує панель навігації. Приховати підписи кнопок навігації - Приховує підписи кнопок на панелі навігації. + Приховує підпис під кожною навігаційною кнопкою. Плеєр Додати кнопку наступне у мініплеєр Додає кнопку наступного треку у мініплеєр. Додати кнопку попереднє у мініплеєр Додає кнопку попереднього треку у мініплеєр. - Увімкнути колірну відповідність плеєрів - Колір мініплеєра повторює колір повноекранного плеєра. - Увімкнути чорний фон плеєра + Змінити колір мініплеєра + Змінює колір мініплеєра на колір повноекранного плеєра. + Змінити колір фону плеєра Змінює адаптивний колір фона плеєра на чорний. Вимкнути жести мініплеєра Вимикає жести перемикання треків у мініплеєрі. Вимкнути жести плеєра Вимикає жести перемикання треків у плеєрі. Увімкнути мініплеєр на постійній основі - Тримає плеєр згорнутим, навіть коли відтворюється інший трек. + Вмикає мініплеєр на постійній основі під час переходу на новий трек. Увімкнути жест закриття мініплеєру Вмикає жест вниз для закриття мініплеєру. Увімкнути режим \"Дзен\" - Змінює колір фона плеєра на світло-сірий, щоб зменшити навантаження на очі. + Вмикає світло-сірий колір фону плеєра, щоб зменшити навантаження на очі. Увімкнути режим \"Дзен\" у подкастах - Режим \"Дзен\" також застосовується до подкастів. + Вмикає режим \"Дзен\" для подкастів. Приховати правила каналу Приховує правила каналу у верхній частині секції коментарів. Приховати фільтр подвійного натискання Приховує затемнення, яке з’являється під час подвійного натискання для перемотування. - Приховати мітку часу та емодзі - Приховує кнопки мітки часу та емодзі під час введення коментарів. + Приховати емодзі та кнопку мітки часу + Приховує кнопки емодзі та мітки часу під час введення коментарів. Приховати \"Поділитися\" повноекранного режиму Приховує кнопку \"Поділитися\" в повноекранному плеєрі. Приховати перемикач \"пісня | відео\" @@ -234,11 +237,11 @@ Запам\'ятовувати стан перемішування Запам\'ятовує стан кнопки \"Перемішати\". Відновити старі спливаючі панелі коментарів - Повертає старий стиль спливаючих панелей коментарів. + Відновлює старий стиль спливаючих панелей коментарів. Відновити старий фон плеєра - Повертає фон плеєра до старого стилю. + Відновлює фон плеєра до старого стилю. Відновити старий інтерфейс плеєра - "Повертає інтерфейс плеєра до старого стилю. + "Відновлює інтерфейс плеєра до старого стилю. Деякі функції можуть працювати не належним чином у старому інтерфейсі плеєра." Меню налаштувань @@ -368,7 +371,7 @@ Різне Імпорт / Експорт налаштувань - Імпортує або експортує налаштування. + Імпортує або експортує налаштування RVX Music. Експорт налаштувань у файл Імпорт налаштувань із файлу Імпорт або експорт налаштувань у вигляді тексту @@ -382,7 +385,7 @@ Скинути Налаштування скопійовано до буфера обміну. Змінити домен зображень - Замінює домен для зображень, заблокований у деяких регіонах, що дозволить отримувати мініатюри списків відтворення, аватари каналів тощо. + Обходить домен для зображень, заблокований у деяких регіонах, що дозволить отримувати мініатюри списків відтворення, аватари каналів тощо. Змінити діалог поширення Змінює тип вікна діалогу поширення з вбудованого на системний. Вимкнути сплеш анімацію Каїр @@ -405,13 +408,13 @@ Увімкнути ведення журналу буфера налагодження Включає буфер у журнал налагодження. Увімкнути кодек OPUS - "Вмикає кодек OPUS, якщо відповідь від сервера містить кодек OPUS. + "Вмикає кодек OPUS, якщо відповідь від сервера містить його. Інформація: • Останні YouTube Music клієнти за умовчанням використовують аудіокодек OPUS. • Це буде корисно лише для користувачів, які користуються дуже старими клієнтами." Обробляти поширення посилань - Видаляє параметри запиту відстеження з URL-адрес під час обміну посиланнями. + Видаляє параметри запиту відстеження з посилання перед тим, як поділитися ним. Підміна клієнта "Підробити клієнт, щоб запобігти проблемам із відтворенням. @@ -435,8 +438,8 @@ Android Music Відкрити налаштування за замовчуванням Щоб відкривати посилання на YouTube Music у RVX Music, увімкніть \"Відкривати підтримувані посилання\" та активуйте підтримувані веб-адреси. - Відкрити GmsCore - Увімкніть \"Хмарні повідомлення\", щоб отримувати сповіщення. + Відкрити налаштування GmsCore + Щоб отримувати сповіщення у RVX Music, увімкніть \"Хмарні повідомлення\". GmsCore не встановлено. Встановіть. Потрібна дія "GmsCore не дозволено працювати у фоні. diff --git a/patches/src/main/resources/music/translations/vi-rVN/strings.xml b/patches/src/main/resources/music/translations/vi-rVN/strings.xml index 3e646efcd..52647048e 100644 --- a/patches/src/main/resources/music/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/music/translations/vi-rVN/strings.xml @@ -18,7 +18,7 @@ Ẩn tên người dùng khỏi trình đơn Tài khoản. Ẩn mục Bảo mật và Điều khoản Ẩn các mục Chính sách quyền riêng tư và Điều khoản dịch vụ khỏi trình đơn Tài khoản. - + Thanh thao tác Ẩn các nút Thích/Không thích Ẩn nút Thích và nút Không thích.\n\nLưu ý: Tuỳ chọn này không hoạt động trong bố cục trình phát kiểu cũ. @@ -56,7 +56,7 @@ Hạn chế: Ẩn quảng cáo chung Ẩn quảng cáo xuất hiện trước khi phát. Ẩn quảng cáo - Ẩn quảng cáo xuất hiện trước khi phát nhạc. + Ẩn quảng cáo xuất hiện trong khi phát nhạc. Ẩn nhãn quảng cáo được tài trợ Ẩn nhãn quảng cáo được tài trợ. Ẩn quảng cáo bật lên @@ -65,7 +65,7 @@ Hạn chế: Ẩn quảng cáo biểu ngữ mua Music Premium. Ẩn biểu ngữ thông báo khuyến mãi Ẩn biểu ngữ thông báo khuyến mãi. - + Trình đơn tuỳ chọn Cắt bỏ khoảng lặng "Thêm tính năng Cắt bỏ khoảng lặng vào mục tuỳ chọn tốc độ phát. @@ -179,10 +179,13 @@ Hạn chế: 4.27.53 - Tắt chế độ Đài phát ở một số vùng của Canada 6.11.52 - Tắt lời bài hát theo thời gian thực 7.16.53 - Khôi phục thanh thao tác kiểu cũ - + Thanh điều hướng - Thanh điều hướng màu đen - Đặt màu thanh điều hướng phía dưới cùng thành màu đen. + Màu thanh điều hướng tuỳ chỉnh + Chỉnh màu cho thanh điều hướng. + Tuỳ chỉnh giá trị màu sắc + Nhập mã màu hex của thanh điều hướng mà bạn muốn thay đổi. + Mã màu hex không hợp lệ. Ẩn nút Trang chủ Ẩn thẻ Trang chủ khỏi thanh điều hướng. Ẩn thẻ Đoạn nhạc @@ -312,7 +315,7 @@ Nhấp vào đây để xem các bước phát hành khóa API." SponsorBlock Kích hoạt SponsorBlock - SponsorBlock là một tiện tích được đóng góp bởi cộng đồng nhằm bỏ qua các phân đoạn gây khó chịu trong video YouTube. + SponsorBlock là một tiện tích được đóng góp bởi cộng đồng nhằm bỏ qua các phân đoạn gây khó chịu trong video trên YouTube. Thông báo ngắn nếu API không khả dụng Hiển thị một thông báo ngắn nếu API của SponsorBlock không khả dụng. Thông báo ngắn khi tự động bỏ qua @@ -368,7 +371,7 @@ Nhấp vào đây để xem các bước phát hành khóa API." Cài đặt khác Nhập/Xuất cài đặt - Nhập hoặc xuất các tuỳ chọn cài đặt của bạn. + Nhập hoặc xuất các tuỳ chọn cài đặt RVX Music của bạn. Xuất cài đặt dưới dạng tệp Nhập cài đặt từ tệp Nhập/Xuất cài đặt dưới dạng văn bản @@ -382,9 +385,9 @@ Nhấp vào đây để xem các bước phát hành khóa API." Đặt lại Đã sao chép cài đặt sang bảng nhớ tạm. Bỏ qua hạn chế khu vực cho hình ảnh - Thay thế miền bị chặn ở một số khu vực để có thể thu được được hình thu nhỏ video của danh sách phát, ảnh đại diện kênh, v. v. - Thay đổi giao diện chia sẻ - Chuyển giao diện chia sẻ trong ứng dụng sang của hệ thống. + Bỏ qua miền bị chặn ở một số khu vực để có thể thu được được hình thu nhỏ video của danh sách phát, ảnh đại diện kênh, v. v. + Thay đổi bảng chia sẻ + Chuyển bảng chia sẻ trong ứng dụng Youtube sang của hệ thống Android. Vô hiệu hóa hoạt ảnh kiểu Cairo Vô hiệu hóa hoạt ảnh kiểu Cairo khi ứng dụng khởi chạy. Vô hiệu hoá audio DRC diff --git a/patches/src/main/resources/music/translations/zh-rCN/strings.xml b/patches/src/main/resources/music/translations/zh-rCN/strings.xml index f20f321e1..9b30f988b 100644 --- a/patches/src/main/resources/music/translations/zh-rCN/strings.xml +++ b/patches/src/main/resources/music/translations/zh-rCN/strings.xml @@ -17,7 +17,7 @@ 隐藏账号菜单中的句柄 隐藏服务条款栏 隐藏服务条款栏 - + 快捷操作栏 隐藏点赞和点踩按钮 隐藏点赞和点踩按钮(在旧的播放器布局中不生效) @@ -59,7 +59,7 @@ 隐藏 Premium 推广弹出窗口 隐藏 Premium 续订横幅 隐藏 Premium 续订横幅 - + 弹出菜单 新增修改静音开关 "将修改静音开关新增至播放速度弹出式选单 @@ -170,10 +170,8 @@ 选择伪装的应用版本 4.27.53 - 在加拿大地区禁用收音机模式 6.11.52 - 禁用实时歌词 - + 导航栏 - 黑色导航栏 - 将导航栏设为黑色 隐藏首页按钮 隐藏首页按钮 隐藏样品按钮 diff --git a/patches/src/main/resources/music/translations/zh-rTW/strings.xml b/patches/src/main/resources/music/translations/zh-rTW/strings.xml index 04536a60a..3b261f8e4 100644 --- a/patches/src/main/resources/music/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/music/translations/zh-rTW/strings.xml @@ -18,7 +18,7 @@ 隱藏帳戶選單中的用戶名稱 隱藏術語 隱藏服務條款 - + 導覽列 隱藏 \"讚\" 與 \"倒讚\" 按鈕 隱藏 \"讚\" 與 \"倒讚\" 按鈕 @@ -62,7 +62,7 @@ 隱藏 Premium 續訂橫幅 Hide promotion alert banner 隱藏促銷提醒橫幅。 - + 彈出式選單 新增修改靜音開關 "將修改靜音開關新增至播放速度彈出式選單 @@ -177,10 +177,8 @@ 4.27.53 - 在加拿大地區停用電台模式 6.11.52 - 停用即時歌詞 7.16.53 - 還原舊的動作欄 - + 導覽列 - 啟用黑色導覽列 - 將導覽列的顏色設成黑色 隱藏首頁按鈕 隱藏首頁按鈕 隱藏樣品按鈕 diff --git a/patches/src/main/resources/youtube/overlaybuttons/shared/host/layout/youtube_controls_bottom_ui_container.xml b/patches/src/main/resources/youtube/overlaybuttons/shared/host/layout/youtube_controls_bottom_ui_container.xml index f184aac3b..ec050e03f 100644 --- a/patches/src/main/resources/youtube/overlaybuttons/shared/host/layout/youtube_controls_bottom_ui_container.xml +++ b/patches/src/main/resources/youtube/overlaybuttons/shared/host/layout/youtube_controls_bottom_ui_container.xml @@ -1,11 +1,12 @@ - - - - - - - - + + + + + + + + + diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_grey600_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_grey600_24.png index d631ae0d3..f11bb81cf 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_grey600_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_grey600_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_white_24.png index d631ae0d3..f11bb81cf 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_exit_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_grey600_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_grey600_24.png index e4702e744..569b00f1b 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_grey600_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_grey600_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_white_24.png index e4702e744..569b00f1b 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/quantum_ic_fullscreen_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_button.png index 4a417b065..c135fe1ec 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_timestamp_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_timestamp_button.png index f9b2fce71..c91087128 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_timestamp_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_copy_timestamp_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_download_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_download_button.png index 7ee1a52af..3ba08b6f8 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_download_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_download_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_play_all_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_play_all_button.png index a6eb2c90a..a42b2d02e 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_play_all_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_play_all_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_speed_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_speed_button.png index 222f3495f..ebbedb817 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_speed_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_speed_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_muted_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_muted_button.png index a80d65d28..db1c7c17a 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_muted_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_muted_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_unmuted_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_unmuted_button.png index e9c207ab3..c64727032 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_unmuted_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_volume_unmuted_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_whitelist_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_whitelist_button.png index 3d8403fcc..e00e05d20 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_whitelist_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/revanced_whitelist_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_fill_arrow_repeat_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_fill_arrow_repeat_white_24.png index 8265eb714..2e35f5f44 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_fill_arrow_repeat_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_fill_arrow_repeat_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_repeat_1_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_repeat_1_white_24.png index 27289d274..9a918c452 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_repeat_1_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_repeat_1_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_1_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_1_white_24.png index cdc76769a..9101ac6d0 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_1_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_1_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_black_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_black_24.png new file mode 100644 index 000000000..6f19afdfb Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_arrow_shuffle_black_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_gear_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_gear_white_24.png index 097ca76a8..a8d2249cb 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_gear_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_gear_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_black_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_black_24.png new file mode 100644 index 000000000..97f1a8140 Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_black_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_white_24.png new file mode 100644 index 000000000..a42b2d02e Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_list_play_arrow_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_exit_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_exit_white_24.png index d631ae0d3..f11bb81cf 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_exit_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_exit_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_vd_theme_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_vd_theme_24.png index e4702e744..569b00f1b 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_vd_theme_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_vd_theme_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_white_24.png index e4702e744..569b00f1b 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xhdpi/yt_outline_screen_full_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_grey600_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_grey600_24.png index ec962d35e..0574f38f7 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_grey600_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_grey600_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_white_24.png index ec962d35e..0574f38f7 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_exit_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_grey600_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_grey600_24.png index 87eb4b20e..56c1a07ef 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_grey600_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_grey600_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_white_24.png index 87eb4b20e..56c1a07ef 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/quantum_ic_fullscreen_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_button.png index dddff2044..5acdce4f0 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_timestamp_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_timestamp_button.png index f4032b711..f67dedde7 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_timestamp_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_copy_timestamp_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_download_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_download_button.png index 7414a3d62..0649594d5 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_download_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_download_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_play_all_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_play_all_button.png index cf45b643c..d1988833e 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_play_all_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_play_all_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_speed_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_speed_button.png index 976cfda93..85dbffe58 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_speed_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_speed_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_muted_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_muted_button.png index 620286389..49b9e511f 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_muted_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_muted_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_unmuted_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_unmuted_button.png index 9dc60eef6..1d756e979 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_unmuted_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_volume_unmuted_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_whitelist_button.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_whitelist_button.png index c75eb21bf..f1f7de8f7 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_whitelist_button.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/revanced_whitelist_button.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_fill_arrow_repeat_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_fill_arrow_repeat_white_24.png index e7fa8c7c5..d7b4c51ff 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_fill_arrow_repeat_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_fill_arrow_repeat_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_repeat_1_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_repeat_1_white_24.png index 8fe13239c..38065ec0e 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_repeat_1_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_repeat_1_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_1_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_1_white_24.png index f7471cec2..789839769 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_1_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_1_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_black_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_black_24.png new file mode 100644 index 000000000..62b930e2e Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_arrow_shuffle_black_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_black_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_black_24.png new file mode 100644 index 000000000..d1793dff9 Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_black_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_white_24.png new file mode 100644 index 000000000..d1988833e Binary files /dev/null and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_list_play_arrow_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_exit_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_exit_white_24.png index ec962d35e..0574f38f7 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_exit_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_exit_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_vd_theme_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_vd_theme_24.png index 87eb4b20e..56c1a07ef 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_vd_theme_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_vd_theme_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_white_24.png b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_white_24.png index 87eb4b20e..56c1a07ef 100644 Binary files a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_white_24.png and b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable-xxhdpi/yt_outline_screen_full_white_24.png differ diff --git a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable/yt_outline_screen_vertical_vd_theme_24.xml b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable/yt_outline_screen_vertical_vd_theme_24.xml index a460f6a95..3e9fc362b 100644 --- a/patches/src/main/resources/youtube/overlaybuttons/thin/drawable/yt_outline_screen_vertical_vd_theme_24.xml +++ b/patches/src/main/resources/youtube/overlaybuttons/thin/drawable/yt_outline_screen_vertical_vd_theme_24.xml @@ -1,5 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/patches/src/main/resources/youtube/settings/host/values/arrays.xml b/patches/src/main/resources/youtube/settings/host/values/arrays.xml index 55d4d5583..7b65a3b73 100644 --- a/patches/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/patches/src/main/resources/youtube/settings/host/values/arrays.xml @@ -38,47 +38,53 @@ @string/revanced_change_start_page_entry_default - @string/revanced_change_start_page_entry_search - @string/revanced_change_start_page_entry_shorts - @string/revanced_change_start_page_entry_subscriptions - @string/revanced_change_start_page_entry_explore - @string/revanced_change_start_page_entry_notifications - @string/revanced_change_start_page_entry_library - @string/revanced_change_start_page_entry_your_clips - @string/revanced_change_start_page_entry_liked_videos - @string/revanced_change_start_page_entry_watch_later - @string/revanced_change_start_page_entry_history - @string/revanced_change_start_page_entry_trending - @string/revanced_change_start_page_entry_courses - @string/revanced_change_start_page_entry_gaming - @string/revanced_change_start_page_entry_live - @string/revanced_change_start_page_entry_music - @string/revanced_change_start_page_entry_movies - @string/revanced_change_start_page_entry_sports @string/revanced_change_start_page_entry_browse + @string/revanced_change_start_page_entry_courses + @string/revanced_change_start_page_entry_explore + @string/revanced_change_start_page_entry_fashion + @string/revanced_change_start_page_entry_gaming + @string/revanced_change_start_page_entry_history + @string/revanced_change_start_page_entry_library + @string/revanced_change_start_page_entry_liked_videos + @string/revanced_change_start_page_entry_live + @string/revanced_change_start_page_entry_movies + @string/revanced_change_start_page_entry_music + @string/revanced_change_start_page_entry_news + @string/revanced_change_start_page_entry_notifications + @string/revanced_change_start_page_entry_podcasts + @string/revanced_change_start_page_entry_search + @string/revanced_change_start_page_entry_shopping + @string/revanced_change_start_page_entry_shorts + @string/revanced_change_start_page_entry_sports + @string/revanced_change_start_page_entry_subscriptions + @string/revanced_change_start_page_entry_trending + @string/revanced_change_start_page_entry_watch_later + @string/revanced_change_start_page_entry_your_clips ORIGINAL - - SEARCH - SHORTS - - SUBSCRIPTIONS - EXPLORE - NOTIFICATIONS - LIBRARY - YOUR_CLIPS - LIKED_VIDEO - WATCH_LATER - HISTORY - TRENDING - COURSES - GAMING - LIVE - MUSIC - MOVIE - SPORTS BROWSE + COURSES + EXPLORE + FASHION + GAMING + HISTORY + LIBRARY + LIKED_VIDEO + LIVE + MOVIE + MUSIC + NEWS + NOTIFICATIONS + PODCASTS + SEARCH + SHOPPING + SHORTS + SPORTS + SUBSCRIPTIONS + TRENDING + WATCH_LATER + YOUR_CLIPS @string/revanced_change_shorts_repeat_state_entry_default @@ -183,6 +189,114 @@ MEMBERSHIPS_SHORTS_ONLY MEMBERSHIPS_LIVESTREAMS_ONLY + + @string/revanced_language_DEFAULT + @string/revanced_language_AR + @string/revanced_language_AZ + @string/revanced_language_BG + @string/revanced_language_BN + @string/revanced_language_CA + @string/revanced_language_CS + @string/revanced_language_DA + @string/revanced_language_DE + @string/revanced_language_EL + @string/revanced_language_EN + @string/revanced_language_ES + @string/revanced_language_ET + @string/revanced_language_FA + @string/revanced_language_FI + @string/revanced_language_FR + @string/revanced_language_GU + @string/revanced_language_HI + @string/revanced_language_HR + @string/revanced_language_HU + @string/revanced_language_ID + @string/revanced_language_IT + @string/revanced_language_JA + @string/revanced_language_KK + @string/revanced_language_KO + @string/revanced_language_LT + @string/revanced_language_LV + @string/revanced_language_MK + @string/revanced_language_MN + @string/revanced_language_MR + @string/revanced_language_MS + @string/revanced_language_MY + @string/revanced_language_NL + @string/revanced_language_OR + @string/revanced_language_PA + @string/revanced_language_PL + @string/revanced_language_PT + @string/revanced_language_RO + @string/revanced_language_RU + @string/revanced_language_SK + @string/revanced_language_SL + @string/revanced_language_SR + @string/revanced_language_SV + @string/revanced_language_SW + @string/revanced_language_TA + @string/revanced_language_TE + @string/revanced_language_TH + @string/revanced_language_TR + @string/revanced_language_UK + @string/revanced_language_UR + @string/revanced_language_VI + @string/revanced_language_ZH + + + DEFAULT + AR + AZ + BG + BN + CA + CS + DA + DE + EL + EN + ES + ET + FA + FI + FR + GU + HI + HR + HU + ID + IT + JA + KK + KO + LT + LV + MK + MN + MR + MS + MY + NL + OR + PA + PL + PT + RO + RU + SK + SL + SR + SV + SW + TA + TE + TH + TR + UK + UR + VI + ZH + @string/revanced_miniplayer_type_entry_0 @string/revanced_miniplayer_type_entry_1 @@ -255,12 +369,14 @@ @string/revanced_spoof_streaming_data_type_entry_android_vr + @string/revanced_spoof_streaming_data_type_entry_android_vr_no_auth @string/revanced_spoof_streaming_data_type_entry_android_unplugged @string/revanced_spoof_streaming_data_type_entry_ios_unplugged @string/revanced_spoof_streaming_data_type_entry_ios ANDROID_VR + ANDROID_VR_NO_AUTH ANDROID_UNPLUGGED IOS_UNPLUGGED IOS diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 29974fd4e..ae042b980 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -9,7 +9,7 @@ Search %s Reset to default values. - Experimental Flags + Experimental flags Do you wish to proceed? Restart to load the layout normally Refresh and restart @@ -22,6 +22,59 @@ "%1$s is not installed. Please download %2$s from the website." %s is not installed. Please install it. + RVX language + App language + Arabic + Azerbaijani + Bulgarian + Bengali + Catalan + Czech + Danish + German + Greek + English + Spanish + Estonian + Persian + Finnish + French + Gujarati + Hindi + Croatian + Hungarian + Indonesian + Italian + Japanese + Kazakh + Korean + Lithuanian + Latvian + Macedonian + Mongolian + Marathi + Malay + Burmese + Dutch + Odia + Punjabi + Polish + Portuguese + Romanian + Russian + Slovak + Slovene + Serbian + Swedish + Swahili + Tamil + Telugu + Thai + Turkish + Ukrainian + Urdu + Vietnamese + Chinese @@ -75,7 +128,7 @@ Please download %2$s from the website." DeArrow & still captures Still captures DeArrow - "DeArrow provides crowd-sourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube. + "DeArrow provides crowdsourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube. If enabled, video URLs will be sent to the API server and no other data is sent. If a video does not have DeArrow thumbnails, then the original or still captures are shown. @@ -113,14 +166,15 @@ Tap here to learn more about DeArrow." Hide Captions button Captions button is hidden. Captions button is shown. - Hide carousel shelf - "Hides the following shelves: + Hide carousel shelves + "Carousel shelves are hidden, such as: • Breaking news • Continue watching • Explore more channels • Listen again • Shopping • Watch it again" + Carousel shelves are shown. Hide chips shelf Chips shelf is hidden. Chips shelf is shown. @@ -154,18 +208,18 @@ Tap here to learn more about DeArrow." Hide Playables Playables are hidden. Playables are shown. - Hide Show more button - Show more button is hidden. - Show more button is shown. Hide search bar Search bar is hidden. Search bar is shown. - Hide surveys - Surveys are hidden. - Surveys are shown. + Hide Show more button + Show more button is hidden. + Show more button is shown. Hide subscriptions carousel Subscriptions carousel is hidden. Subscriptions carousel is shown. + Hide surveys + Surveys are hidden. + Surveys are shown. Hide ticket shelves Ticket shelves are hidden. Ticket shelves are shown. @@ -275,11 +329,12 @@ Limitations: Recommended video Hide low views video - Hide videos with less than 1,000 views from home feeds that have been uploaded from unsubscribed channels. + "Hide videos with less than 1,000 views from home feeds that have been uploaded from unsubscribed channels. + +This filter may no longer work, use 'View count filter' instead." Hide recommended videos "Hides the following recommended videos: -• Videos with the Members only tag. • Videos with phrases such as 'People also watched' underneath." @@ -319,18 +374,12 @@ If the layout of the player screen changes due to server-side changes, unintende General - Change layout - Original - Phone - Phone (Max 480 dp) - Tablet - Tablet (Min 600 dp) - Change start page + Default Browse channels Courses / Learning - Default Explore + Fashion & Beauty Gaming History Library @@ -338,8 +387,11 @@ If the layout of the player screen changes due to server-side changes, unintende Live Movies Music + News Notifications + Podcasts Search + Shopping Shorts Sports Subscriptions @@ -373,13 +425,19 @@ Limitation: Back button on the toolbar may not work." Hide gray separators Gray separators are hidden. Gray separators are shown. - Hide snack bar - Snack bar is hidden. - Snack bar is shown. Remove viewer discretion dialog "Removes the viewer discretion dialog. This does not bypass the age restriction. It just accepts it automatically." + Change layout + Original + Phone + Phone (Max 480 dp) + Tablet + Tablet (Min 600 dp) + Change live ring click action + Channel opens when the live ring is clicked. + Live stream opens when the live ring is clicked. Spoof app version Version spoofed Version not spoofed @@ -441,7 +499,7 @@ Some components may not be hidden." Playlist downloader package name Package name of your installed external downloader app, such as YTDLnis. - + Override YouTube Music button YouTube Music button opens the RVX Music. YouTube Music button opens the native app. @@ -455,7 +513,7 @@ Some components may not be hidden." Miniplayer - Change the style of the in app minimized player. + Change the style of the in-app minimized player. Miniplayer type Disabled @@ -482,7 +540,7 @@ Miniplayer can be dragged to any corner of the screen." Enable horizontal drag gesture. "Horizontal drag gesture enabled. -Miniplayer can be dragged off screen to the left or right." +Miniplayer can be dragged off-screen to the left or right." Horizontal drag gesture disabled. Hide close button Close button is hidden. @@ -567,9 +625,9 @@ If this setting do not take effect, try switching to Incognito mode." Hide Data saving menu Data saving menu is hidden. Data saving menu is shown. - Hide Autoplay menu - Autoplay menu is hidden. - Autoplay menu is shown. + Hide Autoplay or Playback menu + Autoplay or Playback menu is hidden. + Autoplay or Playback menu is shown. Hide Video quality preferences menu Video quality preferences menu is hidden. Video quality preferences menu is shown. @@ -616,6 +674,28 @@ If this setting do not take effect, try switching to Incognito mode." About menu is hidden. About menu is shown. + + Snack bar + Hide or change components related to snack bar. + + Hide snack bar + Snack bar is hidden. + Snack bar is shown. + Hide server-side snack bar + Server-side snack bar is hidden. + Server-side snack bar is shown. + Invert snack bar theme + Theme of the snack bar is inverted. + Theme of the snack bar is not inverted. + Change server-side snack bar background + Background color of the server-side snackbar has changed. + Background color of the server-side snackbar has not changed. + "Some snack bars use a theme defined on the server side, not the app theme. + +Change the background color of these snack bars. + +If there are server-side changes, the background color of the snack bar may not change." + Toolbar Hide or change components located on the toolbar, such as the search bar, toolbar buttons, and header. @@ -627,12 +707,17 @@ If this setting do not take effect, try switching to Incognito mode." Wide search bar is enabled. Wide search bar is disabled. Enable wide search bar with header - Wide search bar does not hide the YouTube header. - Wide search bar hides the YouTube header. + Wide search bar is enabled along with the YouTube header. + Wide search bar disables and uses the YouTube header space. Enable wide search bar in You tab - "Enabling this setting will disable the Settings button in the You tab. + "Wide search bar is enabled in the You tab. -In this case, please use the following path to access the settings: +To access settings, please use the following path: +You tab → View channel → Menu → Settings" + Wide search bar is disabled in the You tab. + "Enabling this setting will disable the Settings button in the You tab. + +In this case, you may need to use the following path to access the settings: You tab → View channel → Menu → Settings" Hide Cast button Cast button is hidden. @@ -679,7 +764,7 @@ Tap and hold to open RVX settings." "Auto switch mix playlists is enabled when autoplay is turned on. Autoplay can be changed in YouTube settings: -Settings → Autoplay → Autoplay next video" +Settings → Autoplay / Playback → Autoplay next video" Enabling this feature will disable automatic switching to YouTube Mix when playing music while autoplay is turned on. Disable player popup panels Auto player popup panels are disabled. @@ -705,9 +790,9 @@ Note: Hide end screen cards End screen cards are hidden. End screen cards are shown. - Hide film strip overlay - Film strip overlay is hidden. - Film strip overlay is shown. + Hide filmstrip overlay + Filmstrip overlay is hidden. + Filmstrip overlay is shown. Hide info cards Info cards are hidden. Info cards are shown. @@ -783,6 +868,43 @@ Settings → Autoplay / Playback → Autoplay next video" Thanks button is hidden. Thanks button is shown. + + Hide by index + + Hide first button + First button is hidden. + First button is shown. + Hide second button + Second button is hidden. + Second button is shown. + Hide third button + Third button is hidden. + Third button is shown. + Hide fourth button + Fourth button is hidden. + Fourth button is shown. + Hide fifth button + Fifth button is hidden. + Fifth button is shown. + Hide sixth button + Sixth button is hidden. + Sixth button is shown. + Hide seventh button + Seventh button is hidden. + Seventh button is shown. + Hide eighth button + Eighth button is hidden. + Eighth button is shown. + + + Hide by index in live stream + + About Hide action button by index + "Hide the action buttons by index before the action buttons are initialized. + +- Hiding the action buttons leaves no empty space. +- Index of the action buttons may not always be the same button." + Ambient mode Disable Ambient mode or bypass Ambient mode restrictions. @@ -987,7 +1109,7 @@ Limitation: Video title disappears when clicked." Configure the spacing from the seekbar to the quick action container, between 0-32. Quick actions top margin must be between 0-32. - + Disable landscape mode Video orientation is portrait mode in fullscreen. Video orientation follows device settings in fullscreen. @@ -995,7 +1117,8 @@ Limitation: Video title disappears when clicked." Controls overlay does not fill the fullscreen. Controls overlay fills the fullscreen. Keep landscape mode - Keeps landscape mode when turning the screen off and on in fullscreen. + Videos continue to play in landscape mode after turning the screen off and on. + Videos play in portrait mode after turning the screen off and on. Keep landscape mode timeout The amount of milliseconds the landscape mode is forced after the screen in turned on. @@ -1196,7 +1319,7 @@ This feature works best with a very fast internet connection." Transcript section is hidden. Transcript section is shown. - + Disable video description interaction "Disables the following interactions when the video description is expanded: @@ -1224,7 +1347,7 @@ The Expand video description option may not work if the entered string does not "Floating buttons like 'Use this sound' are hidden in the Shorts channel tab." "Floating buttons like 'Use this sound' are shown in the Shorts channel tab." - + Shorts shelves Hide Shorts shelves @@ -1250,13 +1373,16 @@ Info: Hidden in watch history. Shown in watch history. - + Change Shorts background repeat state Change Shorts repeat state Autoplay Default Pause Repeat + Open Shorts in regular player + Open Shorts in the regular player. + Do not open Shorts in the regular player. Shorts player @@ -1409,11 +1535,11 @@ Press and hold the More button to show the Custom actions dialog." Repeat state menu is shown. Repeat state menu is hidden. About Custom actions - "This feature is still experimental, so there is no guarantee that it will work perfectly. + "This feature is still experimental, so there is no guarantee that it will work perfectly. Most bugs cannot be fixed due to client-side limitations, so use it only for testing purposes." - + Enable timestamps "Timestamp is enabled. @@ -1586,14 +1712,14 @@ A different codec will be applied after about 20 seconds of buffering." Dislikes are shown. Dislikes are not shown. Show dislikes on Shorts - Dislikes shown on Shorts. - "Dislikes shown on Shorts. + Dislikes are shown on Shorts. + "Dislikes are shown on Shorts. Limitation: Dislikes may not appear if the user is not logged in or in incognito mode." - Dislikes hidden on Shorts. + Dislikes are hidden on Shorts. Dislikes as percentage - Dislikes shown as a percentage. - Dislikes shown as a number. + Dislikes are shown as a percentage. + Dislikes are shown as a number. Compact Like button Like button styled for minimum width. Like button styled for best appearance. @@ -1634,7 +1760,7 @@ Limitation: Dislikes may not appear if the user is not logged in or in incognito The daily quota for API keys on the free plan is 10,000, and 1 quota is used to replace a handle with a username for 1 comment. -Click to see how to issue a API key." +Click to see how to issue an API key." Issue YouTube Data API v3 developer key 1. Go to <a href=%1$s>Create a new project</a>.<br>2. Click the <b>CREATE</b> button.<br>3. Go to <a href=%2$s>YouTube Data API v3</a>.<br>4. Click the <b>ENABLE</b> button.<br>5. Click the <b>CREATE CREDENTIALS</b> button.<br>6. Select the <b>Public data</b> option.<br>7. Click the <b>NEXT</b> button.<br>8. Copy the API key.<br><br>※ API key should never be shared with others, so it is not included in Import / Export settings. @@ -1642,7 +1768,7 @@ Click to see how to issue a API key." SponsorBlock Enable SponsorBlock - SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos. + SponsorBlock is a crowdsourced system for skipping annoying parts of YouTube videos. Appearance @@ -1766,13 +1892,13 @@ Click to see how to issue a API key." API URL changed. Copy Import / Export settings - Your SponsorBlock JSON configuration that can be imported / exported to ReVanced Extended and other SponsorBlock platforms. - Your SponsorBlock JSON configuration that can be imported / exported to ReVanced Extended and other SponsorBlock platforms. This includes your private user id. Be sure to share this wisely. + Your SponsorBlock JSON configuration that can be imported / exported to RVX and other SponsorBlock platforms. + Your SponsorBlock JSON configuration that can be imported / exported to RVX and other SponsorBlock platforms. This includes your private user id. Be sure to share this wisely. Settings imported successfully. Failed to import: %s. Failed to export: %s. - Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n + Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password, and it should never be shared.\n Do not show again SponsorBlock temporarily unavailable. @@ -1845,28 +1971,28 @@ Click to see how to issue a API key." Miscellaneous + Bypass URL redirects + URL redirects are bypassed. + URL redirects are not bypassed. Disable QUIC protocol - "Disable CronetEngine's QUIC protocol." + "Disables CronetEngine's QUIC protocol." Enable debug logging Debug logs are enabled. Debug logs are disabled. Enable debug buffer logging Debug logs include the buffer. Debug logs do not include the buffer. - Enable external browser - External browser is enabled. - External browser is disabled. - Enable open links directly - Bypassing URL redirects. - Following default redirect policy. + Open links externally + Opens links in the external browser. + Opens links in the in-app browser. Sanitize sharing links Sanitizes sharing links by removing tracking query parameters. Open default app settings - To open YouTube links in RVX, enable \'Open supported links\' and enable the supported web addresses. + To open YouTube links in RVX, enable Open supported links and enable all the Supported web addresses. Open GmsCore settings - Opens GmsCore settings. Then enable cloud messaging to receive notifications. + To receive notifications in RVX, enable Cloud Messaging. GmsCore is not installed. Install it. Action needed "GmsCore does not have permission to run in the background. @@ -1886,11 +2012,11 @@ Tap the continue button and allow optimization changes." System share sheet is used. In-app share sheet is used. Enable OPUS codec - Enable the OPUS codec if the player response includes the OPUS codec. + Enables the OPUS codec if the player response includes it. Import / Export settings - Import or export settings. + Import / Export RVX settings. Import / Export as file @@ -1902,7 +2028,7 @@ Tap the continue button and allow optimization changes." Import / Export as text Import / Export as text - Import or export settings as text. + Import / Export settings as text. Failed to export settings. Settings were successfully exported. @@ -1925,6 +2051,8 @@ Tap the continue button and allow optimization changes." "Android TV (Login required)" Android VR + "Android VR +(No auth)" "iOS (PoToken required)" "iOS TV @@ -1946,6 +2074,7 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi Show in Stats for nerds Client used to fetch streaming data is shown in Stats for nerds. Client used to fetch streaming data is hidden in Stats for nerds. + VR default audio stream language PoToken / VisitorData @@ -2001,3 +2130,4 @@ Click to see more information." Included Stock + diff --git a/patches/src/main/resources/youtube/settings/values-v21/strings.xml b/patches/src/main/resources/youtube/settings/values-v21/strings.xml index 6fe87a4c3..760062454 100644 --- a/patches/src/main/resources/youtube/settings/values-v21/strings.xml +++ b/patches/src/main/resources/youtube/settings/values-v21/strings.xml @@ -4,4 +4,5 @@ @string/revanced_spoof_streaming_data_side_effects_android @string/revanced_spoof_streaming_data_side_effects_android @string/revanced_spoof_streaming_data_side_effects_android + @string/revanced_spoof_streaming_data_side_effects_android diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 8b7041508..ddf290997 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -102,7 +102,7 @@ - + @@ -114,10 +114,10 @@ - - + + SETTINGS: HIDE_FEED_COMPONENTS --> - + @@ -226,7 +226,7 @@ - + @@ -244,12 +244,21 @@ SETTINGS: HIDE_LAYOUT_COMPONENTS --> + + + SETTINGS: HIDE_LAYOUT_COMPONENTS --> @@ -301,8 +309,11 @@ - + + + + + + + + + + + + SETTINGS: SHORTS_CUSTOM_ACTIONS_SHARED --> @@ -646,7 +684,8 @@ SETTINGS: SHORTS_REPEAT_STATE_BACKGROUND --> + + SETTINGS: SHORTS_COMPONENTS --> @@ -714,7 +753,6 @@ @@ -798,6 +836,7 @@ + @@ -816,6 +855,9 @@ SETTINGS: WATCH_HISTORY --> + + @@ -823,11 +865,8 @@ SETTINGS: ENABLE_DEBUG_LOGGING --> - - - + @@ -839,6 +878,8 @@ PREFERENCE: GMS_CORE_SETTINGS --> + + @@ -869,6 +910,8 @@ + + @@ -876,10 +919,10 @@ - + @@ -913,12 +956,12 @@ + - - + diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index 8da01b007..c228283c4 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -19,6 +19,59 @@ "لم يتم تثبيت %1$s. الرجاء تنزيل %2$s من الموقع." %s لم يتم تثبيته. الرجاء تثبيته. + لغة RVX + لغة التطبيق + العربيّة + Azerbaijani + Bulgarian + Bengali + Catalan + Czech + Danish + German + Greek + English + Spanish + Estonian + فارسى + Finnish + French + Gujarati + Hindi + Croatian + Hungarian + Indonesian + Italian + Japanese + Kazakh + Korean + Lithuanian + Latvian + Macedonian + Mongolian + Marathi + Malay + Burmese + Dutch + Odia + Punjabi + Polish + Portugese + Romanian + Russian + Slovak + Slovene + Serbian + Swedish + Swahili + Tamil + Telugu + Thai + Turkish + Ukrainian + Urdu + Vietnamese + Chinese الإعلانات إخفاء إعلانات ملء الشاشة @@ -66,9 +119,9 @@ DeArrow & اللقطات الثابتة اللقطات الثابتة DeArrow - "يوفر DeArrow مُصغَّرات فيديو من مصادر جماعية لفيديوهات YouTube. غالبًا ما تكون مُصغَّرات الفيديو هذه ذات صلة أكثر من تلك التي يقدمها موقع YouTube. + "يوفر DeArrow مُصغَّرات فيديو تم جمعها من الجمهور لفيديوهات YouTube. غالبًا ما تكون مُصغَّرات الفيديو هذه ذات صلة أكثر من تلك التي يقدمها موقع YouTube. -في حالة التمكين، سيتم إرسال عناوين URL للفيديو إلى خادم API ولن يتم إرسال أي بيانات أخرى. إذا لم يكن الفيديو يحتوي على مُصغَّرات لـ DeArrow، فسيتم عرض اللقطات الأصلية أو الثابتة. +اذا تم تمكين هذا الخيار، سيتم إرسال عناوين URL للفيديو إلى خادم API ولن يتم إرسال أي بيانات أخرى. إذا لم يكن الفيديو يحتوي على مُصغَّرات لـ DeArrow، فسيتم عرض اللقطات الأصلية أو الثابتة. انقر هنا لمعرفة المزيد عن DeArrow." عرض ملاحظة إذا كان API غير متوفر @@ -101,14 +154,15 @@ إخفاء زر التَرْجَمَة تم إخفاء زر التَرْجَمَة. يتم عرض زر التَرْجَمَة. - إخفاء الرف الدائري - "يخفي الرفوف التالية: + إخفاء الرفوف الدوارة + "تم إخفاء الرفوف الدوارة، مثل: • أخبار عاجلة • متابعة المشاهدة • اكتشف المزيد من القنوات • استمع مجددا • التسوق • مشاهده مرة أخرى" + يتم عرض الرفوف الدوارة. إخفاء رف الشرائح تم إخفاء رف الشرائح. يتم عرض رف الشرائح. @@ -142,18 +196,18 @@ إخفاء هيّا نلعب تم إخفاء هيّا نلعب. يتم عرض هيّا نلعب. - إخفاء زر عرض المزيد - تم إخفاء زر عرض المزيد. - يتم عرض زر عرض المزيد. إخفاء شريط البحث تم إخفاء شريط البحث. يتم عرض شريط البحث. - إخفاء الاستبيانات - تم إخفاء الاستبيانات. - يتم عرض الاستبيانات الموجز. + إخفاء زر عرض المزيد + تم إخفاء زر عرض المزيد. + يتم عرض زر عرض المزيد. إخفاء دوائر الاشتراكات تم إخفاء دوائر الاشتراكات. يتم عرض دوائر الاشتراكات. + إخفاء الاستبيانات + تم إخفاء الاستبيانات. + يتم عرض الاستبيانات الموجز. إخفاء رفوف التذاكر تم إخفاء رفوف التذاكر. يتم عرض رفوف التذاكر. @@ -252,11 +306,12 @@ الفيديو الموصى به إخفاء فيديو المشاهدات المنخفضة - إخفاء الفيديوهات التي حصلت على أقل من 1000 مشاهدة من موجز الصفحة الرئيسية التي تم تحميلها من القنوات غير المشترك بها. + "إخفاء الفيديوهات التي حصلت على أقل من 1000 مشاهدة من موجز الصفحة الرئيسية التي تم تحميلها من القنوات غير المشترك بها. + +قد لا يعمل هذا الفلتر بعد الآن، استخدم \"فلتر عدد المشاهدات\" بدلاً من ذلك." إخفاء الفيديوهات الموصى بها "يخفي الفيديوهات الموصى بها التالية: -• الفيديوهات التي تحمل علامة للأعضاء فقط. • فيديوهات تحتوي على عبارات مثل 'شاهد الأشخاص أيضًا' أسفلها." تصفية عدد المشاهدات @@ -291,17 +346,12 @@ الموازن عام - تغيير التخطيط - الأساسي - الجوّال - الجوّال (الحد الأقصى 480 dp) - الجهاز اللوحي - الجهاز اللوحي (الحد الأدنى 600 dp) تغيير صفحة البداية + الافتراضي تصفح القنوات الدورات / التعلم - الافتراضي اكتشف + الموضة & الجمال ألعاب فيديو السجلّ المكتبة @@ -309,8 +359,11 @@ بث مباشر أفلام موسيقى + أخبار الإشعارات + البودكاست البحث + التسوق Shorts رياضة الاشتراكات @@ -343,11 +396,17 @@ إخفاء الفواصل الرمادية تم إخفاء الفواصل الرمادية. يتم عرض الفواصل الرمادية. - إخفاء شريط Snack Bar - تم إخفاء شريط Snack Bar. - يتم عرض شريط Snack Bar. إزالة مربع حوار تقدير المشاهد "يزيل مربع حوار تقدير المشاهد. هذا لا يتجاوز القيود العمرية. إنه يقبل ذلك تلقائيًا." + تغيير التخطيط + الأساسي + الجوّال + الجوّال (الحد الأقصى 480 dp) + الجهاز اللوحي + الجهاز اللوحي (الحد الأدنى 600 dp) + تغيير إجراء النقر على البث المباشر + يتم فتح القناة عند النقر على الحلقة المباشرة. + يتم فتح البث المباشر عند النقر على الحلقة المباشرة. إصدار تطبيق وهمي تم تغيير اصدار التطبيق لم يتم تغيير اصدار التطبيق @@ -401,7 +460,7 @@ يفتح زر تنزيل الفيديو أداة التنزيل الأصلية داخل التطبيق. اسم حزمة تنزيل قائمة التشغيل اسم الحزمة لتطبيق التنزيل الخارجي المثبت لديك، مثل YTDLnis. - + تجاوز زر موسيقى YouTube زر موسيقى YouTube يفتح موسيقى RVX. زر موسيقى YouTube يفتح التطبيق الأصلي. @@ -520,9 +579,9 @@ إخفاء قائمة توفير البيانات تم إخفاء قائمة توفير البيانات. يتم عرض قائمة توفير البيانات. - إخفاء قائمة التشغيل التلقائي - تم إخفاء قائمة التشغيل التلقائي. - يتم عرض قائمة التشغيل التلقائي. + إخفاء قائمة التشغيل التلقائي أو التشغيل + تم إخفاء قائمة التشغيل التلقائي أو التشغيل. + يتم عرض قائمة التشغيل التلقائي أو التشغيل. إخفاء قائمة الجودة المفضلة للفيديو تم إخفاء قائمة الجودة المفضلة للفيديو. يتم عرض قائمة الجودة المفضلة للفيديو. @@ -568,6 +627,26 @@ إخفاء قائمة لمحة تم إخفاء قائمة لمحة. يتم عرض قائمة لمحة. + + Snack Bar + إخفاء أو تغيير المكونات المتعلقة بشريط Snack Bar. + إخفاء شريط Snack Bar + تم إخفاء شريط Snack Bar. + يتم عرض شريط Snack Bar. + إخفاء شريط Snack Bar على جانب الخادم + تم إخفاء شريط Snack Bar على جانب الخادم. + يتم عرض شريط Snack Bar على جانب الخادم. + عكس سمة شريط Snack Bar + يتم عكس سمة شريط Snack Bar. + لا يتم عكس سمة شريط Snack Bar. + تغيير خلفية شريط Snack Bar على جانب الخادم + تم تغيير لون الخلفية لشريط Snack Bar على جانب الخادم. + لا يتم تغيير لون الخلفية لشريط Snack Bar على جانب الخادم. + "تستخدم بعض شرائط Snack Bar سمة محددة على جانب الخادم، وليس سمة التطبيق. + +غيّر لون الخلفية لشرائط Snack Bar هذه. + +إذا كانت هناك تغييرات على جانب الخادم، فقد لا يتغير لون خلفية شريط Snack Bar." شريط الأدوات إخفاء أو تغيير المكونات الموجودة على شريط الأدوات، مثل شريط الأدوات وأزرار شريط الأدوات والعلامة. @@ -578,13 +657,18 @@ تم تمكين شريط البحث العريض. تم تعطيل شريط البحث العريض. تمكين شريط البحث العريض مع العلامة - لا يخفي شريط البحث العريض علامة YouTube. - يخفي شريط البحث العريض علامة YouTube. + تم تمكين شريط البحث العريض جنبًا إلى جنب مع علامة YouTube. + يؤدي شريط البحث العريض إلى تعطيل مساحة علامة YouTube واستخدامها. تمكين شريط البحث العريض في علامة التبويب أنت - "سيؤدي تمكين هذا الإعداد إلى تعطيل زر الإعدادات في علامة التبويب أنت. + "تم تمكين شريط البحث العريض في علامة التبويب \"أنت\". -في هذه الحالة، يرجى استخدام المسار التالي للوصول إلى الإعدادات: -علامة التبويب أنت ← عرض القناة ← القائمة ← الإعدادات" +للوصول إلى الإعدادات، يرجى استخدام المسار التالي: +علامة التبويب \"أنت\" ← عرض القناة ← القائمة ← الإعدادات" + تم تعطيل شريط البحث العريض في علامة التبويب \"أنت\". + "سيؤدي تمكين هذا الإعداد إلى تعطيل زر \"الإعدادات\" في علامة التبويب \"أنت\". + +في هذه الحالة، قد تحتاج إلى استخدام المسار التالي للوصول إلى الإعدادات: +علامة التبويب \"أنت\" ← عرض القناة ← القائمة ← الإعدادات" إخفاء زر البث تم إخفاء زر البث. يتم عرض زر البث. @@ -626,7 +710,7 @@ "تم تمكين التبديل التلقائي لقوائم تشغيل التشكيلة عند تمكين التشغيل التلقائي. يمكن تغيير التشغيل التلقائي في إعدادات YouTube: -الإعدادات ← التشغيل التلقائي ← تشغيل الفيديو التالي تلقائيًا" +الإعدادات ← التشغيل التلقائي / التشغيل ← تشغيل الفيديو التالي تلقائيًا" سيؤدي تمكين هذه الميزة إلى تعطيل التبديل التلقائي إلى YouTube Mix عند تشغيل الموسيقى أثناء تمكين التشغيل التلقائي. تعطيل لوحات المشغل المنبثقة تم تعطيل لوحات المشغل المنبثقة تلقائيًا. @@ -677,7 +761,7 @@ "تم إخفاء شاشة نهاية الفيديو المقترح عند إيقاف التشغيل التلقائي. يمكن تغيير التشغيل التلقائي في إعدادات YouTube: -الإعدادات ← التشغيل التلقائي ← تشغيل الفيديو التالي تلقائيًا" +الإعدادات ← التشغيل التلقائي \ التشغيل ← تشغيل الفيديو التالي تلقائيًا" يتم عرض شاشة نهاية الفيديو المقترح. تخطي العد التنازلي للتشغيل التلقائي إذا تم تمكين التشغيل التلقائي، فسيتم تشغيل الفيديو التالي على الفور. @@ -727,6 +811,39 @@ إخفاء زر شكرًا تم إخفاء زر شكرًا. يتم عرض زر شكرًا. + + إخفاء حسب الفهرس + إخفاء الزر الأول + تم إخفاء الزر الأول. + يتم عرض الزر الأول. + إخفاء الزر الثاني + تم إخفاء الزر الثاني. + يتم عرض الزر الثاني. + إخفاء الزر الثالث + تم إخفاء الزر الثالث. + يتم عرض الزر الثالث. + إخفاء الزر الرابع + تم إخفاء الزر الرابع. + يتم عرض الزر الرابع. + إخفاء الزر الخامس + تم إخفاء الزر الخامس. + يتم عرض الزر الخامس. + إخفاء الزر السادس + تم إخفاء الزر السادس. + يتم عرض الزر السادس. + إخفاء الزر السابع + تم إخفاء الزر السابع. + يتم عرض الزر السابع. + إخفاء الزر الثامن + تم إخفاء الزر الثامن. + يتم عرض الزر الثامن. + + إخفاء حسب الفهرس في البث المباشر + لمحة عن إخفاء زر الإجراء حسب الفهرس + "إخفاء أزرار الإجراءات بواسطة الفهرس قبل تهيئة أزرار الإجراءات. + +- إخفاء أزرار الإجراءات لا يترك أي مساحة فارغة. +- قد لا يكون فهرس أزرار الإجراءات هو الزر نفسه دائمًا." وضع الإضاءة السينمائية تعطيل وضع الإضاءة السينمائية أو تجاوز قيود وضع الإضاءة السينمائية. @@ -919,7 +1036,7 @@ هامش إجراءات سريعة أعلى تكوين التباعد من شريط التقدم إلى حاوية الإجراء السريع، بين 0-32. يجب أن يكون الهامش العلوي للإجراءات السريعة بين 0-32. - + تعطيل الوضع الأفقي اتجاه الفيديو هو وضع عمودي في ملء الشاشة. اتجاه الفيديو يتبع إعدادات ملء الشاشة في الجهاز. @@ -927,7 +1044,8 @@ لا يملأ تراكب عناصر التحكم الشاشة الكاملة. يملأ تراكب عناصر التحكم الشاشة الكاملة. الإبقاء على الوضع الأفقي - يحافظ على الوضع الأفقي عند إيقاف تشغيل الشاشة وتشغيلها في وضع ملء الشاشة. + تستمر مقاطع الفيديو في التشغيل في الوضع الأفقي بعد إيقاف تشغيل الشاشة وتشغيلها. + يتم تشغيل مقاطع الفيديو في الوضع الطولي بعد إيقاف تشغيل الشاشة وتشغيلها. مهلة إبقاء الوضع الأفقي مقدار اجزاء الثانية التي يتم فرضها على الوضع الأفقي بعد تشغيل الشاشة. @@ -1115,7 +1233,7 @@ إخفاء قسم النص تم إخفاء قسم النص. يتم عرض قسم النص. - + تعطيل تفاعل وصف الفيديو "تعطيل التفاعلات التالية عند توسيع وصف الفيديو: @@ -1139,7 +1257,7 @@ إخفاء الزر العائم "تم إخفاء الأزرار العائمة مثل 'استخدام هذا الصوت' في علامة تبويب قناة Shorts." "يتم عرض الأزرار العائمة مثل 'استخدام هذا الصوت' في علامة تبويب قناة Shorts." - + رفوف Shorts إخفاء رفوف Shorts "إخفاء رفوف Shorts @@ -1163,13 +1281,16 @@ إخفاء في سجل المشاهدة مخفي في سجل المشاهدة. يُعرض في سجل المشاهدة. - + تغيير حالة تكرار فيديوهات Shorts في الخلفية تغيير حالة تكرار Shorts التشغيل التلقائي الافتراضي إيقاف تكرار + فتح Shorts في المشغل العادي + يتم فتح فيديوهات Shorts في المشغل العادي. + لا يتم فتح فيديوهات Shorts في المشغل العادي. مُشَغِل Shorts إخفاء أو عرض المكونات في مشغل Shorts. @@ -1315,10 +1436,10 @@ يتم عرض قائمة حالة التكرار. تم إخفاء قائمة حالة التكرار. لمحة عن الإجراءات المخصصة - "لا تزال هذه الميزة تجريبية، لذا لا يوجد ضمان بأنها ستعمل بشكل مثالي. + "لا تزال هذه الميزة تجريبية، لذا لا يوجد ضمان بأنها ستعمل بشكل مثالي. لا يمكن إصلاح معظم الأخطاء بسبب القيود المفروضة على جانب العميل، لذا استخدمها لأغراض الاختبار فقط." - + تمكين الطوابع الزمنية "تم تمكين الطابع الزمني. @@ -1371,17 +1492,11 @@ تم تمكين إيماءات التمرير في وضع شاشة القفل. تم تعطيل إيماءات التمرير في وضع شاشة القفل. شفافية خلفية واجهة إيماءة التمرير - قيمة شفافية خلفية واجهة التمرير (0-255). - -الافتراضي:127 + شفافية خلفية واجهة التمرير. مقدار حد التمرير - مقدار الحد الأدنى للتمرير قبل اكتشاف الإيماءة. - -الافتراضي:0 + الحد الأقصى للتمرير قبل اكتشاف الإيماءة. حجم نص واجهة إيماءة التمرير - حجم النص على واجهة التمرير. - -الافتراضي:27 + حجم النص في واجهة التمرير. حجم واجهة إيماءة التمرير النسبة المئوية لمساحة الشاشة القابلة للتمرير السريع.\n\nملاحظة: سيؤدي هذا أيضًا إلى تغيير حجم مساحة الشاشة لإيماءة النقر المزدوج للتقديم أو التأخير. لا يمكن أن يزيد حجم المنطقة القابلة للتمرير السريع عن 50. @@ -1538,7 +1653,7 @@ SponsorBlock تمكين SponsorBlock - مانِع الرُعَاة هو نظام جماعي لتخطي الأجزاء المُمِلَّة في فيديوهات YouTube. + SponsorBlock مانِع الرُعَاة هو نظام جماعي لتخطي الأجزاء المزعجة من فيديوهات YouTube. المظهر عرض زر التصويت @@ -1654,12 +1769,12 @@ تم تغيير رابط API. نسخ استيراد / تصدير الإعدادات - تكوين SponsorBlock JSON الخاص بك والذي يمكن استيراده/تصديره إلى ReVanced Extended ومنصات SponsorBlock الأخرى. - تكوين SponsorBlock الخاص بك كتنسيق JSON الذي يمكن استيراده / تصديره إلى ReVanced Extended وغيره من منصات SponsorBlock الأخرى. يتضمن هذا معرف المستخدم الفريد الخاص بك. تأكد من مشاركته بحكمة. + تكوين SponsorBlock JSON الخاص بك والذي يمكن استيراده / تصديره إلى RVX ومنصات SponsorBlock الأخرى. + تكوين SponsorBlock الخاص بك كتنسيق JSON الذي يمكن استيراده / تصديره إلى RVX وغيره من منصات SponsorBlock الأخرى. يتضمن هذا معرف المستخدم الفريد الخاص بك. تأكد من مشاركته بحكمة. تم استيراد الإعدادات بنجاح. فشل استيراد: %s. فشل تصدير: %s. - تحتوي إعداداتك على معرف مستخدم خاص لـ SponsorBlock.\n\n معرف المستخدم الخاص بك يشبه كلمة المرور ويجب عدم مشاركته أبدًا.\n + تحتوي إعداداتك على معرف مستخدم SponsorBlock خاص.\n\nمعرف المستخدم الخاص بك يشبه كلمة مرور، ولا ينبغي مشاركته مطلقًا.\n لا تعرض مرة أخرى SponsorBlock غير متوفر مؤقتًا. SponsorBlock غير متوفر مؤقتًا (الحالة %d). @@ -1723,26 +1838,26 @@ يتم توفير البيانات بواسطة SponsorBlock API. اضغط هنا لمعرفة المزيد والتنزيل لمنصات أخرى. خيارات متنوعة + تجاوز عمليات إعادة توجيه عناوين URL + تم تجاوز عمليات إعادة توجيه عناوين URL. + لا يتم تجاوز عمليات إعادة توجيه عناوين URL. تعطيل بروتوكول QUIC - "تعطيل بروتوكول QUIC الخاص بـ CronetEngine." + "تم تعطيل بروتوكول QUIC الخاص بـ CronetEngine." تمكين سجلات التصحيح تم تمكين Debug Logs. تم تعطيل Debug Logs. تمكين تسجيل تصحيح المخزن المؤقت سجلات التصحيح تشمل التخزين المؤقت. سجلات التصحيح لا تشمل التخزين المؤقت. - تمكين المتصفح الخارجي - تم تمكين المتصفح الخارجي. - تم تعطيل المتصفح الخارجي. - تمكين فتح الروابط بشكل مباشر - تجاوز عمليات إعادة توجيه URL. - يتبع سياسة إعادة التوجيه الافتراضية. + فتح الروابط خارجيًا + يفتح الروابط في المتصفح الخارجي. + يفتح الروابط في متصفح التطبيق. تطهير روابط المشاركة يزيل معلمات استعلام التتبع من عناوين URL عند مشاركة الروابط. فتح إعدادات التطبيق الافتراضية - لفتح روابط YouTube في RVX، قم بتمكين \'فتح الروابط المدعومة\' وتمكين عناوين الويب المدعومة. + لفتح روابط YouTube في RVX، قم بتمكين خيار فتح الروابط المدعومة وتمكين جميع عناوين الويب المدعومة. فتح إعدادات GmsCore - فتح إعدادات GmsCore. ثم قم بتمكين المراسلة السحابية لتلقي الإشعارات. + لتلقي الإشعارات في RVX، قم بتمكين المراسلة السحابية. لم يتم تثبيت GmsCore. قم بتثبيته. الإجراء مطلوب "ليس لدى GmsCore إذن للتشغيل في الخلفية. @@ -1761,10 +1876,10 @@ يتم استخدام لوح مشاركة النظام. يتم استخدام لوح مشاركة داخل التطبيق. تمكين ترميز OPUS - تمكين ترميز OPUS إذا كانت استجابة المشغل تتضمن برنامج ترميز OPUS. + يقوم بتمكين ترميز OPUS إذا كانت استجابة المشغل تتضمن برنامج ترميز OPUS. استيراد / تصدير الإعدادات - إستيراد أو تصدير الإعدادات. + إستيراد \ تصدير إعدادات RVX. استيراد / تصدير كملف تصدير الإعدادات @@ -1774,7 +1889,7 @@ استيراد / تصدير كنص استيراد / تصدير كنص - استيراد أو تصدير الإعدادات كنص. + استيراد \ تصدير الإعدادات كنص. فشل تصدير الإعدادات. تم تصدير الإعدادات بنجاح. استيراد @@ -1795,6 +1910,8 @@ "Android TV (يتطلب تسجيل الدخول)" Android VR + "Android VR +(بدون مصادقة)" "iOS (يتطلب PoToken)" "iOS TV @@ -1816,6 +1933,7 @@ AVC لديه حد أقصى للدقة 1080p، لا يتوفر ترميز الص عرض في إحصاءات تقنية يتم عرض العميل المستخدم لجلب بيانات البث في إحصاءات تقنية. تم إخفاء العميل المستخدم لجلب بيانات البث في إحصاءات تقنية. + لغة البث الصوتي الافتراضية للواقع الافتراضي VR PoToken / VisitorData استخدام PoToken diff --git a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml index 2fc34180a..a7c4c0518 100644 --- a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml +++ b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml @@ -19,6 +19,59 @@ "%1$s не е инсталиран. Моля, изтеглете %2$s от уебсайта." %s не е инсталирано. Моля инсталирайте го. + RVX език + Език на приложението + Арабски + Азербайджански + Български + Бенгалски + Каталонски + Чешки + Датски + Немски + Гръцки + Английски + Испански + Естонски + Персийски + Финландски + Френски + Гуджарати + Хинди + Хърватски + Унгарски + Индонезийски + Италиански + Японски + Казахстански + Корейски + Литовски + Латвийски + Македонски + Монголски + Маратхи + Малайски + Бирмански + Холандски + Ория + Пенджабски + Полски + Португалски + Румънски + Руски + Словашки + Словенски + Сръбски + Шведски + Суахили + Тамилски + Телугу + Тайландски + Турски + Украински + Урду + Виетнамски + Китайски Реклами Скриване на рекламите в режим на цял екран @@ -98,12 +151,14 @@ Бутона за субтити е скрит. Бутона за субтити се показва. Скриване на рафта с Препоръчани - "Скрива следните рафтове: -- Извънредни новини -- Продължете да гледате -- Разгледайте още канали -- Пазаруване -- Гледайте отново" + "Скрива рафтове: +• Извънредни новини +• Продължете да разглеждате +• Още канали +• Слушайте отново +• Покупки +• Гледайте отново" + Показани са рафтовете. Скриване на филмовите рафтове Филмовите рафтове са скрити. Филмовите рафтове се показват. @@ -137,18 +192,18 @@ Игри в YouTube Игри в YouTube са скрити. Игрите в YouTube се показват. - Скриване на бутона Покажи още - Бутона Покажи още е скрит. - Бутона Покажи още се показва. Лента за търсене в емисията Лентата за търсене в емисията е скрита. Лентата за търсене в емисията се показва. - Скриване на анкети в емисиите - Анкетите за емисии са скрити. - Анкетите за емисии се показват. + Скриване на бутона Покажи още + Бутона Покажи още е скрит. + Бутона Покажи още се показва. Секция на канала в раздела „Публикации“ Лентата „Абонаменти“ е скрита. Показва се лентата „Абонаменти“. + Скриване на анкети в емисиите + Анкетите за емисии са скрити. + Анкетите за емисии се показват. Секция за билети Рафтовете с билети са скрити. Рафтовете с билети се показват. @@ -243,7 +298,7 @@ Препоръчани видеоклипове Скриване на видеоклипове с малко гледания - Скрийте видеоклипове с по-малко от 1000 гледания от емисията и от канали, за които сте се абонирали. + "Скрийте видеоклипове с по-малко от 1000 гледания от емисията и от канали, за които сте се абонирали." Скриване на Препоръчани видеоклипове "Скрива следните препоръчани видеоклипове: @@ -279,17 +334,12 @@ Компенсиране Основни настройки - Промяна на резолюция - Оригинал - Телефон - Телефон (Max 480 dip) - Таблет - Таблет (Мин 600 dip) Промяна на началната страница + По подразбиране Разглеждане на канала Курсове / Обучение - По подразбиране Проучване + Мода & Красота Игри История Библиотека @@ -297,8 +347,11 @@ На Живо Филми Музика + Новини Известия + Подкасти Търсене + Пазаруване Shorts Спорт Абонаменти @@ -331,11 +384,17 @@ Скриване на сивия разделител Сивите разделители са скрити. Сивите разделители са показани. - Скриване на лентата за състояние - Лентата на състоянието е скрита. - Лентата на състоянието се показва. Прозорец за възрастово ограничение "Премахва диалоговите прозорци. Това не заобикаля възрастовите ограничения, но ги приема автоматично." + Промяна на резолюция + Оригинал + Телефон + Телефон (Max 480 dip) + Таблет + Таблет (Мин 600 dip) + Действие на кликване върху точка за предаване на живо + Каналът се отваря, когато се щракне върху пръстена на живо. + Потокът на живо се отваря, когато се щракне върху пръстена на живо. Променете версията на приложението Подправена версия Не подправена версия @@ -386,7 +445,7 @@ Бутонът за изтегляне на YouTube отваря собствената програма за изтегляне на приложението. Име на приложението за изтегляне Име на пакета на приложението за изтегляне като NewPipe или YTDLnis. - + Замяна на бутона YouTube Music Бутонът YouTube Music отваря RVX Music. Бутонът YouTube Music отваря вграденото приложение. @@ -504,9 +563,9 @@ Икономия на данни Менюто за икономия на данни е скрито. Менюто за икономия на данни се показва. - Скрийте менюто „Автоматично пускане“ - Менюто „Автоматично пускане“ е скрито. - Показва се менюто „Автоматично пускане“. + Меню за автоматично пускане или възпроизвеждане + Менюто е скрито. + Менюто се показва. Меню „Предпочитания за качество на видеото“ Менюто ескрито. Менюто се показва. @@ -552,6 +611,12 @@ Скрийте менюто „Относно“ Менюто е скрито. Менюто се пказва. + + Snack bar (долната лента със съобщения) + Скрива или модифицира компоненти, свързани със снекбара (бялата лента, която се появява в долната част, когато промените качеството на изображението и т.н.). + Скриване на лентата за състояние + Лентата на състоянието е скрита. + Лентата на състоянието се показва. Лента с инструменти Скрива или променя елементи, разположени в лентата с инструменти, като бутони на лентата с инструменти, лента за търсене, заглавия. @@ -565,8 +630,14 @@ Логото на YouTube се появява до широката лента за търсене. Широка лента за търсене замества логото на YouTube. Активирайте широката лента за търсене в раздела \"Вие\" - "Тази опция ще деактивира бутона \"Настройки\" в раздела \"Вие\" -Използвайте следната последователност: + "Широката лента за търсене е активирана в раздела Вие. + +За достъп до настройките, моля, използвайте следния път: +Вие → Преглед на канала → Меню → Настройки" + Широката лента за търсене е деактивирана в раздела Вие. + "Тази опция ще деактивира бутона \"Настройки\" в раздела \"Вие\" + +Използвайте следната последователност в настройките: раздел \"Вие\" -> Страница на канала -> Меню -> Настройки" Скриване на бутона за предаване на Тв Бутонът за предаване е скрит. @@ -709,6 +780,14 @@ Скриване на бурона за благодарност Бутона за благодарност е скрит. Бутона за благодарност се показва. + + Скриване на третия бутон + Бутона е скрит. + Бутона се показва. + Скриване на четвъртия бутон + Бутона е скрит. + Бутона се показва. + Подсветка около видеото Изключете подсветка около видеото или прескочете ограничението в режим за пестене на батерията. @@ -903,7 +982,7 @@ Височина на лентата за напредък Промяна на височината на лентата за прогрес, стойности между 0-32. Височината трябва да е между 0-32, нулиране. - + Пейзажен режим при отиване на цял екран Пейзажният режим в режим на цял екран е деактивиран. Пейзажният режим в режим на цял екран е активиран. @@ -911,7 +990,6 @@ По-малките стилови контроли са активирани. По-малките стилови контроли са деактивирани. Запазете пейзажен режим - Запазва пейзажен режим при изключване и включване на цял екран. Запазване на времето за изчакване в пейзажен режим Броят милисекунди, за да принудите пейзажния режим да работи. @@ -1096,7 +1174,7 @@ Скриване на раздела за транскрипция Разделът за транскрипция е скрит. Разделът за транскрипция е показан. - + Деактивирайте взаимодействието с описание на видеоклипа "Деактивирайте следните взаимодействия, когато се отвори описанието на видеоклипа: @@ -1120,7 +1198,7 @@ Скриване на изскачащ бутон "Изскачащи бутони като „Използване на този звук“ са скрити в раздела Shorts." "Изскачащи бутони като „Използване на този звук“ Се показват в раздела Shorts." - + Shorts рафтове Скрийте рафтовете Shorts "Скрива рафтовете за кратки видеа @@ -1144,7 +1222,7 @@ Скриване в историята на гледане Скрити в историята на гледане. Показват се в историята на гледане. - + Промяна на фона на Shorts приповторение Промяна на състоянието - повторение на Shorts Автоматично изпълнение @@ -1296,10 +1374,7 @@ Показва се режим на повторение. Режим на повторение е скрит. Относно действията на потребителя - "Експериментална функция! -Без гаранция за работа! -Повечето грешки не могат да бъдат коригирани поради ограничения от страна на клиента, така че го използвайте само за тестване." - + Активиране на дата и час "Времевите показатели са активирани. Ограничения: @@ -1702,12 +1777,6 @@ Вкл. отчети за грешки Файлове с отчети за грешки в буфера. Файлове с отчети за грешки не включват буфера. - Включване на външен браузър - Външния браузър е включен. - Външния браузър е изключен. - Отваряне на връзки директно - Заобикаляне на URL пренасочвания. - Следване на правилата за пренасочване по подразбиране. Почистване на споделените връзки Премахва параметрите на заявката за проследяване от URL адресите при споделяне на връзки. Отвори настройките по подразбиране @@ -1761,6 +1830,8 @@ "Android TV (Изисква се влизане)" Android VR + "Android VR +(Няма удостоверение)" "iOS (Необходим PoToken)" "iOS @@ -1782,6 +1853,7 @@ AVC има максимална разделителна способност о Показване в \"Разширени статистики\" Клиентът, използван за получаване на данни за потока, се показва в Статистика за системни администратори. Клиентът, използван за получаване на данни за поток, е скрит в Статистика за системни администратори. + VR език по подразбиране на аудиопотока PoToken / VisitorData PoToken diff --git a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml index 4e6277bad..d8fe125b8 100644 --- a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml +++ b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml @@ -102,12 +102,6 @@ Tippen Sie hier, um mehr über DeArrow zu erfahren." Schaltfläche \"Untertitel\" ist versteckt. Schaltfläche \"Untertitel\" wird angezeigt. Karussellregal ausblenden - "Versteckt folgende Abschnitte: -- Aktuelle Nachrichten -- Weiterschauen -- Entdecke mehr Kanäle -- Shopping -- Erneut anschauen" Chips-Abschnitt verstecken Chips-Abschnitt wird versteckt. Chips-Abschnitt wird angezeigt @@ -141,18 +135,18 @@ Tippen Sie hier, um mehr über DeArrow zu erfahren." Spielbare Elemente ausblenden Spielbare Elemente sind ausgeblendet. Spielbare Elemente werden angezeigt. - Schaltfläche „Mehr anzeigen“ ausblenden - Die Schaltfläche „Mehr anzeigen“ ist ausgeblendet. - Die Schaltfläche „Mehr anzeigen“ wird angezeigt. Feed Suchleiste ausblenden Feed Suchleiste ist ausgeblendet. Feed Suchleiste wird angezeigt. - Feed-Umfragen verstecken - Feed-Umfragen sind versteckt - Feed-Umfragen werden angezeigt + Schaltfläche „Mehr anzeigen“ ausblenden + Die Schaltfläche „Mehr anzeigen“ ist ausgeblendet. + Die Schaltfläche „Mehr anzeigen“ wird angezeigt. Abonnement-Karussell ausblenden Abonnement-Karussell ist versteckt. Karussell für Abonnements wird angezeigt. + Feed-Umfragen verstecken + Feed-Umfragen sind versteckt + Feed-Umfragen werden angezeigt Ticket-Abschnitte verstecken Ticket-Abschnitte sind versteckt Ticket-Abschnitte werden angezeigt @@ -248,7 +242,7 @@ Einschränkungen: Empfohlene Videos Videos mit wenigen Aufrufen verstecken - Verstecke Videos mit weniger als 1000 Aufrufen von nicht abonnierten Kanälen von der Startseite. + "Verstecke Videos mit weniger als 1000 Aufrufen von nicht abonnierten Kanälen von der Startseite." Empfohlene Videos ausblenden "Versteckt die folgenden empfohlenen Videos: @@ -287,15 +281,9 @@ Wenn sich das Layout des Wiedergabebildschirms aufgrund serverseitiger Änderung Offset Allgemein - Layout ändern - Original - Telefon - Telefon (max. 480 dp) - Tablet - Tablet (min. 600 dp) Startseite ändern - Kanäle durchstöbern Standard + Kanäle durchstöbern Entdecken Spiele Verlauf @@ -333,12 +321,15 @@ Einschränkung: Zurück-Taste in der Symbolleiste funktioniert möglicherweise n Graue Trennzeichen ausblenden Graue Trennzeichen sind ausgeblendet Graue Trennzeichen werden angezeigt - Snackbar verstecken - Snackbar ist versteckt - Snackbar wird angezeigt Diskretion des Betrachters entfernen "Entfernt den Diskretionsdialog des Betrachters. Dies umgeht nicht die Altersbeschränkung. Es akzeptiert ihn nur automatisch." + Layout ändern + Original + Telefon + Telefon (max. 480 dp) + Tablet + Tablet (min. 600 dp) Spoof App Version Version gefälscht Version nicht gefälscht @@ -383,7 +374,7 @@ Manche Komponenten könnten nicht versteckt werden." Download-Button Überschreibe Video-Download-Button - + YouTube Musik-Button überschreiben YouTube Music Button öffnet RVX Music. YouTube Musik-Button öffnet die native App. @@ -480,9 +471,6 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z \"Niedrigerer Datenverbrauch\" ausblenden \"Niedrigerer Datenverbrauch\" wird ausgeblendet. \"Niedrigerer Datenverbrauch\" wird angezeigt. - Autoplay ausblenden - Autoplay wird ausgeblendet. - Autoplay wird angezeigt. Einstellungen für Videoqualität ausblenden Einstellungen für Videoqualität wird ausgeblendet. Einstellungen für Videoqualität wird angezeigt. @@ -528,6 +516,10 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z \"Über\" ausblenden \"Über\" wird ausgeblendet. \"Über\" wird angezeigt. + + Snackbar verstecken + Snackbar ist versteckt + Snackbar wird angezeigt Werkzeugleiste Verstecke oder ändere Toolbar-Komponenten, wie die Suchleiste, Buttons und Header. @@ -541,10 +533,6 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z Breite Suchleiste enthält YouTube Header Breite Suchleiste enthält nicht YouTube Header. Aktiviere breite Suchleiste in deinem Tab - "Aktivieren dieser Einstellung deaktiviert die Einstellungsschaltfläche in der Registerkarte \"Sie\". - -In diesem Fall verwenden Sie bitte den folgenden Pfad: -Sie Registerkarte > Kanal > Menü > Einstellungen." Verstecke Erstellen Schaltfläche Cast Button ist versteckt. Der Cast button wird angezeigt. @@ -679,6 +667,8 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Verstecke \"Danke\" Schaltfläche \"Danke\" Schaltfläche wird versteckt. \"Danke\" Schaltfläche wird angezeigt. + + Ambient-Modus Ambient-Modus deaktivieren oder Einschränkungen des Ambient-Modus umgehen. @@ -837,7 +827,7 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm."Schnelle Aktionen oberer Rand Konfigurieren Sie den Abstand von der Suchleiste auf die Meta-Leiste zwischen 0-32. Der obere Rand der Schnellaktionen muss zwischen 0-32 liegen. Zurückgesetzt auf Standardwerte. - + Querformat deaktivieren Querformat im Fullscreen Modus deaktiviert Querformat im Fullscreen Modus aktiviert @@ -845,7 +835,6 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm."Kompaktsteuerungs-Overlay ist aktiviert Kompaktsteuerungs-Overlay ist deaktiviert Querformat behalten - Bewahrt den Querformat beim Ausschalten des Bildschirms im Vollbild. Timeout für den Wechsel zum Querformat Die Anzahl der Millisekunden nach dem Einschalten des Bildschirms, nachdem Querformat erzwungen wird. @@ -984,7 +973,7 @@ Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen.< Schlüsselkonzepte sind ausgeblendet. Schlüsselkonzepte werden angezeigt. Transkriptabschnitte werden angezeigt - + Videobeschreibungsinteraktion deaktivieren "Deaktiviert die folgenden Interaktionen, wenn die Videobeschreibung erweitert wird: @@ -1002,7 +991,7 @@ Die Option \"Videobeschreibung\" kann nicht funktionieren, wenn die eingegebene Shorts-Player beim App-Start ausblenden Shorts-Player aktiv beim Start der Anwendung. Shorts-Player aktiv beim Start der Anwendung - + Verstecke Ausschnitte aus Shorts in Kanälen "Verstecke Shorts Regale. @@ -1017,7 +1006,7 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Community-Beiträge im Abonnement-Feed sind versteckt. Community-Beiträge im Abonnement-Feed werden angezeigt. Verstecke im Beobachtungsverlauf - + Autoplay Standard Pause @@ -1093,7 +1082,7 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Benutzerdefinierte Aktionen Video-URL kopieren Video öffnen - + Zeitstempel aktivieren "Zeitstempel ist aktiviert. @@ -1429,12 +1418,6 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Debug-Pufferprotokollierung aktivieren Debug-Protokolle enthalten Puffer. Debug-Protokolle enthalten keinen Puffer. - Aktiviere externen Browser - Externer Browser ist aktiviert - Externer Browser ist deaktiviert - Links direkt öffnen - Umgehung von URL-Umleitungen - Standard-Umleitungsrichtlinie folgen Standard-App-Einstellungen öffnen Um RVX in einem externen Browser zu öffnen, aktivieren Sie \'Unterstützte Links öffnen\' und aktivieren Sie die unterstützen Web-Adressen GmsCore öffnen diff --git a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml index cfa6cfb29..9b59a3443 100644 --- a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml @@ -7,7 +7,7 @@ ReVanced Extended Αναζήτηση %s Έγινε επαναφορά στις προεπιλεγμένες τιμές. - Πειραματικές Λειτουργίες + Πειραματικές λειτουργίες Θέλετε να συνεχίσετε; Επανεκκίνηση ώστε να φορτωθεί σωστά η διεπαφή Ανανέωση και επανεκκίνηση @@ -19,6 +19,59 @@ "Το %1$s δεν είναι εγκατεστημένο. Παρακαλούμε εγκαταστήστε το %2$s από την ιστοσελίδα." %s δεν έχει εγκατασταθεί. Παρακαλούμε εγκαταστήστε το. + Γλώσσα ρυθμίσεων RVX + Γλώσσα εφαρμογής + Αραβικά + Αζερική + Βουλγαρικά + Βεγγαλικά + Καταλανικά + Τσέχικα + Δανικά + Γερμανικά + Ελληνικά + Αγγλικά + Ισπανικά + Εσθονικά + Περσικά + Φινλανδικά + Γαλλικά + Γκουτζαρατικά + Χίντι + Κροατικά + Ουγγρικά + Ινδονησιακά + Ιταλικά + Ιαπωνικά + Καζακικά + Κορεάτικα + Λιθουανικά + Λετονικά + Σλαβομακεδονικά + Μογγολικά + Μαράτι + Μαλαισιανά + Βιρμανικά + Ολλανδικά + Οντία + Παντζάμπι + Πολωνικά + Πορτογαλικά + Ρουμανικά + Ρώσικα + Σλοβακικά + Σλοβενικά + Σέρβικα + Σουηδικά + Σουαχίλι + Ταμίλ + Τελούγκου + Ταϊλανδικά + Τούρκικα + Ουκρανικά + Ουρντού + Βιετναμέζικα + Κινέζικα Διαφημίσεις Διαφημίσεις πλήρους οθόνης @@ -100,13 +153,14 @@ Κρυμμένο. Εμφανίζεται. Οριζόντιες ενότητες προτάσεων - "Απόκρυψη ενοτήτων όπως: + "Απόκρυψη ενοτήτων όπως: • Έκτακτη είδηση • Συνέχεια παρακολούθησης • Εξερευνήστε περισσότερα κανάλια • Ακούστε ξανά • Αγορές • Παρακολουθήστε ξανά" + Εμφανίζονται. Ενότητα σχετιζόμενων λέξεων Κρυμμένη. Εμφανίζεται. @@ -140,18 +194,18 @@ Παιχνίδια YouTube Κρυμμένα. Εμφανίζονται. - Κουμπί «Εμφάνιση περισσότερων» - Κρυμμένο. - Εμφανίζεται. Γραμμή αναζήτησης Κρυμμένη. Εμφανίζεται. - Έρευνες - Κρυμμένες. - Εμφανίζονται. + Κουμπί «Εμφάνιση περισσότερων» + Κρυμμένο. + Εμφανίζεται. Ενότητα καναλιών καρτέλας «Εγγραφές» Κρυμμένη. Εμφανίζεται. + Έρευνες + Κρυμμένες. + Εμφανίζονται. Ενότητα εισιτηρίων Κρυμμένη. Εμφανίζεται. @@ -248,11 +302,12 @@ Playlists Προτεινόμενα βίντεο Απόκρυψη βίντεο χαμηλών προβολών - Απόκρυψη των βίντεο με λιγότερες από 1,000 προβολές από τη ροή τα οποία ανήκουν σε κανάλια που δεν είστε συνδρομητές. + "Απόκρυψη των βίντεο με λιγότερες από 1,000 προβολές από τη ροή τα οποία ανήκουν σε κανάλια που δεν είστε συνδρομητές. + +Αυτό το φίλτρο ενδέχεται να μη λειτουργεί πλέον, αντί αυτού χρησιμοποιείστε το «Φίλτρο αριθμού προβολών»." Απόκρυψη προτεινόμενων βίντεο "Απόκρυψη των παρακάτω προτεινόμενων βίντεο: -• Βίντεο με ετικέτα «Μόνο για Μέλη». • Βίντεο με φράσεις όπως «Άλλοι χρήστες παρακολούθησαν επίσης» στο κάτω μέρος τους." Φίλτρο αριθμού προβολών @@ -287,17 +342,12 @@ Playlists Μετατόπιση Γενικά - Αλλαγή διεπαφής - Προεπιλογή - Κινητό - Κινητό (Μέγιστο dp 480) - Τάμπλετ - Τάμπλετ (Μέγιστο dp 600) Αλλαγή αρχικής σελίδας + Προεπιλογή Περιήγηση καναλιών Μαθήματα / Εκμάθηση - Προεπιλογή Εξερεύνηση + Μόδα & ομορφιά Παιχνίδια Ιστορικό Βιβλιοθήκη @@ -305,8 +355,11 @@ Playlists Live Ταινίες Μουσική + Ειδήσεις Ειδοποιήσεις + Podcasts Αναζήτηση + Shopping Shorts Αθλητικά Εγγραφές @@ -339,12 +392,18 @@ Playlists Γκρι διαχωριστικά Κρυμμένα. Εμφανίζονται. - Μηνύματα αλληλεπίδρασης - Κρυμμένα. - Εμφανίζονται. Παράθυρο ηλικιακού περιορισμού "Αφαίρεση του παραθύρου προειδοποίησης ηλικιακού περιορισμού. Αυτό δεν παρακάμπτει τον ηλικιακό περιορισμό, απλά τον αποδέχεται αυτόματα." + Αλλαγή διεπαφής + Προεπιλογή + Κινητό + Κινητό (Μέγιστο dp 480) + Τάμπλετ + Τάμπλετ (Μέγιστο dp 600) + Αλλαγή ενέργειας πατήματος δακτυλίου ζωντανής μετάδοσης + Το κανάλι ανοίγει όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. + Η ζωντανή μετάδοση ανοίγει όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. Παραποίηση έκδοσης εφαρμογής Η έκδοση παραποιείται. Η έκδοση δεν παραποιείται. @@ -392,13 +451,13 @@ Playlists Κουμπί «Λήψη» Μετατροπή κουμπιού λήψης λίστας αναπαραγωγής Το κουμπί λήψης λίστας αναπαραγωγής εμφανίζεται πάντα, και σε δημόσιες λίστες αναπαραγωγής ανοίγει το εξωτερικό πρόγραμμα λήψης σας. - Αν εμφανίζεται, το κουμπί λήψης λίστας αναπαραγωγής ανοίγει το εγγενές πρόγραμμα λήψης του YouTube. + Το κουμπί λήψης λίστας αναπαραγωγής, αν εμφανίζεται, ανοίγει το εγγενές πρόγραμμα λήψης του YouTube. Μετατροπή κουμπιού λήψης βίντεο Το κουμπί λήψης του YouTube ανοίγει το εξωτερικό πρόγραμμα λήψης σας. Το κουμπί λήψης του YouTube ανοίγει το εγγενές πρόγραμμα λήψης της εφαρμογής. Όνομα πακέτου προγράμματος λήψης λίστας αναπαραγωγής Όνομα πακέτου της εγκατεστημένης σας εξωτερικής εφαρμογής λήψης (π.χ YTLDnis). - + Μετατροπή κουμπιού YouTube Music Το κουμπί YouTube Music ανοίγει τo RVX Music. Το κουμπί YouTube Music ανοίγει την εγγενή εφαρμογή. @@ -517,9 +576,9 @@ Playlists Μενού «Εξοικονόμηση δεδομένων» Κρυμμένο. Εμφανίζεται. - Μενού «Αυτόματη αναπαραγωγή» - Κρυμμένο. - Εμφανίζεται. + Μενού «Αναπαραγωγή» + Κρυμμένο. + Εμφανίζεται. Μενού «Προτιμήσεις ποιότητας βίντεο» Κρυμμένο. Εμφανίζεται. @@ -565,6 +624,10 @@ Playlists Μενού «Σχετικά με» Κρυμμένο. Εμφανίζεται. + + Μηνύματα αλληλεπίδρασης + Κρυμμένα. + Εμφανίζονται. Γραμμή εργαλείων Απόκρυψη ή αλλαγή στοιχείων που βρίσκονται στη γραμμή εργαλείων, όπως τα κουμπιά, την γραμμή αναζήτησης, ή την επικεφαλίδα. @@ -576,12 +639,17 @@ Playlists Η ευρεία γραμμή αναζήτησης είναι απενεργοποιημένη. Ευρεία γραμμή αναζήτησης με επικεφαλίδα Η ευρεία γραμμή αναζήτησης περιλαμβάνει την επικεφαλίδα του YouTube. - Η ευρεία γραμμή αναζήτησης δεν περιλαμβάνει την επικεφαλίδα του YouTube. + Η ευρεία γραμμή αναζήτησης κρύβει την επικεφαλίδα του YouTube και χρησιμοποιεί τον χώρο της. Ευρεία γραμμή αναζήτησης στο «Εσείς» - "Η ενεργοποίηση αυτής της ρύθμισης θα απενεργοποιήσει το κουμπί ρυθμίσεων στην καρτέλα «Εσείς» + "Η ευρεία γραμμή αναζήτησης είναι ενεργοποιημένη στην καρτέλα «Εσείς». -Σε αυτή την περίπτωση, για πρόσβαση στις ρυθμίσεις χρησιμοποιήστε το εξής μονοπάτι: -Καρτέλα «Εσείς» → Προβολή καναλιού → Μενού → Ρυθμίσεις." +Για πρόσβαση στις ρυθμίσεις, ακολουθήστε την εξής διαδρομή: +Καρτέλα «Εσείς» → Προβολή καναλιού → Μενού → Ρυθμίσεις" + Η ευρεία γραμμή αναζήτησης είναι απενεργοποιημένη στην καρτέλα «Εσείς». + "Η ενεργοποίηση αυτής της λειτουργίας θα απενεργοποιήσει το κουμπί ρυθμίσεων στην καρτέλα «Εσείς». + +Σε αυτή την περίπτωση, για πρόσβαση στις ρυθμίσεις χρησιμοποιήστε την εξής διαδρομή: +Καρτέλα «Εσείς» → Προβολή καναλιού → Μενού → Ρυθμίσεις" Κουμπί μετάδοσης Κρυμμένο. Εμφανίζεται. @@ -618,12 +686,12 @@ Playlists Αδιαφάνεια φόντου οθόνης αναπαραγωγής Τιμή αδιαφάνειας μεταξύ 0-100, όπου το 0 είναι διαφανές. Η αδιαφάνεια πρέπει να είναι μεταξύ 0-100. - Απενεργοποίηση εναλλαγής λιστών αναπαραγωγής μίξης + Απενεργοποίηση αυτόματης εναλλαγής λιστών αναπαραγωγής μίξης Η αυτόματη εναλλαγή λιστών αναπαραγωγής μίξης είναι απενεργοποιημένη. - "Η αυτόματη εναλλαγή λιστών αναπαραγωγής μίξης είναι ενεργοποιημένη όταν η αυτόματη αναπαραγωγή είναι επίσης ενεργοποιημένη. + "Η αυτόματη εναλλαγή λιστών αναπαραγωγής μίξης είναι ενεργοποιημένη όταν η αυτόματη αναπαραγωγή είναι ενεργοποιημένη. Η αυτόματη αναπαραγωγή μπορεί να αλλαχτεί στις ρυθμίσεις YouTube: -Ρυθμίσεις → Αυτόματη αναπαραγωγή → Αυτόματη αναπαραγωγή επόμενου βίντεο" +Ρυθμίσεις → Αναπαραγωγή → Αυτόματη αναπαραγωγή επόμενου βίντεο" Η ενεργοποίηση αυτής της ρύθμισης θα απενεργοποιήσει την αυτόματη εναλλαγή σε YouTube Mix κατά την αναπαραγωγή μουσικής ενώ η αυτόματη αναπαραγωγή είναι ενεργοποιημένη. Αναδυόμενα παράθυρα οθόνης αναπαραγωγής Κρυμμένα. @@ -675,7 +743,7 @@ Playlists Ισχύει μόνο όταν η αυτόματη αναπαραγωγή είναι απενεργοποιημένη. Η αυτόματη αναπαραγωγή μπορεί να αλλαχτεί στις ρυθμίσεις YouTube: -'Ρυθμίσεις → Αυτόματη αναπαραγωγή → Αυτόματη αναπαραγωγή επόμενου βίντεο'" +'Ρυθμίσεις → Αναπαραγωγή→ Αυτόματη αναπαραγωγή επόμενου βίντεο'" Εμφανίζεται. Άμεση αυτόματη αναπαραγωγή Αν είναι ενεργοποιημένη η αυτόματη αναπαραγωγή, το επόμενο βίντεο παίζει χωρίς αντίστροφη μέτρηση. @@ -725,6 +793,39 @@ Playlists Κουμπί «Σας ευχαριστούμε» Κρυμμένο. Εμφανίζεται. + + Απόκρυψη ανά ευρετήριο + Πρώτο κουμπί + Κρυμμένο. + Εμφανίζεται. + Δεύτερο κουμπί + Κρυμμένο. + Εμφανίζεται. + Τρίτο κουμπί + Κρυμμένο. + Εμφανίζεται. + Τέταρτο κουμπί + Κρυμμένο. + Εμφανίζεται. + Πέμπτο κουμπί + Κρυμμένο. + Εμφανίζεται. + Έκτο κουμπί + Κρυμμένο. + Εμφανίζεται. + Έβδομο κουμπί + Κρυμμένο. + Εμφανίζεται. + Όγδοο κουμπί + Κρυμμένο. + Εμφανίζεται. + + Απόκρυψη ανά ευρετήριο σε ζωντανή μετάδοση + Σχετικά με την απόκρυψη κουμπιού ενέργειας ανά ευρετήριο + "Απόκρυψη των κουμπιών ενεργειών ανά ευρετήριο πριν την αρχικοποίηση των κουμπιών ενεργειών. + +- Η απόκρυψη των κουμπιών ενεργειών δεν αφήνει κενό χώρο. +- Το ευρετήριο των κουμπιών ενεργειών μπορεί να μην είναι πάντα το ίδιο κουμπί." Λειτουργία περιβάλλοντος Παράκαμψη περιορισμών λειτουργίας περιβάλλοντος ή απενεργοποίηση της. @@ -770,18 +871,18 @@ Playlists Επισημασμένοι συνδέσμοι αναζήτησης Κρυμμένοι. Εμφανίζονται. - Μηνύματα ζωντανής συνομιλίας + Μηνύματα ζωντανής συζήτησης Κρυμμένα.\n\nΑυτή η ρύθμιση ισχύει και για τις ζωντανές μεταδόσεις Shorts. Εμφανίζονται.\n\nΑυτή η ρύθμιση ισχύει και για τις ζωντανές μεταδόσεις Shorts. - Σύνοψη συνομιλίας στη ζωντανή συνομιλία + Σύνοψη συζήτησης στη ζωντανή συζήτηση Κρυμμένη. Εμφανίζεται. Προεπισκόπηση σχολίου Κρυμμένη. Εμφανίζεται. Τύπος απόκρυψης προεπισκόπησης σχολίου - Αυτό δεν αλλάζει το μέγεθος της ενότητας σχολίων, οπότε μπορεί να ανοιχτεί η επανάληψη ζωντανής συνομιλίας στην ενότητα σχολίων. - Αυτό αλλάζει το μέγεθος της ενότητας σχολίων, οπότε είναι αδύνατο να ανοιχτεί η επανάληψη ζωντανής συνομιλίας στην ενότητα σχολίων. + Αυτό δεν αλλάζει το μέγεθος της ενότητας σχολίων, οπότε μπορεί να ανοιχτεί η επανάληψη ζωντανής συζήτησης στην ενότητα σχολίων. + Αυτό αλλάζει το μέγεθος της ενότητας σχολίων, οπότε είναι αδύνατο να ανοιχτεί η επανάληψη ζωντανής συζήτησης στην ενότητα σχολίων. Κουμπί «Σας ευχαριστούμε» Κρυμμένο. Εμφανίζεται. @@ -878,7 +979,7 @@ Playlists Εμφανίζεται. Κουμπί επανάληψης ζωντανής συζήτησης Κρυμμένο. - Εμφανίζεται στη λειτουργία πλήρους οθόνης μετά το κλείσιμο της ζωντανής συνομιλίας. + Εμφανίζεται στη λειτουργία πλήρους οθόνης στο κλείσιμο της ζωντανής συζήτησης. Σχετιζόμενο βίντεο Κρυμμένο. @@ -921,7 +1022,7 @@ Playlists Ύψος γραμμής προόδου Αλλαγή ύψους της γραμμής προόδου, τιμές μεταξύ 0-32. Το ύψος πρέπει να είναι μεταξύ 0-32. - + Απενεργοποίηση οριζόντιας λειτουργίας Η οριζόντια λειτουργία σε λειτουργία πλήρους οθόνης είναι απενεργοποιημένη. Η οριζόντια λειτουργία σε λειτουργία πλήρους οθόνης είναι ενεργοποιημένη. @@ -929,7 +1030,8 @@ Playlists Τα στοιχεία ελέγχου μικρότερου στυλ είναι ενεργοποιημένα. Τα στοιχεία ελέγχου μικρότερου στυλ είναι απενεργοποιημένα. Διατήρηση οριζόντιας λειτουργίας - Διατήρηση της οριζόντιας λειτουργίας στο κλείσιμο και άνοιγμα της οθόνης ενώ βρίσκεστε σε λειτουργία πλήρους οθόνης. + Τα βίντεο συνεχίζουν να αναπαράγονται σε οριζόντια λειτουργία ακόμη και όταν κλείνεται και ξανανοίγεται η οθόνη. + Τα βίντεο αναπαράγονται σε κάθετη λειτουργία όταν κλείνεται και ξανανοίγεται η οθόνη. Χρονικό όριο οριζόντιας λειτουργίας Ο αριθμός των χιλιοστών δευτερολέπτου που θα εξαναγκάζεται η οριζόντια λειτουργία. @@ -1133,7 +1235,7 @@ Playlists Ενότητα απομαγνητοφώνησης Κρυμμένη. Εμφανίζεται. - + Απενεργοποίηση αλληλεπίδρασης περιγραφής βίντεο "Απενεργοποίηση των ακόλουθων αλληλεπιδράσεων όταν ανοίγεται η περιγραφή του βίντεο: @@ -1161,7 +1263,7 @@ Playlists "Εμφανίζονται. Αφορά τα αιωρούμενα κουμπιά όπως το «Χρήση αυτού του ήχου» στην καρτέλα Shorts του καναλιού." - + Ενότητα Shorts Απόκρυψη των Shorts "Απόκρυψη της ενότητας Shorts. @@ -1185,13 +1287,16 @@ Playlists Απόκρυψη στο ιστορικό παρακολούθησης Κρυμμένη. Εμφανίζεται. - + Αλλαγή κατάστασης επανάληψης Shorts στο παρασκήνιο Αλλαγή κατάστασης επανάληψης Shorts Αυτόματη αναπαραγωγή Προεπιλογή Παύση Επανάληψη + Άνοιγμα των Shorts στην κανονική οθόνη αναπαραγωγής + Τα Shorts ανοίγουν στην οθόνη αναπαραγωγής κανονικών βίντεο. + Τα Shorts δεν ανοίγουν στην οθόνη αναπαραγωγής κανονικών βίντεο. Οθόνη αναπαραγωγής Shorts Απόκρυψη ή εμφάνιση στοιχείων στην οθόνη αναπαραγωγής Shorts. @@ -1207,8 +1312,8 @@ Playlists Κουμπί «Συμμετοχή» Κρυμμένο. Εμφανίζεται. - Επικεφαλίδα ζωντανής συνομιλίας - Κρυμμένο.\n\nΤο κουμπί επιστροφής στην επικεφαλίδα δεν θα είναι κρυμμένο. + Επικεφαλίδα ζωντανής συζήτησης + Κρυμμένη.\n\nΤο κουμπί επιστροφής στην επικεφαλίδα δεν θα είναι κρυμμένο. Εμφανίζεται. Ετικέτες προώθησης επί πληρωμή Κρυμμένες. @@ -1337,10 +1442,10 @@ Playlists Το μενού κατάστασης επανάληψης εμφανίζεται. Το μενού κατάστασης επανάληψης δεν εμφανίζεται. Σχετικά με τις προσαρμοσμένες ενέργειες - "Αυτή η λειτουργία είναι ακόμα πειραματική, οπότε δεν είναι εγγυημένο ότι θα λειτουργήσει τέλεια. + "Αυτή η λειτουργία είναι ακόμη πειραματική, οπότε δεν είναι εγγυημένο ότι θα λειτουργήσει χωρίς σφάλματα. -Τα περισσότερα σφάλματα δεν γίνεται να διορθωθούν λόγω περιορισμών, οπότε χρησιμοποιήστε την μόνο για σκοπούς δοκιμής." - +Τα περισσότερα σφάλματα δε γίνεται να διορθωθούν λόγω περιορισμών, οπότε χρησιμοποιήστε την μόνο για σκοπούς δοκιμής." + Ενεργοποίηση χρονοσφραγίδων "Οι χρονοσφραγίδες είναι ενεργοποιημένες. @@ -1503,11 +1608,11 @@ Playlists Τα «Δεν μου αρέσει» εμφανίζονται. Τα «Δεν μου αρέσει» δεν εμφανίζονται. Εμφάνιση στα Shorts - Τα dislike εμφανίζονται στα Shorts. %s + Τα dislike εμφανίζονται στα Shorts. "Τα «Δεν μου αρέσει» εμφανίζονται στα Shorts. Περιορισμός: Τα «Δεν μου αρέσει» ενδέχεται να μην εμφανίζονται σε λειτουργία ανώνυμης περιήγησης ή αν δεν έχετε συνδεθεί στον λογαριασμό σας." - Τα dislike δεν εμφανίζονται στα Shorts. + Τα «Δεν μου αρέσει» δεν εμφανίζονται στα Shorts. Εμφάνιση ως ποσοστό Τα «Δεν μου αρέσει» εμφανίζονται ως ποσοστό. Τα «Δεν μου αρέσει» εμφανίζονται ως αριθμός. @@ -1668,8 +1773,8 @@ Playlists Η διεύθυνση URL του API άλλαξε. Αντιγραφή Εισαγωγή / Εξαγωγή ρυθμίσεων - Οι ρυθμίσεις SponsorBlock σας σε μορφή JSON που μπορούν να εισαχθούν / εξαχθούν στο ReVanced Extended και σε άλλες πλατφόρμες SponsorBlock. - Οι ρυθμίσεις SponsorBlock σας σε μορφή JSON που μπορούν να εισαχθούν / εξαχθούν στο ReVanced Extended και σε άλλες πλατφόρμες SponsorBlock. Αυτό περιλαμβάνει το ιδιωτικό σας αναγνωριστικό χρήστη. Φροντίστε να το μοιραστείτε με σύνεση. + Οι ρυθμίσεις SponsorBlock σας σε μορφή JSON που μπορούν να εισαχθούν / εξαχθούν στο RVX και σε άλλες πλατφόρμες SponsorBlock. + Οι ρυθμίσεις SponsorBlock σας σε μορφή JSON που μπορούν να εισαχθούν / εξαχθούν στο RVX και σε άλλες πλατφόρμες SponsorBlock. Αυτό περιλαμβάνει το ιδιωτικό σας αναγνωριστικό χρήστη. Φροντίστε να το μοιραστείτε με σύνεση. Οι ρυθμίσεις εισήχθησαν επιτυχώς. Η εισαγωγή απέτυχε: %s. Η εξαγωγή απέτυχε: %s. @@ -1737,28 +1842,28 @@ Playlists Τα δεδομένα παρέχονται από το SponsorBlock API. Πατήστε για να μάθετε περισσότερα και να δείτε λήψεις για άλλες πλατφόρμες. Διάφορα + Παράκαμψη ανακατευθύνσεων συνδέσμων + Οι ανακατευθύνσεις URL παρακάμπτονται. + Οι ανακατευθύνσεις URL δεν παρακάμπτονται. Απενεργοποίηση πρωτοκόλλου QUIC "Απενεργοποίηση πρωτοκόλλου QUIC του CronetEngine. -Αυτή η λειτουργία αποτρέπει την συμπίεση και αποσυμπίεση των βίντεο κατά την αναπαραγωγή, τα οποία μπορούν να προκαλέσουν κολλήματα, ενδέχεται όμως να χρησιμοποιηθούν περισσότερα δεδομένα." +Αυτή η λειτουργία αποτρέπει την συμπίεση και αποσυμπίεση των βίντεο κατά την αναπαραγωγή, οι οποίες μπορούν να προκαλέσουν κολλήματα, ενδέχεται όμως να χρησιμοποιηθούν περισσότερα δεδομένα." Καταγραφή εντοπισμού σφαλμάτων Η καταγραφή εντοπισμού σφαλμάτων είναι ενεργοποιημένη. Η καταγραφή εντοπισμού σφαλμάτων είναι απενεργοποιημένη. Συμπερίληψη του buffer στην καταγραφή Η καταγραφή εντοπισμού σφαλμάτων περιλαμβάνει το proto buffer. Η καταγραφή εντοπισμού σφαλμάτων δεν περιλαμβάνει το proto buffer. - Εξωτερικό πρόγραμμα περιήγησης - Οι συνδέσμοι ανοίγουν σε εξωτερικό πρόγραμμα περιήγησης. - Οι συνδέσμοι ανοίγουν εσωτερικά στην εφαρμογή. - Παράκαμψη ανακατευθύνσεων συνδέσμων - Οι ανακατευθύνσεις URL παρακάμπτονται κατά το άνοιγμα συνδέσμων. - Οι ανακατευθύνσεις URL δεν παρακάμπτονται κατά το άνοιγμα συνδέσμων. + Άνοιγμα συνδέσμων σε πρόγραμμα περιήγησης + Οι σύνδεσμοι ανοίγουν σε εξωτερικό πρόγραμμα περιήγησης. + Οι σύνδεσμοι ανοίγουν εσωτερικά στην εφαρμογή. Καθαρισμός συνδέσμων κοινοποίησης Αφαίρεση των παραμέτρων παρακολούθησης από τις διευθύνσεις URL κατά την κοινοποίηση συνδέσμων. Άνοιγμα ρυθμίσεων προεπιλεγμένων εφαρμογών Για να ανοίγουν οι συνδέσμοι YouTube στο RVX, ενεργοποιήστε το «Άνοιγμα υποστηριζόμενων συνδέσμων» και τις υποστηριζόμενες διευθύνσεις ιστού. - Άνοιγμα του MicroG GmsCore - Ενεργοποιήστε τις ρυθμίσεις cloud messaging για να λαμβάνετε ειδοποιήσεις. + Άνοιγμα ρυθμίσεων του MicroG GmsCore + Για να λαμβάνετε ειδοποιήσεις στο RVX, ενεργοποιήστε τις ρυθμίσεις Cloud Messaging. Το MicroG GmsCore δεν είναι εγκατεστημένο. Εγκαταστήστε το. Απαιτείται ενέργεια "Το MicroG GmsCore δεν έχει άδεια να τρέχει στο παρασκήνιο. @@ -1780,7 +1885,7 @@ Playlists Ενεργοποίηση του κωδικοποιητή OPUS αν η ανταπόκριση του προγράμματος αναπαραγωγής τον περιλαμβάνει. Εισαγωγή / Εξαγωγή ρυθμίσεων - Εισαγωγή ή εξαγωγή των ρυθμίσεών σας. + Εισαγωγή ή εξαγωγή των ρυθμίσεών RVX σας. Εισαγωγή / Εξαγωγή ως αρχείο Εξαγωγή ρυθμίσεων @@ -1811,6 +1916,8 @@ Playlists "Android TV (Απαιτείται σύνδεση)" Android VR + "Android VR +(χωρίς auth)" "iOS (Απαιτείται αναγνωριστικό PoToken)" "iOS TV @@ -1832,6 +1939,7 @@ Playlists Εμφάνιση στο «Στατιστικά για σπασίκλες» Το πρόγραμμα πελάτη που χρησιμοποιείται για τη λήψη δεδομένων ροής εμφανίζεται στο μενού «Στατιστικά για σπασίκλες». Το πρόγραμμα πελάτη που χρησιμοποιείται για τη λήψη δεδομένων ροής δεν εμφανίζεται στο μενού «Στατιστικά για σπασίκλες». + Προεπιλεγμένη γλώσσα ροής ήχου VR PoToken / VisitorData PoToken προς χρήση diff --git a/patches/src/main/resources/youtube/translations/es-rES/strings.xml b/patches/src/main/resources/youtube/translations/es-rES/strings.xml index 66d3e852e..105917d9a 100644 --- a/patches/src/main/resources/youtube/translations/es-rES/strings.xml +++ b/patches/src/main/resources/youtube/translations/es-rES/strings.xml @@ -19,6 +19,59 @@ "%1$s no está instalado. Por favor, descarga %2$s desde el sitio web." %s no está instalado. Por favor, instálalo. + Idioma de RVX + Idioma de la app + Árabe + Azerbaiyano + Búlgaro + Bengalí + Catalán + Checo + Danés + Alemán + Griego + Inglés + Español + Estoniano + Persa + Finlandés + Francés + Guyaratí + Hindi + Croata + Húngaro + Indonesio + Italiano + Japonés + Kazajo + Coreano + Lituano + Letón + Macedonio + Mongol + Maratí + Malayo + Birmano + Holandés + Odia + Punyabí + Polaco + Portugués + Rumano + Ruso + Eslovaco + Esloveno + Serbio + Sueco + Suajili + Tamil + Télugu + Tailandés + Turco + Ucraniano + Urdu + Vietnamita + Chino Anuncios Ocultar anuncios en pantalla completa @@ -102,13 +155,14 @@ Pulsa aquí para saber más sobre DeArrow." El botón de subtítulos está oculto. El botón de subtítulos está visible. Ocultar estante de carrusel - "Oculta las siguientes estanterías: + "Las estanterías de carrusel están ocultas, tales como: • Noticias de última hora • Seguir viendo • Explorar más canales • Volver a escuchar • Compras • Volver a ver" + Las estanterías de carrusel están visibles. Ocultar estante de fichas El estante de fichas está oculto. El estante de fichas está visible. @@ -142,18 +196,18 @@ Pulsa aquí para saber más sobre DeArrow." Ocultar reproducibles Los reproducibles están ocultos. Los reproducibles están visibles. - Ocultar botón de mostrar más - El botón de mostrar más está oculto. - El botón de mostrar más está visible. Ocultar barra de búsqueda del feed La barra de búsqueda del feed está oculta. La barra de búsqueda del feed está visible. - Ocultar encuestas del feed - Las encuestas del feed están ocultas. - Las encuestas del feed están visibles. + Ocultar botón de mostrar más + El botón de mostrar más está oculto. + El botón de mostrar más está visible. Ocultar carrusel de suscripciones El carrusel de suscripciones está oculto. El carrusel de suscripciones está visible. + Ocultar encuestas del feed + Las encuestas del feed están ocultas. + Las encuestas del feed están visibles. Ocultar estantes de tickets Los estantes de tickets están ocultos. Los estantes de tickets están visibles. @@ -249,7 +303,7 @@ Limitaciones: Vídeos recomendados Ocultar vídeos con pocas visualizaciones - Oculta los vídeos con menos de 1.000 visualizaciones de los feeds de inicio que hayan sido subidos desde canales a los que no estás suscrito. + "Oculta los vídeos con menos de 1.000 visualizaciones de los feeds de inicio que hayan sido subidos desde canales a los que no estás suscrito." Ocultar vídeos recomendados "Oculta los siguientes vídeos recomendados: @@ -289,17 +343,12 @@ Si el diseño de la pantalla del reproductor cambia debido a cambios en el servi Desplazamiento General - Cambiar diseño - Original - Teléfono - Teléfono (máx. 480 dpi) - Tablet - Tablet (min. 600 dpi) Cambiar página de inicio + Predeterminada Explorar canales Cursos / Aprendizaje - Predeterminada Explorar + Moda y belleza Juegos Historial Biblioteca @@ -307,8 +356,11 @@ Si el diseño de la pantalla del reproductor cambia debido a cambios en el servi En directo Películas Música + Noticias Notificaciones + Podcasts Búsqueda + Compras Shorts Deportes Suscripciones @@ -341,12 +393,18 @@ Limitación: Es posible que el botón Atrás de la barra de herramientas no func Ocultar separadores grises Los separadores grises están ocultos. Los separadores grises están visibles. - Ocultar barra de notificaciones - La barra de notificaciones está oculta. - La barra de notificaciones está visible. Eliminar diálogo de discreción del espectador "Elimina el diálogo de discreción del espectador. Esto no evita la restricción de edad. Solo la acepta automáticamente." + Cambiar diseño + Original + Teléfono + Teléfono (máx. 480 dpi) + Tablet + Tablet (min. 600 dpi) + Cambiar acción de pulsación en anillo del directo + El canal se abre al pulsar en el anillo del directo. + El directo se abre al pulsar en el anillo del directo. Falsificar versión de la app Versión falsificada Versión no falsificada @@ -400,7 +458,7 @@ Algunos componentes pueden no estar ocultos." El botón nativo de descarga de vídeo abre el descargador nativo de la aplicación. Nombre del paquete del descargador de listas de reproducción Nombre del paquete de tu aplicación de descargas externas instalada, como YTDLnis. - + Reemplazar botón de YouTube Music El botón de YouTube Music abre RVX Music. El botón de Youtube Music abre la app nativa. @@ -519,9 +577,9 @@ Si este ajuste no surte efecto, prueba a cambiar al modo incógnito." Ocultar menú \"Ahorro de datos\" El menú \"Ahorro de datos\" está oculto. El menú \"Ahorro de datos\" está visible. - Ocultar menú \"Reproducción automática\" - El menú \"Reproducción automática\" está oculto. - El menú \"Reproducción automática\" está visible. + Ocultar menú de reproducción automática o de reproducción + El menú de reproducción automática o de reproducción está oculto. + El menú de reproducción automática o de reproducción está visible. Ocultar menú \"Preferencias de calidad de vídeo\" El menú \"Preferencias de calidad de vídeo\" está oculto. El menú \"Preferencias de calidad de vídeo\" está visible. @@ -567,6 +625,10 @@ Si este ajuste no surte efecto, prueba a cambiar al modo incógnito." Ocultar menú \"Información\" El menú \"Información\" está oculto. El menú \"Información\" está visible. + + Ocultar barra de notificaciones + La barra de notificaciones está oculta. + La barra de notificaciones está visible. Barra de herramientas Ocultar o cambiar los componentes situados en la barra de herramientas, como los botones, la barra de búsqueda o la cabecera. @@ -580,10 +642,15 @@ Si este ajuste no surte efecto, prueba a cambiar al modo incógnito." La barra de búsqueda ancha incluye la cabecera de YouTube. La barra de búsqueda ancha no incluye la cabecera de YouTube. Activar barra de búsqueda ancha en pestaña Tú - "Al activar este ajuste, se desactiva el botón de configuración de la pestaña Tú. + "La barra de búsqueda ancha está activada en la pestaña Tú. -En este caso, utiliza la siguiente ruta: -Pestaña Tú > Ver canal > Menú > Configuración." +Para acceder a la configuración, utilice la siguiente ruta: +Pestaña Tú → Ver canal → Menú → Configuración" + La barra de búsqueda ancha está desactivada en la pestaña Tú. + "Si activas esta opción, se desactivará el botón Configuración de la pestaña Tú. + +En este caso, es posible que tengas que utilizar la siguiente ruta para acceder a la configuración: +Pestaña Tú → Ver canal → Menú → Configuración" Ocultar botón de transmitir El botón de transmitir está oculto. El botón de transmitir está visible. @@ -726,6 +793,39 @@ La reproducción automática se puede cambiar en la configuración de YouTube: Ocultar botón de gracias El botón de gracias está oculto. El botón de gracias está visible. + + Ocultar por índice + Ocultar primer botón + El primer botón está oculto. + El primer botón está visible. + Ocultar segundo botón + El segundo botón está oculto. + El segundo botón está visible. + Ocultar tercer botón + El tercer botón está oculto. + El tercer botón está visible. + Ocultar cuarto botón + El cuarto botón está oculto. + El cuarto botón está visible. + Ocultar quinto botón + El quinto botón está oculto. + El quinto botón está visible. + Ocultar sexto botón + El sexto botón está oculto. + El sexto botón está visible. + Ocultar séptimo botón + El séptimo botón está oculto. + El séptimo botón está visible. + Ocultar octavo botón + El octavo botón está oculto. + El octavo botón está visible. + + Ocultar por índice en directo + Acerca de Ocultar botón de acción por índice + "Oculta los botones de acción por índice antes de que se inicialicen los botones de acción. + +- Al ocultar los botones de acción no se deja ningún espacio vacío. +- El índice de los botones de acción puede no ser siempre el mismo botón." Modo ambiente Omite las restricciones del modo ambiente o desactiva el modo ambiente. @@ -918,7 +1018,7 @@ Limitación: el título de vídeo desaparece cuando se pulsa." Margen superior de acciones rápidas Configura el espacio entre la barra de progreso y el contenedor de acciones rápidas, entre 0-32. El margen superior de las acciones rápidas debe estar entre 0-32. Restablezca a los valores predeterminados. - + Desactivar modo horizontal La orientación del vídeo es vertical en pantalla completa. La orientación del vídeo sigue la configuración del dispositivo en pantalla completa. @@ -926,7 +1026,8 @@ Limitación: el título de vídeo desaparece cuando se pulsa." La superposición de controles no ocupa la pantalla completa. La superposición de controles ocupa la pantalla completa. Mantener modo horizontal - Mantiene el modo horizontal al apagar y encender la pantalla en pantalla completa. + Los vídeos continúan reproduciéndose en modo horizontal después de apagar y encender la pantalla. + Los vídeos se reproducen en modo vertical después de apagar y encender la pantalla. Mantener tiempo de espera del modo horizontal La cantidad de milisegundos que se fuerza el modo horizontal. @@ -1111,7 +1212,7 @@ Esta función funciona mejor con una conexión a Internet muy rápida." Ocultar secciones de transcripción Las secciones de transcripción están ocultas. Las secciones de transcripción están visibles. - + Desactivar interacción de descripción de vídeo "Desactiva las siguientes interacciones cuando se expande la descripción del vídeo: @@ -1136,7 +1237,7 @@ Estos caracteres varían dependiendo de tu idioma. Ocultar botón flotante "Los botones flotantes como \"Utilizar este sonido\" se ocultan en la pestaña Shorts del canal." "Los botones flotantes como \"Utilizar este sonido\" se muestran en la pestaña Shorts del canal." - + Estantes de Shorts Ocultar estantes de Shorts "Oculta los estantes de Shorts. @@ -1160,13 +1261,16 @@ Información: Ocultar en historial de reproducciones Oculto en el historial de reproducciones. Visible en el historial de reproducciones. - + Cambiar estado de repetición de fondo de Shorts Cambiar estado de repetición de Shorts Reproducción automática Predeterminada Pausar Repetir + Abrir Shorts en reproductor normal + Abre los Shorts en el reproductor normal. + No abre los Shorts en el reproductor normal. Reproductor de Shorts Ocultar o mostrar los componentes en el reproductor de Shorts. @@ -1312,10 +1416,10 @@ Mantén pulsado el botón Más para mostrar el cuadro de diálogo Acciones perso El menú del estado de repetición está visible. El menú del estado de repetición está oculto. Acerca de las acciones personalizadas - "Esta función es aún experimental, por lo que no hay garantía de que funcione perfectamente. + "Esta función es aún experimental, por lo que no hay garantía de que funcione perfectamente. La mayoría de los errores no pueden solucionarse debido a las limitaciones del lado del cliente, así que utilízala solo con fines de prueba." - + Activar marcas de tiempo "La marca de tiempo está activada. @@ -1710,6 +1814,9 @@ Toca para ver cómo crear una clave de API." Los datos son proporcionados por la API de SponsorBlock. Pulsa aquí para aprender más y ver las descargas para otras plataformas. Otros + Omitir redirecciones de URL + Se omiten las redirecciones de URL. + No se omiten las redirecciones de URL. Desactivar protocolo QUIC "Desactiva el protocolo QUIC de CronetEngine." Activar registro de depuración @@ -1718,12 +1825,9 @@ Toca para ver cómo crear una clave de API." Incluir búfer en registro de depuración Los registros de depuración incluyen el búfer. Los registros de depuración no incluyen el búfer. - Activar navegador externo - El navegador externo está activado. - El navegador externo está desactivado. - Activar apertura de enlaces directamente - Omitiendo los redireccionamientos de URL. - Siguiendo la política predeterminada de redireccionamiento. + Abrir enlaces en el navegador + Abre enlaces en el navegador externo. + Abre enlaces en el navegador de la app. Desinfectar enlaces compartidos Elimina los parámetros de consulta de seguimiento de las URL al compartir enlaces. Abrir ajustes predeterminados de la app @@ -1780,6 +1884,8 @@ Pulsa el botón de continuar y desactiva las optimizaciones de la batería.""Android TV (Inicio de sesión requerido)" Android VR + "Android VR +(Sin autentificación)" "iOS (PoToken requerido)" "iOS TV @@ -1801,6 +1907,7 @@ AVC tiene una resolución máxima de 1080p, el códec de audio Opus no está dis Mostrar en estadísticas para nerds El cliente utilizado para obtener datos de transmisión se muestra en estadísticas para nerds. El cliente utilizado para obtener datos de transmisión no se muestra en estadísticas para nerds. + Idioma de transmisión de audio por defecto VR PoToken / VisitorData PoToken a utilizar diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index 3192e2a54..e367e9f56 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -19,6 +19,59 @@ "%1$s n'est pas installé. Veuillez télécharger %2$s à partir du site web." %s n\'est pas installé. Veuillez l’installer. + Langue RVX + Langue de l\'application + Arabe + Azerbaïdjan + Bulgare + Bengali + Catalan + Tchèque + Danois + Allemand + Grec + Anglais + Espagnol + Estonien + Persan + Finlandais + Français + Gujarati + Hindou + Croate + Hongrois + Indonésien + Italien + Japonais + Kazakh + Coréen + Lithuanien + Letton + Macédonien + Mongol + Marathi + Malaisien + Birman + Néerlandais + Odia + Pendjabi + Polonais + Portugais + Roumain + Russe + Slovaque + Slovène + Serbe + Suédois + Swahili + Tamoul + Télougou + Thaïlandais + Turc + Ukrainien + Ourdou + Vietnamien + Chinois Publicités Masquer les publicités en plein écran @@ -66,9 +119,9 @@ Veuillez télécharger %2$s à partir du site web." DeArrow & miniatures capturées Méthode de capture DeArrow - "DeArrow propose des miniatures YouTube grâce à un service d'entraide. Ces miniatures sont souvent plus intéressantes que celles fournies par YouTube. + "DeArrow fournit des miniatures pour les vidéos YouTube. Ces miniatures sont souvent plus pertinentes que celles fournies par YouTube. -Si activée, l'URL des vidéos seront envoyés sur le serveur API et aucune autre données ne sera envoyée. Si la vidéo n'a pas de miniatures DeArrow, l'original ou celle capturé sera affiché. +Si activée, l'URL des vidéos sont envoyées au serveur API et aucune autre donnée n'est envoyée. Si une vidéo n'a pas de miniatures DeArrow, l'original ou une capture sera affichés. Cliquez ici pour en savoir plus sur DeArrow." Afficher un message si l\'API est indisponible @@ -101,14 +154,15 @@ Cliquez ici pour en savoir plus sur DeArrow." Masquer le bouton \'Sous-titres\' Le bouton \'Sous-titres\' est masqué. Le bouton \'Sous-titres\' est affiché. - Masquer les étagères à suggestions - "Masque les étagères suivantes : + Masquer les étagères du carrousel + "Les étagères du carrousel sont masqués, tels que : • Actualités • Continuer à regarder • Explorer d'autres chaînes • Écouter à nouveau • Produits • Regarder à nouveau" + Les étagères du carrousel sont affichés. Masquer des étagères L\'étagère \'Vous pourriez aussi aimer\' est masquée. L\'étagère \'Vous pourriez aussi aimer\' est affichée. @@ -142,18 +196,18 @@ Cliquez ici pour en savoir plus sur DeArrow." Masquer \'Jeux intégrés\' Les \'Jeux intégrés\' sont masqués. Les \'Jeux intégrés\' sont affichés. - Masquer le bouton \'Voir plus\' - Le bouton \'Voir plus\' est masqué. - Le bouton \'Voir plus\' est affiché. Masquer la barre de recherche La barre de recherche est masqué. La barre de recherche est affiché. - Masquer les sondages - Les sondages sont masqués. - Les sondages sont affichés. + Masquer le bouton \'Voir plus\' + Le bouton \'Voir plus\' est masqué. + Le bouton \'Voir plus\' est affiché. Masquer la barre \'Abonnements\' La barre \'Abonnements\' est masqué. La barre \'Abonnements\' est affiché. + Masquer les sondages + Les sondages sont masqués. + Les sondages sont affichés. Masquer les étagères à tickets Les étagères à tickets sont masqués. Les étagères à tickets sont affichés. @@ -252,12 +306,13 @@ Limitations : Vidéo recommandée Masquer les vidéos peu vues - Masque les vidéos avec moins de 1,000 vues dans le flux \"accueil\" qui ont été mis en ligne par des personnes dont vous n\'êtes pas abonnés. + "Masque les vidéos ayant moins de 1 000 vues dans les flux 'accueil' et qui ont été mis en ligne par des chaînes dont vous n'êtes pas abonnés. + +Ce filtre peut ne plus fonctionner, utilisez le filtre 'Nombre de vues' à la place." Masquer les vidéos recommandées "Masque les vidéos recommandées suivants : -• Les vidéos avec la mention \"Réservé aux membres\". -• Les vidéos avec des phrases telles que \"Les internautes ont aussi regardé cette vidéo\" en dessous." +• Les vidéos avec des phrases telles que 'Les internautes ont aussi regardé' en dessous." Filtre du compteur de vues Masquer les vidéos de la page d\'accueil par vues @@ -291,17 +346,12 @@ Si la mise en page de l'écran du lecteur change en raison de modifications côt Décalage Interface - Modifier la mise en page - Original - Téléphone - Téléphone (Max 480 dpi) - Tablette - Tablette (Min 600 dpi) Modifier la page de démarrage + Par défaut Parcourir les chaînes Savoir / Culture - Par défaut Explorer + Mode et beauté Jeux vidéos Historique Bibliothèque @@ -309,8 +359,11 @@ Si la mise en page de l'écran du lecteur change en raison de modifications côt Direct Films Musique + Actualités Notifications + Podcasts Rechercher sur YouTube + Produits Shorts Sports Abonnements @@ -331,9 +384,9 @@ Limitation : Le bouton Retour de la barre d'outils peut ne pas fonctionner."Désact. l\'animation de démarrage L\'animation de démarrage est désactivé. L\'animation de démarrage est activé. - Désactiver la barre de navigation translucide - La barre de navigation est opaque. - La barre de navigation est opaque ou translucide. + Désactiver la barre de notification translucide + La barre de notification est opaque. + La barre de notification est opaque ou translucide. Activer dégradé pendant le chargement Le dégradé pendant l\'écran de chargement est activé. Le dégradé pendant l\'écran de chargement est désactivé. @@ -343,12 +396,18 @@ Limitation : Le bouton Retour de la barre d'outils peut ne pas fonctionner."Masquer les séparateurs gris Les séparateurs gris sont masqués. Les séparateurs gris sont affichés. - Masquer les barres d\'actions - Les barres d\'actions présentes en haut ou en bas de l\'écran permettant généralement de rafraîchir la page sont masquée. - Les barres d\'actions présentes en haut ou en bas de l\'écran permettant généralement de rafraîchir la page sont affiché. Suppr. Message \'Confirmer votre âge\' "Supprime le message 'Confirmer votre âge'. Cela ne contourne pas la restriction d'âge, mais le confirme automatiquement." + Modifier la mise en page + Original + Téléphone + Téléphone (Max 480 dpi) + Tablette + Tablette (Min 600 dpi) + Changer l\'action du cercle \'En direct\' + La chaîne s\'ouvre lorsque vous cliquez sur le cercle \'En direct\'. + La diffusion en direct s\'ouvre lorsque vous cliquez sur le cercle \'En direct\'. Falsifier la version de l\'app Version falsifiée Version non falsifiée @@ -402,7 +461,7 @@ Certains composants peuvent ne pas être masqués." Le bouton \'Télécharger\' natif ouvre le téléchargeur de l\'appli. Nom du paquet du téléchargeur de la playlist Nom de package du téléchargeur externe installé, telle que YTDLnis. - + Remplacer le bouton \'YouTube Music\' Le bouton \'YouTube Music\' ouvre RVX Music. Le bouton \'YouTube Music\' ouvre l\'appli natif. @@ -521,9 +580,9 @@ Si ce paramètre ne fait pas effet, essayer de passer en mode Incognito."Masquer le menu \'Économie de données\' Le menu \'Économie de données\' est masqué. Le menu \'Économie de données\' est affiché. - Masquer le menu \'Lecture automatique\' - Le menu \'Lecture automatique\' est masqué. - Le menu \'Lecture automatique\' est affiché. + Masquer le menu \'Lecture auto.\' ou \'Lecture\' + Le menu \'Lecture automatique\' ou \'Lecture\' est masqué. + Le menu \'Lecture automatique\' ou \'Lecture\' est affiché. Masquer le menu \'Préférences de qualité vidéo\' Le menu \'Préférences de qualité vidéo\' est masqué. Le menu \'Préférences de qualité vidéo\' est affiché. @@ -569,6 +628,10 @@ Si ce paramètre ne fait pas effet, essayer de passer en mode Incognito."Masquer le menu \'À propos\' Le menu \'À propos\' est masqué. Le menu \'À propos\' est affiché. + + Masquer les barres d\'actions + Les barres d\'actions présentes en haut ou en bas de l\'écran permettant généralement de rafraîchir la page sont masquée. + Les barres d\'actions présentes en haut ou en bas de l\'écran permettant généralement de rafraîchir la page sont affiché. Barre d\'outils Masque ou change les éléments situés dans la barre d\'outils, tels que les boutons de la barre d\'outils, la barre de recherche, l\'en-tête. @@ -579,12 +642,17 @@ Si ce paramètre ne fait pas effet, essayer de passer en mode Incognito."La barre de recherche large est activée. La barre de recherche large est désactivée. Activ. Barre recherche large avec en-tête - La barre de recherche large ne masque pas l\'en-tête YouTube. - La barre de recherche large masque l\'en-tête YouTube. + La barre de recherche large est activée avec l\'en-tête YouTube. + La barre de recherche large désactive et utilise l\'espace de l\'en-tête de YouTube. Activer la barre de recherche large dans l\'onglet \'Vous\' - "Activer ce paramètre désactive le bouton 'Paramètres' dans l'onglet 'Vous'. + "La barre de recherche large est activée dans l'onglet 'Vous'. -Dans ce cas, veuillez utiliser le chemin suivant pour accéder aux paramètres : +Pour accéder aux paramètres, vous devez utiliser le chemin suivant : +Vous → Afficher la chaîne → Menu → Paramètres" + La barre de recherche large est désactivé dans l\'onglet \'Vous\'. + "Activer ce paramètre désactive le bouton 'Paramètres' dans l'onglet 'Vous'. + +Dans ce cas, vous devez utiliser le chemin suivant pour accéder aux paramètres : Vous → Afficher la chaîne → Menu → Paramètres" Masquer le bouton \'Caster\' Le bouton \'Caster\' est masqué. @@ -627,7 +695,7 @@ Appuyez longuement pour ouvrir les paramètres RVX." "Le mélange auto des playlists est activé lorsque la lecture automatique est activé. La lecture automatique peut être modifiée dans les paramètres de YouTube : -Paramètres → Lecture automatique → Lecture automatique de la vidéo suivante" +Paramètres → Lecture automatique / Lecture → Lecture automatique de la vidéo suivante" Activer cette fonction désactivera le passage automatique à YouTube Mix lors de la lecture de musique lorsque la lecture automatique est activée. Fenêtres pop-up du lecteur automatique Les fenêtres pop-up du lecteur automatique sont désactivées. @@ -678,7 +746,7 @@ Note : "Les suggestions de vidéos à l'écran de fin sont masqué lorsque la lecture automatique est désactivée. La lecture automatique peut être modifiée dans les paramètres de YouTube : -'Paramètres → Lecture automatique → Lecture automatique de la vidéo suivante'" +'Paramètres → Lecture automatique / Lecture → Lecture automatique de la vidéo suivante'" Les suggestions de vidéos à la fin sont affichés. Ignorer le compteur lecture auto Si la lecture automatique est activée, la vidéo suivante sera lue immédiatement. @@ -728,6 +796,39 @@ La lecture automatique peut être modifiée dans les paramètres de YouTube : Masquer le bouton \'Merci\' Le bouton \'Merci\' est masqué. Le bouton \'Merci\' est affiché. + + Masquer par Index + Masquer le premier bouton + Le premier bouton est masqué. + Le premier bouton est affiché. + Masquer le second bouton + Le second bouton est masqué. + Le second bouton est affiché. + Masquer le troisième bouton + Le troisième bouton est masqué. + Le troisième bouton est affiché. + Masquer le quatrième bouton + Le quatrième bouton est masqué. + Le quatrième bouton est affiché. + Masquer le cinquième bouton + Le cinquième bouton est masqué. + Le cinquième bouton est affiché. + Masquer le sixième bouton + Le sixième bouton est masqué. + Le sixième bouton est affiché. + Masquer le septième bouton + Le septième bouton est masqué. + Le septième bouton est affiché. + Masquer le huitième bouton + Le huitième bouton est masqué. + Le huitième bouton est affiché. + + Masquer par index pour diff. en direct + A propos du masquage du bouton d\'action par l\'index + "Masquer les boutons d'action par index avant que les boutons d'action ne soient initialisés. + +- Masque les boutons d'action sans laisser d'espace vide. +- L'index des boutons d'action ne correspond pas toujours au même bouton." Mode ambiant Désactive ou contourne les restrictions du Mode ambiant. @@ -920,7 +1021,7 @@ Limitation : Le titre de la vidéo disparaît lorsque vous cliquez dessus."Hauteur de la barre de progression Configure l\'espacement entre la barre de progression et le conteneur d\'actions rapides, entre 0 et 32. La hauteur de l\'action rapide doit être comprise entre 0 et 32. - + Désactiver le mode paysage Le passage en mode paysage en plein écran est désactivé. Le passage en mode paysage en plein écran est activé. @@ -928,7 +1029,8 @@ Limitation : Le titre de la vidéo disparaît lorsque vous cliquez dessus."La voile des contrôles ne remplit pas le plein écran. La voile des contrôles remplit le plein écran. Maintenir le mode paysage - Maintient le mode paysage lorsque l\'écran est éteint et rallumé en mode plein écran. + Les vidéos continuent à être lues en mode paysage après avoir éteint et allumé l\'écran. + Les vidéos sont lues en mode portrait après avoir éteint et allumé l\'écran. Durée du maintien du mode paysage Durée en millisecondes pendant lesquelles le mode paysage est forcé après l\'allumage de l\'écran. @@ -1116,7 +1218,7 @@ Cette fonction fonctionne mieux avec une connexion internet très rapide."Masquer la section \'Transcription\' La section \'Transcription\' est masqué. La section \'Transcription\' est affiché. - + Désac. interaction avec la description vidéo "Désactive les interactions suivantes lorsque la description de la vidéo est développée : @@ -1140,7 +1242,7 @@ L'option 'Ouvrir la description automatiquement' risque de ne pas fonctionner si Masquer les boutons flottants "Les boutons flottants comme 'Utiliser ce son' sont masqués dans l'onglet Shorts des chaînes." "Les boutons flottants comme Utiliser ce son' sont affichés dans l'onglet Shorts des chaînes." - + Étagères Shorts Masquer les étagères à Shorts "Masque les propositions de Shorts. @@ -1164,13 +1266,16 @@ Information : Masquer dans \'Historique\' Masqué dans \'Historique\'. Affiché dans \'Historique\'. - + Modifier l\'état de répétition de l\'arrière-plan des Shorts Répétition des shorts Lecture auto. Par défaut Pause Répéter + Ouvrir les Shorts dans le lecteur normal + Ouvrir les Shorts dans le lecteur normal. + N\'ouvre pas les Shorts dans le lecteur normal. Lecteur Shorts Masque ou affiche des composants dans le lecteur Shorts. @@ -1316,10 +1421,10 @@ Appuyez longuement sur le bouton \"Plus\" pour afficher les actions personnalis Le menu \'État de répétition\' est affiché. Le menu \'État de répétition\' est masqué. À propos des actions personnalisées - "Cette fonctionnalité est encore expérimentale, il n'y a donc aucune garantie qu'elle ne fonctionne correctement. + "Cette fonctionnalité est actuellement expérimentale, il n'est donc pas garanti qu'elle fonctionne parfaitement. -La plupart des bugs ne peuvent pas être corrigés en raison des limitations côté client, elle ne doit être utilisé qu'à des fins de test." - +La plupart des erreurs ne peuvent pas être corrigées en raison des limitations côté client, c'est pourquoi elle ne doit être utilisée qu'à des fins de test." + Activer l\'horodatage "L'horodatage est activé. @@ -1374,7 +1479,7 @@ Pas de marges en haut et en bas du lecteur." Visibilité du voile lors des gestes La visibilité de l\'opacité du voile lors des gestes. Intensité des gestes - L\'intensité du mouvement à effectuer pour que les gestes se produise. + Seuil de déclenchement pour que le geste de balayage se produise. Taille du texte superposé La taille du texte pendant le voile lors du geste. Taille de la zone de gestes @@ -1483,14 +1588,14 @@ Un codec différent sera appliqué après environ 20 secondes de mise en mémoir Les \'Je n\'aime pas\' sont affichés. Les \'Je n\'aime pas\' ne sont pas affichés. Afficher les \'Je n\'aime pas\' sur les Shorts - Affiche les \'Je n\'aime pas\' sur les Shorts. - "Affiche les 'Je n'aime pas' sur les Shorts. + Les \'Je n\'aime pas\' sont affichés sur les Shorts. + "Les 'Je n'aime pas' sont affichés sur les Shorts. Limitation : les \"Je n'aime pas\" ne seront pas affichées si vous n'êtes pas connectés ou en mode incognito." - Les \'Je n\'aime pas\' sur les Shorts sont masqués. + Les \'Je n\'aime pas\' sont masqués sur les Shorts. \'Je n\'aime pas\' en pourcentage - Affiche les \'Je n\'aime pas\' en pourcentage. - Affiche les \'Je n\'aime pas\' en nombre. + Les \'Je n\'aime pas\' sont affichés en pourcentage. + Les \'Je n\'aime pas\' sont affichés en nombre. Bouton \'J\'aime\' compact Le bouton \'J\'aime\' s\'affiche avec une taille réduite. Le bouton \'J\'aime\' s\'affiche avec une meilleure apparence. @@ -1648,12 +1753,12 @@ Cliquez ici pour découvrir comment créer une clé API." L\'URL de l\'API a été modifiée. Copier Importer / Exporter des paramètres - Votre configuration SponsorBlock au format JSON pouvant être importée/exportée sur ReVanced Extended et sur d\'autres plateformes SponsorBlock. - Votre configuration SponsorBlock au format JSON pouvant être importée/exportée sur ReVanced Extended et sur d\'autres plateformes SponsorBlock. Cela inclut votre identifiant d\'utilisateur privé. Partagez-la prudemment. + Votre configuration SponsorBlock au format JSON pouvant être importée / exportée sur RVX et sur d\'autres plateformes SponsorBlock. + Votre configuration SponsorBlock au format JSON pouvant être importée / exportée sur RVX et sur d\'autres plateformes SponsorBlock. Cela inclut votre identifiant d\'utilisateur privé. Partagez-la prudemment. Paramètres importés avec succès. Importation échouée : %s. Exportation échouée : %s. - Vos paramètres contiennent un identifiant utilisateur SponsorBlock privé.\n\nVotre identifiant d\'utilisateur est comme un mot de passe et ne doit jamais être partagé.\n + Vos paramètres contiennent un identifiant privé pour SponsorBlock.\n\nVotre identifiant est comme un mot de passe et ne doit jamais être partagé.\n Ne plus afficher ce message SponsorBlock est temporairement indisponible. SponsorBlock est temporairement indisponible (status %d). @@ -1717,26 +1822,26 @@ Cliquez ici pour découvrir comment créer une clé API." Les données sont fournies par l\'API SponsorBlock. Cliquez ici pour en savoir plus et voir les téléchargements pour d\'autres plateformes. Paramètres avancés + Contourner les redirections d\'URL + Les redirections d\'URL sont contournées. + Les redirections d\'URL ne sont pas contournées. Protocole QUIC - "Désactiver le protocole QUIC de CronetEngine." + "Désactive le protocole QUIC de CronetEngine." Activer le journal de débogage Le journal de débogage est activés. Les journaux de débogage sont désactivés. Activer info. mémoire tampon dans journal de débogage Les journaux de débogage incluent le tampon. Les journaux de débogage n\'incluent pas de tampon. - Activer le navigateur externe - Le navigateur externe est activé. - Le navigateur externe est désactivé. - Activer l\'ouverture des liens directement - Contourne les redirections URL. - Suit la règle de redirection par défaut. + Ouvrir les liens en externe + Ouvre les liens dans le navigateur externe. + Ouvre les liens dans le navigateur de l\'application. Nettoyer les liens partagés Nettoies les liens de partage en supprimant les paramètres de suivi (tracking). Ouvrir les paramètres \'Liens compatibles\' Pour ouvrir les liens YouTube sur RVX, activez l\'option \'Ouvrir les liens compatibles\' et activez les liens Web compatibles. Ouvrir les paramètres GmsCore - Ouvre les paramètres GmsCore. Puis activez la messagerie cloud pour recevoir les notifications. + Pour recevoir les notifications de RVX, activez la messagerie cloud. GmsCore n\'est pas installé. Veuillez l\'installer. Action requise  "GmsCore n'a pas les permissions pour fonctionner en arrière-plan. @@ -1758,7 +1863,7 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." Active le codec OPUS si la réponse du lecteur inclut le codec OPUS. Importer / Exporter les paramètres - Importer ou exporter les paramètres. + Importer ou exporter les paramètres RVX. Importer / Exporter sous forme de fichier Exporter les paramètres @@ -1789,6 +1894,8 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." "Android TV (Connexion requise)" Android VR + "Android VR +(sans authentification)" "iOS (PoToken requis)" "iOS TV @@ -1810,6 +1917,7 @@ AVC a une résolution maximale de 1080p, le codec audio Opus n'est pas disponibl Afficher dans \'Statistiques pour les nerds\' Le client utilisé pour récupérer les données de lecture en direct est affiché dans \'Statistiques pour les nerds\'. Le client utilisé pour récupérer les données de lecture en direct est masqué dans \'Statistiques pour les nerds\'. + Langue de la piste audio par défaut pour VR PoToken / VisitorData PoToken à utiliser diff --git a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml index 99dd4009b..557782837 100644 --- a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml @@ -19,6 +19,59 @@ "A(z) %1$s nincs telepítve. Töltsd le a(z) %2$s weboldalról." %s nincs telepítve. Kérlek telepítsd. + RVX nyelve + Alkalmazás nyelve + Arab + Azerbajdzsáni + Bolgár + Bengáli + Katalán + Cseh + Dán + Német + Görög + Angol + Spanyol + Észt + Perzsa + Finn + Francia + Gudzsaráti + Hindi + Horvát + Magyar + Indonéz + Olasz + Japán + Kazah + Koreai + Litván + Lett + Macedón + Mongol + Marathi + Maláj + Burmai + Holland + Odia + Pandzsábi + Lengyel + Portugál + Román + Orosz + Szlovák + Szlovén + Szerb + Svéd + Szuahéli + Tamil + Telugu + Thai + Török + Ukrán + Urdu + Vietnámi + Kínai Hirdetések Teljes képernyős hirdetések elrejtése @@ -27,12 +80,12 @@ Töltsd le a(z) %2$s weboldalról." Általános hirdetések elrejtése Az általános hirdetések el vannak rejtve. Az általános hirdetések láthatóak. - Rejtsd el a árucikkek polcokat - Az árupolcok el vannak rejtve. - Az árupolcok láthatóak. + Árucikk polcok elrejtése + Az árucikk polcok el vannak rejtve. + Az árucikk polcok láthatóak. Fizetett promóció címke elrejtése - A fizetett promóció címke rejtve van - A fizetett promóciós címke látható. + A fizetett promóció címke el van rejtve. + A fizetett promóció címke látható. Lejátszó bevásárló polcának elrejtése A bevásárló polc el van rejtve. A bevásárló polc látható. @@ -102,13 +155,14 @@ Koppints ide, ha többet szeretnél megtudni a DeArrow-ról." A Feliratok gomb el van rejtve. A Feliratok gomb megjelenik. Forduló polc elrejtése - "A következő polcokat rejtse el: + "A karusszel polcok rejtettek, továbbá ezek is: • Friss hírek -• Folytassa a nézést -• Fedezze fel további csatornákat +• Folytassa a megtekintést +• Fedezzen fel további csatornákat • Hallgassa meg újra • Vásárlás • Nézze meg újra" + A karusszel polcok láthatóak. Vágások polc elrejtése A vágások polc elrejtve. A vágások polc látható. @@ -142,18 +196,18 @@ Koppints ide, ha többet szeretnél megtudni a DeArrow-ról." Lejátszható elemek elrejtése A játékszoba rejtett A játékszoba megjelenik - \'Továbbiak megjelenítése\' gomb elrejtése - A gomb el van rejtve - A gomb megjelenik Keresősáv elrejtése A keresősáv elrejtve. A keresősáv látható. - Kérdőívek elrejtése - A kérdőívek elrejtve. - A kérdőívek megjelennek. + \'Továbbiak megjelenítése\' gomb elrejtése + A gomb el van rejtve + A gomb megjelenik Feliratkozások rész elrejtése A feliratkozások rész elrejtve. A feliratkozások rész látható. + Kérdőívek elrejtése + A kérdőívek elrejtve. + A kérdőívek megjelennek. Jegy polcok elrejtése A jegy polcok elrejtve. A jegy polcok láthatóak. @@ -252,11 +306,12 @@ Korlátozások: Ajánlott videó Alacsony nézettségű videók elrejtése - Az 1000-nél kevesebb megtekintést elért videók elrejtése a Kezdőlapon, amiket a leiratkozott csatornákról töltöttek fel. + "Az 1000-nél kevesebb megtekintést elért videók elrejtése a Kezdőlapon, amiket a leiratkozott csatornákról töltöttek fel. + +Lehet, hogy ez a szűrő már nem működik, használd helyette a 'Megtekintésszám szűrő' szűrőt." Ajánlott videók elrejtése "Elrejti a következő ajánlott videókat: -• Csak a tagok címkével ellátott videók. • Olyan videók, amelyek alatt olyan kifejezések szerepelnek, mint „Mások is megnézték”." Megtekintések szűrő @@ -291,17 +346,12 @@ Ha a lejátszó képernyőjének elrendezése a szerveroldali változtatások mi Eltolás Általános - Elrendezés megváltoztatása - Eredeti - Telefon - Telefon (max 480 dpi) - Tablet - Tablet (min 600 dpi) Kezdőlap megváltoztatása + Alapértelmezett Csatornák böngészése Kurzusok / Tanulás - Alapértelmezett Felfedezés + Divat & szépség Játékok Előzmények Könyvtár @@ -309,8 +359,11 @@ Ha a lejátszó képernyőjének elrendezése a szerveroldali változtatások mi Élő Filmek Zene + Hírek Értesítések + Podcastok Keresés + Vásárlás Shorts Sport Feliratkozások @@ -343,12 +396,18 @@ Korlátozás: Előfordulhat, hogy az eszköztár Vissza gombja nem működik."Szürke elválasztó elrejtése A szürke elválasztók el vannak rejtve A szürke elválasztók láthatóak - Üzenet sáv elrejtése - Az üzenet sáv el van rejtve. - Az üzenet sáv látható. Távolítsa el a nézői diszkréciós párbeszédpanelt "Eltávolítja a nézői belátás párbeszédpanelt. Ez nem kerüli meg a korhatárt. Csak automatikusan fogadja el." + Elrendezés megváltoztatása + Eredeti + Telefon + Telefon (max 480 dpi) + Tablet + Tablet (min 600 dpi) + Élő közvetítés ikon kattintás műveletének módosítása + A csatorna nyílik meg az ikonra kattintva. + Az élő közvetítés nyílik meg az ikonra kattintva. Alkalmazásverzió hamisítása Verzió hamisítás Verzió nincs hamisítva @@ -402,7 +461,7 @@ Előfordulhat, hogy egyes komponensek nincsenek elrejtve." Az eredeti letöltés gomb megnyitja az eredeti, beépített letöltőt. Lejátszási lista letöltő csomag neve A telepített külső letöltő alkalmazás csomagneve, például YTDLnis. - + YouTube Music gomb felülbírálása A YouTube Music gomb az RVX Music-ot indítja. A YouTube Music gomb az erdetit app-ot nyitja meg. @@ -521,9 +580,9 @@ Ha ez a beállítás nem működik, váltson inkognító módra." Adatmegtakarító menü elejtése Az adatmegtakarító menü el van rejtve. Az adatmegtakarító menü látható. - Automatikus lejátszás menü elrejtése - Az automatikus lejátszás menü el van rejtve. - Az automatikus lejátszás menü látható. + Az automatikus lejátszás vagy a lejátszás menü elrejtése + A visszajátszás vagy az automatikus lejátszás menü el van rejtve. + A visszajátszás vagy az automatikus lejátszás menü látható. Videóminőség beállítás menü elrejtése A videóminőség beállítás menü el van rejtve. A videóminőség beállítás menü látható. @@ -569,6 +628,26 @@ Ha ez a beállítás nem működik, váltson inkognító módra." Névjegy menü elrejtése A névjegy menü el van rejtve. A névjegy menü látható. + + Üzenet sáv + Üzenet sávhoz kapcsolódó összetevők elrejtése vagy módosítása. + Üzenet sáv elrejtése + Az üzenet sáv el van rejtve. + Az üzenet sáv látható. + Szerveroldali üzenet sáv elrejtése + A szerveroldali üzenet sáv el van rejtve. + A szerveroldali üzenet sáv látható. + Üzenet sáv színek inverzálása + Az üzenet sáv színei inverzek. + Az üzenet sáv színei nem inverzek. + Szerveroldali üzenet sáv hátterének módosítása + A szerveroldali üzenet sáv háttérszíne megváltozott. + A szerveroldali üzenet sáv háttérszíne nem változott. + "Egyes üzenet sávok a szerver oldalon meghatározott témát használnak, nem az alkalmazástémát. + +Módosítsa ezen üzenet sávok a háttérszínét. + +Ha szerveroldali változások történnek, előfordulhat, hogy az üzenet sáv háttérszíne nem változik." Eszköztár Elrejt vagy megváltoztat komponenseket az eszköztáron, mint például a keresősáv, eszköztár gombok és fejléc. @@ -582,10 +661,15 @@ Ha ez a beállítás nem működik, váltson inkognító módra." A széles keresősáv nem takarja el a YouTube fejlécét. A széles keresősáv elakarja a YouTube fejlécét. Széles kereső sáv engedélyezése a Te lapon - "Ha bekapcsolja ezt a beállítást, letiltja a beállítások gombot a Te lapon. + "A széles keresősáv engedélyezve van a Te lapon. -Ebben az esetben kérjük használja a következő utat a beállításokhoz való hozzáféréshez: +A beállítások eléréséhez használja a következő utat: Te lap → Csatorna megtekintése → Menü → Beállítások" + A széles keresősáv le van tiltva a Te lapon. + "A beállítás engedélyezése letiltja a Beállítások gombot a Te lapon. + +Ebben az esetben előfordulhat, hogy a következő elérési utat kell használnia a beállítások eléréséhez: +Ön fül → Csatorna megtekintése → Menü → Beállítások" Kivetítés gomb elrejtése A kivetítés gomb el van rejtve. A kivetítés gomb látható. @@ -620,7 +704,7 @@ Te lap → Csatorna megtekintése → Menü → Beállítások" Egyéni lejátszó átlátszóság beállítása Átlátszósági érték 0 és 100 között, ahol a 0 az átlátszó. A lejátszó átlátszóságának 0 és 100 között kell lennie. Visszaállítás alapértelmezettre. - Mix lejátszási listák letiltása + Mix listák automatikus lejátszásának letiltása Az automatikus mix lejátszási listák le vannak tiltva. "Az automatikus mix lejátszási listák engedélyezve vannak, ha az automatikus lejátszás be van kapcsolva. @@ -726,6 +810,39 @@ Beállítások → Automatikus lejátszás → Következő videó automatikus le Köszönet gomb elrejtése A köszönet gomb el van rejtve. A köszönet gomb látható. + + Elrejtés index alapján + Első gomb elrejtése + Az első gomb el van rejtve. + Az első gomb látható. + Második gomb elrejtése + A második gomb el van rejtve. + A második gomb látható. + Harmadik gomb elrejtése + A harmadik gomb el van rejtve. + A harmadik gomb látható. + Negyedik gomb elrejtése + A negyedik gomb el van rejtve. + A negyedik gomb látható. + Ötödik gomb elrejtése + Az ötödik gomb el van rejtve. + Az ötödik gomb látható. + Hatodik gomb elrejtése + A hatodik gomb el van rejtve. + A hatodik gomb látható. + Hetedik gomb elrejtése + A hetedik gomb el van rejtve. + A hetedik gomb látható. + Nyolcadik gomb elrejtése + A nyolcadik gomb el van rejtve. + A nyolcadik gomb látható. + + Elrejtés az élő közvetítésben index alapján + Műveletgomb elrejtése index alapján + "A műveletgombok index szerint elrejtése, mielőtt inicializálná azokat. + +- A műveletgombok elrejtése nem hagy üres helyet. +- Előfordulhat, hogy a műveletgombok indexe nem mindig ugyanaz a gomb." Mozifilmes világítás mód Tiltsa le a mozifilmes világítás módot, vagy kerülje meg a korlátozásait. @@ -918,7 +1035,7 @@ Korlátozás: A videó címe eltűnik, ha rákattint." Gyorsműveletek felső margó Állítsa be a keresősáv és a gyorsművelet rész közötti távolságot 0-32 között. A gyors műveletek felső margójának 0 és 32 között kell lennie. - + Fekvő mód letiltása A videó tájolása álló mód teljes képernyő esetén. A videó tájolása követi a készülék beállításait teljes képernyő esetén. @@ -926,7 +1043,8 @@ Korlátozás: A videó címe eltűnik, ha rákattint." A vezérlők nem töltik ki a teljes képernyőt. A vezérlők kitöltik a teljes képernyőt. Tartsa a fekvő módot - Megtartja a fekvő módot a képernyő ki- és bekapcsolásakor teljes képernyőn. + A videók lejátszása fekvő módban folytatódik a képernyő ki- és bekapcsolása után. + A videók portré módban játszódnak le a képernyő ki- és bekapcsolása után. Fekvő mód tartás időtúllépése Az ezredmásodpercek száma, amelyek alatt a tájkép mód erőltetett, miután a képernyőt bekapcsolták. @@ -1076,9 +1194,9 @@ Információ: Jó minőségű miniatűrök engedélyezése A keresősáv bélyegképei kiváló minőségűek. A keresősáv bélyegképei közepes minőségűek. - "Ezzel visszaállítja az indexképeket az olyan élő közvetítésekhez, amelyek nem rendelkeznek keresősáv-bélyegképekkel. + "Ezzel visszaállítja az indexképeket az olyan élő közvetítésekhez, amelyek nem rendelkeznek keresősáv-indexképekkel. -Az internetes adathasználat magasabb lehet, és a keresősáv bélyegképei kis késéssel jelennek meg. +Az internetes adathasználat magasabb lehet, és a keresősáv indexképei kis késéssel jelennek meg. Ez a funkció nagyon gyors internetkapcsolat mellett működik a legjobban." @@ -1114,7 +1232,7 @@ Ez a funkció nagyon gyors internetkapcsolat mellett működik a legjobban."Átirat rész elrejtése Az átirat rész el van rejtve. Az átirat rész látható. - + Videoleírás interakció letiltása "Letiltja a következő interakciókat, ha a videoleírás ki lett bővítve: @@ -1138,7 +1256,7 @@ A videoleírások kibővítése nem működik, ha a beírt név nem egyezik meg Lebegő gomb elrejtése "Az olyan lebegő gombok, mint a „Használja ezt a hangot”, el vannak rejtve a Shorts csatorna lapon." "Az olyan lebegő gombok, mint a „Használja ezt a hangot”, a Shorts csatorna lapon láthatóak." - + Shorts polcok Shorts polcok elrejtése "Elrejti a Shorts polcokat. @@ -1162,13 +1280,16 @@ Információ: Elrejtés a nézési előzmények között Elrejtve a nézési előzmények között. Megjelenítve a nézési előzmények között. - + Shorts háttér ismétlési állapotának módosítása Shorts ismétlési állapotának módosítása Automatikus lejátszás Alapértelmezett Szünet Ismétlés + Short-ok megnyitása a normál lejátszóban + A Short-ok megnyitása a normál lejátszóban. + A Short-ok megnyitása nem a normál lejátszóban. Shorts lejátszó Komponensek elrejtése vagy megjelenítése a Shorts lejátszójában. @@ -1234,7 +1355,7 @@ Információ: Szuper köszönet gomb elrejtése A Szuper köszönet gomb el van rejtve. A Szuper köszönet gomb látható. - Címkézett termékek elrejtése + Megjelölt termékek elrejtése A címkézett termékek el vannak rejtve. A címkézett termékek láthatóak. Sablon használata gomb elrejtése @@ -1265,9 +1386,9 @@ Információ: A hang gomb látható. Animáció / Visszajelzés - Like gomb animáció elrejtése - A szökőkút animáció le van tiltva a Like gombon. - A szökőkút animáció engedélyezve van a Like gombon. + Tetszik gomb szökőkút animáció elrejtése + A szökőkút animáció le van tiltva a Tetszik gombon. + A szökőkút animáció engedélyezve van a Tetszik gombon. Dupla koppintás animáció Eredeti Felfelé menő hüvelykujj @@ -1314,10 +1435,10 @@ Nyomja meg és tartsa lenyomva a További gombot az egyéni műveletek párbesz Az ismétlés állapot menü látható. Az ismétlés állapot menü el van rejtve. Az egyéni műveletekről - "Ez a funkció még kísérleti jellegű, így nincs garancia arra, hogy tökéletesen fog működni. + "Ez a funkció még kísérleti jellegű, így nincs garancia arra, hogy tökéletesen fog működni. -A legtöbb hiba nem javítható az ügyféloldali korlátozások miatt, ezért csak tesztelési célokra használja." - +A legtöbb hiba nem javítható az ügyféloldali korlátozások miatt, ezért csak tesztelési célokra használd." + Fejezetek engedélyezése "Az időbélyeg engedélyezve van. @@ -1539,7 +1660,7 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." A szegmens szavazógomb nem látható. Kompakt kihagyás gomb használata A kihagyás gomb minimális szélességre formázva. - A kihagyás gomb a legjobb megjelenésre formázva + A kihagyás gomb a legjobb megjelenésre formázva. Automatikusan elrejti a kihagyás gombot A kihagyás gomb néhány másodperc után eltűnik. A kihagyás gomb a teljes szakasz alatt megjelenik. @@ -1560,15 +1681,15 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." Kiemelt A videónak azon része, amit a legtöbben keresnek. Megszakítás / Intro animáció - Egy részlet tartalom nélkül. Lehet szünet, álló képkocka, vagy ismétlődő animáció. Nem használandó információt tartalmazó átmeneteknél - Záróképernyő/Köszönetek - Stáblista, vagy amikor megjelennek a YouTube zárókártyák. Nem tartozik bele az információt tartalmazó összegzés - Előzetes/Ismétlés - Olyan klipek gyűjteménye, amik azt mutatják, hogy mi következik majd ebben, vagy a sorozat más videóiban és minden információ megismétlődik később a videóban - Érintőleges tartalom/Viccek - Csak töltelék vagy humornak hozzáadott részek, amik nem szükségesek a videó fő tartalmának megértéséhez. Ne tartalmazzon olyan szegmenseket, amik kontextust, vagy háttérinformációt szolgáltatnak + Egy részlet tényleges tartalom nélkül. Lehet szünet, álló képkocka, vagy ismétlődő animáció. Ne használja információt tartalmazó átmeneteknél. + Záróképernyő / Köszönetek + Stáblista, vagy amikor megjelennek a YouTube zárókártyák. Nem tartozik bele az információt tartalmazó összegzés. + Előzetes / Ismétlés / Visszautalás + Olyan szakaszok, amik azt mutatják, hogy mi következik majd ebben, vagy a sorozat más videóiban és minden információ megismétlődik később a videóban. + Témától eltérő rész / Viccek + Témától eltérő vagy humoros hozzáadott részek, amik nem szükségesek a videó fő tartalmának megértéséhez. Ne tartalmazzon olyan szegmenseket, amik kontextust, vagy háttérinformációt szolgáltatnak. Zene: zenementes rész - Csak zenei videókhoz használható. Zenei videók zene nélküli részei, amelyek még nem tartoznak más kategóriába + Csak zenei videókhoz használandó. Zenei videók zene nélküli részei, amelyek nem tartoznak más kategóriába. Kihagyás Kiemelt rész Szponzor kihagyása @@ -1621,10 +1742,10 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." Az ezredmásodpercek száma, ameddig az időbeállító gombok léptetnek új szegmensek létrehozásakor. Az értéknek pozitív számnak kell lennie. Irányelvek megtekintése - Az irányelvek szabályokat és ötleteket tartalmaznak a szegmensek beküldésével kapcsolatban. - Kövesse az irányelveket - Olvassa el a SponsorBlock irányelveket szegmensek beküldése előtt. - Már elolvastam + Az irányelvek szabályokat és ötleteket tartalmaznak a szakaszok beküldésével kapcsolatban. + Kövesd az irányelveket + Olvassa el a SponsorBlock irányelveket szakaszok beküldése előtt. + Már elolvastad Mutasd Általános @@ -1632,45 +1753,45 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." Üzenet látható, ha a SponsorBlock nem elérhető. Nem látható üzenet, ha a SponsorBlock nem elérhető. Átugrások számolásának engedélyezése - Értesíti a SponsorBlock ranglistáját, hogy mennyi időt takarított meg. Minden egyes szakasz kihagyásakor üzenetet küld a ranglistának - A kihagyások számának követése nem engedélyezett - Minimális szegmens időtartam + Értesíti a SponsorBlock ranglistáját, hogy mennyi időt takarítottál meg. Minden egyes szakasz kihagyásakor üzenetet küld a ranglistának. + A kihagyások számának követése nem engedélyezett. + Minimálus szakasz időtartam A beállított értéknél (másodpercben) rövidebb szakaszokat nem hagyja ki vagy jeleníti meg. Érvénytelen időtartam. - Az Ön privát felhasználói azonosítója - Ezt bizalmasan kell kezelni. Olyan mint egy jelszó és senkivel sem ajánlott megosztani. Ha valaki megszerzi, meg tudja személyesíteni önt - A privát felhasználói azonosítónak legalább 30 karakter hosszúnak kell lennie + Az privát felhasználói azonosítód + Ezt bizalmasan kell kezelni. Olyan mint egy jelszó és senkivel sem ajánlott megosztani. Ha valaki megszerzi, meg tud személyesíteni téged. + A privát felhasználói azonosítónak legalább 30 karakter hosszúnak kell lennie. API URL módosítása - Az a cím, amelyet a SponsorBlock a szervere eléréséhez használ - API URL alaphelyzetbe állítása - API URL érvénytelen - API URL megváltoztatva + Az a cím, amelyet a SponsorBlock a szervere eléréséhez használ. + Az API URL visszaállítása. + Az API URL érvénytelen. + Az API URL megváltozott. Másolás - Beállítások importálása/exportálása - Az Ön SponsorBlock JSON-konfigurációja, amely importálható/exportálható ReVanced és más SponsorBlock platformokra - A SponsorBlock JSON-konfigurációja, amely importálható/exportálható a ReVanced és más SponsorBlock platformokra. Ez magában foglalja a privát felhasználói azonosítóját is. Ügyeljen arra, hogy ezt bölcsen ossza meg - A beállítások sikeresen importálva - Nem sikerült importálni ezt: %s - Nem sikerült exportálni ezt: %s - A beállításai tartalmazzák a privát SponsorBlock felhasználói azonosítót.\n\nA felhasználói azonosító olyan, mint egy jelszó, és soha nem szabad megosztani.\n + Beállítások importálása / exportálása + A SponsorBlock JSON konfigurációja, amely importálható / exportálható ReVanced Extended és más SponsorBlock platformokra. + A SponsorBlock JSON konfigurációja, amely importálható / exportálható a ReVanced Extended és más SponsorBlock platformokra. Ez magában foglalja a privát felhasználói azonosítódat is. Ügyelj arra, hogy ezt bölcsen oszd meg. + A beállítások sikeresen importálva. + Nem sikerült importálni: %s. + Nem sikerült exportálni: %s. + A beállításaid tartalmazzák a privát SponsorBlock felhasználói azonosítót.\n\nA felhasználói azonosító olyan, mint egy jelszó, és soha nem szabad megosztani.\n Ne jelenjen meg többet - A SponsorBlock átmenetileg nem elérhető - A SponsorBlock jelenleg nem elérhető (állapot %d) - A SponsorBlock jelenleg nem elérhető (API időtúllépés) - Nem lehet beküldeni a szegmenst: %s - A SponsorBlock átmenetileg nem működik - Nem lehet beküldeni a szegmenst (állapot: %1$d %2$s) - Nem sikerült beküldeni a szegmenst.\nGyakorisági korlát (Túl sok beküldés) - Nem lehet beküldeni a szegmenst: %s - Nem sikerült beküldeni a szakaszt.\nMár létezik - A szakasz sikeresen beküldve - Nem lehet szavazni a szegmensre (API időtúllépés) - Nem lehet szavazni erre (állapot: %1$d %2$s) - Nem lehet szavazni a szegmensre: %s - Pozitív szavazás + A SponsorBlock átmenetileg nem elérhető. + A SponsorBlock átmenetileg nem elérhető (állapot %d). + A SponsorBlock átmenetileg nem elérhető (API időtúllépés). + Nem lehet beküldeni a szakaszt: %s. + A SponsorBlock átmenetileg nem működik. + Nem lehet beküldeni a szakaszt (állapot: %1$d %2$s). + Nem lehet beküldeni a szakaszt.\nGyakorisági korlát (túl sok ugyanattól a felhasználótól vagy IP-ről). + A szakasz nem küldhető be: %s. + A szakasz nem küldhető be.\nMár létezik. + A szakasz sikeresen beküldve. + Nem lehet szavazni a szakaszra (API időtúllépés). + Nem lehet szavazni a szakaszra (állapot: %1$d %2$s). + Nem lehet szavazni a szakaszra: %s. + Mellette szavazás Leszavazás - Kategória megváltoztatása - Nincsenek szakaszok, amikre szavazni lehet + Kategória módosítása + Nincsen szakasz, amire szavazni lehet. Válassza ki a szakasz kategóriáját A kategória letiltva a beállításokban. Engedélyezze a beküldéshez. Új SponsorBlock szakasz @@ -1678,67 +1799,71 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." kezdőpont végpont most - A szakasz kezdetének időpontja: - A szakasz végének időpontja: + A szakasz kezdetének időpontja + A szakasz végének időpontja Helyesek az időpontok? A szegmens:\n\n%1$s-tól\n\n%2$s-ig\n\n(%3$s)\n\nKészen állsz a beküldésre? - A kezdetnek a vége előtt kell lennie - Előbb jelöljön meg két pontot az idősávon - Szakasz előnézete a zökkenőmentesen kihagyás érdekében - A szakasz időzítésének kézi beállítása - Akarja szerkeszteni a rész kezdetének vagy végének időzítését? - Érvénytelen idő van megadva + A kezdetnek a vége előtt kell lennie. + Előbb jelöljön meg két pontot az idősávon. + Szakasz előnézete a zökkenőmentes kihagyás érdekében. + Szakasz időzítésének kézi beállítása + Szerkeszteni szeretné a rész kezdetének vagy végének időzítését? + Érvénytelen a megadott idő. Statisztikák - A statisztikák átmenetileg nem elérhetőek (API leállt) + A statisztikák átmenetileg nem elérhetőek (API leállt). Betöltés... - A SponsorBlock ki van kapcsolva - Az ön felhasználóneve: <b>%s</b> - Koppintson ide a felhasználónév megváltoztatásához - A felhasználónév nem módosítható: Állapot: %1$d %2$s - A felhasználónév sikeresen módosítva - Az ön hírneve: <b>%.2f</b> - <b>%s</b> szegmenst készítettél + A SponsorBlock le van tiltva. + Az felhasználóneved: <b>%s</b> + Koppints ide a felhasználónév megváltoztatásához + A felhasználónév nem módosítható: Állapot: %1$d %2$s. + A felhasználónév sikeresen módosítva. + Az hírneved: <b>%.2f</b> + <b>%s</b> szakaszt készítettél Koppintson ide a szegmensek megtekintéséhez. SponsorBlock ranglista - <b>%s</b> szegmenstől mentettél meg másokat - Koppintson ide a globális statisztikák és a kiemelt közreműködők megtekintéséhez - Ez <b>%s</b> az életükből.<br>Koppintson a ranglista megtekintéséhez - <b>%s</b> szakaszt kihagyott - Ez <b>%s</b> - Visszaállítja a kihagyott szakaszok számlálóját? + <b>%s</b> szakasztól mentettél meg másokat + Koppints ide a globális statisztikák és a kiemelt közreműködők megtekintéséhez. + Ez <b>%s</b> az életükből.<br>Koppintson a ranglista megtekintéséhez. + <b>%s</b> szakaszt hagytál ki + Ez <b>%s</b>. + Visszaállítod a kihagyott szakaszok számlálóját? %1$s óra %2$s perc %1$s perc %2$s másodperc %s másodperc - Rólunk + Névjegy sponsor.ajay.app - Az adatokat a SponsorBlock API biztosítja. Koppintson ide, ha többet szeretne megtudni és megtekintené a letöltéseket más platformokra + Az adatokat a SponsorBlock API biztosítja. Koppints további információért és a más platformokra való letöltések megtekintéséhez. Vegyes + URL átirányítások kikerülése + Az URL átirányítások kikerülve. + Az URL átirányítások nincsenek kikerülve. QUIC protokoll letiltása "A CronetEngine QUIC protokoll letiltása." Hibakeresési naplózás engedélyezése - A hibakeresési napló engedélyezve van. + A hibakeresési napló engedélyezett. A hibakeresési napló le van tiltva. Hibakeresési puffernaplózás engedélyezése A hibakeresési naplók tartalmazzák a puffert. A hibakeresési naplók nem tartalmazzák a puffert. - Külső böngésző engedélyezése - A külső böngésző engedélyezve van. - A külső böngésző le van tiltva. - Közvetlen link megnyitások engedélyezése - Az URL átirányítások kikerülése. - Az alapértelmezett átirányítási rendet követi. + Linkek külső megnyitása + A linkek a külső böngészőben nyílnak meg. + A linkek az app böngészőjében nyílnak meg. Megosztási linkek tisztítása - Linkek megosztásakor eltávolítja a nyomkövetés lekérdezési paramétereket az URL-ekből. + A linkek megosztásakor eltávolítja a nyomonkövetési kérést az URL-ekből. Alapértelmezett program beállítások megnyitása - A YouTube linkek megnyitásához az RVX-ben engedélyezze az \'Támogatott linkek megnyitása\' és engedélyezze a támogatott webcímeket. - GmsCore megnyitása + YouTube linkek RVX-el való megnyitásához, engedélyezze a támogatott hivatkozások megnyitását és engedélyezze az összes támogatott webcímet. + GmsCore beállítások megnyitása Engedélyezze a felhő alapú üzenetküldést az értesítések fogadásához. - MicroG GmsCore nincs telepítve. Telepítse. + MicroG GmsCore nincs telepítve. Telepítsd. Művelet szükséges - "A MicroG GmsCore nem rendelkezik engedéllyel, hogy a háttérben futhasson.\n\nKövesse a \"Don't kill my app\" útmutatót a telefonjához és alkalmazza a leírtakat a MicroG telepítésre.\n\nEz szükséges az alkalmazás működéséhez." + "A MicroG GmsCore nem rendelkezik engedéllyel, hogy a háttérben futhasson. + +Kövesse a \"Don't kill my app\" útmutatót a telefonjához és alkalmazza a leírtakat a MicroG telepítésre. + +Ez szükséges az alkalmazás működéséhez." Webhely megnyitása "A GmsCore akkumulátor-optimalizálását ki kell kapcsolni a problémák megelőzése érdekében. @@ -1753,16 +1878,16 @@ Kattints a folytatás gombra és kapcsold ki az akkumulátor-optimalizálásokat Engedélyezi az OPUS kodeket, ha a lejátszó válasza tartalmazza az OPUS kodeket. Beállítások importálása / exportálása - Beállítások importálása vagy exportálása. + RVX beállítások importálása / exportálása. - Importálás / Exportálás fájlként + Import / Export fájlként Beállítások exportálása - Beállítások exportálása egy fájlba. + Beállítások exportálása fájlba. Beállítások importálása - Beállítások importálása egy mentett fájlból. + Beállítások importálása mentett fájlból. - Importálás / Exportálás szövegként - Importálás / exportálás szövegként + Import / Export szövegként + Importálás / Exportálás szövegként Beállítások importálása vagy exportálása szövegként. A beállítások exportálása sikertelen. A beállítások exportálása sikeres. @@ -1784,6 +1909,8 @@ Kattints a folytatás gombra és kapcsold ki az akkumulátor-optimalizálásokat "Android TV (Belépés szükséges)" Android VR + "Android VR +(Nincs hitelesítés)" "iOS (PoToken szükséges)" "iOS TV @@ -1797,7 +1924,7 @@ Kattints a folytatás gombra és kapcsold ki az akkumulátor-optimalizálásokat "• Előfordulhat, hogy a filmeket vagy a fizetős videókat nem lehet lejátszani. • Előfordulhat, hogy a gyerekeknek szánt tartalmat nem lehet lejátszani, ha ki van jelentkezve vagy inkognitó módban van." Kényszerített iOS AVC (H.264) - A videó kodek AVC-re (H.264) van kényszerítve. + A kényszerített videó kodek az AVC (H.264). A videokodek meghatározása automatikusan történik. "Ennek engedélyezése javíthatja az akkumulátor élettartamát és javíthatja a lejátszás akadozását. @@ -1805,6 +1932,7 @@ Az AVC maximális felbontása 1080p, az Opus hangkodek nem érhető el, és a vi Megjelenítés a statisztikában kockáknak Az adatfolyam lekérésére használt kliens a statisztikában kockáknak látható. Az adatfolyam lekérésére használt kliens a statisztikában kockáknak nem látható. + VR alapértelmezett audio adatfolyam nyelve PoToken / VisitorData PoToken használatához diff --git a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml index 9883ed287..22a27e293 100644 --- a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml @@ -19,6 +19,59 @@ "%1$s non è installato. Si prega di scaricare %2$s dal sito web." %s non è installato. Per favore installalo. + Lingua di RVX + Lingua dell\'app + Arabo + Azero + Bulgaro + Bengalese + Catalano + Ceco + Danese + Tedesco + Greco + Inglese + Spagnolo + Estone + Persiano + Finlandese + Francese + Gujarati + Hindi + Croato + Ungherese + Indonesiano + Italiano + Giapponese + Kazako + Coreano + Lituano + Lettone + Macedone + Mongolo + Marathi + Malese + Birmano + Olandese + Odia + Punjabi + Polacco + Portoghese + Rumeno + Russo + Slovacco + Sloveno + Serbo + Svevo + Swahili + Tamil + Telugu + Tailandese + Turco + Ucraino + Urdu + Vietnamita + Cinese Annunci Nascondi gli annunci a schermo intero @@ -101,14 +154,15 @@ Tocca qui per saperne di più su DeArrow." Nascondi il pulsante Sottotitoli Il pulsante Sottotitoli è nascosto. Il pulsante Sottotitoli è visibile. - Nascondi lo scaffale a carosello - "Nasconde i seguenti scaffali: + Nascondi gli scaffali a carosello + "Nascondi i seguenti scaffali a carosello: • Ultime notizie • Continua a guardare • Guarda di nuovo • Ascolta di nuovo • Esplora altri canali • Shopping" + Gli scaffali a carosello sono visibili. Nascondi lo scaffale dei chip Lo scaffale dei chip è nascosto. Lo scaffale dei chip è visibile. @@ -142,18 +196,18 @@ Tocca qui per saperne di più su DeArrow." Nascondi lo scaffale Sala Giochi Lo scaffale Sala Giochi è nascosto. Lo scaffale Sala Giochi è visibile. - Nascondi il pulsante Mostra Altro - Il pulsante Mostra Altro è nascosto. - Il pulsante Mostra Altro è visibile. Nascondi la barra di ricerca La barra di ricerca è nascosta. La barra di ricerca è visibile. - Nascondi i sondaggi - I sondaggi sono nascosti. - I sondaggi sono visibili. + Nascondi il pulsante Mostra Altro + Il pulsante Mostra Altro è nascosto. + Il pulsante Mostra Altro è visibile. Nascondi il carosello delle iscrizioni Il carosello delle iscrizioni è nascosto. Il carosello delle iscrizioni è visibile. + Nascondi i sondaggi + I sondaggi sono nascosti. + I sondaggi sono visibili. Nascondi lo scaffale degli eventi Lo scaffale degli eventi è nascosto. Lo scaffale degli eventi è visibile. @@ -252,11 +306,11 @@ Note: Video consigliati Nascondi i video con poche visualizzazioni - Nascondi i video con meno di 1.000 visualizzazioni dalla scheda Home che sono stati caricati dai canali a cui non sei iscritto. + "Nascondi i video con meno di 1.000 visualizzazioni dalla scheda Home che sono stati caricati dai canali a cui non sei iscritto. + +Nota: questa impostazione potrebbe non funzionare più, usa invece \"Filtro sul numero di visualizzazioni\"." Nascondi i video consigliati - "Nasconde i seguenti video consigliati con: -• Tag \"Riservato agli abbonati\". -• Frasi come \"Le persone hanno guardato anche questo video\" sotto." + "Nascondi i video consigliati con frasi come \"Le persone hanno guardato anche questo video\" sotto." Filtro sul numero di visualizzazioni Nascondi i video della scheda Home per visualizzazioni @@ -276,7 +330,7 @@ Note: Specifica il tuo modello linguistico per il numero di visualizzazioni mostrate sotto ogni video nell\'interfaccia. Ogni chiave (una lettera o una parola nella tua lingua) -> valore (significato della chiave) deve essere su una nuova riga. Le chiavi vanno prima del \"->\" segno. Se cambi la lingua dell\'app o di sistema, devi reimpostare questa impostazione.\n\nEsempi:\nInglese: 10K views = K -> 1000, views -> visualizzazioni\nSpagnolo: 10 K vistas = K -> 1000, vistas -> views Mln di -> 1000000\nMld -> 1000000000\nvisualizzazioni -> views Informazioni sul filtro delle visualizzazioni - "Le schede Home e Iscrizioni e i risultati di ricerca sono filtrati per nascondere i video con visualizzazioni inferiori o superiori ad un numero specificato. + "Le schede Home e Iscrizioni e i risultati di ricerca sono filtrati per nascondere i video con visualizzazioni inferiori o superiori a un numero specificato. Note: • Gli Shorts non possono essere nascosti. @@ -289,18 +343,13 @@ Note: Se l'interfaccia della schermata del riproduttore cambia a causa di modifiche lato server, potrebbero esserci delle interfacce indesiderate nascosti nella schermata del riproduttore." Numero massimo di interfacce - Generale - Cambia l\'interfaccia - Originale - Telefono - Telefono (Massimo 480 dp) - Tablet - Tablet (Minimo 600 dp) + Generali Cambia la scheda iniziale + Predefinita (Home) Esplora canali Apprendimento - Predefinita (Home) Esplora + Moda e bellezza Giochi Cronologia Tu (Raccolta) @@ -308,8 +357,11 @@ Se l'interfaccia della schermata del riproduttore cambia a causa di modifiche la Live Film e TV Musica + Notizie Notifiche + Podcast Cerca + Shopping Shorts Sport Iscrizioni @@ -342,16 +394,22 @@ Nota: il pulsante Indietro della barra degli strumenti potrebbe non funzionare." Nascondi i separatori grigi I separatori grigi sono nascosti. I separatori grigi sono visibili. - Nascondi le notifiche snackbar - Le notifiche snackbar sono nascoste. - Le notifiche snackbar sono visibili. Rimuovi la finestra sulla discrezione dello spettatore "Rimuove la finestra sulla discrezione dello spettatore. Nota: questo non bypassa la restrizione di età, ma la accetta automaticamente." + Cambia l\'interfaccia + Originale + Telefono + Telefono (Massimo 480 dp) + Tablet + Tablet (Minimo 600 dp) + Cambia cosa apre l\'anello live quando viene toccato + Canale + Video live Attiva il camuffamento della versione dell\'app Il camuffamento della versione dell\'app è attivato. Il camuffamento della versione dell\'app è disattivato. - "La versione dell'app sarà camuffata ad una versione precedente di YouTube. + "La versione dell'app sarà camuffata a una versione precedente di YouTube. Questo cambierà l'aspetto e le caratteristiche dell'app, ma potrebbero verificarsi effetti collaterali sconosciuti. @@ -401,7 +459,7 @@ Nota: alcuni componenti potrebbero non essere nascosti." Il pulsante Scarica Video nativo apre il downloader nativo. Nome del pacchetto del downloader esterno delle playlist Il nome del pacchetto dell\'app di download esterna installata, ad esempio YTDLnis. - + Sovrascrivi il pulsante YouTube Music Il pulsante YouTube Music apre l\'app RVX Music. Il pulsante YouTube Music apre l\'app originale. @@ -521,15 +579,15 @@ Se questa impostazione non ha effetto, prova a passare alla navigazione in incog Nascondi il menù Risparmio Dati Il menù Risparmio Dati è nascosto. Il menù Risparmio Dati è visibile. - Nascondi il menù Riproduzione Automatica - Il menù Riproduzione Automatica è nascosto. - Il menù Riproduzione Automatica è visibile. + Nascondi il menù Riproduzione Automatica o Riproduzione + Il menù Riproduzione Automatica o Riproduzione è nascosto. + Il menù Riproduzione Automatica o Riproduzione è visibile. Nascondi il menù Preferenze Relative alla Qualità Video Il menù Preferenze Relative alla Qualità Video è nascosto. Il menù Preferenze Relative alla Qualità Video è visibile. - Nascondi il menù Sfondo - Il menù Sfondo è nascosto. - Il menù Sfondo è visibile. + Nascondi il menù Background e Download o Sfondo + Il menù Background e Download o Sfondo è nascosto. + Il menù Background e Download o Sfondo è visibile. Nascondi il menù Guarda sulla TV Il menù Guarda sulla TV è nascosto. Il menù Guarda sulla TV è visibile. @@ -569,6 +627,26 @@ Se questa impostazione non ha effetto, prova a passare alla navigazione in incog Nascondi il menù Informazioni Il menù Informazioni è nascosto. Il menù Informazioni è visibile. + + Notifiche snackbar + Personalizza i componenti delle notifiche snackbar. + Nascondi le notifiche snackbar + Le notifiche snackbar sono nascoste. + Le notifiche snackbar sono visibili. + Nascondi le notifiche snackbar lato server + Le notifiche snackbar lato server sono nascoste. + Le notifiche snackbar lato server sono visibili. + Inverti il tema delle notifiche snackbar + Il tema delle notifiche snackbar è invertito. + Il tema delle notifiche snackbar non è invertito. + Cambia lo sfondo delle notifiche snackbar lato server + Lo sfondo delle notifiche snackbar lato server è cambiato. + Lo sfondo delle notifiche snackbar lato server non è cambiato. + "Alcune notifiche snackbar usano un tema definito sul lato server, non sul tema dell'app. + +Cambia il colore di sfondo di queste notifiche. + +Se ci sono cambiamenti sul lato server, il colore potrebbe non cambiare." Barra degli strumenti Personalizza i componenti della barra degli strumenti, come la barra di ricerca, i pulsanti e l\'intestazione. @@ -579,12 +657,18 @@ Se questa impostazione non ha effetto, prova a passare alla navigazione in incog La barra di ricerca estesa è attivata. La barra di ricerca estesa è disattivata. Attiva la barra di ricerca estesa con l\'intestazione - La barra di ricerca estesa con l\'intestazione è attivata. - La barra di ricerca estesa con l\'intestazione è disattivata. + La barra di ricerca estesa con l\'intestazione di YouTube è attivata. + La barra di ricerca estesa con l\'intestazione di YouTube è disattivata. Attiva la barra di ricerca estesa nella scheda Tu - "L'attivazione di questa impostazione disattiverà il pulsante Impostazioni nella scheda Tu. + "La barra di ricerca estesa nella scheda Tu è attivato. -In questo caso, seguire questi percorsi per accedere alle impostazioni: +Segui questi percorsi per accedere alle impostazioni: +• Scheda Tu → Visualizza canale → 3 punti verticali → Impostazioni +• Scheda Home → Pulsante Esplora → Tendenze → 3 punti verticali → Impostazioni" + La barra di ricerca estesa nella scheda Tu è disattivato. + "L'attivazione di questa impostazione disattiverà il pulsante Impostazioni nella scheda Tu. + +Perciò segui questi percorsi per accedere alle impostazioni: • Scheda Tu → Visualizza canale → 3 punti verticali → Impostazioni • Scheda Home → Pulsante Esplora → Tendenze → 3 punti verticali → Impostazioni" Nascondi il pulsante Trasmetti @@ -628,7 +712,7 @@ Tocca e tieni premuto per aprire le impostazioni di RVX." "Il cambio automatico alle playlist miste è attivato quando è attivata anche la riproduzione automatica. La riproduzione automatica può essere modificata seguendo questo percorso: -Impostazioni → Riproduzione automatica → Telefono cellulare/tablet" +Impostazioni → Riproduzione automatica / Riproduzione → Riproduci automatic. video successivo" L\'attivazione di questa impostazione disattiverà il cambio automatico alle playlist miste durante la riproduzione di musica con la riproduzione automatica attiva. Disattiva il pannello a comparsa automatico Il pannello a comparsa automatico è disattivato. @@ -679,7 +763,7 @@ Note: "La schermata finale del video consigliato è nascosta quando la riproduzione automatica è disattivata. La riproduzione automatica può essere modificata seguendo questo percorso: -Impostazioni → Riproduzione automatica → Telefono cellulare/tablet" +Impostazioni → Riproduzione automatica / Riproduzione → Riproduci automatic. video successivo" La schermata finale del video consigliato è visibile. Salta il conto alla rovescia della riproduzione automatica Se la riproduzione automatica è attivata, il video successivo verrà riprodotto immediatamente. @@ -729,6 +813,38 @@ Impostazioni → Riproduzione automatica → Telefono cellulare/tablet" Nascondi il pulsante Grazie Il pulsante Grazie è nascosto. Il pulsante Grazie è visibile. + + Nascondi in base all\'indice + Nascondi il primo pulsante + Il primo pulsante è nascosto. + Il primo pulsante è visibile. + Nascondi il secondo pulsante + Il secondo pulsante è nascosto. + Il secondo pulsante è visibile. + Nascondi il terzo pulsante + Il terzo pulsante è nascosto. + Il terzo pulsante è visibile. + Nascondi il quarto pulsante + Il quarto pulsante è nascosto. + Il quarto pulsante è visibile. + Nascondi il quinto pulsante + Il quinto pulsante è nascosto. + Il quinto pulsante è visibile. + Nascondi il sesto pulsante + Il sesto pulsante è nascosto. + Il sesto pulsante è visibile. + Nascondi il settimo pulsante + Il settimo pulsante è nascosto. + Il settimo pulsante è visibile. + Nascondi l\'ottavo pulsante + L\'ottavo pulsante è nascosto. + L\'ottavo pulsante è visibile. + + Nascondi in base all\'indice nei video live + Informazioni sul nascondere in base all\'indice + "Nascondi i pulsanti di azione in base al loro indice prima che vengano inizializzati. + +Nota: in questo modo non ci saranno spazi vuoti tra i pulsanti, ma l'indice potrebbe non corrispondere sempre allo stesso pulsante." Modalità Ambient Disattiva la modalità Ambient o bypassa le sue restrizioni. @@ -921,7 +1037,7 @@ Nota: il titolo scompare quando lo si tocca." Margine superiore delle azioni rapide Configura lo spazio tra la barra di ricerca e il contenitore delle azioni rapide, tra 0 e 32. Il margine superiore delle azioni rapide deve essere tra 0 e 32 - + Disattiva la modalità orizzontale La modalità orizzontale è disattivata. La modalità orizzontale è attivata. @@ -929,7 +1045,8 @@ Nota: il titolo scompare quando lo si tocca." I controlli compatti sono attivati. I controlli compatti sono disattivati. Mantieni la modalità orizzontale - Mantiene la modalità orizzontale quando lo schermo viene spento e acceso a schermo intero. + I video continuano a riprodurre in orizzontale dopo aver spento e acceso lo schermo. + I video vengono riprodotti in verticale dopo aver spento e acceso lo schermo. Durata della modalità orizzontale forzata Il tempo in millisecondi per cui viene forzata la modalità orizzontale dopo l\'accensione dello schermo. @@ -1117,7 +1234,7 @@ Questa impostazione funziona meglio con una connessione internet molto veloce."< Nascondi la sezione Trascrizione La sezione Trascrizione è nascosta. La sezione Trascrizione è visibile. - + Disattiva le interazioni "Disattiva le seguenti interazioni quando la descrizione dei video viene espansa: • Tocca per scorrere. @@ -1141,7 +1258,7 @@ Nota: l'opzione Espandi Automaticamente potrebbe non funzionare se il titolo ins Nascondi i pulsanti fluttuanti "I pulsanti fluttuanti come Usa Questa Traccia Audio sono nascosti." "I pulsanti fluttuanti come Usa Questa Traccia Audio sono visibili." - + Scaffali Nascondi gli scaffali "Nota: l'intestazione ufficiale nei risultati di ricerca sarà nascosta." @@ -1162,13 +1279,16 @@ Nota: solo gli scaffali con l'intestazione Shorts nella scheda Home sono nascost Nascondi nella cronologia delle visualizzazioni Sono nascosti nella cronologia delle visualizzazioni. Sono visibili nella cronologia delle visualizzazioni. - + Cambia lo stato di ripetizione in background Cambia lo stato di ripetizione Riproduzione automatica Predefinito Pausa Ripeti + Apri i Shorts nel riproduttore normale + I Shorts sono aperti nel riproduttore normale. + I Shorts non sono aperti nel riproduttore normale. Riproduttore Personalizza i componenti del riproduttore degli Shorts. @@ -1264,7 +1384,7 @@ Nota: solo gli scaffali con l'intestazione Shorts nella scheda Home sono nascost Il pulsante Suono è nascosto. Il pulsante Suono è visibile. - Animazione e feedback + Animazione o feedback Disattiva le animazioni sopra il pulsante Mi Piace Le animazioni sopra il pulsante Mi Piace sono disattivate. Le animazioni sopra il pulsante Mi Piace sono attivate. @@ -1314,10 +1434,10 @@ Tocca e tieni premuto il pulsante Altro per visualizzare la finestra delle azion Il menù Stato di Ripetizione è visibile. Il menù Stato di Ripetizione è nascosto. Informazioni sulle azioni personalizzate - "Questa impostazione è ancora sperimentale, quindi non c'è garanzia che funzionerà perfettamente. + "Questa impostazione è ancora sperimentale, quindi non c'è garanzia che funzionerà perfettamente. La maggior parte dei bug non può essere risolta a causa di limitazioni lato client, quindi usala solo per scopi di test." - + Mostra il timestamp "Il timestamp è mostrato. @@ -1482,9 +1602,9 @@ Verrà applicato un codec diverso dopo circa 20 secondi di buffering." I non mi piace sono nascosti. Mostra i non mi piace degli Shorts I non mi piace degli Shorts sono visibili. - "I Non mi piace degli Shorts sono visibili. + "I non mi piace degli Shorts sono visibili. -Nota: i non mi piace potrebbero non apparire se l'utente non ha effettuato l'accesso o in navigazione in incognito." +Nota: i non mi piace potrebbero non apparire se l'utente non ha effettuato l'accesso o navigando in incognito." I non mi piace degli Shorts sono nascosti. Cambia il formato dei non mi piace Percentuali @@ -1552,19 +1672,19 @@ Tocca qui per vedere come emettere una chiave API." Cambia il comportamento dei segmenti Sponsor Le promozioni a pagamento, referral a pagamento e pubblicità diretta. Non dovrebbe includere autopromozione e ringraziamenti gratis a cause, creatori, siti web e prodotti di loro gradimento. - Promozione non Pagata e autopromozione + Promozione non pagata o autopromozione Simili agli sponsor, ma sono promozioni non pagate o autopromozioni. Include sezioni sul merchandising, donazioni e informazioni dei collaboratori del video. Promemoria di interazione (Iscrizione) Una breve promemoria per mettere mi piace, iscriversi o seguirli su altre piattaforme durante la visione. Se è lungo o riguarda qualcosa di specifico, dovrebbe essere considerato autopromozione. Momento saliente La parte del video che la maggior parte delle persone sta guardando. - Intermezzo e introduzione animata + Intermezzo o introduzione animata Un intervallo senza contenuto effettivo. Potrebbe essere una pausa, un fotogramma statico o un\'animazione ripetuta. Non dovrebbe includere transizioni con informazioni. - Schede finali e crediti + Schede finali o crediti I crediti o quando appaiono le schede finali. Non dovrebbe includere le conclusioni con informazioni. - Anteprima, riepilogo e pretesto + Anteprima, riepilogo o pretesto Una breve raccolta di anteprime che mostrano ciò che è in programma o ciò che è successo nel video o in altri video di una serie, dove tutte le informazioni sono ripetute altrove. - Tangente di riempimento e battute + Tangente di riempimento o battute Le scene tangenziali aggiunte solo a scopo riempitivo o per umorismo, non necessarie per comprendere il contenuto principale del video. Non dovrebbe includere sezioni con informazioni. Sezione non musicale Le sezioni di video musicali senza musica che non sono già incluse in un\'altra categoria. Solo per i video musicali. @@ -1646,8 +1766,8 @@ Tocca qui per vedere come emettere una chiave API." URL API cambiato Copia Esporta / Importa impostazioni - La tua configurazione di SponsorBlock in JSON può essere esportata e importata su RVX e su altre piattaforme SponsorBlock. - La tua configurazione di SponsorBlock in JSON può essere esportata e importata su RVX e su altre piattaforme SponsorBlock. Questo include il tuo ID utente privato, quindi assicurati di condividerlo con cautela. + La tua configurazione di SponsorBlock in JSON può essere esportata o importata su RVX e su altre piattaforme SponsorBlock. + La tua configurazione di SponsorBlock in JSON può essere esportata o importata su RVX e su altre piattaforme SponsorBlock. Questo include il tuo ID utente privato, quindi assicurati di condividerlo con cautela. Impostazioni importate con successo Importazione non riuscita (%s) Esportazione non riuscita (%s) @@ -1715,6 +1835,9 @@ Tocca qui per vedere come emettere una chiave API." I dati sono forniti dall\'API di SponsorBlock. Tocca qui per saperne di più e vedere i download per altre piattaforme. Varie + Bypassa il reindirizzamento degli URL + Il reindirizzamento degli URL è bypassato. + Il reindirizzamento degli URL non è bypassato. Disattiva il protocollo QUIC "Disattiva il protocollo QUIC di CronetEngine." Attiva il registro del debug @@ -1723,18 +1846,15 @@ Tocca qui per vedere come emettere una chiave API." Attiva il registro del debug con il buffer Il registro del debug include il buffer. Il registro del debug non include il buffer. - Attiva il browser esterno - Il browser esterno è attivato. - Il browser esterno è disattivato. - Attiva l\'apertura diretta dei link - Bypassando i reindirizzamenti degli URL. - Seguendo la regola predefinita di reindirizzamento. + Cambia il modo di aprire i link + Browser esterno + Browser dell\'app Sanitizza i link di condivisione Rimuove i parametri di tracciamento dagli URL durante la condivisione dei link. Apri le impostazioni predefinite dell\'app - Per aprire RVX da un\'applicazione esterna, abilita \"Apri collegamenti supportati\" e gli indirizzi web supportati. + Per aprire RVX da un\'applicazione esterna, attiva \"Apri collegamenti supportati\" e tutti gli indirizzi web supportati. Apri GmsCore - Attiva la messaggistica cloud per ricevere notifiche. + Attiva \"Cloud Messaging\" per ricevere le notifiche di RVX. GmsCore non è installato, installalo Azione necessaria "GmsCore non ha l'autorizzazione per essere eseguito in background. @@ -1785,6 +1905,8 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." "Android TV (Accesso richiesto)" Android VR + "Android VR +(Nessun accesso richiesto)" "iOS (PoToken richiesto)" "iOS TV @@ -1793,10 +1915,10 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." "• Il menù Traccia Audio è nascosto. • Il volume stabile non funziona. • La disattivazione delle tracce audio automatiche forzate non funziona. -• I video per bambini potrebbero non essere riprodotti se si è disconnessi o in incognito." +• I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." • Ci potrebbero essere problemi di riproduzione (PoToken richiesto). "• I film o i video a pagamento potrebbero non essere riproducibili. -• I video per bambini potrebbero non essere riprodotti se si è disconnessi o in incognito." +• I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." Forza iOS AVC (H.264) Il codec video è forzato ad AVC (H.264). Il codec video è determinato automaticamente. @@ -1806,6 +1928,7 @@ Nota: AVC ha una risoluzione massima di 1080p, il codec Opus non è disponibile Mostra nelle statistiche per nerd Il client usato per recuperare i dati in streaming è visibile nelle statistiche per nerd. Il client usato per recuperare i dati in streaming è nascosto nelle statistiche per nerd. + Lingua predefinita dello stream audio VR PoToken / VisitorData PoToken da usare diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index e24df8aaf..b91d26403 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -19,12 +19,65 @@ "%1$s はインストールされていません。 ウェブサイトから %2$s をダウンロードしてください。" %s はインストールされていません。インストールしてください。 + Revanced Extended 設定の言語 + アプリの設定言語に従う + アラビア語 + アゼルバイジャン語 + ブルガリア語 + ベンガル語 + カタロニア語 + チェコ語 + デンマーク語 + ドイツ語 + ギリシャ語 + 英語 + スペイン語 + エストニア語 + ペルシャ語 + フィンランド語 + フランス語 + グジャラート語 + ヒンディー語 + クロアチア語 + ハンガリー語 + インドネシア語 + イタリア語 + 日本語 + カザフ語 + 韓国語 + リトアニア語 + ラトビア語 + マケドニア語 + モンゴル語 + マラーティー語 + マレー語 + ビルマ語 (ミャンマー語) + オランダ語 + オディア語 + パンジャーブ語 + ポーランド語 + ポルトガル語 + ルーマニア語 + ロシア語 + スロバキア語 + スロベニア語 + セルビア語 + スウェーデン語 + スワヒリ語 + タミル語 + テルグ語 + タイ語 + トルコ語 + ウクライナ語 + ウルドゥー語 + ベトナム語 + 中国語 広告 全画面広告を非表示 アプリ起動時に表示される全画面広告を非表示にします。 アプリ起動時に表示される全画面広告を非表示にします。 - 全般的な広告を非表示 + 一般的な広告を非表示 動画以外の広告を非表示にします。 動画以外の広告を非表示にします。 商品欄を非表示 @@ -100,13 +153,20 @@ DeArrow の詳細については、ここをタップしてください。"フィードから字幕ボタンを非表示にします。 フィードから字幕ボタンを非表示にします。 おすすめ欄を非表示 - "以下の欄を非表示にします: + "以下の欄を非表示にします: ・ニュース速報 ・続きを見る ・もう一度見る ・もう一度聴く ・他のチャンネルを探す ・ショッピング" + 以下の欄を非表示にします: +・ニュース速報 +・続きを見る +・もう一度見る +・もう一度聴く +・他のチャンネルを探す +・ショッピング チップ欄を非表示 フィードに表示される、似ている動画のチップ欄を非表示にします。 フィードに表示される、似ている動画のチップ欄を非表示にします。 @@ -140,18 +200,18 @@ DeArrow の詳細については、ここをタップしてください。"Playables を非表示 Playables (アプリやウェブ版ですぐにゲームが遊べる機能) を非表示にします。 Playables (アプリやウェブ版ですぐにゲームが遊べる機能) を非表示にします。 - 「もっと表示」ボタンを非表示 - 動画を検索した際に、検索結果の動画の下に表示される「もっと表示」のボタンを非表示にします。 - 動画を検索した際に、検索結果の動画の下に表示される「もっと表示」のボタンを非表示にします。 検索バーを非表示 フィードから検索バーを非表示にします。 フィードから検索バーを非表示にします。 - アンケートを非表示 - ホームページと登録チャンネルページからアンケートを非表示にします。 - ホームページと登録チャンネルページからアンケートを非表示にします。 + 「もっと表示」ボタンを非表示 + 動画を検索した際に、検索結果の動画の下に表示される「もっと表示」のボタンを非表示にします。 + 動画を検索した際に、検索結果の動画の下に表示される「もっと表示」のボタンを非表示にします。 登録チャンネルのカルーセルを非表示 「登録チャンネル」タブの上部に表示される登録チャンネル一覧を非表示にします。 「登録チャンネル」タブの上部に表示される登録チャンネル一覧を非表示にします。 + アンケートを非表示 + ホームページと登録チャンネルページからアンケートを非表示にします。 + ホームページと登録チャンネルページからアンケートを非表示にします。 チケット欄を非表示 検索結果/関連動画からチケット欄を非表示にします。 検索結果/関連動画からチケット欄を非表示にします。 @@ -250,13 +310,13 @@ DeArrow の詳細については、ここをタップしてください。" おすすめ動画 再生回数が少ない動画を非表示 - 登録していないチャンネルからアップロードされた、再生回数が 1,000 回未満の動画をホームフィードから非表示にします。 + "登録していないチャンネルからアップロードされた、再生回数が 1,000 回未満の動画をホームフィードから非表示にします。 + +このフィルターはもう機能していない可能性があります。代わりに「再生回数フィルター」を使用してください。" おすすめ動画を非表示 "以下のおすすめ動画を非表示にします: -・「メンバーシップ限定」タグの付いた動画 -・動画の下部に「他のユーザーも視聴しています」などのフレーズがある動画 -・登録していないチャンネルからアップロードされた、再生回数が 1,000 回未満の動画" +・動画の下部に「他のユーザーも視聴しています」などのフレーズがある動画" 再生回数フィルター ホームフィードをフィルタリング @@ -289,27 +349,25 @@ DeArrow の詳細については、ここをタップしてください。" オフセット - 全般 - レイアウトを変更 - オリジナル - スマホ - スマホ(最大 480 dp) - タブレット - タブレット(最小 600 dp) + 一般 起動時のページを変更 - チャンネルを探す - コース / 教育 デフォルト + 新しい動画の発見 + コース 探索 + ファッション & 美容 ゲーム 履歴 ライブラリ 高評価した動画 ライブ - 映画 + ムービー&TV 音楽 + ニュース 通知 + ポッドキャスト 検索 + ショッピング ショート スポーツ 登録チャンネル @@ -346,13 +404,19 @@ DeArrow の詳細については、ここをタップしてください。"グレーのセパレーターを非表示 ホームフィードの動画の間に表示される、グレーのセパレーターを非表示にします。 ホームフィードの動画の間に表示される、グレーのセパレーターを非表示にします。 - スナックバーを非表示 - 共有からリンクをコピーした際などに画面下部に表示されるポップアップを非表示にします。 - 共有からリンクをコピーした際などに画面下部に表示されるポップアップを非表示にします。 年齢制限ダイアログを削除 "年齢制限ダイアログを削除します。 注意: 年齢制限を回避することはできませんが、自動的に同意します。" + レイアウトを変更 + オリジナル + スマホ + スマホ(最大 480 dp) + タブレット + タブレット(最小 600 dp) + ライブ状態のアイコンをタップした際の動作を変更 + 現在の設定: 「ライブ」状態のアイコンをタップすると、チャンネルが開きます。 + 現在の設定: 「ライブ」状態のアイコンをタップすると、ライブ配信が開きます。 アプリのバージョンを偽装 アプリのバージョンを偽装できます。 アプリのバージョンを偽装できます。 @@ -406,7 +470,7 @@ DeArrow の詳細については、ここをタップしてください。"「オフライン」ボタンで外部ダウンローダーを開きます。 プレイリストの外部ダウンローダーのパッケージ名 NewPipe や YTDLnis などの、インストールされている外部ダウンローダーアプリのパッケージ名です。 - + YouTube Music ボタンを置換 「YouTube Music」ボタンで RVX Music を開けるようにします。 「YouTube Music」ボタンで RVX Music を開けるようにします。 @@ -520,14 +584,14 @@ DeArrow の詳細については、ここをタップしてください。"「全般」メニューを非表示にします。 「全般」メニューを非表示にします。 アカウントメニューを非表示 - 「アカウント」メニューを非表示にします。 - 「アカウント」メニューを非表示にします。 + 「アカウントを切り替える」メニューを非表示にします。 + 「アカウントを切り替える」メニューを非表示にします。 データの節約メニューを非表示 「データの節約」メニューを非表示にします。 「データの節約」メニューを非表示にします。 - 自動再生メニューを非表示 - 「自動再生」メニューを非表示にします。 - 「自動再生」メニューを非表示にします。 + 再生メニューを非表示 + 「再生」メニューを非表示にします。 + 「再生」メニューを非表示にします。 動画の画質設定メニューを非表示 「動画の画質設定」メニューを非表示にします。 「動画の画質設定」メニューを非表示にします。 @@ -573,6 +637,26 @@ DeArrow の詳細については、ここをタップしてください。"アプリに関する情報メニューを非表示 「アプリに関する情報」メニューを非表示にします。 「アプリに関する情報」メニューを非表示にします。 + + スナックバー + スナックバー(画質を変更した時などに下部に表示される白いバー)に関連するコンポーネントを非表示または変更します。 + スナックバーを非表示 + 共有からリンクをコピーした際などに画面下部に表示されるポップアップを非表示にします。 + 共有からリンクをコピーした際などに画面下部に表示されるポップアップを非表示にします。 + サーバー側のスナックバーを非表示 + サーバー側のスナックバーを非表示にします。 + サーバー側のスナックバーを非表示にします。 + スナックバーのテーマを反転 + スナックバーのテーマを反転させます。 + スナックバーのテーマを反転させます。 + サーバー側のスナックバーの背景を変更 + サーバー側のスナックバーの背景を変更します。 + サーバー側のスナックバーの背景を変更します。 + "一部のスナックバーでは、アプリのテーマではなく、サーバー側で定義されたテーマが使用されます。 + +これらのスナックバーの背景色を変更します。 + +サーバー側で変更があった場合、スナックバーの背景色は変更されない可能性があります。" ツールバー ツールバーのボタン、検索バー、ヘッダーなどのツールバーにあるコンポーネントを非表示または変更できます。 @@ -586,10 +670,17 @@ DeArrow の詳細については、ここをタップしてください。"ヘッダー付きの幅広い検索バーを有効化します。 ヘッダー付きの幅広い検索バーを有効化します。 マイページ タブで幅広い検索バーを有効化 - "この設定を有効にすると、[マイページ] タブ内の設定ボタンが無効になります。 + "[マイページ] タブで幅広い検索バーを有効化します。 -この場合、以下の手順に従ってください: -[マイページ] タブ > チャンネルを表示 > メニュー > 設定" +注意: +この設定を有効にすると、[マイページ] タブ内の設定ボタンが無効になります。 +設定にアクセスするには、次の手順に従ってください: +[マイページ] タブ → チャンネルを表示 → メニュー → 設定" + [マイページ] タブで幅広い検索バーを有効化します。\n\n注意:\nこの設定を有効にすると、[マイページ] タブ内の設定ボタンが無効になります。\n設定にアクセスするには、次の手順に従ってください:\n[マイページ] タブ → チャンネルを表示 → メニュー → 設定 + "この設定を有効にすると、[マイページ] タブ内の設定ボタンが無効になります。 + +この場合、設定にアクセスするためには次の手順に従ってください: +[マイページ] タブ → チャンネルを表示 → メニュー → 設定" キャストボタンを非表示 「キャスト」ボタンを非表示にします。 「キャスト」ボタンを非表示にします。 @@ -617,10 +708,10 @@ DeArrow の詳細については、ここをタップしてください。"「作成」ボタンを置換 「作成」ボタンを「設定」ボタンに置き換えます。 ボタンに割り当てるアクションの種類 - "タップすると RVX 設定が開きます。 + "タップすると Revanced Extended 設定が開きます。 長押しすると YouTube 設定が開きます。" "タップすると YouTube の設定が開きます。 -長押しすると RVX 設定が開きます。" +長押しすると Revanced Extended 設定が開きます。" プレーヤー プレーヤーのオーバーレイのカスタム不透明度 @@ -628,7 +719,7 @@ DeArrow の詳細については、ここをタップしてください。"プレーヤーのオーバーレイの不透明度は 0 ~ 100 の間でなければなりません。デフォルト値にリセットします。 ミックスプレイリストの自動切り替えを無効化 自動再生がオフの場合、音楽を再生した際に自動的にミックスプレイリストに切り替わるのを無効化できます。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」 - "自動再生がオフの場合、音楽を再生した際にミックスプレイリストへの自動切り替えを無効化できます。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」" + "自動再生がオフの場合、音楽を再生した際にミックスプレイリストへの自動切り替えを無効化できます。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 再生 → 次の動画を自動再生」" 自動再生がオフの場合、音楽を再生した際にミックスプレイリストへの自動切り替えを無効化できます。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」 プレーヤーのポップアップパネルを無効化 再生リストとライブチャットのパネルが自動で開くのを無効化します。 @@ -655,8 +746,8 @@ DeArrow の詳細については、ここをタップしてください。"動画の最後に表示される作成者が追加したエンドカードを非表示にします。 動画の最後に表示される作成者が追加したエンドカードを非表示にします。 フィルムストリップオーバーレイを非表示 - シークバーを上スワイプで表示されるフィルムストリップを非表示にします。 - シークバーを上スワイプで表示されるフィルムストリップを非表示にします。 + シークバーを上スワイプで表示されるフィルムストリップオーバーレイを非表示にします。 + シークバーを上スワイプで表示されるフィルムストリップオーバーレイを非表示にします。 情報カードを非表示 プレーヤーの右上に表示される情報カードを非表示にします。 プレーヤーの右上に表示される情報カードを非表示にします。 @@ -676,7 +767,9 @@ DeArrow の詳細については、ここをタップしてください。"プレーヤー上の「Premium のコントロール」などの提案を非表示にします。 プレーヤー上の「Premium のコントロール」などの提案を非表示にします。 おすすめされる動画の終了画面を非表示 - "自動再生がオフの場合、おすすめの動画は動画の終了画面で表示されません。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」" + "自動再生がオフの場合、おすすめの動画は動画の終了画面で表示されません。 + +自動再生は YouTube アプリ内の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」" 自動再生がオフの場合、おすすめの動画は動画の終了画面で表示されません。\n\n自動再生は YouTube の設定で変更できます: 「設定 → 自動再生 → 次の動画を自動再生」 自動再生カウントダウンをスキップ 自動再生がオンの場合、次の動画をカウントダウンなしで再生します。 @@ -726,6 +819,40 @@ DeArrow の詳細については、ここをタップしてください。"「Thanks」ボタンを非表示 「Thanks」ボタンを非表示にします。 「Thanks」ボタンを非表示にします。 + + インデックスで非表示 + 1 番目のボタンを非表示 + 1 番目のボタンを非表示にします。 + 1 番目のボタンを非表示にします。 + 2 番目のボタンを非表示 + 2 番目のボタンを非表示にします。 + 2 番目のボタンを非表示にします。 + 3 番目のボタンを非表示 + 3 番目のボタンを非表示にします。 + 3 番目のボタンを非表示にします。 + 4 番目のボタンを非表示 + 4 番目のボタンを非表示にします。 + 4 番目のボタンを非表示にします。 + 5 番目のボタンを非表示 + 5 番目のボタンを非表示にします。 + 5 番目のボタンを非表示にします。 + 6 番目のボタンを非表示 + 6 番目のボタンを非表示にします。 + 6 番目のボタンを非表示にします。 + 7 番目のボタンを非表示 + 7 番目のボタンを非表示にします。 + 7 番目のボタンを非表示にします。 + 8 番目のボタンを非表示 + 8 番目のボタンを非表示にします。 + 8 番目のボタンを非表示にします。 + + ライブ配信でインデックスで非表示 + 「インデックスで非表示」について + "アクションボタンが初期化される前に、インデックスによってアクションボタンを非表示にします。 + +注意: +・アクションボタンを非表示にすると、空きスペースが残りません。 +・ボタンの順序は YouTube のバージョン、地域、動画によって異なる場合があります。" アンビエントモード アンビエントモードの制限を回避またはアンビエントモードを無効化します。 @@ -918,7 +1045,7 @@ DeArrow の詳細については、ここをタップしてください。"クイック操作上部の余白 シークバーからクイックアクション コンテナーまでの間隔を 0 ~ 32 の間で設定してください。 クイックアクションの上部の余白は 0 ~ 32 の間でなければなりません。デフォルト値にリセットします。 - + 横画面モードを無効化 縦向きの全画面表示を有効化します。 縦向きの全画面表示を有効化します。 @@ -926,7 +1053,8 @@ DeArrow の詳細については、ここをタップしてください。"コントロールのオーバーレイを全画面に表示せず、コンパクトに表示します。 コントロールのオーバーレイを全画面に表示せず、コンパクトに表示します。 横画面モードを維持 - 全画面表示時に、画面をオン/オフしても、横向きモードを維持します。 + 画面をオフにしても全画面表示の状態を維持します。 + 画面をオフにしても全画面表示の状態を維持します。 横画面モードのタイムアウトを維持 画面がオンになってから横画面モードが強制されるまでのミリ秒数です。 @@ -951,8 +1079,8 @@ DeArrow の詳細については、ここをタップしてください。"プレーヤーボタン プレーヤー内のボタンを非表示または表示します。 自動再生ボタンを非表示 - 「自動再生」ボタンを非表示にします。 - 「自動再生」ボタンを非表示にします。 + 自動再生のボタンを非表示にします。 + 自動再生のボタンを非表示にします。 字幕ボタンを非表示 「字幕」ボタンを非表示にします。 「字幕」ボタンを非表示にします。 @@ -960,14 +1088,14 @@ DeArrow の詳細については、ここをタップしてください。"「キャスト」ボタンを非表示にします。 「キャスト」ボタンを非表示にします。 最小化ボタンを非表示 - 「プレーヤーの最小化」ボタンを非表示にします。 - 「プレーヤーの最小化」ボタンを非表示にします。 + プレーヤーの最小化ボタンを非表示にします。 + プレーヤーの最小化ボタンを非表示にします。 全画面表示のボタンを非表示 全画面表示のボタンを非表示にします。 全画面表示のボタンを非表示にします。 前の動画に戻る/次の動画に進むボタンを非表示 - 「前の動画に戻る」「次の動画に進む」ボタンを非表示にします。 - 「前の動画に戻る」「次の動画に進む」ボタンを非表示にします。 + 前の動画に戻る/次の動画に進むボタンを非表示にします。 + 前の動画に戻る/次の動画に進むボタンを非表示にします。 YouTube Music ボタンを非表示 「YouTube Music」ボタンを非表示にします。 「YouTube Music」ボタンを非表示にします。 @@ -1112,7 +1240,7 @@ DeArrow の詳細については、ここをタップしてください。"文字起こし欄を非表示 概要欄の文字起こしセクションを非表示にします。 概要欄の文字起こしセクションを非表示にします。 - + 概要欄の操作を無効化 "概要欄が展開されている場合、以下のインタラクションを無効にします: @@ -1136,7 +1264,7 @@ DeArrow の詳細については、ここをタップしてください。"フローティングボタンを非表示 "「このサウンドを使用する」のようなフローティングボタンを、ショートタブから非表示にします。" "「このサウンドを使用する」のようなフローティングボタンを、ショートタブから非表示にします。" - + ショート欄 ショート欄を非表示 "ショート欄を非表示にします。 @@ -1159,13 +1287,16 @@ DeArrow の詳細については、ここをタップしてください。"再生履歴から非表示 再生履歴から非表示にします。 再生履歴から非表示にします。 - + ショートのバックグラウンド再生時のリピート状態を変更 リピート状態を変更 次の動画を自動再生 デフォルト 一時停止 リピート再生 + 通常のプレーヤーでショートを再生 + 通常のプレーヤーでショートを再生します。 + 通常のプレーヤーでショートを再生します。 プレーヤー ショートのプレーヤー内のコンポーネントを非表示または表示します。 @@ -1242,7 +1373,7 @@ DeArrow の詳細については、ここをタップしてください。"ショートで楽曲ボタンを押した際に表示される「このサウンドを使用する」ボタンを非表示にします。 プレーヤー下部(共有、クリップなど)のボタン - 高評価ボタンを非表示 + 「高評価」ボタンを非表示 「高評価」ボタンを非表示にします。 「高評価」ボタンを非表示にします。 「低評価」ボタンを非表示 @@ -1311,10 +1442,10 @@ DeArrow の詳細については、ここをタップしてください。"リピート状態のメニューを表示します。 リピート状態のメニューを表示します。 カスタムアクションについて - "この機能はまだ実験段階であるため、完璧に動作するという保証はありません。 + "この機能はまだ実験段階であるため、完璧に動作するという保証はありません。 ほとんどのバグはクライアント側の制限により修正できないため、テスト目的でのみ使用してください。" - + タイムスタンプを表示 "プレーヤーの左下にタイムスタンプを表示します。 @@ -1368,7 +1499,7 @@ DeArrow の詳細については、ここをタップしてください。"スワイプジェスチャーを「画面のロック」モードで有効化します。 スワイプジェスチャーを「画面のロック」モードで有効化します。 スワイプオーバーレイの背景の透明度 - 背景の不透明度の値は 0 ~ 255 の間で、0 が透明です。 + スワイプオーバーレイの背景の透明度です。 スワイプ可能な領域のしきい値 スワイプとして検出する量のしきい値です。 スワイプオーバーレイのテキストサイズ @@ -1440,8 +1571,8 @@ DeArrow の詳細については、ここをタップしてください。"ショートのデフォルト再生速度を有効化 デフォルトの再生速度をショートに適用します。 デフォルトの再生速度をショートに適用します。 - プリロードバッファをスキップしました。 - プリロードバッファをスキップ + 事前に読み込まれたバッファをスキップしました。 + 事前に読み込まれたバッファをスキップ "動画開始時に予め読み込まれたバッファをスキップして、デフォルトの画質を即座に適用します。 注意: @@ -1480,11 +1611,11 @@ DeArrow の詳細については、ここをタップしてください。"低評価数の表示を復活させます。\n\n注意: 正確な値ではありません。 低評価数の表示を復活させます。\n\n注意: 正確な値ではありません。 ショートで低評価数を表示 - ショートで低評価数を表示します。\n\n注意: シークレットモードでは低評価数が表示されないことがあります。 + ショートで低評価数を表示します。\n\n注意: ログインをしていない or シークレットモードでは低評価数が表示されないことがあります。 "ショートで低評価数を表示します。 -注意: シークレットモードでは低評価数が表示されないことがあります。" - ショートで低評価数を表示します。\n\n注意: シークレットモードでは低評価数が表示されないことがあります。 +注意: ログインをしていない or シークレットモードでは低評価数が表示されない可能性があります。" + ショートで低評価数を表示します。\n\n注意: ログインをしていない or シークレットモードでは低評価数が表示されないことがあります。 低評価数をパーセントで表示 低評価数をパーセントで表示します。 低評価数をパーセントで表示します。 @@ -1650,7 +1781,7 @@ API キーの発行方法については、ここをタップしてください 設定は正常にインポートされました。 インポート失敗: %s エクスポート失敗: %s - この設定には SponsorBlock のプライベーユーザー ID が含まれています。\n\nユーザー ID はパスワードのようなもののため、誰とも共有しないようにしてください。\n + この設定には SponsorBlock のプライベートユーザー ID が含まれています。\n\nユーザー ID はパスワードのようなものであるため、誰とも共有しないようにしてください。\n 今後表示しない SponsorBlock は一時的に利用できません。 SponsorBlock は一時的に利用できません。(ステータス %d) @@ -1714,6 +1845,9 @@ API キーの発行方法については、ここをタップしてください データは SponsorBlock API によって提供されています。他のプラットフォームのダウンロードや詳細については、ここをタップしてください。 その他 + URL リダイレクトをバイパス + URL リダイレクト (youtube.com/redirect) をバイパスします。 + URL リダイレクト (youtube.com/redirect) をバイパスします。 QUIC プロトコルを無効化 "CronetEngine の QUIC プロトコルを無効化します。これにより動画の読み込み速度が多少改善されます。" デバッグログを有効化 @@ -1722,12 +1856,9 @@ API キーの発行方法については、ここをタップしてください デバッグバッファログを有効化 バッファログをデバッグログに含めます。 バッファログをデバッグログに含めます。 - 外部ブラウザを有効化 - 外部ブラウザを有効化します。 - 外部ブラウザを有効化します。 - 直リンクを有効化 - URL リダイレクト (youtube.com/redirect) をバイパスします。 - URL リダイレクト (youtube.com/redirect) をバイパスします。 + 外部ブラウザでリンクを開く + 外部ブラウザでリンクを開きます。 + 外部ブラウザでリンクを開きます。 共有リンクのクリーンアップ リンクを共有する際に、URL からトラッキングクエリパラメーターを削除します。 「デフォルトで開く」の設定を開く @@ -1735,7 +1866,7 @@ API キーの発行方法については、ここをタップしてください GmsCore の設定を開く 通知を受け取るには、Cloud Messaging の設定を有効にしてください。 GmsCore がインストールされていません。インストールしてください。 - アクションが必要です + 操作が必要です "MicroG GmsCore はバックグラウンドで実行する権限がありません。 あなたの端末の \"Don't kill my app\"のガイドに従って、MicroG のインストールに適用してください。 @@ -1752,7 +1883,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 「共有」ボタンをタップした際に表示される共有メニューを、システムの共有メニューに置き換えます。 「共有」ボタンをタップした際に表示される共有メニューを、システムの共有メニューに置き換えます。 OPUS コーデックを有効化 - プレーヤーの応答に OPUS コーデックが含まれている場合、OPUS コーデックを有効化します。 + プレーヤーの応答に OPUS コーデックが含まれている場合、OPUS コーデックを有効にします。 設定のインポート/エクスポート 設定をインポートまたはエクスポートします。 @@ -1786,6 +1917,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に "Android TV (Google アカウントへのログインが必要)" Android VR + "Android VR +(認証なし)" "iOS (PoToken が必要)" "iOS TV @@ -1810,6 +1943,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 統計情報に偽装したクライアントを表示 統計情報に偽装したクライアントを表示します。 統計情報に偽装したクライアントを表示します。 + 偽装するクライアントを Android VR に設定した際にデフォルトで使用する音声トラックの言語 PoToken / VisitorData 使用する PoToken を入力 diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 90f7f9a22..8e5f53140 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -19,6 +19,59 @@ "%1$s 가 설치되어 있지 않습니다. 웹사이트에서 %2$s 를 다운로드하세요." %s가 설치되지 않았습니다. 설치하세요. + RVX 언어 + 앱 언어 + 아랍어 + 아제르바이잔어 + 불가리아어 + 뱅골어 + 카탈루냐어 + 체코어 + 덴마크어 + 독일어 + 그리스어 + 영어 + 스페인어 + 에스토니아어 + 페르시아어 + 핀란드어 + 프랑스어 + 구자라트어 + 힌디어 + 크로아티아어 + 헝가리어 + 인도네시아어 + 이탈리아어 + 일본어 + 카자흐어 + 한국어 + 리투아니아어 + 라트비아어 + 마케도니아어 + 몽골어 + 마라티어 + 말레이어 + 버마어 + 네덜란드어 + 오리야어 + 펀자브어 + 폴란드어 + 포르투갈어 + 루마니아어 + 러시아어 + 슬로바키아어 + 슬로베니아어 + 세르비아어 + 스웨덴어 + 스와힐리어 + 타밀어 + 텔루구어 + 태국어 + 터키어 + 우크라이나어 + 우르두어 + 베트남어 + 중국어 광고 전체 화면 광고 숨기기 @@ -101,8 +154,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 피드 자막 버튼 숨기기 자막 버튼이 숨겨집니다. 자막 버튼이 표시됩니다. - 좌우 슬라이드형 선반 숨기기 - "다음 선반들이 숨겨집니다: + 회전형 선반 숨기기 + "다음 선반이 숨겨집니다: • 다시 듣기 • 다시 시청하기 • 이어서 시청하기 @@ -111,7 +164,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 주요 뉴스, 뉴스 속보 • 맞춤 실시간 스트림 • 라이브 쇼핑 -• 보건 정보 출처 ..." +• 보건 정보 출처, etc." + 다음 선반이 표시됩니다:\n• 다시 듣기\n• 다시 시청하기\n• 이어서 시청하기\n• 채널 더보기\n• 이 게임 더보기\n• 주요 뉴스, 뉴스 속보\n• 맞춤 실시간 스트림\n• 라이브 쇼핑\n• 보건 정보 출처, etc. 더 많은 주제 탐색 선반 숨기기 더 많은 주제 탐색 선반이 숨겨집니다. 더 많은 주제 탐색 선반이 표시됩니다. @@ -145,18 +199,18 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." Playables(게임 룸) 선반 숨기기 Playables(게임 룸) 선반이 숨겨집니다.\n• YouTube 앱에 내장된 미니 게임\n• 일부 국가에서는 아직 서비스가 제공되지 않습니다. Playables(게임 룸) 선반이 표시됩니다.\n• YouTube 앱에 내장된 미니 게임\n• 일부 국가에서는 아직 서비스가 제공되지 않습니다. - \'자세히 보기\' 버튼 숨기기 - \'자세히 보기\' 버튼이 숨겨집니다. - \'자세히 보기\' 버튼이 표시됩니다. 피드 검색창 숨기기 피드 검색창이 숨겨집니다. 피드 검색창이 표시됩니다. - 피드 설문 조사 숨기기 - 피드 설문 조사가 숨겨집니다. - 피드 설문 조사가 표시됩니다. + \'자세히 보기\' 버튼 숨기기 + \'자세히 보기\' 버튼이 숨겨집니다. + \'자세히 보기\' 버튼이 표시됩니다. 구독 채널 섹션 숨기기 구독 피드 상단에서 구독 채널 섹션이 숨겨집니다. 구독 피드 상단에서 구독 채널 섹션이 표시됩니다. + 피드 설문 조사 숨기기 + 피드 설문 조사가 숨겨집니다. + 피드 설문 조사가 표시됩니다. 콘서트 티켓 선반 숨기기 콘서트 티켓 선반이 숨겨집니다.\n• 일부 국가에서는 아직 서비스가 제공되지 않습니다. 콘서트 티켓 선반이 표시됩니다.\n• 일부 국가에서는 아직 서비스가 제공되지 않습니다. @@ -254,10 +308,12 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 추천 동영상 조회수가 낮은 추천 동영상 숨기기 - 구독하지 않는 채널에서 업로드한 동영상 중 조회수가 1,000회 미만인 동영상이 홈 피드에서 숨겨집니다. + "구독하지 않는 채널에서 업로드한 동영상 중 조회수가 1,000회 미만인 동영상이 홈 피드에서 숨겨집니다. + +이 필터는 더 이상 작동하지 않을 수 있으므로 대신 '조회수 필터'를 사용하세요." 추천 동영상 숨기기 "다음 추천 동영상이 숨겨집니다: -• '회원 전용' 태그가 있는 동영상 + • 썸네일 하단에 '시청자가 이 동영상도 시청함'와 같은 문구가 있는 동영상" 조회수 필터 @@ -292,17 +348,12 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 오프셋 일반 - 레이아웃 변경하기 - 기기 기본값 사용 - - 폰 (최대 너비: 480 dp) - 태블릿 - 태블릿 (최소 너비: 600 dp) 앱 시작 페이지 변경하기 + 홈 (기본값) 채널 둘러보기 학습 프로그램 - 홈 (기본값) 탐색 + 패션 및 뷰티 게임 기록 내 페이지 @@ -310,8 +361,11 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 실시간 영화 음악 + 뉴스 알림 + 팟캐스트 검색 + 쇼핑 Shorts 스포츠 구독 @@ -345,11 +399,17 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 회색 구분선 숨기기 동영상들 사이에서 회색 구분선이 숨겨집니다. 동영상들 사이에서 회색 구분선이 표시됩니다. - 스낵바(팝업 메시지바) 숨기기 - 스낵바(팝업 메시지바)가 숨겨집니다. - 스낵바(팝업 메시지바)가 표시됩니다. 시청 경고 다이얼로그 제거하기 "• 이 설정은 다이얼로그를 자동으로 허용하기만 하며, 연령 제한(성인인증 절차)을 우회할 수 없습니다.\n• 즉, 성인인증이 필요한 동영상에서 인증을 하려 할 때, 휴대폰 번호가 필요하다고 알려주는 소형 팝업창(다이얼로그) 없이 바로 휴대폰 번호 인증 페이지가 표시됩니다.\n• '당신은 혼자가 아닙니다' 페이지는 제거할 수 없으며, 해당 페이지에서 '확인하기' 버튼이 표시되지 않는다면 이 설정이 아닌 플레이어 설정에서 '정보 패널 숨기기'를 비활성화해야 합니다." + 레이아웃 변경하기 + 기기 기본값 사용 + + 폰 (최대 너비: 480 dp) + 태블릿 + 태블릿 (최소 너비: 600 dp) + 라이브 링 누르기 동작 변경하기 + 라이브 링이 있는 채널 아바타를 누르면 채널 페이지로 연결됩니다.\n\n• Shorts 실시간 스트림일 경우에는 채널 페이지로 연결되지 않을 수 있습니다. + 라이브 링이 있는 채널 아바타를 누르면 실시간 스트림 동영상으로 연결됩니다. 앱 버전 변경하기 앱 버전을 변경합니다. 앱 버전을 변경하지 않습니다. @@ -388,7 +448,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 잘못된 필터 값입니다: %s 버튼 재정의 - \'앱 내에 있는 버튼을 터치 시 실행 동작\'을 재정의할 수 있습니다. + \'앱 내에 있는 버튼을 누를 시 실행 동작\'을 재정의할 수 있습니다. 오프라인 저장 버튼 재생목록 오프라인 저장 버튼 재정의하기 @@ -399,7 +459,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 동영상 오프라인 저장 버튼으로 기본 다운로더를 실행할 수 있습니다. (YouTube Premium 기능) 재생목록 외부 다운로더 앱 패키지명 YTDLnis와 같은 설치된 외부 다운로더 앱 패키지명을 설정하세요. - + YouTube Music 버튼 재정의하기 YouTube Music 버튼으로 RVX Music을 실행할 수 있습니다. YouTube Music 버튼으로 순정 YouTube Music을 실행할 수 있습니다. @@ -517,9 +577,9 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 데이터 절약 메뉴 숨기기 데이터 절약 메뉴가 숨겨집니다. 데이터 절약 메뉴가 표시됩니다. - 자동재생 메뉴 숨기기 - 자동재생 메뉴가 숨겨집니다. - 자동재생 메뉴가 표시됩니다. + 자동재생 / 재생 메뉴 숨기기 + 자동재생 / 재생 메뉴가 숨겨집니다. + 자동재생 / 재생 메뉴가 표시됩니다. 동영상 화질 환경설정 메뉴 숨기기 동영상 화질 환경설정 메뉴가 숨겨집니다. 동영상 화질 환경설정 메뉴가 표시됩니다. @@ -565,6 +625,26 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 정보 메뉴 숨기기 정보 메뉴가 숨겨집니다. 정보 메뉴가 표시됩니다. + + 스낵바 (팝업메세지바) + 스낵바와 관련된 구성요소를 숨기거나 변경할 수 있습니다. + 스낵바 숨기기 + 스낵바가 숨겨집니다. + 스낵바가 표시됩니다. + 서버 측 스낵바 숨기기 + 서버 측 스낵바가 숨겨집니다. + 서버 측 스낵바가 표시됩니다. + 스낵바 테마 반전시키기 + 스낵바 테마를 반전시킵니다. + 스낵바 테마를 반전시키지 않습니다. + 서버 측 스낵바 배경 변경하기 + 서버 측 스낵바 배경 색상을 변경합니다 + 서버 측 스낵바 배경 색상을 변경하지 않습니다. + "일부 스낵바는 앱 테마가 아닌 서버 측에 정의된 테마가 사용됩니다. + +이러한 스낵바 배경 색상을 변경할 수 있습니다. + +서버 측 변경 사항이 있는 경우에는 스낵바 배경 색상이 변경되지 않을 수 있습니다." 툴바 툴바에서 버튼, 검색창, 헤더와 같은 구성요소를 숨기거나 변경할 수 있습니다. @@ -575,12 +655,17 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 넓은 검색창을 활성화합니다. 넓은 검색창을 비활성화합니다. 헤더가 있는 넓은 검색창 활성화하기 - YouTube 헤더가 있는 넓은 검색창 - YouTube 헤더가 없는 넓은 검색창 + YouTube 헤더가 있는 넓은 검색창을 활성화합니다. + YouTube 헤더가 없는 넓은 검색창을 활성화합니다. 내 페이지에서 넓은 검색창 활성화하기 - "이 설정을 활성화하면 내 페이지에서 설정 버튼이 비활성화됩니다. + "내 페이지에서 넓은 검색창을 활성화합니다. -이 경우에 설정 메뉴를 보려면 다음 경로를 사용하세요: +설정 메뉴에 접근하려면, 다음 경로를 사용하새요: +내 페이지 → 채널 보기 → 메뉴 더보기 (툴바) → 설정" + 내 페이지에서 넓은 검색창을 비활성화합니다. + "이 설정을 활성화하면 내 페이지의 설정 버튼이 비활성화됩니다. + +이 경우에는 다음 경로를 사용하여 설정에 접근할 수 있습니다: 내 페이지 → 채널 보기 → 메뉴 더보기 (툴바) → 설정" 크롬캐스트 버튼 숨기기 크롬캐스트 버튼이 숨겨집니다. @@ -623,7 +708,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." "자동재생이 켜져 있으면 믹스 재생목록 자동전환을 활성화합니다. 자동재생은 YouTube 설정에서 변경할 수 있습니다: -설정 → 자동재생 → 다음 동영상 자동재생" +설정 → 자동재생 / 재생 → 다음 동영상 자동재생" 이 설정을 활성화하면 자동재생이 켜져 있는 동안에 음악 동영상을 재생하면 YouTube 믹스 재생목록으로 자동전환되지 않습니다. 플레이어 팝업 패널 비활성화하기 자동 플레이어 팝업 패널을 비활성화합니다.\n• 재생목록, 실시간 채팅, 제품 패널 ... @@ -672,10 +757,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 동작 추천바가 숨겨집니다. 동작 추천바가 표시됩니다. 최종 화면에서 \'다음 재생 추천 동영상\' 숨기기 - "자동재생을 비활성화하면 최종 화면에서 '다음 재생 추천 동영상'이 숨겨집니다. + "자동재생이 꺼져 있으면 최종 화면에서 '다음 재생 추천 동영상'이 숨겨집니다. 자동재생은 YouTube 설정에서 변경할 수 있습니다: -설정 → 자동재생 → 다음 동영상 자동재생" +설정 → 자동재생 / 재생 → 다음 동영상 자동재생" 최종 화면에서 \'다음 재생 추천 동영상\'이 표시됩니다. 자동재생 카운트다운 건너뛰기 자동재생이 활성화되어 있으면, 카운트다운 없이 다음 동영상을 재생합니다. @@ -725,6 +810,39 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." Thanks 버튼 숨기기 Thanks 버튼이 숨겨집니다. Thanks 버튼이 표시됩니다. + + 인덱스로 액션 버튼 숨기기 + 첫 번째 버튼 숨기기 + 첫 번째 버튼이 숨겨집니다. + 첫 번째 버튼이 표시됩니다. + 두 번째 버튼 숨기기 + 두 번째 버튼이 숨겨집니다. + 두 번째 버튼이 표시됩니다. + 세 번째 버튼 숨기기 + 세 번째 버튼이 숨겨집니다. + 세 번째 버튼이 표시됩니다. + 네 번째 버튼 숨기기 + 네 번째 버튼이 숨겨집니다. + 네 번째 버튼이 표시됩니다. + 다섯 번째 버튼 숨기기 + 다섯 번째 버튼이 숨겨집니다. + 다섯 번째 버튼이 표시됩니다. + 여섯 번째 버튼 숨기기 + 여섯 번째 버튼이 숨겨집니다. + 여섯 번째 버튼이 표시됩니다. + 일곱 번째 버튼 숨기기 + 일곱 번째 버튼이 숨겨집니다. + 일곱 번째 버튼이 표시됩니다. + 여덟 번째 버튼 숨기기 + 여덟 번째 버튼이 숨겨집니다. + 여덟 번째 버튼이 표시됩니다. + + 실시간 스트림에서 인덱스로 숨기기 + \'인덱스로 액션 버튼 숨기기\' 정보 + "액션 버튼이 초기화되기 전에 인덱스로 액션 버튼이 숨겨집니다. + +• 액션 버튼이 숨겨지면 빈 공간이 남겨지지 않습니다. +• 액션 버튼의 인덱스는 항상 같은 버튼이 아닐 수도 있습니다." 앰비언트 모드 앰비언트 모드 제한을 우회하거나 앰비언트 모드를 비활성화할 수 있습니다. @@ -919,7 +1037,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 빠른 작업 상단 여백 재생바에서 빠른 작업 컨테이너까지의 간격을 0-32 사이에서 지정할 수 있습니다. 빠른 작업 상단 여백 값은 0-32 사이어야 합니다. - + 전체 화면에서 세로 모드 활성화하기 전체 화면에서 동영상의 방향을 세로 모드로 활성화합니다. 전체 화면에서 동영상의 방향을 기기의 설정에 따라 활성화합니다. @@ -927,7 +1045,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 전체 화면에서 컨트롤 오버레이를 작게 표시합니다. 전체 화면에서 컨트롤 오버레이를 작게 표시하지 않습니다. 가로 모드 유지하기 - 자동 회전 모드를 켜지 않고, 전체 화면으로 시청 중 화면을 껐다 켰을 때, 가로 모드를 유지합니다. + 화면을 껐다 켜도 동영상을 가로 모드에서 계속 재생합니다. + 화면을 껐다 켜면 동영상을 세로 모드에서 재생합니다. 가로 모드 유지하기 제한 시간 가로 모드로 강제로 유지되는 시간을 지정할 수 있습니다. (밀리초)\n\n화면을 끄고 이 시간이 지나고 다시 켰을 때는 세로 모드로 적용됩니다. @@ -1044,7 +1163,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 추가되는 정보 유형 현재 동영상 화질 값을 추가합니다. 현재 동영상 재생 속도 값을 추가합니다. - 타임스탬프 액션 변경하기 + 타임스탬프 누르기 동작 변경하기 타임스탬프를 누르면 동영상 재생 속도 또는 동영상 화질 설정 메뉴 구성요소를 열 수 있습니다. 타임스탬프를 누르면 남은 시간을 표시할 수 있습니다. 재생바 챕터 비활성화하기 @@ -1115,7 +1234,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 스크립트 섹션 숨기기 스크립트 섹션이 숨겨집니다. 스크립트 섹션이 표시됩니다. - + 동영상 설명 상호 작용 비활성화하기 "동영상 설명이 펼쳐질 때, 다음 상호 작용을 비활성화합니다: @@ -1139,7 +1258,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 플로팅 버튼 숨기기 "'이 사운드 사용'과 같은 플로팅 버튼이 Shorts 채널 탭에서 숨겨집니다." "'이 사운드 사용'과 같은 플로팅 버튼이 Shorts 채널 탭에서 표시됩니다." - + Shorts 선반 Shorts 선반 숨기기 "Shorts 선반이 숨겨집니다. @@ -1168,13 +1287,16 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 시청 기록에서 Shorts 숨기기 시청 기록에서 Shorts가 숨겨집니다. 시청 기록에서 Shorts가 표시됩니다. - + Shorts 백그라운드 재생 반복 상태 변경하기 Shorts 반복 상태 변경하기 자동넘김 기본값 일시정지 반복하기 + 일반 플레이어에서 Shorts 재생하기 + 일반 플레이어에서 Shorts 동영상을 재생합니다.\n\n• 하단바 Shorts 버튼을 눌러서는 일반 플레이어로 재생되지 않을 수 있습니다. + 일반 플레이어에서 Shorts 동영상을 재생하지 않습니다. Shorts 플레이어 Shorts 플레이어에서 구성요소를 숨기거나 표시할 수 있습니다. @@ -1320,10 +1442,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 반복 상태 변경 메뉴가 표시됩니다. 반복 상태 변경 메뉴가 숨겨집니다. 사용자 정의 동작 정보 - "이 기능은 아직 실험 단계이므로, 완벽하게 작동한다는 보장은 없습니다. + "이 설정은 아직 실험 기능이므로 완벽하게 작동한다는 보장은 없습니다. 대부분의 버그는 클라이언트 측의 제한으로 인해 수정할 수 없으므로 테스트 목적으로만 사용하세요." - + 타임스탬프 활성화하기 "타임스탬프를 활성화합니다. @@ -1531,7 +1653,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." API Key를 발급받는 방법을 보려면 여기를 누르세요." YouTube Data API v3 Developer Key 발급받기 - 1. <a href=%1$s>새 프로젝트 만들기</a> 로 이동합니다.<br>2. <b>만들기</b> 버튼을 터치합니다.<br>3. <a href=%2$s>YouTube Data API v3</a> 로 이동합니다.<br>4. <b>사용</b> 버튼을 터치합니다.<br>5. <b>사용자 인증 정보 만들기</b> 버튼을 터치합니다.<br>6. <b>공개 데이터</b> 옵션을 선택합니다.<br>7. <b>다음</b> 버튼을 터치합니다.<br>8. API Key를 복사합니다.<br><br>※ API Key는 다른 사람과 공유해서는 안 되므로 가져오기 / 내보내기 설정에 포함되지 않습니다. + 1. <a href=%1$s>새 프로젝트 만들기</a> 로 이동합니다.<br>2. <b>만들기</b> 버튼을 누릅니다.<br>3. <a href=%2$s>YouTube Data API v3</a> 로 이동합니다.<br>4. <b>사용</b> 버튼을 누릅니다.<br>5. <b>사용자 인증 정보 만들기</b> 버튼을 누릅니다.<br>6. <b>공개 데이터</b> 옵션을 선택합니다.<br>7. <b>다음</b> 버튼을 누릅니다.<br>8. API Key를 복사합니다.<br><br>※ API Key는 다른 사람과 공유해서는 안 되므로 가져오기 / 내보내기 설정에 포함되지 않습니다. SponsorBlock SponsorBlock 활성화하기 @@ -1651,8 +1773,8 @@ API Key를 발급받는 방법을 보려면 여기를 누르세요." API URL을 변경하였습니다. 복사 설정 가져오기 / 내보내기 - ReVanced Extended 및 다른 SponsorBlock 플랫폼에서 가져오거나 내보낼 수 있는 SponsorBlock JSON 구성입니다. - ReVanced Extended 및 다른 SponsorBlock 플랫폼으로부터 가져오거나 내보낼 수 있는 SponserBlock JSON의 전체 구성 파일입니다. 비공개 사용자 아이디를 포함하고 있으므로 주의하세요. + RVX 및 다른 SponsorBlock 플랫폼에서 가져오거나 내보낼 수 있는 SponsorBlock JSON 구성입니다. + RVX 및 다른 SponsorBlock 플랫폼으로부터 가져오거나 내보낼 수 있는 SponserBlock JSON의 전체 구성 파일입니다. 비공개 사용자 아이디를 포함하고 있으므로 주의하세요. 설정을 성공적으로 가져왔습니다. 설정을 가져올 수 없습니다: %s 설정을 내보낼 수 없습니다: %s @@ -1720,24 +1842,24 @@ API Key를 발급받는 방법을 보려면 여기를 누르세요." 건너뛸 구간의 데이터는 SponsorBlock API에 의해 제공됩니다. 자세한 정보를 보려면 여기를 누르세요. 기타 + 리다이렉션 없이 링크 바로 열기 + 앱 내에서 외부 링크를 열 때, URL 리다이렉션(youtube.com/redirect)을 거치지 않고 연결됩니다. + 앱 내에서 외부 링크를 열 때, URL 리다이렉션(youtube.com/redirect)을 거쳐서 연결됩니다. QUIC 프로토콜 비활성화하기 - "QUIC 프로토콜을 비활성화해서 동영상을 불러올 때 발생하는 동영상 압축과 푸는 과정을 제거하여 동영상 로딩 속도를 향상시킵니다. 더 많은 모바일 데이터가 사용되오니 주의하세요." + "QUIC 프로토콜을 비활성화합니다.\n동영상 로딩 속도가 개선될 수 있습니다." 디버그 로깅 활성화하기 디버그 로그를 출력합니다. 디버그 로그를 출력하지 않습니다. 디버그 버퍼 로깅 활성화하기 디버그 로그에 버퍼를 포함합니다. 디버그 로그에 버퍼를 포함하지 않습니다. - 외부 브라우저 사용하기 - 앱 내에서 외부 링크를 열 때, 외부 브라우저를 사용합니다. - 앱 내에서 외부 링크를 열 때, 내부 브라우저를 사용합니다. - 리다이렉션 없이 링크 바로 열기 - 앱 내에서 외부 링크를 열 때, URL 리다이렉션(youtube.com/redirect)을 거치지 않고 다이렉트로 연결됩니다. - 앱 내에서 외부 링크를 열 때, URL 리다이렉션(youtube.com/redirect)을 거쳐서 연결됩니다. + 외부 브라우저 사용하기 + 앱 내에서 외부 링크를 열 때, 외부 브라우저를 사용합니다. + 앱 내에서 외부 링크를 열 때, 내부 브라우저를 사용합니다. 추적 쿼리를 제거한 링크 공유하기 링크를 공유할 때, URL에서 추적 쿼리 매개변수를 제거합니다. (URL의 뒷부분 \'?si=...\' 이 제거됨.) 기본 앱 설정 열기 - 다른 앱에서 YouTube 링크를 ReVanced Extended로 열려면 \'지원되는 링크 열기\'를 활성화하고 지원되는 링크를 추가하세요. 링크 추가가 잠겨있다면 순정 YouTube 앱 정보 → \'기본적으로 열기\'에서 \'지원되는 링크 열기\'를 비활성화한 후에 추가할 수 있습니다. + 다른 앱에서 YouTube 링크를 RVX로 열려면 \'지원되는 링크 열기\'를 활성화하고 지원되는 링크를 추가하세요. 링크 추가가 잠겨있다면 순정 YouTube 앱 정보 → \'기본적으로 열기\'에서 \'지원되는 링크 열기\'를 비활성화한 후에 추가할 수 있습니다. GmsCore 설정 열기 알림 수신을 위한 클라우드 메시징 설정을 할 수 있습니다. GmsCore가 설치되어 있지 않습니다. 설치하세요. @@ -1792,6 +1914,8 @@ GmsCore 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 "Android TV (로그인이 요구됨)" Android VR + "Android VR +(미인증)" "iOS (PoToken이 요구됨)" "iOS TV @@ -1818,6 +1942,7 @@ AVC의 최대 화질 값은 1080p이고, OPUS 코덱을 사용불가 및 HDR 동 전문 통계에서 표시하기 \'스트리밍 데이터를 가져오는 데 사용되는 클라이언트\'가 전문 통계에서 표시됩니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. \'스트리밍 데이터를 가져오는 데 사용되는 클라이언트\'가 전문 통계에서 숨겨집니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. + Android VR 기본 오디오 스트림 언어 PoToken / VisitorData 사용할 PoToken diff --git a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml index 8b9957240..8f545aaef 100644 --- a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml @@ -7,7 +7,7 @@ ReVanced Extended Wyszukaj w %s Przywrócono domyślne wartości. - Ustawienia Eksperymentalne + Eksperymentalne flagi Czy chcesz kontynuować? Uruchom ponownie, aby wczytać poprawnie układ aplikacji Odśwież i uruchom ponownie @@ -19,6 +19,59 @@ "%1$s nie jest zainstalowany. Pobierz %2$s ze strony internetowej." %s nie jest zainstalowany. Proszę go zainstalować. + Język RVX + Język aplikacji + Arabski + Azerbejdżański + Bułgarski + Bengalski + Kataloński + Czeski + Duński + Niemiecki + Grecki + Angielski + Hiszpański + Estoński + Perski + Fiński + Francuski + Gudżaracki + Hindi + Chorwacki + Węgierski + Indonezyjski + Włoski + Japoński + Kazachski + Koreański + Litewski + Łotewski + Macedoński + Mongolski + Maratyjski + Malajski + Birmański + Niderlandzki + Orija + Pendżabski + Polski + Portugalski + Rumuński + Rosyjski + Słowacki + Słoweński + Serbski + Szwedzki + Suahili + Tamilski + Telugu + Tajski + Turecki + Ukraiński + Urdu + Wietnamski + Chiński Reklamy Pełnoekranowe reklamy @@ -66,7 +119,9 @@ Pobierz %2$s ze strony internetowej." DeArrow i miniaturki przechwycone z filmu Miniaturki przechwycone z filmu DeArrow - "DeArrow dostarcza miniaturki filmów z YouTube pochodzące z procesu crowdsourcingu. Miniaturki te są często bardziej trafne niż te dostarczane przez YouTube. Jeśli opcja ta jest włączona, adresy URL filmów będą wysyłane do serwera API i nie będą wysyłane żadne inne dane. Jeśli film nie posiada miniaturki od DeArrow, to wyświetla się oryginalna lub przechwycona z filmu. + "DeArrow dostarcza miniaturki filmów z YouTube pochodzące z procesu crowdsourcingu. Miniaturki te są często bardziej trafne niż te dostarczane przez YouTube. + +Jeśli opcja ta jest włączona, adresy URL filmów będą wysyłane do serwera API i nie będą wysyłane żadne inne dane. Jeśli film nie posiada miniaturki od DeArrow, to wyświetla się oryginalna lub przechwycona z filmu. Stuknij tutaj, aby dowiedzieć się więcej o DeArrow." Komunikat, jeśli API jest niedostępne @@ -100,13 +155,14 @@ Stuknij tutaj, aby dowiedzieć się więcej o DeArrow." Ukryty Widoczny Półki karuzelowe - "Ukrywa półki: -• Z najnowszymi informacjami -• Z filmami, które nie zostały dokończone -• Od odkrywania kanałów -• Z muzyką do ponownego odsłuchania -• Od kupowania -• Z filmami, które nie zostały obejrzane" + "Ukryte, konkretnie półki: +• z najnowszymi informacjami +• z filmami, które nie zostały dokończone +• od odkrywania kanałów +• z muzyką do ponownego odsłuchania +• od kupowania +• z filmami, które nie zostały obejrzane" + Widoczne Paski z kategoriami Ukryte Widoczne @@ -140,18 +196,18 @@ Stuknij tutaj, aby dowiedzieć się więcej o DeArrow." Pokój gier Ukryte Widoczne - Przycisk \'Pokaż więcej\' - Ukryty - Widoczny Pasek wyszukiwania na stronie głównej Ukryty Widoczny - Ankiety na stronie głównej - Ukryte - Widoczne + Przycisk \'Pokaż więcej\' + Ukryty + Widoczny Półki karuzelowe z subskrypcjami Ukryte Widoczne + Ankiety na stronie głównej + Ukryte + Widoczne Półki z biletami Ukryte Widoczne @@ -250,11 +306,12 @@ Ograniczenia: Rekomendowane filmy Ukryj filmy z małą ilością wyświetleń - Ukrywa filmy poniżej 1000 wyświetleń ze strony głównej, które zostały przesłane z niesubskrybowanych kanałów. + "Ukrywa filmy poniżej 1000 wyświetleń ze strony głównej, które zostały przesłane z niesubskrybowanych kanałów. + +Filtr może już nie działać - zamiast niego użyj filtru ilości wyświetleń." Ukryj rekomendowane filmy "Ukrywa następujące rekomendowane filmy: -• Filmy z tagiem 'Dla wspierających' • Filmy z takimi frazami jak 'Inne osoby również obejrzały' u dołu filmu" Filtr ilości wyświetleń @@ -289,17 +346,12 @@ Jeśli układ ekranu odtwarzacza zmieni się w skutek zmian po stronie serwera, Przesunięcie Ogólne - Układ aplikacji - Oryginalny - Telefonowy - Telefonowy (max. 480 dpi) - Tabletowy - Tabletowy (max. 600 dpi) Strona startowa + Domyślna Przeglądaj kanały Nauka - Domyślna Odkrywanie + Moda i uroda Gry Historia Biblioteka @@ -307,8 +359,11 @@ Jeśli układ ekranu odtwarzacza zmieni się w skutek zmian po stronie serwera, Na żywo Filmy Muzyka + Wiadomości Powiadomienia + Podcasty Wyszukiwanie + Zakupy Shortsy Sport Subskrypcje @@ -341,12 +396,18 @@ Ograniczenie: Przycisk wstecz na pasku narzędzi może nie działać." Szare separatory Ukryte Widoczne - Komunikaty - Ukryte - Widoczne Usuń okno dialogowe treści ograniczonej do oglądania "Usuwa okno dialogowe treści ograniczonej do oglądania. Nie pomija to ograniczeń wiekowych, lecz akceptuje je automatycznie." + Układ aplikacji + Oryginalny + Telefonowy + Telefonowy (max. 480 dpi) + Tabletowy + Tabletowy (max. 600 dpi) + Zachowanie po kliknięciu okręgu od transmisji na żywo + Otwarcie kanału + Otwarcie transmisji na żywo Oszukiwanie wersji aplikacji Włączone Wyłączone @@ -400,7 +461,7 @@ Niektóre komponenty mogą nie być ukryte." Natywne pobieranie Nazwa pakietu aplikacji od pobierania (playlisty) Nazwa pakietu zainstalowanej zewnętrznej aplikacji od pobierania, takiej jak YTDLnis. - + Aplikacja otwierana przyciskiem do YouTube Music RVX Music YouTube Music @@ -512,15 +573,15 @@ Jeśli opcja nie przynosi skutku, spróbuj przełączyć się na tryb incognito. Ogólne Ukryte Widoczne - Konto + Przełącz konto Ukryte Widoczne Oszczędzanie danych Ukryte Widoczne - Autoodtwarzanie - Ukryte - Widoczne + Autoodtwarzanie/odtwarzanie + Ukryte + Widoczne Preferencje dotyczące jakości filmu Ukryte Widoczne @@ -566,6 +627,26 @@ Jeśli opcja nie przynosi skutku, spróbuj przełączyć się na tryb incognito. Informacje Ukryte Widoczne + + Komunikaty + Ukryj lub zmień elementy komunikatów + Komunikaty + Ukryte + Widoczne + Komunikaty po stronie serwera + Ukryte + Widoczne + Odwróć motyw komunikatów + Tak + Nie + Tło komunikatów po stronie serwera + Zmienione + Niezmienione + "Większość komunikatów używa zdefiniowanego motywu po stronie serwera, a nie motywu aplikacji. + +To ustawienie zmienia kolor tła tych komunikatów. + +Jeśli zajdą zmiany po stronie serwera, kolor tła tych komunikatów może się nie zmienić." Pasek narzędzi Ukryj lub pokazuj przyciski na pasku narzędzi, takie jak pasek wyszukiwania, nagłówek i inne @@ -579,9 +660,15 @@ Jeśli opcja nie przynosi skutku, spróbuj przełączyć się na tryb incognito. Włączony Wyłączony Szeroki pasek wyszukiwania na stronie Ty - "Włączenie tej opcji ukryje przycisk ustawień w zakładce Ty. + "Włączony -W tym przypadku, proszę użyć następującej ścieżki dostania się do ustawień: +By dostać się do ustawień, użyj następującej ścieżki: +Zakładka Ty → Zobacz kanał → Menu → Ustawienia +" + Wyłączony + "Włączenie tego ustawienia ukryje przycisk ustawień w zakładce Ty. + +W takim razie, by dostać się do ustawień, użyj następującej ścieżki: Zakładka Ty → Zobacz kanał → Menu → Ustawienia" Przycisk od castowania Ukryty @@ -624,7 +711,7 @@ Stuknij i przytrzymaj, by otworzyć ustawienia RVX." "Włączone, gdy autoodtwarzanie jest włączone. Autoodtwarzanie może być zmienione w ustawieniach YouTube: -Ustawienia → Autoodtwarzanie → Autoodtwarzanie następnego filmu" +Ustawienia → Autoodtwarzanie / Odtwarzanie → Autoodtwarzanie następnego filmu" Włączenie tej funkcji wyłączy automatyczne zmienianie na YouTube Mix, podczas odtwarzania muzyki z włączonym autoodtwarzaniem. Wyskakujące panele w odtwarzaczu Widoczne @@ -675,7 +762,7 @@ Notki: "Ukryte, lecz wyłącznie, gdy autoodtwarzanie jest wyłączone. Autoodtwarzanie można zmienić w ustawieniach YouTube: -'Ustawienia → Autoodtwarzanie → Autoodtwarzanie następnego filmu'" +Ustawienia → Autoodtwarzanie/Odtwarzanie → Autoodtwarzanie następnego filmu" Widoczne Pomiń odliczanie do automatycznego odtwarzania Jeżeli automatyczne odtwarzanie jest włączone, następny film zostanie odtworzony bez odliczania. @@ -725,6 +812,39 @@ Autoodtwarzanie można zmienić w ustawieniach YouTube: Przycisk od dziękowania Ukryty Widoczny + + Ukryj wg indeksu + Pierwszy przycisk + Ukryty + Widoczny + Drugi przycisk + Ukryty + Widoczny + Trzeci przycisk + Ukryty + Widoczny + Czwarty przycisk + Ukryty + Widoczny + Piąty przycisk + Ukryty + Widoczny + Szósty przycisk + Ukryty + Widoczny + Siódmy przycisk + Ukryty + Widoczny + Ósmy przycisk + Ukryty + Widoczny + + Ukryj wg indeksu w transmisjach na żywo + O ukrywaniu przycisków akcji po indeksie + "Ukrywa przyciski akcji według indeksu przed zainicjowaniem przycisków akcji. + +- ukrywanie przycisków akcji nie pozostawia pustego miejsca +- indeks przycisków akcji nie zawsze jest tym samym przyciskiem" Oświetlenie kinowe Wyłącz oświetlenie kinowe lub obejdź jego ograniczenia @@ -917,7 +1037,7 @@ Ograniczenie: tytuły filmów znikają po stuknięciu w nie." Górny margines przycisków na dole odtwarzacza Skonfiguruj odstęp od paska postępu filmu do kontenera szybkich akcji, w zakresie od 0 do 32. Górny margines przycisków na dole odtwarzacza musi wynosić między 0 a 32. - + Tryb poziomy Orientacja filmu jest w trybie pionowym w trybie pełnoekranowym. Orientacja filmu jest zgodna z ustawieniami urządzenia w trybie pełnoekranowym. @@ -925,7 +1045,8 @@ Ograniczenie: tytuły filmów znikają po stuknięciu w nie." Przyciski w odtwarzaczu nie zajmują całego ekranu Przyciski w odtwarzaczu zajmują cały ekran Zachowaj tryb poziomy - Zachowuje tryb poziomy, gdy wyłączysz i włączysz ekran w trybie pełnoekranowym. + Filmy są nadal odtwarzane w trybie poziomym po wyłączeniu i włączeniu ekranu. + Filmy są odtwarzane w trybie pionowym po wyłączeniu i włączeniu ekranu. Limit czasu zachowania trybu poziomego Ilość milisekund, podczas których tryb poziomy jest wymuszony. @@ -971,7 +1092,7 @@ Ograniczenie: tytuły filmów znikają po stuknięciu w nie." Ukryty Widoczny - Przyciski w odtwarzaczu + Dodatkowe przyciski w odtwarzaczu Przycisk od pętli "Stuknij, by zmienić stan pętli. Stuknij i przytrzymaj, by zmienić stan pętli z pauzą." @@ -1113,7 +1234,7 @@ Funkcja działa najlepiej przy bardzo szybkim połączeniu internetowym."Transkrypcje Ukryte Widoczne - + Wyłącz interakcje z opisami filmów "Wyłącza następujące interakcje, gdy opis filmu jest otworzony: @@ -1137,7 +1258,7 @@ Opcja rozwijania opisu filmu może nie działać, jeśli wprowadzony ciąg znak Pływające przyciski nad tytułami "Ukryte" "Widoczne" - + Półki z Shortsami Półki z Shortsami "Ukrywa półki z Shortsami. @@ -1161,13 +1282,16 @@ Informacja: W historii oglądania Ukryte Widoczne - + Zmień stan powtarzania w tle Shortsów Zmień stan powtarzania Shortsów Automatyczne odtwarzanie Domyślny Wstrzymywanie Powtarzanie + Otwieranie Shortsów w zwykłym odtwarzaczu + Włączone + Wyłączone Odtwarzacz Shortsów Ukryj lub pokazuj przyciski w odtwarzaczu Shortsów @@ -1313,10 +1437,10 @@ Kliknij i przytrzymaj przycisk 'Więcej', by wyświetlić okno z własnymi akcja Widoczne Ukryte O własnych akcjach - "Funkcja ta jest nadal eksperymentalna, więc nie ma gwarancji, że będzie działać perfekcyjnie. + "Funkcja jest nadal eksperymentalna, więc nie ma gwarancji, że będzie działać perfekcyjnie. -Większość błędów nie może być naprawiona w skutek ograniczeń po stronie klienta, więc używaj tej funkcji jedynie do celów testowych." - +Większość błędów nie może być naprawiona w skutek ograniczeń po stronie klienta, więc używaj tej funkcji w celach testowych." + Czas Shortsa "Włączony @@ -1644,8 +1768,8 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Adres API został zmieniony. Skopiuj Zaimportuj / Wyeksportuj ustawienia - Twoja konfiguracja JSON SponsorBlock może zostać zaimportowana / wyeksportowana do ReVacned Extended i innych platform SponsorBlock. - Twoja konfiguracja JSON SponsorBlock, która może zostać zaimportowana / wyeksportowana do ReVanced Extended i innych platform SponsorBlocka. Zawiera twój prywatny identyfikator użytkownika. Dziel się nią mądrze. + Twoja konfiguracja JSON SponsorBlock może zostać zaimportowana / wyeksportowana do RVX i innych platform SponsorBlocka. + Twoja konfiguracja JSON SponsorBlock, która może zostać zaimportowana / wyeksportowana do RVX i innych platform SponsorBlocka. Zawiera twój prywatny identyfikator użytkownika. Dziel się nią mądrze. Ustawienia zostały pomyślnie zaimportowane. Nie udało się zaimportować: %s. Nie udało się wyeksportować: %s. @@ -1713,6 +1837,9 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Dane są dostarczane przez API SponsorBlock. Stuknij tutaj, aby dowiedzieć się więcej i pobrać na inne platformy. Pozostałe + Bezpośrednie otwieranie linków + Tak + Nie Wyłącz protokół QUIC "Wyłącz protokół QUIC w CronetEngine" Logi do debugowania @@ -1721,18 +1848,15 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Logi do debugowania buforu Z buforem Bez bufora - Zewnętrzna przeglądarka - Włączona - Wyłączona - Bezpośrednie otwieranie linków - Tak - Nie + Zewnętrzna przeglądarka + Włączona + Wyłączona Oczyść udostępniane linki Usuwa śledzące parametry z adresów URL podczas udostępniania linków Otwórz systemowe ustawienia aplikacji Aby otwierać linki YouTube w RVX, przejdź do opcji obsługiwanych linków w ustawieniach i włącz obsługiwane adresy internetowe dla RVX. Otwórz ustawienia GmsCore - Otwiera ustawienia GmsCore. Następnie włącz cloud messaging, by otrzymywać powiadomienia. + Aby otrzymywać powiadomienia w RVX, włącz Cloud Messaging. GmsCore nie jest zainstalowany. Zainstaluj go. Wymagana akcja "GmsCore nie ma uprawnień do działania w tle. @@ -1754,7 +1878,7 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." Włącza kodek OPUS, jeśli odpowiedź odtwarzacza zawiera ten kodek. Zaimportuj / Wyeksportuj ustawienia - Ustawienia importu oraz eksportu + Zaimportuj / wyeksportuj ustawienia RVX Zaimportuj / Wyeksportuj jako plik Wyeksportuj ustawienia @@ -1764,7 +1888,7 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." Zaimportuj / Wyeksportuj jako tekst Zaimportuj / Wyeksportuj jako tekst - Importuje bądź eksportuje ustawienia w formie tekstu + Importuje / eksportuje ustawienia w formie tekstu Nie udało się wyeksportować ustawień. Ustawienia zostały pomyślnie wyeksportowane. Zaimportuj @@ -1785,6 +1909,8 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." "Android TV (Wymagane zalogowanie)" Android VR + "Android VR +(Bez autoryzacji)" "iOS (Wymagany PoToken)" "iOS TV @@ -1806,6 +1932,7 @@ AVC obsługuje maksymalnie rozdzielczość 1080p, kodek audio OPUS nie jest dost Informacja w statystykach dla nerdów Widoczna Ukryta + Domyślny język dla transmisji na żywo dla VR PoToken / VisitorData PoToken do użycia diff --git a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml index 6fbead4f3..e08aafd10 100644 --- a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml @@ -19,6 +19,59 @@ "%1$s não está instalado. Por favor, baixe %2$s do site." %s não está instalado. Por favor, instale-o. + Idioma do RVX + Idioma do app + Árabe + Azerbaijano + Búlgaro + Bengalês + Catalão + Tcheco + Dinamarquês + Alemão + Grego + Inglês + Espanhol + Estoniano + Persa + Finlandês + Francês + Guzerate + Hindu + Croata + Húngaro + Indonésio + Italiano + Japonês + Cazaque + Coreano + Lituano + Letão + Macedônio + Mongol + Marata + Malaio + Birmanês + Holandês + Odia + Punjabi + Polonês + Português + Romeno + Russo + Eslovaco + Esloveno + Sérvio + Sueco + Suaíli + Tâmil + Telugu + Tailandês + Turco + Ucraniano + Urdu + Vietnamita + Chinês Anúncios Ocultar anúncios em tela cheia @@ -102,13 +155,14 @@ Toque aqui para saber mais sobre o DeArrow." O botão de legendas está oculto. O botão de legendas será exibido. Ocultar painel de carrossel - "Oculta os seguintes painéis: + "Os painéis do carrossel estão ocultas, como: • Últimas notícias -• Continue assistindo -• Explore mais canais +• Continuar assistindo +• Explorar mais canais • Ouça novamente • Compras -• Assista novamente" +• Assistir novamente" + Os painéis do carrossel serão exibidos. Ocultar painel de chips O painel de chips está oculto. O painel de chips será exibido. @@ -142,18 +196,18 @@ Toque aqui para saber mais sobre o DeArrow." Ocultar Reproduções As reproduções estão ocultas. As reproduções serão exibidas. - Ocultar botão \'Mostrar mais\' - O botão \'Mostrar mais\' está oculto. - O botão \'Mostrar mais\' será exibido. Ocultar barra de pesquisa no feed A barra de pesquisa no feed está oculta. A barra de pesquisa no feed será exibida. - Ocultar pesquisas no feed - As pesquisas no feed estão ocultas. - As pesquisas no feed serão exibidas. + Ocultar botão \'Mostrar mais\' + O botão \'Mostrar mais\' está oculto. + O botão \'Mostrar mais\' será exibido. Ocultar inscrições em carrossel As inscrições em carrossel estão ocultas. As inscrições em carrossel serão exibidas. + Ocultar pesquisas no feed + As pesquisas no feed estão ocultas. + As pesquisas no feed serão exibidas. Ocultar painel de ingressos Os painéis de ingressos estão ocultos. Os painéis de ingressos serão exibidos. @@ -249,7 +303,7 @@ Limitações: Vídeo recomendado Ocultar vídeos com baixas visualizações - Ocultar vídeos com menos de 1.000 visualizações do feed de início que foram enviadas de canais não inscritos. + "Ocultar vídeos com menos de 1.000 visualizações do feed de início que foram enviadas de canais não inscritos." Ocultar vídeos recomendados "Oculta os seguintes vídeos recomendados: @@ -289,17 +343,12 @@ Se o layout da tela do reprodutor mudar devido a alterações no lado do servido Desvio Geral - Alterar layout - Original - Telefone - Telefone (Máximo 480 dp) - Tablet - Tablet (Min 600 dp) Alterar a página inicial + Padrão Explorar canais Cursos / Aprendizagem - Padrão Explorar + Moda e Beleza Jogos Histórico Biblioteca @@ -307,8 +356,11 @@ Se o layout da tela do reprodutor mudar devido a alterações no lado do servido Ao Vivo Filmes Música + Notícias Notificações + Podcasts Buscar + Compras Shorts Esportes Inscrições @@ -341,12 +393,18 @@ Limitação: O botão voltar na barra de ferramentas pode não funcionar."Ocultar separador cinza Os separadores cinza estão ocultos. Os separadores cinza serão exibidos. - Ocultar barra de busca - A barra de busca está oculta. - A barra de busca será exibida. Remover o diálogo discricionário do visualizador "Remover o diálogo discricionário de visualização. Isso não ignora a restrição de idade, apenas aceita isso automaticamente." + Alterar layout + Original + Telefone + Telefone (Máximo 480 dp) + Tablet + Tablet (Min 600 dp) + Alterar ação de clique do anel ao vivo + O canal é aberto quando o anel ao vivo é clicado. + A transmissão ao vivo é aberta quando o anel ao vivo é clicado. Falsificar versão do aplicativo Versão falsificada Versão não falsificada @@ -400,7 +458,7 @@ Alguns componentes podem não ser ocultos" O botão de download de vídeo nativo abre o download nativo do aplicativo. Nome do pacote do aplicativo de download de playlist Nome do pacote do seu aplicativo de download externo instalado, como YTDLnis. - + Substituir botão do YouTube Music O botão do YouTube Music abre o RVX Music. O botão do YouTube Music abre o aplicativo nativo. @@ -519,9 +577,9 @@ Se essa configuração não surtir efeito, tente alternar para o modo anônimo." Ocultar menu Economia de dados O menu Economia de dados está oculto. O menu Economia de dados será exibido. - Ocultar menu Reprodução automática - O menu Reprodução automática está oculto. - O menu Reprodução automática será exibido. + Ocultar menu de reprodução automática ou de reprodução + O menu de reprodução automática ou reprodução está oculto. + O menu de reprodução automática ou reprodução será exibido. Ocultar menu Preferências de qualidade de vídeo O menu Preferências de qualidade de vídeo está oculto. O menu Preferências de qualidade de vídeo será exibido. @@ -567,6 +625,26 @@ Se essa configuração não surtir efeito, tente alternar para o modo anônimo." Ocultar menu Sobre O menu Sobre está oculto. O menu Sobre será exibido. + + Barra de busca + Ocultar ou alterar componentes relacionados à barra de busca. + Ocultar barra de busca + A barra de busca está oculta. + A barra de busca será exibida. + Ocultar barra de busca do servidor + A barra de busca do servidor está oculta. + A barra de busca do servidor será exibida. + Inverter o tema da barra de busca + O tema da barra de busca está invertido. + O tema da barra de busca não está invertido. + Alterar fundo da barra de busca do servidor + A cor de fundo da barra de busca do servidor foi alterada. + A cor de fundo da barra de busca do servidor não foi alterada. + "Algumas barras de buscas usam um tema definido no lado do servidor, não o tema do aplicativo. + +Altere a cor de fundo dessas barras de busca. + +Se houver alterações no lado do servidor, a cor de fundo da barra de busca pode não mudar." Barra de ferramentas Ocultar ou alterar componentes localizados na barra de ferramentas, como botões da barra de ferramentas, barra de pesquisa, cabeçalho. @@ -580,10 +658,15 @@ Se essa configuração não surtir efeito, tente alternar para o modo anônimo." A barra de pesquisa ampla inclui o cabeçalho do YouTube. A barra de pesquisa ampla não inclui o cabeçalho do YouTube. Ativar a barra de pesquisa ampla na aba Você - "Ativar essa configuração desativará o botão de configurações na aba Você. + "A barra de pesquisa ampla está ativada na aba Você. -Nesse caso, por favor, use o seguinte caminho: -Aba Você > Visualizar canal > Menu > Configurações." +Para acessar as configurações, por favor, use o seguinte caminho: +Aba Você → Ver canal → Menu → Configurações" + A barra de pesquisa ampla está desativada na aba Você. + "Ativar esta configuração irá desativar o botão Configurações na aba Você. + +Neste caso, você pode precisar usar o seguinte caminho para acessar as configurações: +Aba Você → Ver canal → Menu → Configurações" Ocultar botão de transmissão O botão de transmissão está oculto. O botão de transmissão será exibido. @@ -726,6 +809,39 @@ A reprodução automática pode ser alterada nas configurações do YouTube: Ocultar botão valeu O botão valeu está oculto. O botão valeu será exibido. + + Ocultar por índice + Ocultar o primeiro botão + O primeiro botão está oculto. + O primeiro botão será exibido. + Ocultar o segundo botão + O segundo botão está oculto. + O segundo botão será exibido. + Ocultar o terceiro botão + O terceiro botão está oculto. + O terceiro botão será exibido. + Ocultar o quarto botão + O quarto botão está oculto. + O quarto botão será exibido. + Ocultar o quinto botão + O quinto botão está oculto. + O quinto botão será exibido. + Ocultar o sexto botão + O sexto botão está oculto. + O sexto botão será exibido. + Ocultar o sétimo botão + O sétimo botão está oculto. + O sétimo botão será exibido. + Ocultar o oitavo botão + O oitavo botão está oculto. + O oitavo botão será exibido. + + Ocultar por índice na transmissão ao vivo + Sobre o Ocultar botão de ação por índice + "Oculte os botões de ação por índice antes que os botões de ação sejam inicializados. + +- Ocultar os botões de ação não deixa espaço vazio. +- Índice dos botões de ação podem não ser sempre o mesmo botão." Modo ambiente Ignorar restrições do modo ambiente ou desativar o modo ambiente. @@ -918,7 +1034,7 @@ Limitação: Título do vídeo desaparece quando clicado." Margem superior das ações rápidas Configure o espaçamento da barra de progresso para o contêiner de ação rápida, entre 0-32. A margem superior das ações rápidas deve ser entre 0-32. Redefinir para os valores padrão. - + Desativar modo paisagem A orientação do vídeo é o modo retrato em tela cheia. A orientação do vídeo segue as configurações do dispositivo em tela cheia. @@ -926,7 +1042,8 @@ Limitação: Título do vídeo desaparece quando clicado." A sobreposição de controles não preenche a tela inteira. A sobreposição de controles preenche a tela inteira. Manter o modo paisagem - Mantenha o modo paisagem ao desligar e ligar em tela cheia. + Os vídeos continuam sendo reproduzidos no modo paisagem depois de desligar e ligar a tela. + Os vídeos serão reproduzidos no modo retrato depois de desligar e ligar a tela. Tempo limite para manter o modo paisagem A quantidade de milissegundos que o modo paisagem é forçado. @@ -1112,7 +1229,7 @@ Este recurso funciona melhor com uma conexão de Internet muito rápida."Ocultar seções de transcrição As seções de transcrição estão ocultas. As seções de transcrição serão exibidas. - + Desativar interação com a descrição do vídeo "Desabilita as seguintes interações quando a descrição do vídeo é expandida: @@ -1137,7 +1254,7 @@ Estes caracteres variam dependendo do seu idioma. Ocultar botão flutuante "Os botões flutuantes como \"Usar este som\" estão ocultos na aba do canal do Shorts." "Os botões flutuantes como \"Usar este som\" serão exibidos na aba do canal do Shorts." - + Painel de shorts Ocultar painel de Shorts "Oculta o painel de shorts. @@ -1161,13 +1278,16 @@ info: Ocultar no histórico de exibição Oculto no histórico de exibição. Exibindo no histórico de exibição. - + Alterar estado de repetição de plano de fundo do Shorts Alterar estado de repetição do shorts Reprodução automática Padrão Pausar Repetir + Abrir Shorts no reprodutor normal + Abrir Shorts no reprodutor normal. + Não abrir Shorts no reprodutor normal. Reprodutor de shorts Ocultar ou mostrar componentes no reprodutor de shorts. @@ -1313,10 +1433,10 @@ Pressione e segure o botão Mais para mostrar o diálogo de ações personalizad O menu estado de repetição será exibido. O menu estado de repetição está oculto. Sobre ações personalizadas - "Esse recurso ainda é experimental, então não há garantia de que ele funcionará perfeitamente. + "Esse recurso ainda é experimental, então não há garantia de que ele funcionará perfeitamente. A maioria dos bugs não podem ser corrigidos devido a limitações no lado do cliente, então use-o apenas para fins de teste." - + Ativar marcação de tempo "A marcação de tempo está ativada. @@ -1711,6 +1831,9 @@ Clique para ver como emitir uma chave de API." Os dados são fornecidos pela API do SponsorBlock. Toque aqui para aprender mais e ver downloads para outras plataformas. Diversos + Ignorar redirecionamentos de URL + Os redirecionamentos de URL são ignorados. + Os redirecionamentos de URL não são ignorados. Desativar protocolo QUIC "Desativar o protocolo QUIC do CronetEngine." Ativar o registro de depuração @@ -1719,12 +1842,9 @@ Clique para ver como emitir uma chave de API." Ativar o registro de depuração do buffer Os registros de depuração incluem o buffer. Os registros de depuração não incluem o buffer. - Ativar navegador externo - O navegador externo está ativado. - O navegador externo está desativado. - Ativar abrir links diretamente - Ignorando redirecionamentos de URL - Seguindo a política de redirecionamento padrão + Abrir links no navegador + Abre links no navegador externo. + Abre links no navegador do aplicativo. Limpar links compartilhados Remove os parâmetros de consulta de rastreamento das URLs ao compartilhar os links. Abrir configurações padrão do aplicativo @@ -1781,6 +1901,8 @@ Toque no botão continuar e desative as otimizações da bateria." "Android TV (é necessário logar)" Android VR + "Android VR +(Sem autenticação)" "iOS (requer PoToken)" "iOS TV @@ -1802,6 +1924,7 @@ O AVC tem uma resolução máxima de 1080p, o codec de áudio Opus não está di Exibir em Estatísticas para nerds O cliente usado para buscar dados de streaming é mostrado em Estatísticas para nerds. O cliente usado para buscar dados de streaming está oculto em Estatísticas para nerds. + Idioma padrão de áudio do VR PoToken / VisitorData PoToken a ser utilizado diff --git a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml index 4f16e4b28..1be890ce9 100644 --- a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml @@ -19,6 +19,59 @@ "%1$s не установлен. Пожалуйста, скачайте %2$s с сайта." %s не установлен. Установите его. + Язык RVX + Язык приложения + عَرَبِيّ + Azərbaycan + Български + বাংলা + Català + Čeština + Dansk + Deutsch + Ελληνικά + English + Español + Eesti keel + فارسی + Suomalainen + Le français + ગુજરાતી + हिन्दी + Hrvatski + Magyar + Indonesia + Italiano + 日本語 + Қазақ + 한국어 + Lietùvių + Latviešu + Македонски + Монгол + Marāṭhī / मराठी + Melayu + မြန်မာ + Nederlands + ଓଡ଼ିଆ + ਪੰਜਾਬੀ / پنجابی + Polski + Português + Romanesc + Русский + Slovenský + Slovenski + Српски + Svenska + Kiswahili + தமிழ் + తెలుగు + แบบไทย + Türkçe + Українська + اردو + Tiếng Việt + 中文 Реклама Полноэкранная реклама @@ -103,13 +156,14 @@ Кнопка \"Субтитры\" в ленте скрыта. Кнопка \"Субтитры\" в ленте отображена. Скрыть рекомендуемые секции - "Скрывает следующие полки: + "Скрывает полки карусели: • Срочные новости • Продолжить просмотр • Больше каналов • Слушать ещё раз • Покупки • Смотреть ещё раз" + Полки карусели отображены. Полка эпизодов Полка эпизодов скрыта. Полка эпизодов отображена. @@ -143,18 +197,18 @@ Встроенные игры Встроенные игры скрыты. Встроенные игры отображены. - Кнопка \"Показать еще\" - Кнопка \"Показать еще\" скрыта. - Кнопка \"Показать еще\" отображена. Панель поиска в ленте Панель поиска в ленте скрыта. Панель поиска в ленте отображена. - Опросы в ленте - Опросы в ленте скрыты. - Опросы в ленте отображены. + Кнопка \"Показать еще\" + Кнопка \"Показать еще\" скрыта. + Кнопка \"Показать еще\" отображена. Строка иконок с подписками Строка иконок с подписками скрыта. Строка иконок с подписками отображена. + Опросы в ленте + Опросы в ленте скрыты. + Опросы в ленте отображены. Полки билетов Полки билетов скрыты. Полки билетов отображены. @@ -253,7 +307,7 @@ Shorts Рекомендованное видео Скрыть видео с низкими просмотрами - Скрыть видео с менее 1000 просмотров из ленты, из каналов от которых Вы отписались. + "Скрыть видео с менее 1000 просмотров из ленты, из каналов от которых Вы отписались." Скрыть рекомендованные видео "Скрывает следующие рекомендованные видео: @@ -302,17 +356,12 @@ Shorts Оффсет - Алгоритм выдачи похожих видео Основные настройки - Изменить макет - Оригинал - Телефон - Телефон (Макс. 480 dip) - Планшет - Планшет (Мин. 600 dip) Начальная страница + По умолчанию Обзор каналов Курсы / Обучение - По умолчанию Навигатор + Модная Игры История Библиотека @@ -320,8 +369,11 @@ Shorts Трансляции Фильмы Музыка + Новости Уведомления + Подкасты Поиск + Покупки Shorts Спорт Подписки @@ -353,11 +405,17 @@ Shorts Серые разделители Серые разделители скрыты. Серые разделители отображены. - Виджет коротких уведомлений - Виджет коротких уведомлений скрыт. - Виджет коротких уведомлений отображен. Скрыть диалог возрастного ограничения "Возрастные ограничения будут приниматься автоматически." + Изменить макет + Оригинал + Телефон + Телефон (Макс. 480 dip) + Планшет + Планшет (Мин. 600 dip) + Действие нажатия на точку прямого эфира + Открывается канал. + Открывается прямой эфир. Подмена версии приложения Версия приложения подменена Версия приложения не подменена @@ -411,7 +469,7 @@ Shorts Кнопка \"Скачать\" использует внутренний загрузчик. Внешний загрузчик для плейлиста, название пакета Например: NewPipe или YTDLnis, или др. (Для плейлиста). - + Переопределить кнопку YouTube Music Кнопка YouTube Music открывает RVX Music. Кнопка YouTube Music открывает встроенное приложение. @@ -531,9 +589,9 @@ Shorts Экономия трафика Экономия трафика скрыта. Экономия трафика отображена. - Автовоспроизведение - Автовоспроизведение скрыто. - Автовоспроизведение отображено. + Меню автовоспроизведения или воспроизведения + Скрыто. + Отображено. Качество видео Качество видео скрыто. Качество видео отображено. @@ -579,6 +637,10 @@ Shorts О приложении О приложении скрыто. О приложении отображено. + + Виджет коротких уведомлений + Виджет коротких уведомлений скрыт. + Виджет коротких уведомлений отображен. Панель инструментов Скрыть или изменить компоненты на панели инструментов - строка поиска, кнопки и заголовок. @@ -592,9 +654,15 @@ Shorts Логотип YouTube отображается рядом с широкой строкой поиска. Широкая строка поиска замещает логотип YouTube. Широкая строка поиска во вкладке \"Вы\" - "Эта опция отключит кнопку \"Настройки\" во вкладке \"Вы\". + "Широкая панель поиска во вкладке «Вы» включена. -Используйте такую последовательность: Вкладка \"Вы\" -> Страница канала -> Меню -> Настройки." +Настройки здесь: +Вкладка «Вы» → Просмотр канала → Меню → Настройки" + Широкая панель поиска во вкладке «Вы» отключена. + "Включая эту функцию кнопка Настройки отключится во вкладке «Вы». + +Настройки здесь: +Вкладка «Вы» → Просмотр канала → Меню → Настройки" Кнопка \"Трансляция\" Кнопка \"Трансляция\" скрыта. Кнопка \"Трансляция\" отображена. @@ -737,6 +805,39 @@ Shorts Кнопка \"Спасибо\" Кнопка \"Спасибо\" скрыта. Кнопка \"Спасибо\" отображена. + + Скрытие по индексу + Первая кнопка + Скрыта. + Отображена. + Вторая кнопка + Скрыта. + Отображена. + Третья кнопка + Скрыта. + Отображена. + Четвертая кнопка + Скрыта. + Отображена. + Пятая кнопка + Скрыта. + Отображена. + Шестая кнопка + Скрыта. + Отображена. + Седьмая кнопка + Скрыта. + Отображена. + Восьмая кнопка + Скрыта. + Отображена. + + Скрытие по индексу в прямых эфирах + О скрытии по индексу + "Скрытие кнопок по индексу до их инициализации. + +- Скрытие кнопок действий не оставляет пустого места. +- Индекс кнопок действий не всегда может быть одной и той же кнопкой." Окружающая подсветка Отключить окружающую подсветку или обойти ограничение в режиме экономии заряда батареи. @@ -932,7 +1033,7 @@ Shorts Отступ над быстрыми действиями Значение отступа поля быстрых действий от шкалы воспроизведения\nДиапазон от 0 до 32. Значение должно быть в диапазоне от 0 до 32. Сброс по умолчанию. - + Альбомный режим Портретная ориентация в полноэкранном режиме включена. Ориентация в полноэкранном режиме по настройкам устройства. @@ -940,7 +1041,8 @@ Shorts Наложение элементов управления не полноэкранное. Наложение элементов управления полноэкранное. Удерживать альбомный режим - Удерживает альбомный режим в полноэкранном режиме. + Ландшафтный режим при выкл / вкл экрана. + Портретный режим при выкл / вкл экрана. Сохранять таймаут альбомного режима Количество миллисекунд, в течение которых принудительно работает альбомный режим. @@ -1125,7 +1227,7 @@ Shorts Секция \"Расшифровка видео\" Секция \"Расшифровка видео\" скрыта. Секция \"Расшифровка видео\" отображена. - + Взаимодействие с описанием видео "Отключает следующее взаимодействие при расширении описания видео: @@ -1150,7 +1252,7 @@ Shorts Всплывающая кнопка "Всплывающие кнопки, такие как «Использовать этот звук», во вкладке Shorts скрыты." "Всплывающие кнопки, такие как «Использовать этот звук», во вкладке Shorts отображены." - + Настройки скрытия Shorts Полки Shorts "Скрывает полки Shorts. @@ -1175,13 +1277,16 @@ Shorts Shorts в истории просмотра В истории просмотра скрыты. В истории просмотра отображены. - + Состояние повтора Shorts в фоне Состояние повторов в Shorts Автопереход По умолчанию Остановить Повторять + Открывать Shorts в обычном плеере + Включено. + Отключено. Плеер Shorts Компоненты в плеере Shorts. @@ -1331,11 +1436,11 @@ Shorts Меню режима повтора отображено. Меню режима повтора скрыто. О пользовательских действиях - "Экспериментальная функция! + "Экспериментальная функция! Гарантии работы нет! Большинство ошибок не может быть исправлено из-за ограничений со стороны клиента, поэтому используйте их только для тестирования." - + Метка времени "Метка времени включена. @@ -1736,6 +1841,9 @@ Shorts Данные предоставлены SponsorBlock API. Нажмите здесь, чтобы узнать больше и скачать версии для других платформ. Разное + Обход URL переадресации + Включено. + Отключено. Отключить протокол QUIC "Отключает протокол, построенный поверх UDP, переходя на TCP." Журнал отладки @@ -1744,12 +1852,9 @@ Shorts Журнал отладки буфера Журнал отладки буфера включен. Журнал отладки буфера отключен. - Внешние ссылки - Внешние ссылки открываются в браузере. - Внешние ссылки открываются в приложении. - Перенаправление ссылок - Обход youtube.com/redirect при открытии ссылок включен. - Обход youtube.com/redirect при открытии ссылок отключен. + Открывать внешние ссылки + Открывает ссылки во внешнем браузере. + Открывает ссылки в браузере приложения. Очистить ссылки при отправке Убирает параметры отслеживания запросов из URL при отправке ссылки. Использование по умолчанию @@ -1807,6 +1912,8 @@ Shorts "Android TV (Требуется вход)" Android VR + "Android VR +(Без автора)" "iOS (Необходим PoToken)" "iOS @@ -1830,6 +1937,7 @@ Shorts Статистике для сисадминов Клиент потоковых данных отображается в Статистике для сисадминов. Клиент потоковых данных скрыт в Статистике для сисадминов. + Язык аудио потока по умолчанию VR PoToken / VisitorData PoToken diff --git a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml index 768ac6e84..7b1c29ed5 100644 --- a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml +++ b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml @@ -100,7 +100,6 @@ DeArrow hakkında daha fazla bilgi edinmek için buraya dokunun." Altyazılar butonu gizleniyor. Altyazılar butonu gizlenmiyor. Atlıkarınca rafını gizle - "Döner rafı ana sayfa ve keşfet sekmesinden gizler." Buna benzer daha çok video çipini gizle Silindirik öneri butonları ve menüleri gizleniyor Silindirik öneri butonları ve menüleri gösteriliyor @@ -134,18 +133,18 @@ DeArrow hakkında daha fazla bilgi edinmek için buraya dokunun." Oynanabilirleri gizle Oynanabilir öğeler gizli. Oynanabilir öğeler görünür. - \'Daha fazla göster\' düğmesini gizle - \"Daha fazla göster\" butonu gizleniyor. - \"Daha fazla göster\" butonu gizlenmiyor. Akışta çıkan arama çubuğunu gizle Akış arama çubuğu gizleniyor. Akış arama çubuğu gizlenmiyor. - Akışta çıkan anketleri gizle - YouTube\'un anketleri gizleniyor - YouTube\'un anketleri gösteriliyor + \'Daha fazla göster\' düğmesini gizle + \"Daha fazla göster\" butonu gizleniyor. + \"Daha fazla göster\" butonu gizlenmiyor. Abonelikler karosel rafını gizle Abonelikler karosel rafı gizleniyor. Abonelikler karosel rafı gizlenmiyor. + Akışta çıkan anketleri gizle + YouTube\'un anketleri gizleniyor + YouTube\'un anketleri gösteriliyor Biletler kısmını gizle Gizleniyor Gizlenmiyor @@ -241,7 +240,7 @@ Kısıtlamalar: Önerilen video Az izlenen videoları gizle - Abone olunmayan kanallardan yüklenen ana sayfa yayınlarında 1.000\'den az izlenen videoları gizleyin. + "Abone olunmayan kanallardan yüklenen ana sayfa yayınlarında 1.000'den az izlenen videoları gizleyin." Önerilen videoları gizle "Aşağıdaki önerilen videoları gizler: @@ -280,15 +279,9 @@ Sunucu tarafındaki değişiklikler nedeniyle oynatıcı ekranı düzeni değiş Ofset Genel - Düzeni değiştir - Orijinal - Telefon - Telefon (En fazla 480 dp) - Tablet - Tablet (En az 600 dp) Başlangıç ​​sayfasını değiştir - Kanalları Tara Varsayılan + Kanalları Tara Keşfet Gaming Geçmiş @@ -326,11 +319,14 @@ Sınırlama: Araç çubuğundaki geri butonu çalışmayabilir." Gri ayırıcıyı gizle Video ve topluluk gönderisi arasındaki gri çubuk gizleniyor. Video ve topluluk gönderisi arasındaki gri çubuk gizlenmiyor. - Yapılan eylemi bildiren çubuğu gizle - Gizleniyor - Gizlenmiyor İzleyicinin takdirine bağlı iletişim kutusunu kaldır "Görüntüleyicinin takdirine ilişkin iletişim kutusunu kaldırır. Bu yaş sınırlamasını atlamaz. Sadece otomatik olarak kabul ediyor." + Düzeni değiştir + Orijinal + Telefon + Telefon (En fazla 480 dp) + Tablet + Tablet (En az 600 dp) Uygulama Versiyonunu taklit et Sürüm taklit ediliyor Sürüm taklit edilmiyor @@ -381,7 +377,7 @@ Daha sonra kapatılırsa kullanıcı arayüzü hatalarını önlemek için uygul Yerel video indirme butonu, yerel uygulama içi indiriciyi açar. Oynatma listesi indirici paket ismi Yüklü harici indirici uygulamanızın paket adı, örneğin YTDLnis. - + YouTube Müzik düğmesini geçersiz kıl YouTube Müzik butonu RVX Müzik\'i açar. YouTube Müzik düğmesi yerel uygulamayı açar. @@ -497,15 +493,16 @@ Bu ayar etkili olmazsa Gizli moda geçmeyi deneyin." Veri tasarrufu menüsünü gizle Veri tasarrufu menüsü gizlendi. Veri tasarrufu menüsü gösteriliyor. - Otomatik oynatma butonunu gizle - Otomatik oynatma menüsü gizleniyor. - Otomatik oynatma menüsü gösteriliyor. Video kalitesi tercihleri menüsünü gizle Video kalitesi tercihleri menüsü gizlendi. Video kalitesi tercihleri menüsü gösteriliyor. Arkaplan menüsünü gizle Arkaplan menüsü gizlendi. Arkaplan menüsü gösteriliriyor. + + Yapılan eylemi bildiren çubuğu gizle + Gizleniyor + Gizlenmiyor Araç Çubuğu Araç çubuğu düğmeleri, arama çubuğu, başlık gibi araç çubuğunda bulunan bileşenleri gizleyin veya değiştirin. @@ -519,10 +516,6 @@ Bu ayar etkili olmazsa Gizli moda geçmeyi deneyin." Geniş arama çubuğu YouTube başlığını içerir. Geniş arama çubuğu YouTube başlığını içermez. \"Siz\" sekmesinde de etkinleştir - "Bu ayarın etkinleştirilmesi, Siz sekmesindeki Ayarlar butonunu kaldıracaktır. - -Bu durumda lütfen şu yolu kullanın: -Siz sekmesi→ Kanalı görüntüle→ Menü→ Ayarlar" Yayınla butonunu gizle \"Yayınla\" butonu gizli durumda. Yansıtma düğmesi görünür. @@ -648,6 +641,8 @@ Otomatik oynatma YouTube ayarlarından değiştirilebilir: Teşekkürler butonunu gizle \"Teşekkürler\" butonu gizleniyor. \"Teşekkürler\" butonu gösteriliyor. + + Ortam modu Ambiyans modu kısıtlamalarını atlayın veya ortam modunu devre dışı bırakın. @@ -827,7 +822,7 @@ Sınırlama: Tıklandığında video başlığı kayboluyor." Hızlı ayarlar çubuğunun yerden yüksekliği Zaman çubuğundan hızlı işlem kapsayıcısına kadar olan aralığı 0-32 arasında yapılandırın. Hızlı eylemler üst kenar boşluğu 0-32 arasında olmalıdır. Varsayılan değerlere sıfırlayın. - + Videoyu otomatik yatay moda geçirmeyi kapat Videoyu tam ekrana alırken otomatik olarak yatay moda geçme devre dışı Videoyu tam ekrana alırken otomatik olarak yatay moda geçme etkin @@ -835,7 +830,6 @@ Sınırlama: Tıklandığında video başlığı kayboluyor." Tam ekran videoda sıkışık oynatıcı etkin. Tam ekran videoda sıkışık oynatıcı etkin değil Manzara modunu tut - Ekranı tam ekranda kapatıp açarken yatay modu korur. Manzara modunu tutma zaman aşımı Manzara modunun zorlandığı milisaniye miktarı. @@ -987,7 +981,7 @@ Bilgi: \"Transkripti göster\" butonunu gizle \"Transkripti göster\" butonu gizleniyor \"Transkripti göster\" butonu gizlenmiyor - + Video açıklama etkileşimini devre dışı bırak "Video açıklaması genişletildiğinde aşağıdaki etkileşimleri devre dışı bırakır: @@ -1005,7 +999,7 @@ Bilgi: Shorts oynatıcı açılışta devam etmeyecek Shorts oynatıcı açılışta devam edecek Butonları gizle - + Shorts rafları Shorts raflarını gizle "Shorts raflarını gizler. @@ -1023,7 +1017,7 @@ Bilinen sorun: Arama sonuçlarındaki resmi başlıklar da gizlenebiliyor."İzleme geçmişinde gizle İzleme geçmişinde gizli. İzleme geçmişinde gizlenmiyor. - + Shorts tekrarlama durumunu değiştirme Otomatik Oynat Varsayılan @@ -1113,7 +1107,7 @@ Bilinen sorun: Arama sonuçlarındaki resmi başlıklar da gizlenebiliyor."Buton arka planı gizli. Buton arka planı gizlenmiyor. - + Zaman damgalarını etkinleştir "Zaman damgası etkin. @@ -1450,12 +1444,6 @@ Bir örnek görmek için buraya dokunun. Hata ayıklama günlüklerine arabelleği kaydet Hata ayıklama günlükleri arabellek içeriyor Hata ayıklama günlükleri arabellek içermiyor - Harici tarayıcıyı kullan - Harici tarayıcı etkin - Harici tarayıcı devre dışı - Bağlantıları direkt açmayı etkinleştir - URL yönlendirmeleri atlanıyor. - Varsayılan yönlendirme politikası takip ediliyor. Paylaşılan bağlantıları sterilize edin Bağlantıları paylaşırken, tracking query parametrelerini URL\'lerden kaldırır. Varsayılan uygulama ayarlarını aç diff --git a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml index d62072317..c60ae35df 100644 --- a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml @@ -19,6 +19,59 @@ "%1$s не встановлено. Будь ласка, завантажте %2$s з сайту." %s не встановлено. Будь ласка, встановіть його. + Мова RVX + Мова додатка + Арабська + Азербайджанська + Болгарська + Бенгальська + Каталонська + Чеська + Данська + Німецька + Грецька + Англійська + Іспанська + Естонська + Перська + Фінська + Французька + Гуджаратська + Хінді + Хорватська + Угорська + Індонезійська + Італійська + Японська + Казахська + Корейська + Литовська + Латвійська + Македонська + Монгольська + Маратхі + Малайська + Бірманська + Голландська + Одія + Пенджабі + Польська + Португальська + Румунська + Російська + Словацька + Словенська + Сербська + Шведська + Суахілі + Тамільська + Телуґу + Тайська + Турецька + Українська + Урду + В’єтнамська + Китайська Реклама Приховати повноекранну рекламу @@ -66,7 +119,9 @@ DeArrow та кадри Кадри DeArrow - "DeArrow надає краудсорсингові мініатюри для відео з YouTube. Ці мініатюри часто більш релевантні, ніж ті, що надаються YouTube. Якщо увімкнено, URL-адреси відео надсилатиметься на сервер API, а інші дані не надсилатиметься. Якщо для відео немає мініатюр DeArrow, зображається оригінал або кадр. + "DeArrow надає краудсорсингові мініатюри для відео з YouTube. Ці мініатюри часто більш релевантні, ніж ті, що надаються YouTube. + +Якщо увімкнено, URL-адреси відео надсилатиметься на сервер API, а інші дані не надсилатиметься. Якщо для відео немає мініатюр DeArrow, зображається оригінал або кадр. Натисніть тут, щоб дізнатися більше про DeArrow." Показувати тост, якщо API не доступний @@ -99,14 +154,15 @@ Приховати кнопку Субтитри Кнопку субтитрів приховано. Кнопку субтитрів показується. - Приховати карусельну полицю - "Приховати наступні полиці: + Приховати карусельні полиці + "Карусельні полиці приховано: • Важливі новини • Продовжити перегляд • Переглянути більше каналів • Прослухати знову • Покупки • Переглянути ще раз" + Карусельні полиці показується. Приховати полицю фішок Полицю фішок приховано Полицю фішок показується @@ -140,18 +196,18 @@ Приховати Ігрову кімнату Ігрову кімнату приховано. Ігрову кімнату показується. - Приховати кнопку \'Показати більше\' - Кнопку \'Показати більше\' приховано. - Кнопку \'Показати більше\' показується. Приховати панель пошуку Панель пошуку приховано. Панель пошуку показується. - Приховати опитування - Опитування приховано. - Опитування показується. + Приховати кнопку \'Показати більше\' + Кнопку \'Показати більше\' приховано. + Кнопку \'Показати більше\' показується. Приховати карусель підписок Карусель підписок приховано. Карусель підписок показується. + Приховати опитування + Опитування приховано. + Опитування показується. Приховати полицю квитків Полиці квитків приховано. Полиці квитків показується. @@ -250,11 +306,12 @@ Рекомендовані відео Приховати відео з малою кількістю переглядів - Приховати відео з менш ніж 1,000 переглядів з головної стрічки, вантажені з каналів, на які не підписані. + "Приховати відео з менш ніж 1,000 переглядів з головної стрічки, вантажені з каналів, на які не підписані. + +Цей фільтр може більше не працювати, натомість використовуйте \"Фільтр кількості переглядів\"." Приховати рекомендовані відео "Приховуються такі рекомендовані відео: -• Відео з тегом 'Тільки для спонсорів'. • Відео з фразами на кшталт 'Людей також дивилися' внизу." Фільтр за кількістю переглядів @@ -289,17 +346,12 @@ Зміщення Загальне - Змінити макет - Оригінал - Телефонний - Телефонний (Макс 480 dp) - Планшетний - Планшетний (Мін 600 dp) Змінити початкову сторінку + Стандартна Перегляд каналів Навчання - Стандартна Що нового + Мода і краса Ігри Історія Бібліотека @@ -307,8 +359,11 @@ Наживо Фільми Музика + Новини Сповіщення + Подкасти Пошук + Покупки YouTube Shorts Спорт Підписки @@ -341,12 +396,18 @@ Приховати сірий роздільник Сірі роздільники приховано. Сірі роздільники показується. - Приховати панель взаємодії - Панель взаємодії приховано. - Панель взаємодії показується. Вилучати діалогове вікно "Вилучається діалогове вікно. Це не обходить вікові обмеження, а просто приймається автоматично." + Змінити макет + Оригінал + Телефонний + Телефонний (Макс 480 dp) + Планшетний + Планшетний (Мін 600 dp) + Змінити дію натискання на кружечок наживо + При натисканні на кружечок наживо відкривається канал. + При натисканні на кружечок наживо відкривається пряма трансляція. Підробити версію програми Версію підроблено Версію не підроблено @@ -400,7 +461,7 @@ Кнопка завантаження відео відкриває вбудований завантажувач. Ім\'я пакета завантажувача списку відтворення Ім\'я пакета встановленого зовнішнього завантажувача, наприклад YTDLnis. - + Перевизначити кнопку YouTube Music Кнопка YouTube Music відкриває RVX Music. Кнопка YouTube Music відкриває стандартний додаток. @@ -519,9 +580,9 @@ Приховати меню Заощадження трафіку Меню Заощадження трафіку приховано. Меню Заощадження трафіку показується. - Приховати меню Автоматичне відтворення - Меню Автоматичне відтворення приховано. - Меню Автоматичне відтворення показується. + Приховати меню Автовідтворення чи Відтворення + Меню Автовідтворення чи Відтворення приховано. + Меню Автовідтворення чи Відтворення показується. Приховати меню Параметри якості відео Меню Параметри якості відео приховано. Меню Параметри якості відео показується. @@ -567,6 +628,26 @@ Приховати меню Про додаток Меню Про додаток приховано. Меню Про додаток показується. + + Панель взаємодії + Приховати або змінити компоненти, пов\'язані з панеллю взаємодії. + Приховати панель взаємодії + Панель взаємодії приховано. + Панель взаємодії показується. + Приховати серверну панель взаємодії + Серверну панель взаємодії приховано. + Серверну панель взаємодії показується. + Інвертувати тему панелі взаємодії + Тема панелі взаємодії інвертована. + Тема панелі взаємодії не інвертована. + Змінити фон серверної панелі взаємодії + Колір фону серверної панелі взаємодії змінений. + Колір фону серверної панелі взаємодії не змінений. + "Деякі панелі взаємодії використовують тему, задану на стороні сервера, а не тему програми. + +Змінюється колір фону цих панелей взаємодії. + +Якщо є серверні зміни, колір фону панелі взаємодії може не змінитися." Панель інструментів Приховати або змінити компоненти, розташовані на панелі інструментів, такі як кнопки панелі інструментів, панель пошуку, заголовок. @@ -577,13 +658,18 @@ Широку панель пошуку увімкнено. Широку панель пошуку вимкнено. Увімкнути широку панель пошуку з заголовком - Широка панель пошуку включає заголовок YouTube. - Широка панель пошуку не включає заголовок YouTube. + Широка панель пошуку включно зі заголовком YouTube. + Широка панель пошуку виключає та використовує місце заголовка YouTube. Увімкнути широку панель пошуку у вкладці Ви - "Увімкнення цього налаштування вимкне кнопку налаштувань у вкладці Ви. + "Широку панель пошуку увімкнено у вкладці Ви. -У цьому випадку, будь ласка, використовуйте такий шлях для доступу до налаштувань: -'Вкладка Ви → Перегляд каналу → Меню → Налаштування'" +Для доступу до налаштувань, будь ласка, використовуйте такий шлях: +Вкладка Ви → Перегляд каналу → Меню → Налаштування" + Широку панель пошуку вимкнено у вкладці Ви. + "Увімкнення цього налаштування вимкне кнопку Налаштування у вкладці Ви. + +У цьому випадку, потрібно використовувати такий шлях для доступу до налаштувань: +Вкладка Ви → Перегляд каналу → Меню → Налаштування" Приховати кнопку трансляції Кнопку трансляції приховано. Кнопку трансляції показується. @@ -625,7 +711,7 @@ "Автоперемикання списків створення Мікс увімкнено коли автовідтворення увімкнене. Автовідтворення можна змінити у налаштуваннях YouTube: -Налаштування → Автоматичне відтворення → Автовідтворення наступного відео" +Налаштування → Автоматичне відтворення / Відтворення → Автовідтворення наступного відео" Вмикання цієї функції вимкне автоматичне перемикання на YouTube Mix коли музика відтворюється якщо автовідтворення увімкнене. Вимкнути висувні панелі плеєра Автовисувні панелі плеєра вимкнено. @@ -726,6 +812,39 @@ Приховати кнопку Дякую Кнопку Дякую приховано. Кнопку Дякую показується. + + Приховати за індексом + Приховати першу кнопку + Першу кнопку приховано. + Першу кнопку показується. + Приховати другу кнопку + Другу кнопку приховано. + Другу кнопку показується. + Приховати третю кнопку + Третю кнопку приховано. + Третю кнопку показується. + Приховати четверту кнопку + Четверту кнопку приховано. + Четверту кнопку показується. + Приховати п\'яту кнопку + П\'яту кнопку приховано. + П\'яту кнопку показується. + Приховати шосту кнопку + Шосту кнопку приховано. + Шосту кнопку показується. + Приховати сьому кнопку + Сьому кнопку приховано. + Сьому кнопку показується. + Приховати восьму кнопку + Восьму кнопку приховано. + Восьму кнопку показується. + + Приховати за індексом у прямій трансляції + Про Приховати кнопку дії за індексом + "Приховати кнопки дії за індексом до ініціалізації кнопок дій. + +- Приховування кнопок дій не залишає порожнього місця. +- Індекс кнопок дій може не завжди бути потрібної кнопки." Кінематографічне освітлення Обходити обмеження кінематографічного освітлення чи вимкнути кінематографічне освітлення. @@ -918,7 +1037,7 @@ Верхній відступ швидких дій Налаштуйте відстань від панелі прогресу до контейнера швидких дій, діапазон 0-32. Верхній відступ швидких дій повинен бути в межах 0-32. - + Вимкнути ландшафтний режим Орієнтація відео портретна в повноекранному режимі. Орієнтація відео згідно налаштувань пристрою в повноекранному режимі. @@ -926,7 +1045,8 @@ Компактне керування не заповнює весь екран. Компактне керування заповнює весь екран. Зберігати ландшафтний режим - Зберігає ландшафтний режим під час вимкнення та ввімкнення екрана у повноекранному режимі. + Відео відтворюється у ландшафтному режимі після перемикання екрана. + Відео відтворюється у портретному режимі після перемикання екрана. Скільки зберігати ландшафтний режим Кількість мілісекунд примусового ландшафтного режиму. @@ -1114,7 +1234,7 @@ Приховати секції Текст відео Секції Текст відео приховано. Секції Текст відео показується. - + Вимкнути взаємодію з описом відео "Вимикається такі взаємодії під час розгортання опису відео: @@ -1139,7 +1259,7 @@ Приховати плавучу кнопку "Плавучі кнопки, такі як 'Використати цей звук' приховано у вкладці YouTube Shorts каналу." "Плавучі кнопки, такі як 'Використати цей звук' показується у вкладці YouTube Shorts каналу." - + Полиця Shorts Приховати полицю Shorts "Приховується полиці Shorts. @@ -1163,13 +1283,16 @@ Приховати в історії перегляду Приховано в історії перегляду. Показується в історії перегляду. - + Змінити стан повторення Shorts у фоні Змінити стан повторення Shorts Автовідворення Стандартно Призупинити Повторювати + Відкривати Shorts у поточному плеєрі + Shorts відкриваються у поточному плеєрі. + Shorts не відкриваються у поточному плеєрі. Плеєр Shorts Приховувати чи показувати компоненти у плеєрі Shorts. @@ -1315,10 +1438,10 @@ Меню Стан повторення показується. Меню Стан повторення приховано. Про Спеціальні дії - "Ця функція все ще експериментальна, тому немає гарантії, що буде працювати. + "Ця функція все ще експериментальна, тому немає гарантії, що буде працювати. Більшість помилок неможливо виправити через обмеження на стороні клієнта, тому використовуйте лише для тестування." - + Увімкнути мітку часу "Мітку часу увімкнено. @@ -1715,6 +1838,9 @@ Дані надаються Спонсорблок API. Натисніть тут, щоб дізнатися більше та побачити завантаження для інших платформ Різне + Обходити перенаправлення посилань + Перенаправлення посилань обходяться. + Перенаправлення посилань не обходяться. Вимкнути протокол QUIC "Вимкнути протокол CronetEngine's QUIC" Увімкнути журнал налагодження @@ -1723,18 +1849,15 @@ Увімкнути ведення журналу буфера налагодження Журнали налагодження містять буфер. Журнали налагодження не містять буфер. - Увімкнути зовнішній браузер - Зовнішній браузер увімкнено. - Зовнішній браузер вимкнено. - Увімкнути безпосереднє відкриття посилань - Обхід URL переадресацій. - Політика перенаправлення. + Відкривати посилання ззовні + Посилання відкриваються у зовнішньому браузері. + Посилання відкриваються у браузері додатка. Обробляти поширення посилань Вилучає параметри запиту відстеження з посилань під час поширення посилань. Відкрити налаштування - Щоб відкривати додаток у зовнішньому перегляді, увімкніть \"Відкривати підтримувані посилання\" та підтримувані вебадреси + Щоб відкривати додаток у зовнішньому перегляді, увімкніть Відкривати всі підтримувані посилання та підтримувані вебадреси. Відкрити налаштування GmsCore - Відкриються налаштування GmsCore. Після цього увімкніть хмарний обмін повідомленнями, щоб отримувати сповіщення. + Щоб отримувати сповіщення у RVX, увімкніть Хмарні повідомлення. GmsCore не встановлено. Встановіть. Потрібна дія "GmsCore не дозволено працювати у фоні.\n\nДотримуйтесь посібника \"Don't kill my app\" для вашого телефону і застосуйте інструкції для встановлення GmsCore.\n\nЦе необхідно для того, щоб програма працювала." @@ -1749,10 +1872,10 @@ Використовується системний діалог поширення. Використовується діалог Поділитися додатка. Увімкнути кодек OPUS - Вмикає кодек OPUS, якщо відповідь плеєра включає кодек OPUS. + Вмикає кодек OPUS, якщо відповідь плеєра включає його. Імпорт/Експорт налаштувань - Імпортувати або експортувати налаштування. + Імпортувати / експортувати налаштування. Імпорт / Експорт як файл Експортувати налаштування @@ -1762,7 +1885,7 @@ Імпорт / Експорт як текст Імпорт / Експорт як текст - Імпортувати або експортувати налаштування у вигляді тексту. + Імпортувати / експортувати налаштування у вигляді тексту. Не вдалося експортувати налаштування. Налаштування було вдало експортовано. Імпортувати @@ -1783,6 +1906,8 @@ "Android TV (Потрібна авторизація)" Android VR + "Android VR +(Без авторизації)" "iOS (Потрібен PoToken)" "iOS TV @@ -1804,6 +1929,7 @@ AVC має максимальну роздільну здатність 1080p, Показувати в Статистика для сисадмінів Клієнт, що використовується для отримання даних трансляції показується у Статистика для сисадмінів. Клієнт, що використовується для отримання даних трансляції приховано у Статистика для сисадмінів. + Мова звукової доріжки для VR PoToken / VisitorData PoToken для використання diff --git a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml index 61de113af..a7663399e 100644 --- a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml @@ -19,6 +19,59 @@ "Có vẻ như %1$s chưa được cài đặt. Vui lòng tải xuống %2$s từ trang web." Hiện %s chưa được cài đặt. Hãy cài đặt và thử lại. + Ngôn ngữ trong cài đặt RVX + Theo ứng dụng + Tiếng Ả Rập + Tiếng Azerbaijan + Tiếng Bulgaria + Tiếng Bengal + Tiếng Catalan + Tiếng Séc + Tiếng Đan Mạch + Tiếng Đức + Tiếng Hy Lạp + Tiếng Anh + Tiếng Tây Ban Nha + Tiếng Estonia + Tiếng Ba Tư + Tiếng Phần Lan + Tiếng Pháp + Tiếng Gujarati + Tiếng Hindi + Tiếng Croatia + Tiếng Hungary + Tiếng Indonesia + Tiếng Ý + Tiếng Nhật + Tiếng Kazakh + Tiếng Hàn + Người Lithuania + Tiếng Latvia + Tiếng Macedonia + Tiếng Mông Cổ + Tiếng Marathi + Tiếng Mã Lai + Tiếng Miến Điện + Tiếng Hà Lan + Tiếng Odia + Tiếng Punjab + Tiếng Ba Lan + Tiếng Bồ Đào Nha + Tiếng Romania + Tiếng Nga + Tiếng Slovak + Tiếng Slovenia + Tiếng Serbia + Tiếng Thuỵ Điển + Tiếng Swahili + Tiếng Tamil + Tiếng Telugu + Tiếng Thái + Tiếng Thổ Nhĩ Kỳ + Tiếng Ukraina + Tiếng Urdu + Tiếng Việt + Tiếng Trung Quảng cáo Ẩn quảng cáo toàn màn hình @@ -102,14 +155,14 @@ Nhấn vào đây để tìm hiểu thêm về DeArrow." Nút Phụ đề đã ẩn. Nút Phụ đề được hiển thị. Ẩn các kệ được cá nhân hoá - "Ẩn các kệ sau: - + "Các kệ đã ẩn, chẳng hạn như: • Tin nổi bật • Tiếp tục xem • Khám phá các chủ đề khác • Nghe lại • Mua sắm • Xem lại" + Các kệ được hiển thị. Ẩn kệ danh mục được đề xuất Kệ danh mục được đề xuất đã ẩn. Kệ danh mục được đề xuất được hiển thị. @@ -131,7 +184,7 @@ Nhấn vào đây để tìm hiểu thêm về DeArrow." Ẩn nút Video mới nhất Nút Video mới nhất đã ẩn. Nút Video mới nhất được hiển thị. - Ẩn Danh sách kết hợp + Ẩn danh sách kết hợp Danh sách kết hợp đã ẩn. Danh sách kết hợp được hiển thị. Ẩn kệ Phim và chương trình @@ -143,18 +196,18 @@ Nhấn vào đây để tìm hiểu thêm về DeArrow." Ẩn kệ Chơi game trên YouTube Kệ Chơi game trên YouTube đã ẩn. Kệ Chơi game trên YouTube được hiển thị. - Ẩn nút Hiện thêm - Nút Hiện thêm đã ẩn. - Nút Hiện thêm được hiển thị. Ẩn thanh tìm kiếm Thanh tìm kiếm đã ẩn. Thanh tìm kiếm được hiển thị. - Ẩn khảo sát - Khảo sát đã ẩn. - Khảo sát được hiển thị. + Ẩn nút Hiện thêm + Nút Hiện thêm đã ẩn. + Nút Hiện thêm được hiển thị. Ẩn băng chuyền Kênh đăng ký Băng chuyền Kênh đăng ký đã ẩn. Băng chuyền Kênh đăng ký được hiển thị. + Ẩn khảo sát + Khảo sát đã ẩn. + Khảo sát được hiển thị. Ẩn kệ bán vé Kệ bán vé đã ẩn. Kệ bán vé được hiển thị. @@ -253,11 +306,12 @@ Bộ lọc có phân biệt chữ hoa chữ thường, vì vậy bạn cần nh Video được đề xuất Ẩn video có lượt xem thấp - Ẩn các video có dưới 1.000 lượt xem từ các kênh chưa đăng ký khỏi thẻ Trang chủ. - Ẩn video được đề xuất - "Ẩn các video được đề xuất sau: + "Ẩn các video có dưới 1.000 lượt xem được tải lên từ các kênh bạn không đăng ký khỏi thẻ Trang chủ. + +Bộ lọc này có thể không còn hoạt động nữa, thay vào đó, hãy sử dụng tính năng \"Bộ lọc số lượt xem\"." + Ẩn video được đề xuất + "Ẩn các video đề xuất sau: -• Video có nhãn \"Chỉ dành cho hội viên\". • Video có cụm từ như \"Mọi người cũng xem video này\" ở bên dưới hình thu nhỏ." Bộ lọc số lượt xem @@ -292,17 +346,12 @@ Nếu bố cục của màn hình trình phát thay đổi do các thay đổi t Độ lệch Tổng quan - Thay đổi giao diện - Gốc - Điện thoại - Điện thoại (Tối đa 480 dp) - Máy tính bảng - Máy tính bảng (Tối thiểu 600 dp) Thay đổi trang khởi động + Mặc định Duyệt kênh Học tập - Mặc định Khám phá + Thời trang & Làm đẹp Trò chơi Video đã xem Bạn @@ -310,8 +359,11 @@ Nếu bố cục của màn hình trình phát thay đổi do các thay đổi t Trực tiếp Phim Âm nhạc + Tin tức Thông báo + Podcast Tìm kiếm + Mua sắm Shorts Thể thao Kênh đăng ký @@ -344,12 +396,18 @@ Hạn chế: Nút Quay lại trên thanh công cụ có thể không hoạt đ Ẩn các dải phân cách màu xám Các dải phân cách màu xám đã ẩn. Các dải phân cách màu xám được hiển thị. - Ẩn thanh thông báo nhanh - Thanh thông báo nhanh đã ẩn. - Thanh thông báo nhanh được hiển thị. Loại bỏ hộp thoại cảnh báo trước khi xem "Loại bỏ hộp thoại cảnh báo nội dung cần cân nhắc trước khi xem. Tuỳ chọn này chỉ tự động chấp nhận hộp thoại cảnh báo, chứ không thể bỏ qua giới hạn về độ tuổi." + Thay đổi giao diện + Gốc + Điện thoại + Điện thoại (Tối đa 480 dp) + Máy tính bảng + Máy tính bảng (Tối thiểu 600 dp) + Thay đổi thao tác nhấn vào vòng phát trực tiếp + Mở kênh khi nhấn vào vòng phát trực tiếp. + Mở video đang phát trực tiếp khi nhấn vào vòng phát trực tiếp. Giả mạo phiên bản ứng dụng Phiên bản được giả mạo Phiên bản không được giả mạo @@ -403,7 +461,7 @@ Một số mục có thể không bị ẩn." Khi thao tác với nút tải xuống video sẽ mở trình tải xuống được tích hợp sẵn của Youtube. Tên gói trình tải xuống danh sách phát Chọn hoặc nhập tên gói ứng dụng trình tải xuống đã được cài đặt trên thiết bị của bạn, chẳng hạn như YTDLnis. - + Ghi đè nút Youtube Music Nút Youtube Music sẽ mở ứng dụng RVX Music. Nút Youtube Music sẽ mở ứng dụng YT Music. @@ -522,9 +580,9 @@ Nếu cài đặt này không có hiệu lực, hãy thử chuyển sang chế Ẩn mục Tiết kiệm dữ liệu Mục Tiết kiệm dữ liệu đã ẩn. Mục Tiết kiệm dữ liệu được hiển thị. - Ẩn mục Tự động phát - Mục Tự động phát đã ẩn. - Mục Tự động phát được hiển thị. + Ẩn mục Tự động phát hoặc mục Phát + Mục Tự động phát hoặc mục Phát đã ẩn. + Mục Tự động phát hoặc mục Phát được hiển thị. Ẩn mục Lựa chọn ưu tiên về chất lượng video Mục Lựa chọn ưu tiên về chất lượng video đã ẩn. Mục Lựa chọn ưu tiên về chất lượng video được hiển thị. @@ -570,6 +628,24 @@ Nếu cài đặt này không có hiệu lực, hãy thử chuyển sang chế Ẩn mục Giới thiệu Mục Giới thiệu đã ẩn. Mục Giới thiệu được hiển thị. + + Thanh thông báo ngắn + Ẩn hoặc thay đổi các thành phần liên quan đến thanh thông báo ngắn ở bên dưới cùng của màn hình. + Ẩn thanh thông báo nhanh + Thanh thông báo nhanh đã ẩn. + Thanh thông báo nhanh được hiển thị. + Ẩn thanh thông báo ngắn từ phía máy chủ + Thanh thông báo ngắn phía máy chủ đã ẩn. + Thanh thông báo ngắn phía máy chủ được hiển thị. + Đảo ngược chủ đề + Chủ đề của thanh thông báo ngắn đã được đảo ngược. + Chủ đề của thanh thông báo ngắn như mặc định. + Thay đổi nền của thanh thông báo ngắn từ phía máy chủ + Nền của thanh thông báo ngắn phía máy chủ đã được thay đổi. + Nền của thanh thông báo ngắn phía máy chủ như mặc định. + "Một số thanh thông báo ngắn lấy chủ đề từ phía máy chủ, chứ không phải chủ đề của ứng dụng. + +Bạn có thể đổi màu nền cho chúng, nhưng nếu phía máy chủ thay đổi, màu nền có thể sẽ không cập nhật theo được." Thanh công cụ Ẩn hoặc thay đổi các thành phần trên thanh công cụ, chẳng hạn như thanh tìm kiếm, các nút trên thanh công cụ và tiêu đề YouTube. @@ -581,11 +657,16 @@ Nếu cài đặt này không có hiệu lực, hãy thử chuyển sang chế Thanh tìm kiếm mặc định đang được áp dụng. Thanh tìm kiếm rộng với tiêu đề YouTube Thanh tìm kiếm rộng được hiển thị cùng với tiêu đề YouTube. - Thanh tìm kiếm rộng sẽ làm ẩn tiêu đề YouTube. + Thanh tìm kiếm rộng đã ẩn và làm ẩn tiêu đề YouTube. Thanh tìm kiếm rộng trên thẻ Bạn - "Bật cài đặt này sẽ làm ẩn nút Cài đặt trong thẻ Bạn. + "Thanh tìm kiếm rộng được bật trong thẻ Bạn. -Trong trường hợp đó, vui lòng làm theo các bước sau để vào Cài đặt: +Để vào cài đặt, vui lòng thao tác theo đường dẫn sau: +Thẻ Bạn → Xem kênh → Trình đơn → Cài đặt" + Thanh tìm kiếm rộng đã tắt trong thẻ Bạn. + "Bật cài đặt này sẽ làm ẩn nút Cài đặt trong thẻ Bạn. + +Trong trường hợp đó, bạn cần thao tác theo đường dẫn sau để vào Cài đặt: Thẻ Bạn → Xem kênh → Trình đơn → Cài đặt" Ẩn nút Truyền Nút Truyền đã ẩn. @@ -625,10 +706,10 @@ Nhấn và giữ để mở cài đặt RVX." Độ mờ của lớp phủ trình phát phải nằm trong khoảng 0 - 100. Tắt tự động chuyển sang danh sách kết hợp Tự động chuyển sang danh sách phát kết hợp đã tắt. - "Tự động chuyển sang danh sách kết hợp đã bật khi tính năng Tự động phát đang bật. + "Tự động chuyển sang danh sách kết hợp được bật khi tính năng Tự động phát đang bật. Tính năng Tự động phát có thể thay đổi trong Cài đặt YouTube: -Cài đặt → Tự động phát → Tự động phát video tiếp theo" +Cài đặt → Tự động phát/Phát → Tự động phát video tiếp theo" Bật tính năng này sẽ tắt việc tự động chuyển sang YouTube Mix khi phát nhạc trong khi chế độ phát tự động cũng đang bật. Tắt bảng tự động bật lên khi phát Bảng tự động bật lên khi phát video (Danh sách phát, Trò chuyện trực tiếp,...) đã tắt. @@ -676,10 +757,10 @@ Lưu ý: Hành động đề xuất đã ẩn. Hành động đề xuất được hiển thị. Ẩn video đề xuất ở màn hình kết thúc - "Video đề xuất ở màn hình kết thúc đã ẩn khi tắt tính năng Tự động phát. + "Video đề xuất ở màn hình kết thúc đã ẩn khi tính năng Tự động phát đang tắt. Tính năng Tự động phát có thể thay đổi trong Cài đặt YouTube: -Cài đặt → Tự động phát → Tự động phát video tiếp theo." +Cài đặt → Tự động phát/Phát → Tự động phát video tiếp theo" Video đề xuất ở màn hình kết thúc được hiển thị. Bỏ qua thời gian đếm ngược trước khi phát Nếu tính năng Tự động phát được bật, video tiếp theo sẽ được phát ngay lập tức mà không cần đếm ngược. @@ -729,6 +810,39 @@ Cài đặt → Tự động phát → Tự động phát video tiếp theo."Ẩn nút Cảm ơn Nút Cảm ơn đã ẩn. Nút Cảm ơn được hiển thị. + + Ẩn theo chỉ mục + Ẩn nút đầu tiên + Nút đầu tiên đã ẩn. + Nút đầu tiên được hiển thị. + Ẩn nút thứ hai + Nút thứ hai đã ẩn. + Nút thứ hai được hiển thị. + Ẩn nút thứ ba + Nút thứ ba đã ẩn. + Nút thứ ba được hiển thị. + Ẩn nút thứ tư + Nút thứ tư đã ẩn. + Nút thứ tư được hiển thị. + Ẩn nút thứ năm + Nút thứ năm đã ẩn. + Nút thứ năm được hiển thị. + Ẩn nút thứ sáu + Nút thứ sáu đã ẩn. + Nút thứ sáu được hiển thị. + Ẩn nút thứ bảy + Nút thứ bảy đã ẩn. + Nút thứ bảy được hiển thị. + Ẩn nút thứ tám + Nút thứ tám đã ẩn. + Nút thứ tám được hiển thị. + + Ẩn theo chỉ mục trong phát trực tiếp + Giới thiệu về Ẩn nút thao tác theo chỉ mục + "Ẩn các nút thao tác theo chỉ mục trước khi nút được khởi tạo. + +- Khi các nút thao tác đã ẩn, không để lại khoảng trống. +- Chỉ mục của các nút thao tác có thể thay đổi, không phải lúc nào cũng là cùng một nút." Chế độ môi trường xung quanh Tắt hoặc bỏ qua các hạn chế của Chế độ môi trường xung quanh. @@ -907,11 +1021,11 @@ Hạn chế: Tiêu đề video sẽ biến mất khi nhấn vào." Nút thêm (...) đã ẩn. Nút thêm (...) được hiển thị. Ẩn nút Danh sách kết hợp - Nút Danh sách kết hợp đã ẩn. - Nút Danh sách kết hợp được hiển thị. + Nút danh sách kết hợp đã ẩn. + Nút danh sách kết hợp được hiển thị. Ẩn nút Danh sách phát - Nút Danh sách phát đã ẩn. - Nút Danh sách phát được hiển thị. + Nút danh sách phát đã ẩn. + Nút danh sách phát được hiển thị. Ẩn nút Lưu vào danh sách phát Nút Lưu vào danh sách phát đã ẩn. Nút Lưu vào danh sách phát được hiển thị. @@ -921,7 +1035,7 @@ Hạn chế: Tiêu đề video sẽ biến mất khi nhấn vào." Lề trên bảng nút thao tác nhanh Giá trị khoảng cách từ thanh tiến trình đến bảng nút thao tác nhanh trong khoảng từ 0 đến 32. Lề trên bảng nút thao tác nhanh phải nằm trong khoảng 0 - 32. - + Xem ở chế độ toàn màn hình dọc Phát video ở chế độ toàn màn hình dọc được áp dụng. Phát video ở chế độ toàn màn hình mặc định. @@ -929,7 +1043,8 @@ Hạn chế: Tiêu đề video sẽ biến mất khi nhấn vào." Lớp phủ điều khiển trình phát thu gọn đã bật. Lớp phủ điều khiển trình phát thu gọn đã tắt. Giữ chế độ toàn màn hình - Giữ chế độ toàn màn hình hoạt động trong lúc bạn tắt và đánh thức thiết bị khi đang xem chế độ toàn màn hình. + Video sẽ tiếp tục phát ở chế độ toàn màn hình ngang ngay cả khi tắt và bật màn hình. + Video sẽ tiếp tục phát ở chế độ toàn màn hình dọc ngay cả khi tắt và bật màn hình. Thời gian giữ chế độ toàn màn hình (mili giây) Số mili giây mà chế độ toàn màn hình được giữ. @@ -1117,7 +1232,7 @@ Vì vậy, bạn nên bật tính năng này khi có kết nối mạng ổn đ Ẩn phần Bản chép lời Phần Bản chép lời đã ẩn. Phần Bản chép lời được hiển thị. - + Tắt tương tác mô tả video "Tắt các tương tác sau khi mô tả video được mở rộng: @@ -1141,7 +1256,7 @@ Mở rộng mô tả video có thể không hoạt động nếu bạn nhập n Ẩn nút nổi "Các nút nổi như \"Dùng âm thanh này\" đã ẩn trong thẻ kênh Shorts." "Các nút nổi như \"Dùng âm thanh này\" được hiển thị trong thẻ kênh Shorts." - + Kệ Shorts Ẩn kệ Shorts "\nHạn chế: Tiêu đề chính thức trong kết quả tìm kiếm sẽ được ẩn." @@ -1163,13 +1278,16 @@ Cụ thể: Ẩn trong phần Nhật ký xem Ẩn trong phần Nhật ký xem. Hiển thị trong phần Nhật ký xem. - + Thay đổi trạng thái lặp lại khi phát trong nền của video ngắn Thay đổi trạng thái lặp lại của video ngắn Tự động phát Mặc định Dừng Lặp lại + Mở video ngắn trong trình phát + Đang mở video ngắn trong trình phát thay vì trình phát Shorts. + Đang mở video ngắn trong trình phát Shorts. Trình phát Shorts Ẩn hoặc hiển thị các thành phần trong trình phát Shorts. @@ -1315,10 +1433,10 @@ Nhấn và giữ nút Thêm (⋮) để hiển thị hộp thoại Tác vụ tu Mục trạng thái lặp lại được hiển thị. Mục trạng thái lặp lại đã ẩn. Giới thiệu về Tác vụ tuỳ chọn - "Hiện tính năng này vẫn đang trong giai đoạn thử nghiệm, vì vậy, không có gì đảm bảo rằng tính năng này sẽ hoạt động một cách hoàn hảo. + "Hiện tính năng này vẫn đang trong giai đoạn thử nghiệm, vì vậy, không có gì đảm bảo rằng tính năng này sẽ hoạt động một cách hoàn hảo. Hầu hết các lỗi không thể sửa được do hạn chế tới từ phía ứng dụng, cuối cùng, vui lòng chỉ sử dụng chúng cho mục đích thử nghiệm." - + Dấu thời gian "Dấu thời gian được bật. @@ -1647,8 +1765,8 @@ Nhấp vào đây để xem các bước phát hành khóa API." URL của API đã thay đổi. Sao chép Nhập/Xuất cài đặt - Cấu hình tệp JSON SponsorBlock của bạn có thể được nhập/xuất tới ReVanced Extended và các nền tảng SponsorBlock khác. - Cấu hình tệp JSON SponsorBlock của bạn có thể được nhập/xuất tới ReVanced Extended và các nền tảng SponsorBlock khác. Điều này bao gồm cả ID riêng tư của bạn. Vì vậy hãy thật cẩn thận khi chia sẻ nó. + Cấu hình tệp JSON SponsorBlock của bạn có thể được nhập/xuất tới RVX và các nền tảng SponsorBlock khác. + Cấu hình tệp JSON Chặn nhà tài trợ của bạn có thể được nhập/xuất tới RVX và các nền tảng SponsorBlock khác. Điều này bao gồm cả ID riêng tư của bạn. Vì vậy hãy thật cẩn thận khi chia sẻ nó. Nhập cài đặt thành công. Nhập cài đặt thất bại: %s. Xuất cài đặt thất bại: %s. @@ -1716,6 +1834,9 @@ Nhấp vào đây để xem các bước phát hành khóa API." Dữ liệu này được cung cấp bởi API SponsorBlock. Nhấn vào đây để tìm hiểu thêm và xem các bản tải xuống cho các nền tảng khác. Cài đặt khác + Mở liên kết trực tiếp + Đang bỏ qua chuyển hướng URL khi mở các liên kết xuất hiện trên YouTube. + Đang chuyển hướng URL khi mở các liên kết xuất hiện trên YouTube. Vô hiệu hoá giao thức QUIC "Vô hiệu hoá giao thức QUIC của CronetEngine để giảm độ trễ khi phát video." Nhật ký gỡ lỗi @@ -1724,16 +1845,13 @@ Nhấp vào đây để xem các bước phát hành khóa API." Nhật ký gỡ lỗi bộ đệm Đang ghi nhật ký gỡ lỗi bao gồm thông tin bộ đệm. Đang ghi nhật ký gỡ lỗi mà không có thông tin bộ đệm. - Mở liên kết bằng trình duyệt bên ngoài - Đang mở các liên kết xuất hiện trên YouTube bằng trình duyệt bên ngoài. - Đang mở các liên kết xuất hiện trên YouTube trong ứng dụng. - Mở liên kết trực tiếp - Đang bỏ qua chuyển hướng URL khi mở các liên kết xuất hiện trên YouTube. - Đang chuyển hướng URL khi mở các liên kết xuất hiện trên YouTube. + Mở liên kết trong trình duyệt + Đang mở các liên kết xuất hiện trên YouTube bằng trình duyệt bên ngoài. + Đang mở các liên kết xuất hiện trên YouTube bằng trình duyệt trong ứng dụng. Rút gọn liên kết chia sẻ Rút gọn liên kết chia sẻ bằng cách loại bỏ các tham số truy vết. Mở theo mặc định - Để mở liên kết YouTube trong RVX, hãy bật \'Mở các đường liên kết được hỗ trợ\' và thêm các đường liên kết được hỗ trợ. + Để mở liên kết YouTube trong RVX, hãy bật \"Mở các đường liên kết được hỗ trợ\" và thêm các đường liên kết được hỗ trợ. Cài đặt GmsCore Chuyển hướng tới cài đặt GmsCore và bật Cloud Messaging để nhận thông báo đẩy. GmsCore chưa được cài đặt. Hãy cài đặt nó đi nào. @@ -1757,7 +1875,7 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p Kích hoạt codec OPUS nếu phản hồi của trình phát bao gồm codec OPUS. Nhập/Xuất cài đặt - Nhập hoặc xuất cài đặt. + Nhập hoặc xuất tuỳ chọn cài đặt RVX của bạn. Nhập/Xuất dưới dạng tập tin Xuất cài đặt @@ -1767,7 +1885,7 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p Nhập/Xuất dưới dạng văn bản Nhập/Xuất dưới dạng văn bản - Nhập hoặc xuất toàn bộ cài đặt của bạn dưới dạng văn bản. + Nhập hoặc xuất toàn bộ tuỳ chọn cài đặt của bạn dưới dạng văn bản. Xuất cài đặt thất bại. Cài đặt đã được xuất thành công. Nhập @@ -1788,6 +1906,8 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p "Android TV (Yêu cầu Đăng nhập)" Android VR + "Android VR +(Không xác thực)" "iOS (Yêu cầu PoToken)" "iOS TV @@ -1812,6 +1932,7 @@ Hạn chế: Hiển thị trong Thống kê chi tiết Ứng dụng khách sử dụng để nạp luồng dữ liệu trực tuyến được hiển thị trong Thống kê chi tiết. Ứng dụng khách sử dụng để nạp luồng dữ liệu trực tuyến đã ẩn trong Thống kê chi tiết. + Ngôn ngữ luồng âm thanh mặc định cho ứng dụng khách VR PoToken/VisitorData PoToken diff --git a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml index d9ede254f..c9e27093d 100644 --- a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml @@ -102,13 +102,6 @@ 隐藏字幕按钮 显示字幕按钮 隐藏轮播内容 - "隐藏以下分类: -• 突发新闻 -• 继续观看 -• 探索更多频道 -• 再次收听 -• 购物 -• 重新观看" 隐藏 Chips 视频栏 Chips 视频栏已隐藏 Chips 视频栏已显示 @@ -142,18 +135,18 @@ 隐藏可播放内容 可播放内容已隐藏 可播放内容已显示 - 隐藏“显示更多”按钮 - “显示更多”按钮已隐藏 - “显示更多”按钮已显示 隐藏新闻源搜索栏 隐藏动态搜索栏 显示动态搜索栏 - 隐藏问卷调查 - 问卷调查已隐藏 - 问卷调查已显示 + 隐藏“显示更多”按钮 + “显示更多”按钮已隐藏 + “显示更多”按钮已显示 隐藏订阅轮播 订阅轮播已隐藏 订阅轮播已显示 + 隐藏问卷调查 + 问卷调查已隐藏 + 问卷调查已显示 隐藏购票栏 购票栏已隐藏 购票栏已显示 @@ -249,7 +242,7 @@ 推荐视频 隐藏低播放量的视频 - 从主页隐藏未订阅的频道上传的且播放量少于 1,000 的推荐视频 + "从主页隐藏未订阅的频道上传的且播放量少于 1,000 的推荐视频" 隐藏推荐视频 "隐藏以下推荐视频: @@ -289,15 +282,9 @@ 偏移 常规设置 - 调整布局 - 原版 - 手机 - 手机 (最大 480 dip) - 平板 - 平板 (最小 600 dip) 更改起始页 - 浏览频道 默认 + 浏览频道 探索 游戏 历史 @@ -335,12 +322,15 @@ 隐藏灰色分隔符 灰色分隔符已隐藏 灰色分隔符已显示 - 隐藏弹出消息 - 弹出消息已隐藏 - 弹出消息已显示 移除查看器的自由裁量对话框 "移除查看器的自由裁量对话框 这不会绕过年龄限制它只会自动同意" + 调整布局 + 原版 + 手机 + 手机 (最大 480 dip) + 平板 + 平板 (最小 600 dip) 伪装应用版本 客户端版本已伪装 客户端版本未伪装 @@ -392,7 +382,7 @@ 视频下载按钮打开应用内下载器 播放列表下载器名称 已安装的外部下载器应用包名,例如 YTDLnis - + 覆盖 YouTube Music 按钮 YouTube Music 按钮会打开 RVX Music YouTube Music 按钮会打开原生应用 @@ -480,9 +470,6 @@ 隐藏数据保存菜单 数据保存菜单已隐藏 数据保存菜单已显示 - 隐藏自动播放菜单 - 自动播放菜单已隐藏 - 自动播放菜单已显示 隐藏视频质量偏好菜单 视频质量偏好菜单已隐藏 视频质量首选项菜单已显示 @@ -528,6 +515,10 @@ 隐藏关于菜单 关于菜单已隐藏 关于菜单已显示 + + 隐藏弹出消息 + 弹出消息已隐藏 + 弹出消息已显示 工具栏 隐藏或更改工具栏上的组件,如工具栏按钮、搜索栏、标题 @@ -541,10 +532,6 @@ 宽搜索栏包括 YouTube 标题 宽搜索栏不包括 YouTube 标题 在你的选项卡中启用宽搜索栏 - "启用此设置将禁用你的选项卡中的设置按钮 - -在这种情况下,请使用以下路径访问设置: -你的选项卡 → 查看频道 → 菜单 → 设置" 隐藏 Cast 按钮 Cast 按钮已隐藏 Cast 按钮已显示 @@ -685,6 +672,8 @@ 隐藏感谢按钮 感谢按钮已隐藏 感谢按钮已显示 + + 氛围模式 绕过氛围模式限制或禁用氛围模式 @@ -864,7 +853,7 @@ 快速操作顶部边距 配置从进度条到快速操作容器的间距,范围在0-32之间 快速操作顶部边距必须在 0-32 之间 重置为默认值 - + 横屏模式 全屏时的横屏模式已禁用 全屏时的横屏模式已启用 @@ -872,7 +861,6 @@ 紧凑的播放器布局已启用 紧凑的播放器布局已禁用 保持横屏模式 - 在全屏状态下关闭和打开屏幕时,保持横屏模式 保持横屏模式超时 强制横屏模式的毫秒数 @@ -1035,7 +1023,7 @@ 隐藏转写文稿部分 转写文稿部分已隐藏 转写文稿部分已显示 - + 禁用视频描述交互 "展开视频描述时禁用以下交互: @@ -1056,7 +1044,7 @@ 隐蔽悬浮按钮 "‘使用此声音’等浮动按钮已在 Shorts 频道标签中隐藏" "‘使用此声音’等浮动按钮已在短视频频道标签中显示" - + Shorts 栏 隐藏 Shorts 栏 "隐藏 Shorts 栏 @@ -1080,7 +1068,7 @@ 在观看历史中隐藏 在观看历史中隐藏 在观看历史中显示 - + 更改 Shorts 重复状态 自动播放 默认 @@ -1196,7 +1184,7 @@ 按钮背景已隐藏 按钮背景已显示 - + 启用时间戳 "时间戳已启用 @@ -1577,12 +1565,6 @@ 启用 Debug 缓冲区日志记录 Debug 日志不包括缓冲区 Debug 日志不包括缓冲区 - 启用外部浏览器 - 外部浏览器已启用 - 外部浏览器已禁用 - 启用直接打开链接 - 绕过链接重定向 - 遵循默认重定向策略 清理共享链接 共享链接时,删除 URL 中的跟踪查询参数 打开默认应用设置 diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index 110dafd0c..0bc804a8c 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -19,6 +19,59 @@ "%1$s 未安裝 請從網站下載 %2$s" %s 未安裝,請先安裝 + RVX語言 + 應用語言 + 阿拉伯語 + 亞塞拜然語 + 保加利亞語 + 孟加拉語 + 加泰隆尼亞語 + 捷克語 + 丹麥語 + 德語 + 希臘語 + 英語 + 西班牙語 + 愛沙尼亞語 + 波斯語 + 芬蘭語 + 法語 + 古吉拉特語 + 印地語 + 克羅埃西亞語 + 匈牙利語 + 印尼語 + 義大利語 + 日語 + 哈薩克語 + 韓語 + 立陶宛語 + 拉脫維亞語 + 馬其頓語 + 蒙古語 + 馬拉提語 + 馬來語 + 緬甸語 + 荷蘭語 + 歐迪亞語 + 旁遮普語 + 波蘭語 + 葡萄牙語 + 羅馬尼亞語 + 俄語 + 斯洛伐克語 + 斯洛維尼亞語 + 塞爾維亞語 + 瑞典語 + 史瓦希利語 + 坦米爾語 + 泰盧固語 + 泰語 + 土耳其語 + 烏克蘭語 + 烏爾都語 + 越南語 + 中文 廣告 隱藏全螢幕廣告 @@ -102,13 +155,14 @@ 字幕按鈕已隱藏 字幕按鈕已顯示 隱藏輪播內容 - "隱藏以下分類區: -・最新消息 -・繼續觀看 -・探索更多頻道 -・再次收聽 -・購物 -・再看一次" + "隱藏以下分類區,如: +• 突發新聞 +• 繼續觀看 +• 探索更多管道 +• 再聽一遍 +• 購物 +• 再看一遍" + 分類區已顯示 隱藏剪輯 剪輯已隱藏 剪輯已顯示 @@ -142,18 +196,18 @@ 隱藏 Youtube 遊戲 Youtube 遊戲已隱藏 Youtube 遊戲已顯示 - 隱藏「顯示更多」按鈕 - 「顯示更多」按鈕已隱藏 - 「顯示更多」按鈕已顯示 隱藏動態搜尋欄 動態搜尋欄已隱藏 動態搜尋欄已顯示 - 隱藏動態問卷調查 - 動態問卷調查已隱藏 - 動態問卷調查已顯示 + 隱藏「顯示更多」按鈕 + 「顯示更多」按鈕已隱藏 + 「顯示更多」按鈕已顯示 隱藏訂閱輪播 訂閱輪播已隱藏。 訂閱輪播已顯示。 + 隱藏動態問卷調查 + 動態問卷調查已隱藏 + 動態問卷調查已顯示 隱藏購票庫 購票庫已隱藏 購票庫已顯示 @@ -249,7 +303,7 @@ 推薦影片 隱藏低觀看次數的影片 - 在首頁隱藏來自未訂閱頻道的、觀看次數少於 1,000 次的影片。 + "在首頁隱藏來自未訂閱頻道的、觀看次數少於 1,000 次的影片。" 隱藏推薦影片 "隱藏以下推薦影片: @@ -288,17 +342,12 @@ 偏移 一般設定 - 變更佈局 - 原始 - 手機 - 手機 (最大 480 dip) - 平板電腦 - 平板電腦 (最少 600 dip) 更改起始頁 + 預設 瀏覽頻道 課程/學習 - 預設 探索 + 時尚 & 美妝 遊戲 歷史 媒體庫 @@ -306,8 +355,11 @@ 直播 電影 音樂 + 新聞 通知 + 播客 搜尋 + 購物 短片 運動 訂閱 @@ -340,12 +392,18 @@ 隱藏灰色分隔線 灰色分隔線已隱藏 灰色分隔線已顯示 - 隱藏彈出訊息 - 彈出訊息已隱藏 - 彈出訊息已顯示 移除查看器的自由裁量對話框 "移除觀眾酌情觀看對話方塊。 這項選項不會繞過年齡限制,它只會自動接受。" + 變更佈局 + 原始 + 手機 + 手機 (最大 480 dip) + 平板電腦 + 平板電腦 (最少 600 dip) + เปลี่ยนการกระทำคลิกวงแหวนสด + 點擊直播按鈕 頻道將會開啟。 + 點擊直播按鈕 直播將會開啟。 偽裝應用程式版本 已偽裝版本 未偽裝版本 @@ -399,7 +457,7 @@ 原生影片下載按鈕可開啟本機應用程式內下載器。 播放清單下載器套件名稱 你安裝的外部下載器應用程式的套件名稱,例如 YTDLnis。 - + 覆蓋 YouTube音樂 按鈕 YouTube音樂 按鈕可開啟 RVX 音樂。 YouTube音樂 按鈕可開啟本機應用程式。 @@ -518,9 +576,9 @@ 隱藏資料保存選單 資料保存選單已隱藏。 資料保存選單已顯示。 - 隱藏自動播放選單 - 自動播放選單已隱藏。 - 自動播放選單已顯示。 + 隱藏自動播放或播放選單 + 自動播放或播放選單已隱藏。 + 顯示自動播放或播放選單。 隱藏影片品質選項選單 影片品質選項選單已隱藏。 影片品質選項選單已顯示。 @@ -566,6 +624,10 @@ 隱藏關於選單 關於選單已隱藏。 關於選單已顯示。 + + 隱藏彈出訊息 + 彈出訊息已隱藏 + 彈出訊息已顯示 工具欄 隱藏或變更工具欄上的元件,例如工具欄按鈕、搜尋欄、標題 @@ -579,10 +641,15 @@ 寬搜尋欄包括 YouTube 標題 寬搜尋欄不包括 YouTube 標題 在你的內容分頁中啟用寬搜尋欄 - "啟用這項設定後,將停用「你的內容」分頁中的設定按鈕 + "您標籤中啟用了寬搜尋欄。 -在這種情況下,請依序輕觸以下路徑來存取設定: -你的內容分頁 → 瀏覽頻道 → 選單 → 設定" +若要存取設置,請使用以下路徑: +您標籤 → 檢視頻道 → 選單 → 設定" + 您標籤中的寬搜尋欄已停用。 + "啟用此設定將停用您標籤中的設定按鈕。 + +在這種情況下,您可能需要使用以下路徑來存取設定: +您標籤 → 檢視頻道 → 選單 → 設定" 隱藏螢幕投放按鈕 投放按鈕已隱藏 投放按鈕已顯示 @@ -725,6 +792,39 @@ 隱藏感謝按鈕 感謝按鈕已隱藏 感謝按鈕已顯示 + + 按索引隱藏 + 隱藏第一個按鈕 + 第一個按鈕已隱藏。 + 第一個按鈕已顯示。 + 隱藏第二個按鈕 + 第二個按鈕已隱藏。 + 第二個按鈕已顯示。 + 隱藏第三個按鈕 + 第三個按鈕已隱藏。 + 第三個按鈕已顯示。 + 隱藏第四個按鈕 + 第四個按鈕已隱藏。 + 第四個按鈕已顯示。 + 隱藏第五個按鈕 + 第五個按鈕已隱藏。 + 第五個按鈕已顯示。 + 隱藏第六個按鈕 + 第六個按鈕已隱藏。 + 第六個按鈕已顯示。 + 隱藏第七個按鈕 + 第七個按鈕已隱藏。 + 第七個按鈕已顯示。 + 隱藏第八個按鈕 + 第八個按鈕已隱藏。 + 第八個按鈕已顯示。 + + 在直播串流中按索引隱藏 + 關於按索引隱藏操作按鈕 + "在初始化操作按鈕之前按下索引隱藏操作按鈕。 + +- 隱藏操作按鈕,不留任何空白。 +- 操作按鈕的索引可能不會總是相同的按鈕。" 微光模式 繞過微光模式限制或停用微光模式 @@ -917,7 +1017,7 @@ 快速操作頂部邊距 配置從進度條到快速操作容器的間距,範圍在 0 到 32 之間。 快速操作上邊距必須介於 0-32 之間。 重設為預設值。 - + 停用橫向模式 進入全螢幕時橫向模式已停用 進入全螢幕時橫向模式已啟用 @@ -925,7 +1025,8 @@ 精簡控制選單已啟用 緊湊的播放器佈局已停用 保持橫向模式 - 在全螢幕模式下關閉和開啟螢幕時保持橫向模式。 + 關閉和開啟螢幕後,影片繼續以橫向模式播放。 + 關閉和開啟螢幕後,影片會以縱向模式播放。 保持橫向模式的超時時間 已強制橫向模式的毫秒數。 @@ -1110,7 +1211,7 @@ 隱藏轉寫文稿部分 轉寫文稿部分已隱藏 轉寫文稿部分已顯示 - + 停用影片描述交互 "當影片描述展開時,停用以下互動: @@ -1134,7 +1235,7 @@ 隱藏浮動按鈕 "「使用此聲音」等浮動按鈕隱藏在 短片頻道標籤中。" "「使用此聲音」等浮動按鈕顯示在 短片頻道標籤中。" - + 短片欄 隱藏短片欄 "隱藏短片欄 @@ -1158,13 +1259,16 @@ 在觀看歷史中隱藏 在觀看歷史中隱藏 在觀看歷史中顯示 - + 變更 短影片背景重複狀態 更改短片重複狀態 自動播放 預設 暫停 重複播放 + 在一般播放器中開啟 Shorts + 在一般播放器中開啟 Shorts。 + 不要在普通播放器中開啟 Shorts。 短片播放器 隱藏或顯示短片播放器中的組件 @@ -1310,10 +1414,10 @@ 重複狀態選單已顯示。 重複狀態選單被已隱藏。 關於自訂操作 - "此功能仍處於實驗階段,因此不能保證它能完美運作。 + "此功能仍處於實驗階段,因此不能保證它能完美運作。 由於用戶端限制,大多數錯誤無法修復,因此僅將其用於測試目的。" - + 啟用時間戳 "已知問題:由於這是 Google 開發階段的功能,因此佈局可能會被破壞。" 時間戳已停用。 @@ -1713,6 +1817,9 @@ 點擊此處了解更多資訊並查看其他平台的下載 其他設定 + 繞過 URL 重新導向 + 已繞過 URL 重新導向。 + 未繞過 URL 重新導向。 停用 QUIC 協議 "停用 Cronet 引擎的 QUIC 協議" 啟用 Debug 日誌 @@ -1721,12 +1828,9 @@ 啟用 Debug 緩衝區日誌記錄 Debug 日誌不包括緩衝區 Debug 日誌不包括緩衝區 - 啟用外部瀏覽器 - 外部瀏覽器已啟用 - 外部瀏覽器已停用 - 啟用直接打開連結 - 繞過連結重定向 - 跟隨預設的重新載入行為 + 在瀏覽器中開啟連結 + 在外部瀏覽器中開啟連結。 + 在應用程式內瀏覽器中開啟連結。 清理共享連結 共享連結時,刪除 URL 中的跟蹤查詢參數 開啟預設應用程式設定 @@ -1783,6 +1887,8 @@ "Android TV (需要登入)" Android VR + "Android VR +(無授權)" "iOS (需要 PoToken)" "iOS TV @@ -1804,6 +1910,7 @@ AVC 的最大解析度為 1080p,Opus 音訊編解碼器不可用,影片播 顯示統計資料 用於取得串流資料的用戶端顯示在統計資料中。 用於獲取串流資料的用戶端隱藏在統計資料中。 + VR預設音訊串流語言 Potoken / 訪客數據 使用PoToken