Compare commits

..

9 Commits

Author SHA1 Message Date
semantic-release-bot
cba44ccfc8 chore: Release v5.39.0-dev.1 [skip ci]
# [5.39.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.2...v5.39.0-dev.1) (2025-09-17)

### Features

* **YouTube - Hide video action buttons:** Add "Hide Shop button" setting ([a84db7b](a84db7be7f))
2025-09-17 07:19:06 +00:00
LisoUseInAIKyrios
a84db7be7f feat(YouTube - Hide video action buttons): Add "Hide Shop button" setting 2025-09-17 11:14:24 +04:00
semantic-release-bot
2520129ace chore: Release v5.38.1-dev.2 [skip ci]
## [5.38.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.1...v5.38.1-dev.2) (2025-09-16)

### Bug Fixes

* **YouTube Music - Spoof video streams:** Remove iPadOS client ([7eeffd3](7eeffd3392))
2025-09-16 21:49:36 +00:00
LisoUseInAIKyrios
7eeffd3392 fix(YouTube Music - Spoof video streams): Remove iPadOS client 2025-09-17 01:44:48 +04:00
LisoUseInAIKyrios
6c3391164e chore: Remove spoof stream data migration since iPadOS can cause 1 minute playback failure for users in some regions 2025-09-16 23:44:01 +04:00
semantic-release-bot
0b8b46c73e chore: Release v5.38.1-dev.1 [skip ci]
## [5.38.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.0...v5.38.1-dev.1) (2025-09-16)

### Bug Fixes

* **YouTube - Spoof video streams:** Do not use Android Creator for livestreams ([cbe576b](cbe576bc38))
2025-09-16 19:27:03 +00:00
LisoUseInAIKyrios
cbe576bc38 fix(YouTube - Spoof video streams): Do not use Android Creator for livestreams 2025-09-16 23:24:07 +04:00
github-actions[bot]
3a29f2a805 chore: Sync translations (#5909) 2025-09-16 23:21:01 +04:00
LisoUseInAIKyrios
50069c7e05 chore: Fix merge typo 2025-09-16 17:26:48 +04:00
37 changed files with 211 additions and 155 deletions

View File

@@ -1,3 +1,24 @@
# [5.39.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.2...v5.39.0-dev.1) (2025-09-17)
### Features
* **YouTube - Hide video action buttons:** Add "Hide Shop button" setting ([a84db7b](https://github.com/ReVanced/revanced-patches/commit/a84db7be7fde2e9bb3ac41aec709a1681e845fe1))
## [5.38.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.1...v5.38.1-dev.2) (2025-09-16)
### Bug Fixes
* **YouTube Music - Spoof video streams:** Remove iPadOS client ([7eeffd3](https://github.com/ReVanced/revanced-patches/commit/7eeffd3392c57555342173103d3a417c038d0970))
## [5.38.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.0...v5.38.1-dev.1) (2025-09-16)
### Bug Fixes
* **YouTube - Spoof video streams:** Do not use Android Creator for livestreams ([cbe576b](https://github.com/ReVanced/revanced-patches/commit/cbe576bc384ef5f5ee2fa341147925ed0dff568b))
# [5.38.0](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.38.0) (2025-09-16)

View File

@@ -1,5 +1,6 @@
package app.revanced.extension.music.patches.spoof;
import static app.revanced.extension.music.settings.Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48;
import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
@@ -22,6 +23,8 @@ public class SpoofVideoStreamsPatch {
VISIONOS
);
StreamingDataRequest.setClientOrderToUse(availableClients, ANDROID_VR_1_43_32);
ClientType client = SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setPreferredClient(client);
StreamingDataRequest.setClientOrderToUse(availableClients, client);
}
}

View File

@@ -3,8 +3,12 @@ package app.revanced.extension.music.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.EnumSetting;
import app.revanced.extension.shared.spoof.ClientType;
public class Settings extends BaseSettings {
@@ -18,4 +22,8 @@ public class Settings extends BaseSettings {
// Player
public static final BooleanSetting PERMANENT_REPEAT = new BooleanSetting("revanced_music_play_permanent_repeat", FALSE, true);
// Miscellaneous
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type",
ClientType.ANDROID_VR_1_43_32, true, parent(SPOOF_VIDEO_STREAMS));
}

View File

@@ -1,6 +1,4 @@
package app.revanced.extension.youtube;
import androidx.annotation.NonNull;
package app.revanced.extension.shared;
import java.nio.charset.StandardCharsets;
@@ -39,7 +37,7 @@ public final class ByteTrieSearch extends TrieSearch<byte[]> {
return replacement;
}
public ByteTrieSearch(@NonNull byte[]... patterns) {
public ByteTrieSearch(byte[]... patterns) {
super(new ByteTrieNode(), patterns);
}
}

View File

@@ -1,6 +1,4 @@
package app.revanced.extension.youtube;
import androidx.annotation.NonNull;
package app.revanced.extension.shared;
/**
* Text pattern searching using a prefix tree (trie).
@@ -28,7 +26,7 @@ public final class StringTrieSearch extends TrieSearch<String> {
}
}
public StringTrieSearch(@NonNull String... patterns) {
public StringTrieSearch(String... patterns) {
super(new StringTrieNode(), patterns);
}
}

View File

@@ -1,6 +1,5 @@
package app.revanced.extension.youtube;
package app.revanced.extension.shared;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
@@ -8,8 +7,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* Searches for a group of different patterns using a trie (prefix tree).
/**Searches for a group of different patterns using a trie (prefix tree).
* Can significantly speed up searching for multiple patterns.
*/
public abstract class TrieSearch<T> {
@@ -136,7 +134,7 @@ public abstract class TrieSearch<T> {
* @param patternLength Length of the pattern.
* @param callback Callback, where a value of NULL indicates to always accept a pattern match.
*/
private void addPattern(@NonNull T pattern, int patternIndex, int patternLength,
private void addPattern(T pattern, int patternIndex, int patternLength,
@Nullable TriePatternMatchedCallback<T> callback) {
if (patternIndex == patternLength) { // Reached the end of the pattern.
if (endOfPatternCallback == null) {
@@ -308,13 +306,13 @@ public abstract class TrieSearch<T> {
private final List<T> patterns = new ArrayList<>();
@SafeVarargs
TrieSearch(@NonNull TrieNode<T> root, @NonNull T... patterns) {
TrieSearch(TrieNode<T> root, T... patterns) {
this.root = Objects.requireNonNull(root);
addPatterns(patterns);
}
@SafeVarargs
public final void addPatterns(@NonNull T... patterns) {
public final void addPatterns(T... patterns) {
for (T pattern : patterns) {
addPattern(pattern);
}
@@ -325,7 +323,7 @@ public abstract class TrieSearch<T> {
*
* @param pattern Pattern to add. Calling this with a zero length pattern does nothing.
*/
public void addPattern(@NonNull T pattern) {
public void addPattern(T pattern) {
addPattern(pattern, root.getTextLength(pattern), null);
}
@@ -333,31 +331,31 @@ public abstract class TrieSearch<T> {
* @param pattern Pattern to add. Calling this with a zero length pattern does nothing.
* @param callback Callback to determine if searching should halt when a match is found.
*/
public void addPattern(@NonNull T pattern, @NonNull TriePatternMatchedCallback<T> callback) {
public void addPattern(T pattern, TriePatternMatchedCallback<T> callback) {
addPattern(pattern, root.getTextLength(pattern), Objects.requireNonNull(callback));
}
void addPattern(@NonNull T pattern, int patternLength, @Nullable TriePatternMatchedCallback<T> callback) {
void addPattern(T pattern, int patternLength, @Nullable TriePatternMatchedCallback<T> callback) {
if (patternLength == 0) return; // Nothing to match
patterns.add(pattern);
root.addPattern(pattern, 0, patternLength, callback);
}
public final boolean matches(@NonNull T textToSearch) {
public final boolean matches(T textToSearch) {
return matches(textToSearch, 0);
}
public boolean matches(@NonNull T textToSearch, @NonNull Object callbackParameter) {
public boolean matches(T textToSearch, Object callbackParameter) {
return matches(textToSearch, 0, root.getTextLength(textToSearch),
Objects.requireNonNull(callbackParameter));
}
public boolean matches(@NonNull T textToSearch, int startIndex) {
public boolean matches(T textToSearch, int startIndex) {
return matches(textToSearch, startIndex, root.getTextLength(textToSearch));
}
public final boolean matches(@NonNull T textToSearch, int startIndex, int endIndex) {
public final boolean matches(T textToSearch, int startIndex, int endIndex) {
return matches(textToSearch, startIndex, endIndex, null);
}
@@ -370,11 +368,11 @@ public abstract class TrieSearch<T> {
* @param callbackParameter Optional parameter passed to the callbacks.
* @return If any pattern matched, and it's callback halted searching.
*/
public boolean matches(@NonNull T textToSearch, int startIndex, int endIndex, @Nullable Object callbackParameter) {
public boolean matches(T textToSearch, int startIndex, int endIndex, @Nullable Object callbackParameter) {
return matches(textToSearch, root.getTextLength(textToSearch), startIndex, endIndex, callbackParameter);
}
private boolean matches(@NonNull T textToSearch, int textToSearchLength, int startIndex, int endIndex,
private boolean matches(T textToSearch, int textToSearchLength, int startIndex, int endIndex,
@Nullable Object callbackParameter) {
if (endIndex > textToSearchLength) {
throw new IllegalArgumentException("endIndex: " + endIndex

View File

@@ -5,9 +5,6 @@ import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.AudioStreamLanguageOverrideAvailability;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.spoof.ClientType;
/**
* Settings shared across multiple apps.
* <p>
@@ -31,13 +28,4 @@ public class BaseSettings {
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
public static final EnumSetting<AppLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability());
public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS));
// Client type must be last spoof setting due to cyclic references.
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_61_48, true, parent(SPOOF_VIDEO_STREAMS));
static {
if (SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED) {
Logger.printInfo(() -> "Migrating from iOS Unplugged to iPadOS");
SPOOF_VIDEO_STREAMS_CLIENT_TYPE.save(ClientType.IPADOS);
}
}
}

View File

@@ -31,7 +31,6 @@ public enum ClientType {
"132.0.6808.3",
"1.61.48",
false,
false,
"Android VR 1.61"
),
/**
@@ -50,7 +49,6 @@ public enum ClientType {
Objects.requireNonNull(ANDROID_VR_1_61_48.buildId),
"107.0.5284.2",
"1.43.32",
ANDROID_VR_1_61_48.requiresAuth,
ANDROID_VR_1_61_48.useAuth,
"Android VR 1.43"
),
@@ -71,7 +69,6 @@ public enum ClientType {
"132.0.6779.0",
"23.47.101",
true,
true,
"Android Creator"
),
/**
@@ -86,7 +83,6 @@ public enum ClientType {
"0.1",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
false,
false,
"visionOS"
),
/**
@@ -111,25 +107,7 @@ public enum ClientType {
"19.22.3",
"com.google.ios.youtube/19.22.3 (iPad7,6; U; CPU iPadOS 17_7_10 like Mac OS X; " + Locale.getDefault() + ")",
false,
false,
"iPadOS"
),
/**
* Obsolete and broken client. Here only to migrate data.
*/
@Deprecated
IOS_UNPLUGGED(
33,
"IOS_UNPLUGGED",
"Apple",
"iPhone16,2",
"iOS",
"18.2.22C152",
"8.49",
"dummy user-agent",
true,
true,
"iOS TV"
);
/**
@@ -197,12 +175,6 @@ public enum ClientType {
*/
public final String clientVersion;
/**
* If this client requires authentication and does not work
* if logged out or in incognito mode.
*/
public final boolean requiresAuth;
/**
* If the client should use authentication if available.
*/
@@ -227,7 +199,6 @@ public enum ClientType {
@NonNull String buildId,
@NonNull String cronetVersion,
String clientVersion,
boolean requiresAuth,
boolean useAuth,
String friendlyName) {
this.id = id;
@@ -241,7 +212,6 @@ public enum ClientType {
this.buildId = buildId;
this.cronetVersion = cronetVersion;
this.clientVersion = clientVersion;
this.requiresAuth = requiresAuth;
this.useAuth = useAuth;
this.friendlyName = friendlyName;
@@ -267,7 +237,6 @@ public enum ClientType {
String osVersion,
String clientVersion,
String userAgent,
boolean requiresAuth,
boolean useAuth,
String friendlyName) {
this.id = id;
@@ -278,7 +247,6 @@ public enum ClientType {
this.osVersion = osVersion;
this.clientVersion = clientVersion;
this.userAgent = userAgent;
this.requiresAuth = requiresAuth;
this.useAuth = useAuth;
this.friendlyName = friendlyName;
this.packageName = null;

View File

@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Objects;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
@@ -17,14 +18,6 @@ import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
@SuppressWarnings("unused")
public class SpoofVideoStreamsPatch {
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.VISIONOS;
@Nullable
private static volatile AppLanguage languageOverride;
/**
* Domain used for internet connectivity verification.
* It has an empty response body and is only used to check for a 204 response code.
@@ -40,6 +33,13 @@ public class SpoofVideoStreamsPatch {
private static final String INTERNET_CONNECTION_CHECK_URI_STRING = "https://www.google.com/gen_204";
private static final Uri INTERNET_CONNECTION_CHECK_URI = Uri.parse(INTERNET_CONNECTION_CHECK_URI_STRING);
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
@Nullable
private static volatile AppLanguage languageOverride;
private static volatile ClientType preferredClient = ClientType.ANDROID_VR_1_61_48;
/**
* @return If this patch was included during patching.
*/
@@ -47,8 +47,9 @@ public class SpoofVideoStreamsPatch {
return false; // Modified during patching.
}
public static boolean spoofingToClientWithNoMultiAudioStreams() {
return isPatchIncluded() && BaseSettings.SPOOF_VIDEO_STREAMS.get();
@Nullable
public static AppLanguage getLanguageOverride() {
return languageOverride;
}
/**
@@ -59,9 +60,14 @@ public class SpoofVideoStreamsPatch {
languageOverride = language;
}
@Nullable
public static AppLanguage getLanguageOverride() {
return languageOverride;
public static void setPreferredClient(ClientType client) {
preferredClient = Objects.requireNonNull(client);
}
public static boolean spoofingToClientWithNoMultiAudioStreams() {
return isPatchIncluded()
&& SPOOF_STREAMING_DATA
&& preferredClient != ClientType.IPADOS;
}
/**
@@ -276,8 +282,7 @@ public class SpoofVideoStreamsPatch {
public static final class AudioStreamLanguageOverrideAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
// Since all current clients are un-authenticated, this works for all spoof clients.
return BaseSettings.SPOOF_VIDEO_STREAMS.get();
return BaseSettings.SPOOF_VIDEO_STREAMS.get() && !preferredClient.useAuth;
}
}
}

View File

@@ -42,10 +42,10 @@ final class PlayerRoutes {
JSONObject context = new JSONObject();
AppLanguage language = SpoofVideoStreamsPatch.getLanguageOverride();
if (language == null || BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ANDROID_VR_1_43_32) {
if (language == null || clientType == ANDROID_VR_1_43_32) {
// Force original audio has not overrode the language.
// Or if YT has fallen over to the very last client (VR 1.43), then always
// use the app language because forcing an audio stream of specific languages
// Or if YT has fallen over to the last unauthenticated client (VR 1.43), then
// always use the app language because forcing an audio stream of specific languages
// can sometimes fail so it's better to try and load something rather than nothing.
language = BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get();
}

View File

@@ -1,5 +1,6 @@
package app.revanced.extension.shared.spoof.requests;
import static app.revanced.extension.shared.ByteTrieSearch.convertStringsToBytes;
import static app.revanced.extension.shared.spoof.requests.PlayerRoutes.GET_STREAMING_DATA;
import androidx.annotation.NonNull;
@@ -13,12 +14,18 @@ import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import app.revanced.extension.shared.ByteTrieSearch;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
@@ -93,6 +100,16 @@ public class StreamingDataRequest {
}
});
/**
* Strings found in the response if the video is a livestream.
*/
private static final ByteTrieSearch liveStreamBufferSearch = new ByteTrieSearch(
convertStringsToBytes(
"yt_live_broadcast",
"yt_premiere_broadcast"
)
);
private static volatile ClientType lastSpoofedClientType;
public static String getLastSpoofedClientName() {
@@ -160,7 +177,7 @@ public class StreamingDataRequest {
}
}
if (!authHeadersIncludes && clientType.requiresAuth) {
if (!authHeadersIncludes && clientType.useAuth) {
Logger.printDebug(() -> "Skipping client since user is not logged in: " + clientType
+ " videoId: " + videoId);
return null;
@@ -221,9 +238,13 @@ public class StreamingDataRequest {
while ((bytesRead = inputStream.read(buffer)) >= 0) {
baos.write(buffer, 0, bytesRead);
}
lastSpoofedClientType = clientType;
if (clientType == ClientType.ANDROID_CREATOR && liveStreamBufferSearch.matches(buffer)) {
Logger.printDebug(() -> "Skipping Android Studio as video is a livestream: " + videoId);
} else {
lastSpoofedClientType = clientType;
return ByteBuffer.wrap(baos.toByteArray());
return ByteBuffer.wrap(baos.toByteArray());
}
}
}
} catch (IOException ex) {

View File

@@ -10,7 +10,7 @@ import java.util.List;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")

View File

@@ -74,6 +74,10 @@ final class ButtonsFilter extends Filter {
Settings.HIDE_ASK_BUTTON,
"yt_fill_spark"
),
new ByteArrayFilterGroup(
Settings.HIDE_SHOP_BUTTON,
"yt_outline_bag"
),
new ByteArrayFilterGroup(
Settings.HIDE_STOP_ADS_BUTTON,
"yt_outline_slash_circle_left"

View File

@@ -14,7 +14,7 @@ import java.util.regex.Pattern;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.ByteTrieSearch;
import app.revanced.extension.shared.ByteTrieSearch;
import app.revanced.extension.youtube.settings.Settings;
/**

View File

@@ -1,6 +1,6 @@
package app.revanced.extension.youtube.patches.components;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType;

View File

@@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.youtube.ByteTrieSearch;
import app.revanced.extension.shared.ByteTrieSearch;
abstract class FilterGroup<T> {
final static class FilterGroupResult {

View File

@@ -5,9 +5,9 @@ import androidx.annotation.NonNull;
import java.util.*;
import java.util.function.Consumer;
import app.revanced.extension.youtube.ByteTrieSearch;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.youtube.TrieSearch;
import app.revanced.extension.shared.ByteTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.shared.TrieSearch;
abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<T> {

View File

@@ -14,9 +14,9 @@ import java.util.concurrent.atomic.AtomicReference;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.ByteTrieSearch;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.youtube.TrieSearch;
import app.revanced.extension.shared.ByteTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.shared.TrieSearch;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.NavigationBar;
import app.revanced.extension.youtube.shared.PlayerType;

View File

@@ -10,7 +10,7 @@ import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.youtube.patches.ChangeHeaderPatch;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.NavigationBar;

View File

@@ -8,7 +8,7 @@ import java.util.List;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")

View File

@@ -12,7 +12,7 @@ import app.revanced.extension.youtube.patches.ReturnYouTubeDislikePatch;
import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.TrieSearch;
import app.revanced.extension.shared.TrieSearch;
/**
* Searches for video id's in the proto buffer of Shorts dislike.

View File

@@ -8,9 +8,9 @@ import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
import java.util.List;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.spoof.ClientType;
import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class SpoofVideoStreamsPatch {
@@ -22,14 +22,13 @@ public class SpoofVideoStreamsPatch {
List<ClientType> availableClients = List.of(
ANDROID_VR_1_61_48,
VISIONOS,
IPADOS,
// Creator must be next to last, because livestreams fetch successfully but don't playback.
ANDROID_CREATOR,
// VR 1.43 must be last as spoof streaming data handles it slightly differently.
ANDROID_VR_1_43_32
ANDROID_VR_1_43_32,
IPADOS
);
StreamingDataRequest.setClientOrderToUse(availableClients,
BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get());
ClientType client = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setPreferredClient(client);
StreamingDataRequest.setClientOrderToUse(availableClients, client);
}
}

View File

@@ -41,6 +41,7 @@ import app.revanced.extension.shared.settings.LongSetting;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
import app.revanced.extension.shared.spoof.ClientType;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
@@ -229,6 +230,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
public static final BooleanSetting HIDE_SAVE_BUTTON = new BooleanSetting("revanced_hide_save_button", FALSE);
public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
public static final BooleanSetting HIDE_SHOP_BUTTON = new BooleanSetting("revanced_hide_shop_button", FALSE);
public static final BooleanSetting HIDE_STOP_ADS_BUTTON = new BooleanSetting("revanced_hide_stop_ads_button", TRUE);
public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", TRUE);
@@ -356,6 +358,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true,
"revanced_spoof_device_dimensions_user_dialog_message");
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_61_48, true, parent(SPOOF_VIDEO_STREAMS));
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, false,
"revanced_debug_protobuffer_user_dialog_message", parent(BaseSettings.DEBUG));

View File

@@ -15,6 +15,7 @@ import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.spoof.ClientType;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings({"deprecation", "unused"})
public class SpoofStreamingDataSideEffectsPreference extends Preference {
@@ -69,7 +70,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
}
private void updateUI() {
ClientType clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
ClientType clientType = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
if (currentClientType == clientType) {
return;
}

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.38.0
version = 5.39.0-dev.1

View File

@@ -38,7 +38,7 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
)
},
executeBlock = {
addResources("shared", "misc.spoof.spoofVideoStreamsPatch")
addResources("music", "misc.fix.playback.spoofVideoStreamsPatch")
PreferenceScreen.MISC.addPreferences(
PreferenceScreenPreference(

View File

@@ -49,6 +49,7 @@ val hideButtonsPatch = resourcePatch(
SwitchPreference("revanced_hide_report_button"),
SwitchPreference("revanced_hide_save_button"),
SwitchPreference("revanced_hide_share_button"),
SwitchPreference("revanced_hide_shop_button"),
SwitchPreference("revanced_hide_stop_ads_button"),
SwitchPreference("revanced_hide_thanks_button"),
)

View File

@@ -89,10 +89,16 @@ Davam et düyməsinə toxun və optimallaşdırma dəyişikliklərin qəbul et."
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string name="revanced_spoof_video_streams_screen_title">Video yayımları saxtalaşdır</string>
<string name="revanced_spoof_video_streams_screen_summary">Oynatma problemlərin önləmək üçün qəbuledici video yayımların saxtalaşdır</string>
<string name="revanced_spoof_video_streams_screen_title">Video yayımların saxtalaşdır</string>
<string name="revanced_spoof_video_streams_screen_summary">Oynatma problemlərin önləmək üçün qəbuledici video yayımların saxtalaşdır</string>
<string name="revanced_spoof_video_streams_title">Video yayımları saxtalaşdır</string>
<string name="revanced_spoof_video_streams_summary_on">"Video yayımları saxtalaşdırılıb
Əgər YouTube Premium istifadəçisisinizsə, bu tənzimlənmə tələb olunmaya bilər"</string>
<string name="revanced_spoof_video_streams_summary_off">"Video yayımları saxtalaşmayıb
Oynatma işləməyə bilər"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Bu tənzimləməni qapatmaq oynatma problemlərinə səbəb ola bilər.</string>
<string name="revanced_spoof_video_streams_client_type_title">İlkin qəbuledici</string>
</patch>
<patch id="misc.debugging.enableDebuggingPatch">
@@ -713,6 +719,9 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı
<string name="revanced_hide_player_flyout_audio_track_summary_on">Səs axını menyusu gizlidir</string>
<string name="revanced_hide_player_flyout_audio_track_summary_off">Səs axını menyusu göstərilir</string>
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Səs trek menyusu gizlidir
Səs treki menyusunu göstərmək üçün \"Video yayımları saxtalaşdır\"ı iPadOS-a dəyiş"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"VR-da İzləni\" gizlət</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR menyusunda izləmə gizlidir</string>
@@ -1541,6 +1550,7 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_spoof_video_streams_about_android_title">Android saxtalaşdırma yan təsirləri</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Səs treki menyusu əlçatmazdır
• Sabit səs səviyyəsi yoxdur"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video 01:00-da dayana bilər və ya bəzi bölgələrdə mövcud olmaya bilər</string>
<string name="revanced_spoof_video_streams_about_experimental">• Təcrübi qəbuledici və hər vaxt işləməyi dayandıra bilər</string>
<string name="revanced_spoof_video_streams_about_no_av1">• AV1 video kodlayıcı yoxdur</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Giriş edilməyəndə və ya gizli rejimdə uşaq videoları oynadıla bilməz</string>
@@ -1549,6 +1559,7 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Qəbuledici nerd üçün Statistikada gizlidir</string>
<string name="revanced_spoof_video_streams_language_title">Səs yayım dili</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">Xüsusi səs dilini seçmək üçün \"Orijinal səs dilini zorlanı\" qapat</string>
</patch>
</app>
<app id="music">
@@ -1556,18 +1567,31 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_settings_music_screen_0_about_title">Haqqında</string>
<string name="revanced_settings_music_screen_1_ads_title">Reklamlar</string>
<string name="revanced_settings_music_screen_2_general_title">Ümumi</string>
<string name="revanced_settings_music_screen_3_player_title">Oyunçu</string>
<string name="revanced_settings_music_screen_3_player_title">Oynadıcı</string>
<string name="revanced_settings_music_screen_4_misc_title">Çoxvariantlı</string>
</patch>
<patch id="ad.video.hideVideoAdsPatch">
<string name="revanced_music_hide_video_ads_title">Video reklamlarını gizlət</string>
<string name="revanced_music_hide_video_ads_summary_on">Video reklamları gizlidir</string>
<string name="revanced_music_hide_video_ads_summary_off">Video reklamları görünür</string>
</patch>
<patch id="interaction.permanentrepeat.permanentRepeatPatch">
<string name="revanced_music_play_permanent_repeat_title">Kəsintisiz təkrarlamanı aktivləşdir</string>
<string name="revanced_music_play_permanent_repeat_summary_on">Kəsintisiz təkrarlama aktivdir</string>
<string name="revanced_music_play_permanent_repeat_summary_off">Kəsintisiz təkrarlama qapalıdır</string>
</patch>
<patch id="layout.compactheader.hideCategoryBar">
<string name="revanced_music_hide_category_bar_title">Kateqoriya cizgisin gizlət</string>
<string name="revanced_music_hide_category_bar_summary_on">Kateqoriya cizgisi gizlidir</string>
<string name="revanced_music_hide_category_bar_summary_off">Kateqoriya cizgisi görünür</string>
</patch>
<patch id="layout.premium.hideGetPremiumPatch">
<string name="revanced_music_hide_get_premium_label_title"> \'Musiqi Premiumu Əldə et\' etiketini gizlət</string>
<string name="revanced_music_hide_get_premium_label_summary_on">Etiket gizlidir</string>
<string name="revanced_music_hide_get_premium_label_summary_off">Etiket görünür</string>
</patch>
<patch id="layout.upgradebutton.hideUpgradeButtonPatch">
<string name="revanced_music_hide_upgrade_button_title">Təkmilləşdirmə düyməsini gizlət</string>
<string name="revanced_music_hide_upgrade_button_summary_on">Düymə gizlidir</string>
<string name="revanced_music_hide_upgrade_button_summary_off">Düymə görünür</string>
</patch>

View File

@@ -721,7 +721,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_player_flyout_audio_track_summary_on">Κρυμμένο</string>
<string name="revanced_hide_player_flyout_audio_track_summary_off">Εμφανίζεται</string>
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Το μενού «Κομμάτι ήχου» είναι κρυμμένο
<string name="revanced_hide_player_flyout_audio_track_not_available">"Κρυμμένο
Για να εμφανίζεται το μενού κομματιού ήχου, αλλάξτε την «Παραποίηση ροών βίντεο» σε iPadOS"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
@@ -1550,7 +1550,7 @@ Second \"item\" text"</string>
<string name="revanced_spoof_video_streams_about_android_title">Παρενέργειες παραποίησης σε Android</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Το μενού «Κομμάτι ήχου» λείπει
Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">Το βίντεο ενδέχεται να σταματήσει στο 1:00 ή ενδέχεται να μην είναι διαθέσιμο σε ορισμένες περιοχές</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">Το βίντεο ενδέχεται να σταματήσει στο 1:00 ή να μην είναι διαθέσιμο σε ορισμένες περιοχές</string>
<string name="revanced_spoof_video_streams_about_experimental">• Πειραματικός πελάτης και μπορεί να σταματήσει να λειτουργεί ανά πάσα στιγμή</string>
<string name="revanced_spoof_video_streams_about_no_av1">• Δεν υπάρχει ο κωδικοποιητής βίντεο AV1</string>
<string name="revanced_spoof_video_streams_about_kids_videos">Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεδεμένοι ή σε λειτουργία ανώνυμης περιήγησης</string>
@@ -1559,12 +1559,12 @@ Second \"item\" text"</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Το πρόγραμμα πελάτη δεν εμφανίζεται στο μενού «Στατιστικά για σπασίκλες»</string>
<string name="revanced_spoof_video_streams_language_title">Γλώσσα ροής ήχου</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">Για να επιλέξετε μια συγκεκριμένη γλώσσα ήχου, απενεργοποιήστε το \'Επιβολή αρχικής γλώσσας ήχου\'</string>
<string name="revanced_spoof_video_streams_language_not_available">Για να επιλέξετε μια συγκεκριμένη γλώσσα ήχου, απενεργοποιήστε το «Εξαναγκασμός αρχικής γλώσσας ήχου»</string>
</patch>
</app>
<app id="music">
<patch id="misc.settings.settingsPatch">
<string name="revanced_settings_music_screen_0_about_title">Ομάδα προγραμματιστών</string>
<string name="revanced_settings_music_screen_0_about_title">Σχετικά με</string>
<string name="revanced_settings_music_screen_1_ads_title">Διαφημίσεις</string>
<string name="revanced_settings_music_screen_2_general_title">Γενικά</string>
<string name="revanced_settings_music_screen_3_player_title">Οθόνη αναπαραγωγής</string>
@@ -1581,17 +1581,17 @@ Second \"item\" text"</string>
<string name="revanced_music_play_permanent_repeat_summary_off">Η μόνιμη επανάληψη είναι απενεργοποιημένη</string>
</patch>
<patch id="layout.compactheader.hideCategoryBar">
<string name="revanced_music_hide_category_bar_title">Απόκρυψη γραμμής κατηγοριών</string>
<string name="revanced_music_hide_category_bar_summary_on">Η γραμμή κατηγοριών είναι κρυμμένη</string>
<string name="revanced_music_hide_category_bar_summary_off">Η γραμμή κατηγοριών εμφανίζεται</string>
<string name="revanced_music_hide_category_bar_title">Γραμμή κατηγοριών</string>
<string name="revanced_music_hide_category_bar_summary_on">Κρυμμένη</string>
<string name="revanced_music_hide_category_bar_summary_off">Εμφανίζεται</string>
</patch>
<patch id="layout.premium.hideGetPremiumPatch">
<string name="revanced_music_hide_get_premium_label_title">Απόκρυψη ετικέτας «Απόκτηση Music Premium»</string>
<string name="revanced_music_hide_get_premium_label_summary_on">Η ετικέτα είναι κρυμμένη</string>
<string name="revanced_music_hide_get_premium_label_summary_off">Η ετικέτα εμφανίζεται</string>
<string name="revanced_music_hide_get_premium_label_title">Ετικέτα «Αποκτήστε το Music Premium»</string>
<string name="revanced_music_hide_get_premium_label_summary_on">Κρυμμένη</string>
<string name="revanced_music_hide_get_premium_label_summary_off">Εμφανίζεται</string>
</patch>
<patch id="layout.upgradebutton.hideUpgradeButtonPatch">
<string name="revanced_music_hide_upgrade_button_title">Απόκρυψη κουμπιού αναβάθμισης</string>
<string name="revanced_music_hide_upgrade_button_title">Κουμπί «Αναβάθμιση»</string>
<string name="revanced_music_hide_upgrade_button_summary_on">Κρυμμένο</string>
<string name="revanced_music_hide_upgrade_button_summary_off">Εμφανίζεται</string>
</patch>

View File

@@ -94,10 +94,10 @@ Appuyez sur le bouton Continuer et autorisez les modifications."</string>
<string name="revanced_spoof_video_streams_title">Falsifier les flux vidéo</string>
<string name="revanced_spoof_video_streams_summary_on">"Les flux vidéo sont falsifiés
Si vous avez YouTube Premium, il est possible que ce paramètre ne soit pas nécessaire"</string>
Si vous êtes abonné à YouTube Premium, ce paramètre n'est peut-être pas nécessaire"</string>
<string name="revanced_spoof_video_streams_summary_off">"Les flux vidéo ne sont pas falsifiés
La lecture est susceptible de ne pas fonctionner"</string>
Il est possible que la lecture ne fonctionne pas"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">La désactivation de ce paramètre peut entraîner des problèmes de lecture.</string>
<string name="revanced_spoof_video_streams_client_type_title">Client par défaut</string>
</patch>
@@ -1063,9 +1063,9 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d
<string name="revanced_sb_general_min_duration">Durée minimale d\'un segment</string>
<string name="revanced_sb_general_min_duration_sum">Les segments dont la durée est inférieure à cette valeur (en secondes) ne seront ni affichés ni ignorés</string>
<string name="revanced_sb_general_min_duration_invalid">Durée invalide</string>
<string name="revanced_sb_general_uuid">Votre ID privé d\'utilisateur</string>
<string name="revanced_sb_general_uuid">Votre ID d\'utilisateur privé</string>
<string name="revanced_sb_general_uuid_sum">Cet identifiant doit rester confidentiel. Cet identifiant est comme un mot de passe et ne doit être partagé avec qui que ce soit. Si quelqu\'un venait à mettre la main dessus, il pourrait usurper votre identité.</string>
<string name="revanced_sb_general_uuid_invalid">L\'ID privé d\'utilisateur doit comporter au moins 30 caractères</string>
<string name="revanced_sb_general_uuid_invalid">ID d\'utilisateur privé trop court (30+ caractères)</string>
<string name="revanced_sb_general_api_url">Modifier l\'URL de l\'API</string>
<string name="revanced_sb_general_api_url_sum">L\'adresse utilisée par SponsorBlock pour contacter son serveur</string>
<string name="revanced_sb_api_url_reset">URL de l\'API réinitialisée</string>
@@ -1074,11 +1074,11 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d
<string name="revanced_sb_settings_ie">Importer/Exporter les paramètres</string>
<string name="revanced_sb_settings_copy">Copier</string>
<string name="revanced_sb_settings_ie_sum">Votre configuration SponsorBlock au format JSON qui peut être importée/exportée vers ReVanced et les autres plateformes SponsorBlock</string>
<string name="revanced_sb_settings_ie_sum_warning">Votre configuration SponsorBlock au format JSON qui peut être importée/exportée vers ReVanced et d\'autres plateformes SponsorBlock. Votre ID privé d\'utilisateur y est présent, partagez-la avec prudence.</string>
<string name="revanced_sb_settings_ie_sum_warning">Votre configuration SponsorBlock au format JSON qui peut être importée/exportée vers ReVanced et d\'autres plateformes SponsorBlock. Votre ID d\'utilisateur privé y est présent, partagez-la avec prudence.</string>
<string name="revanced_sb_settings_import_successful">Paramètres importés avec succès</string>
<string name="revanced_sb_settings_import_failed">Échec de l\'importation : %s</string>
<string name="revanced_sb_settings_export_failed">Échec de l\'exportation : %s</string>
<string name="revanced_sb_settings_revanced_export_user_id_warning">"Vos paramètres contiennent un ID privé d'utilisateur.
<string name="revanced_sb_settings_revanced_export_user_id_warning">"Vos paramètres contiennent un ID d'utilisateur SponsorBlock privé.
Votre ID d'utilisateur est comme un mot de passe et ne doit jamais être partagé."</string>
<string name="revanced_sb_settings_revanced_export_user_id_warning_dismiss">Ne plus afficher</string>

View File

@@ -721,7 +721,7 @@ Jika mengubah setelan ini tidak berpengaruh, coba beralih ke mode Penyamaran."</
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Menu trek audio disembunyikan
Untuk menampilkan menu trek audio, ubah 'Spoof stream video' ke iPadOS"</string>
Untuk menampilkan menu trek audio, ubah 'Palsukan aliran video' ke iPadOS"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
<string name="revanced_hide_player_flyout_watch_in_vr_title">Sembunyikan Tonton di VR</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu tonton di VR disembunyikan</string>
@@ -1548,9 +1548,9 @@ Mengaktifkan ini dapat membuka kualitas video yang lebih tinggi"</string>
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string name="revanced_spoof_video_streams_about_title">Efek samping pemalsuan</string>
<string name="revanced_spoof_video_streams_about_android_title">Efek samping pemalsuan Android</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Menu trek audio tidak ada
<string name="revanced_spoof_video_streams_about_android_summary">"• Menu trek audio hilang
• Volume stabil tidak tersedia"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video mungkin berhenti pada pukul 1:00, atau mungkin tidak tersedia di beberapa wilayah</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video mungkin berhenti pada menit 1:00, atau mungkin tidak tersedia di beberapa wilayah</string>
<string name="revanced_spoof_video_streams_about_experimental">• Klien eksperimental dan dapat berhenti berfungsi kapan saja</string>
<string name="revanced_spoof_video_streams_about_no_av1">• Tidak ada codec video AV1</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Video anak-anak mungkin tidak dapat diputar saat keluar atau dalam mode penyamaran</string>

View File

@@ -1558,7 +1558,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 탭하세요"</string>
<string name="revanced_spoof_video_streams_about_android_title">Android 변경에 따른 부작용</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• 오디오 트랙 메뉴가 표시되지 않습니다
• 안정적인 볼륨을 사용할 수 없습니다"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• 동영상이 1:00에서 중지되거나 일부 지역에서 제공되지 않을 수 있습니다</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• 동영상이 1:00에 멈출 수 있으며, 일부 지역에서는 이용이 불가능할 수 있습니다</string>
<string name="revanced_spoof_video_streams_about_experimental">• 실험용 클라이언트이며 언제든지 작동이 중단될 수 있습니다</string>
<string name="revanced_spoof_video_streams_about_no_av1">• AV1 코덱이 지원되지 않습니다</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Kids 동영상은 로그인을 하지 않았거나 시크릿 모드에서는 재생되지 않을 수 있습니다</string>
@@ -1567,7 +1567,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 탭하세요"</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">동영상 스트림을 가져오는 데 사용되는 클라이언트가 전문 통계에서 표시되지 않습니다</string>
<string name="revanced_spoof_video_streams_language_title">오디오 스트림 언어</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">특정 오디오 언어를 선택하려면 \"원본 오디오 언어 강제 적용\"을 끄십시오.</string>
<string name="revanced_spoof_video_streams_language_not_available">특정 오디오 스트림 언어를 선택하려면, \'원본 오디오 스트림 언어 강제로 활성화하기\'를 끄세요</string>
</patch>
</app>
<app id="music">

View File

@@ -89,13 +89,13 @@ Dodirnite dugme „Nastavi” i dozvolite promene optimizacije."</string>
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string name="revanced_spoof_video_streams_screen_title">Lažirani video strimovi</string>
<string name="revanced_spoof_video_streams_screen_summary">Lažiranje klijenta video strimova da bi se sprečili problemi sa reprodukcijom</string>
<string name="revanced_spoof_video_streams_screen_title">Lažiranje video tokova</string>
<string name="revanced_spoof_video_streams_screen_summary">Lažirajte video tokove klijenta da biste sprečili probleme sa reprodukcijom.</string>
<string name="revanced_spoof_video_streams_screen_title">Lažirani video strimovi</string>
<string name="revanced_spoof_video_streams_screen_summary">Lažiranje video strimova klijenta da bi se sprečili problemi sa reprodukcijom</string>
<string name="revanced_spoof_video_streams_title">Lažirani video strimovi</string>
<string name="revanced_spoof_video_streams_summary_on">"Video strimovi su lažirani
Ako ste korisnik YouTube Premiuma, ovo podešavanje možda neće biti potrebno"</string>
<string name="revanced_spoof_video_streams_summary_off">"Video tokovi nisu lažirani
<string name="revanced_spoof_video_streams_summary_off">"Video strimovi nisu lažirani
Reprodukcija možda neće raditi"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Isključivanje ovog podešavanja može izazvati probleme sa reprodukcijom.</string>
@@ -721,7 +721,7 @@ Ako se promena ove opcije ne primeni, pokušajte da pređete u režim bez arhivi
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Meni „Audio snimak” je skriven
Da biste prikazali meni „Audio snimak”, promenite „Lažirani video strimovi” u iPadOS"</string>
Da biste prikazali meni „Audio snimak”, promenite opciju „Lažirani video strimovi” na iPadOS"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
<string name="revanced_hide_player_flyout_watch_in_vr_title">Sakrij dugme „Gledaj u VR”</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Dugme „Gledaj u VR” je skriveno</string>
@@ -1550,7 +1550,7 @@ Ako ovo omogućite, mogu biti otključani viši kvaliteti videa"</string>
<string name="revanced_spoof_video_streams_about_android_title">Neželjeni efekti lažiranja na Android</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Meni „Audio snimak” nedostaje
• Opcija „Ujednačena jačina zvuka” nije dostupna"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video se može zaustaviti u 1:00, ili možda neće biti dostupan u nekim regionima</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Video se može zaustaviti u 1:00 ili možda neće biti dostupan u nekim regionima</string>
<string name="revanced_spoof_video_streams_about_experimental">• Eksperimentalni klijent i može prestati da radi bilo kada</string>
<string name="revanced_spoof_video_streams_about_no_av1">• Nema video kodeka AV1</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Videi za decu se možda neće puštati kada ste odjavljeni ili u režimu bez arhiviranja</string>
@@ -1559,12 +1559,12 @@ Ako ovo omogućite, mogu biti otključani viši kvaliteti videa"</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Tip klijenta je skriven u „Statistici za znalce”</string>
<string name="revanced_spoof_video_streams_language_title">Jezik audio strima</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">Da biste odabrali određeni audio jezik, isključite \'Prisiljavanje originalnog audio jezika\'</string>
<string name="revanced_spoof_video_streams_language_not_available">Da biste izabrali određeni jezik zvuka, isključite opciju „Prisili originalni jezik zvuka”</string>
</patch>
</app>
<app id="music">
<patch id="misc.settings.settingsPatch">
<string name="revanced_settings_music_screen_0_about_title">O</string>
<string name="revanced_settings_music_screen_0_about_title">O programu</string>
<string name="revanced_settings_music_screen_1_ads_title">Oglasi</string>
<string name="revanced_settings_music_screen_2_general_title">Opšte</string>
<string name="revanced_settings_music_screen_3_player_title">Plejer</string>
@@ -1586,7 +1586,7 @@ Ako ovo omogućite, mogu biti otključani viši kvaliteti videa"</string>
<string name="revanced_music_hide_category_bar_summary_off">Traka kategorija je prikazana</string>
</patch>
<patch id="layout.premium.hideGetPremiumPatch">
<string name="revanced_music_hide_get_premium_label_title">Sakrij oznaku „Preuzmi Music Premium”</string>
<string name="revanced_music_hide_get_premium_label_title">Sakrij oznaku „Nabavite Music Premium”</string>
<string name="revanced_music_hide_get_premium_label_summary_on">Oznaka je skrivena</string>
<string name="revanced_music_hide_get_premium_label_summary_off">Oznaka je prikazana</string>
</patch>

View File

@@ -89,13 +89,13 @@ Second \"item\" text"</string>
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string name="revanced_spoof_video_streams_screen_title">Лажирани видео стримови</string>
<string name="revanced_spoof_video_streams_screen_summary">Лажирање клијента видео стримова да би се спречили проблеми са репродукцијом</string>
<string name="revanced_spoof_video_streams_screen_title">Фалсификујте видео стримове</string>
<string name="revanced_spoof_video_streams_screen_summary">Фалсификујте клијентске видео стримове да бисте спречили проблеме са репродукцијом</string>
<string name="revanced_spoof_video_streams_screen_title">Лажирани видео стримови</string>
<string name="revanced_spoof_video_streams_screen_summary">Лажирање видео стримова клијента да би се спречили проблеми са репродукцијом</string>
<string name="revanced_spoof_video_streams_title">Лажирани видео стримови</string>
<string name="revanced_spoof_video_streams_summary_on">"Видео стримови су лажирани
Ако сте корисник YouTube Premium-а, ово подешавање можда неће бити потребно"</string>
<string name="revanced_spoof_video_streams_summary_off">"Видео стримови нису фалсификовани
<string name="revanced_spoof_video_streams_summary_off">"Видео стримови нису лажирани
Репродукција можда неће радити"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Искључивање овог подешавања може изазвати проблеме са репродукцијом.</string>
@@ -721,7 +721,7 @@ Second \"item\" text"</string>
<!-- 'Spoof video streams' should be the same translation used for 'revanced_spoof_video_streams_screen_title'. -->
<string name="revanced_hide_player_flyout_audio_track_not_available">"Мени „Аудио снимак” је скривен
Да бисте приказали мени „Аудио снимак”, промените „Лажирани видео стримови” на iPadOS"</string>
Да бисте приказали мени „Аудио снимак”, промените опцију „Лажирани видео стримови” на iPadOS"</string>
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
<string name="revanced_hide_player_flyout_watch_in_vr_title">Сакриј дугме „Гледај у ВР”</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Дугме „Гледај у ВР” је скривено</string>
@@ -1553,7 +1553,7 @@ Second \"item\" text"</string>
<string name="revanced_spoof_video_streams_about_android_title">Нежељени ефекти лажирања на Android</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• Мени „Аудио снимак” недостаје
• Опција „Уједначена јачина звука” није доступна"</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Видео се може зауставити на 1:00, или можда неће бити доступан у неким регионима</string>
<string name="revanced_spoof_video_streams_about_ipados_summary">• Видео се може зауставити на 1:00 или можда неће бити доступан у неким регионима</string>
<string name="revanced_spoof_video_streams_about_experimental">• Експериментални клијент и може престати да ради било када</string>
<string name="revanced_spoof_video_streams_about_no_av1">• Нема видео кодека AV1</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• Видеи за децу се можда неће пуштати када сте одјављени или у режиму без архивирања</string>
@@ -1562,7 +1562,7 @@ Second \"item\" text"</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Тип клијента је скривен у „Статистици за зналце”</string>
<string name="revanced_spoof_video_streams_language_title">Језик аудио стрима</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">Да бисте изабрали одређени аудио језик, искључите „Принудно коришћење оригиналног аудио језика“</string>
<string name="revanced_spoof_video_streams_language_not_available">Да бисте изабрали одређени језик звука, искључите опцију „Присили оригинални језик звука”</string>
</patch>
</app>
<app id="music">
@@ -1589,7 +1589,7 @@ Second \"item\" text"</string>
<string name="revanced_music_hide_category_bar_summary_off">Трака категорија је приказана</string>
</patch>
<patch id="layout.premium.hideGetPremiumPatch">
<string name="revanced_music_hide_get_premium_label_title">Сакриј ознаку „Преузми Music Premium”</string>
<string name="revanced_music_hide_get_premium_label_title">Сакриј ознаку „Набавите Music Premium”</string>
<string name="revanced_music_hide_get_premium_label_summary_on">Ознака је скривена</string>
<string name="revanced_music_hide_get_premium_label_summary_off">Ознака је приказана</string>
</patch>

View File

@@ -1559,7 +1559,7 @@ Second \"item\" text"</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Тип клієнта приховано у вікні \"Статистика для сисадмінів\"</string>
<string name="revanced_spoof_video_streams_language_title">Мова звукової доріжки</string>
<!-- 'Force original audio language' should use the same text as revanced_force_original_audio_title -->
<string name="revanced_spoof_video_streams_language_not_available">Щоб вибрати певну аудіомову, вимкніть \"Примусово використовувати оригінальну аудіомову\"</string>
<string name="revanced_spoof_video_streams_language_not_available">Щоб вибрати певну звукову доріжку, вимкніть \"Примусово оригінальна мова звукової доріжки\"</string>
</patch>
</app>
<app id="music">

View File

@@ -121,6 +121,20 @@
<item>ZH</item>
</string-array>
</patch>
</app>
<app id="music">
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string-array name="revanced_spoof_video_streams_client_type_entries">
<item>Android VR</item>
<item>visionOS</item>
</string-array>
<string-array name="revanced_spoof_video_streams_client_type_entry_values">
<item>ANDROID_VR_1_43_32</item>
<item>VISIONOS</item>
</string-array>
</patch>
</app>
<app id="youtube">
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string-array name="revanced_spoof_video_streams_client_type_entries">
<item>Android VR</item>
@@ -133,8 +147,6 @@
<item>IPADOS</item>
</string-array>
</patch>
</app>
<app id="youtube">
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
<string-array name="revanced_swipe_overlay_style_entries">
<item>@string/revanced_swipe_overlay_style_entry_1</item>

View File

@@ -684,6 +684,10 @@ Adjust volume by swiping vertically on the right side of the screen"</string>
<string name="revanced_hide_clip_button_title">Hide Clip</string>
<string name="revanced_hide_clip_button_summary_on">Clip button is hidden</string>
<string name="revanced_hide_clip_button_summary_off">Clip button is shown</string>
<!-- 'Shop' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_shop_button_title">Hide Shop</string>
<string name="revanced_hide_shop_button_summary_on">Shop button is hidden</string>
<string name="revanced_hide_shop_button_summary_off">Shop button is shown</string>
<!-- 'Save' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_save_button_title">Hide Save</string>
<string name="revanced_hide_save_button_summary_on">Save button is hidden</string>