Compare commits

...

15 Commits

Author SHA1 Message Date
semantic-release-bot
4b2b5e3029 chore: Release v5.33.0-dev.11 [skip ci]
# [5.33.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.10...v5.33.0-dev.11) (2025-08-04)

### Bug Fixes

* **YouTube - Video quality:** Fix 144p default not always used ([9afa7d2](9afa7d2ac6))
2025-08-04 19:03:03 +00:00
LisoUseInAIKyrios
9afa7d2ac6 fix(YouTube - Video quality): Fix 144p default not always used 2025-08-04 15:00:14 -04:00
semantic-release-bot
1a8146dbc8 chore: Release v5.33.0-dev.10 [skip ci]
# [5.33.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.9...v5.33.0-dev.10) (2025-08-04)

### Bug Fixes

* **YouTube - Video quality:** Fix wrong qualities sometimes shown in player button dialog ([178eed7](178eed7fcd))
2025-08-04 17:23:50 +00:00
LisoUseInAIKyrios
178eed7fcd fix(YouTube - Video quality): Fix wrong qualities sometimes shown in player button dialog 2025-08-04 13:21:02 -04:00
semantic-release-bot
621292644c chore: Release v5.33.0-dev.9 [skip ci]
# [5.33.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.8...v5.33.0-dev.9) (2025-08-04)

### Bug Fixes

* **YouTube - Force original audio:** Disable a/b feature flag that forces localized audio ([#5582](https://github.com/ReVanced/revanced-patches/issues/5582)) ([1dd01cf](1dd01cf54a))
2025-08-04 01:27:12 +00:00
LisoUseInAIKyrios
1dd01cf54a fix(YouTube - Force original audio): Disable a/b feature flag that forces localized audio (#5582) 2025-08-03 21:23:27 -04:00
semantic-release-bot
8c31374c53 chore: Release v5.33.0-dev.8 [skip ci]
# [5.33.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.7...v5.33.0-dev.8) (2025-08-03)

### Bug Fixes

* **NFC Tools:** Remove broken patch that is no longer supported ([#5584](https://github.com/ReVanced/revanced-patches/issues/5584)) ([2e177a8](2e177a8839))
2025-08-03 23:44:42 +00:00
LisoUseInAIKyrios
2e177a8839 fix(NFC Tools): Remove broken patch that is no longer supported (#5584) 2025-08-03 19:41:54 -04:00
github-actions[bot]
cfffd422f8 chore: Sync translations (#5586) 2025-08-03 19:41:07 -04:00
github-actions[bot]
37aab8382e chore: Sync translations (#5585) 2025-08-03 19:38:17 -04:00
semantic-release-bot
f4950ec2ea chore: Release v5.33.0-dev.7 [skip ci]
# [5.33.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.6...v5.33.0-dev.7) (2025-08-03)

### Features

* **YouTube:** Add player button to change video quality ([#5435](https://github.com/ReVanced/revanced-patches/issues/5435)) ([7bdc328](7bdc32867a))
2025-08-03 15:26:39 +00:00
MarcaD
7bdc32867a feat(YouTube): Add player button to change video quality (#5435)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-08-03 11:23:46 -04:00
semantic-release-bot
6e60ac6963 chore: Release v5.33.0-dev.6 [skip ci]
# [5.33.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.5...v5.33.0-dev.6) (2025-07-31)

### Bug Fixes

* **YouTube - Video quality:** Use 1080p enhanced bitrate for Premium users ([#5565](https://github.com/ReVanced/revanced-patches/issues/5565)) ([1adbd56](1adbd563b2))
2025-07-31 18:30:03 +00:00
LisoUseInAIKyrios
1adbd563b2 fix(YouTube - Video quality): Use 1080p enhanced bitrate for Premium users (#5565) 2025-07-31 14:27:17 -04:00
github-actions[bot]
9ccf13b680 chore: Sync translations (#5567) 2025-07-31 14:27:05 -04:00
115 changed files with 1713 additions and 402 deletions

View File

@@ -1,3 +1,45 @@
# [5.33.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.10...v5.33.0-dev.11) (2025-08-04)
### Bug Fixes
* **YouTube - Video quality:** Fix 144p default not always used ([2f7483a](https://github.com/ReVanced/revanced-patches/commit/2f7483a2d789c28a243b58bb7a252c0d590858ee))
# [5.33.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.9...v5.33.0-dev.10) (2025-08-04)
### Bug Fixes
* **YouTube - Video quality:** Fix wrong qualities sometimes shown in player button dialog ([7378ae3](https://github.com/ReVanced/revanced-patches/commit/7378ae3c5fc88f91bf5cd6db47c6cd170a8c5a4f))
# [5.33.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.8...v5.33.0-dev.9) (2025-08-04)
### Bug Fixes
* **YouTube - Force original audio:** Disable a/b feature flag that forces localized audio ([#5582](https://github.com/ReVanced/revanced-patches/issues/5582)) ([9fe13ee](https://github.com/ReVanced/revanced-patches/commit/9fe13ee1af104c009efd19b826adef375e48e191))
# [5.33.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.7...v5.33.0-dev.8) (2025-08-03)
### Bug Fixes
* **NFC Tools:** Remove broken patch that is no longer supported ([#5584](https://github.com/ReVanced/revanced-patches/issues/5584)) ([cd3a6be](https://github.com/ReVanced/revanced-patches/commit/cd3a6be75c6bd3cc33c0b17a044bd6147f27b5ce))
# [5.33.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.6...v5.33.0-dev.7) (2025-08-03)
### Features
* **YouTube:** Add player button to change video quality ([#5435](https://github.com/ReVanced/revanced-patches/issues/5435)) ([d5f51bf](https://github.com/ReVanced/revanced-patches/commit/d5f51bf400dd22626ff65d7563b6fde70d53fb25))
# [5.33.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.5...v5.33.0-dev.6) (2025-07-31)
### Bug Fixes
* **YouTube - Video quality:** Use 1080p enhanced bitrate for Premium users ([#5565](https://github.com/ReVanced/revanced-patches/issues/5565)) ([bd3ace0](https://github.com/ReVanced/revanced-patches/commit/bd3ace0bd04ccd0369adb49d63aa0cf986402346))
# [5.33.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.33.0-dev.4...v5.33.0-dev.5) (2025-07-31)

View File

@@ -1460,6 +1460,16 @@ public class Utils {
return (int) (metrics.widthPixels * (percentage / 100.0f));
}
/**
* Uses {@link #adjustColorBrightness(int, float)} depending if light or dark mode is active.
*/
@ColorInt
public static int adjustColorBrightness(@ColorInt int baseColor, float lightThemeFactor, float darkThemeFactor) {
return isDarkModeEnabled()
? adjustColorBrightness(baseColor, darkThemeFactor)
: adjustColorBrightness(baseColor, lightThemeFactor);
}
/**
* Adjusts the brightness of a color by lightening or darkening it based on the given factor.
* <p>

View File

@@ -24,6 +24,16 @@ public class ForceOriginalAudioPatch {
}
}
/**
* Injection point.
*/
public static boolean ignoreDefaultAudioStream(boolean original) {
if (Settings.FORCE_ORIGINAL_AUDIO.get()) {
return false;
}
return original;
}
/**
* Injection point.
*/
@@ -50,7 +60,6 @@ public class ForceOriginalAudioPatch {
return isOriginal;
} catch (Exception ex) {
Logger.printException(() -> "isDefaultAudioStream failure", ex);
return isDefault;
}
}

View File

@@ -18,7 +18,7 @@ import app.revanced.extension.youtube.settings.Settings;
public final class AdvancedVideoQualityMenuPatch {
/**
* Injection point.
* Injection point. Regular videos.
*/
public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
@@ -61,22 +61,12 @@ public final class AdvancedVideoQualityMenuPatch {
});
}
/**
* Injection point.
*
* Used to force the creation of the advanced menu item for the Shorts quality flyout.
*/
public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) {
return Settings.ADVANCED_VIDEO_QUALITY_MENU.get() || original;
}
/**
* Injection point.
*
* Shorts video quality flyout.
*/
public static void showAdvancedVideoQualityMenu(ListView listView) {
public static void addVideoQualityListMenuListener(ListView listView) {
if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@@ -91,7 +81,6 @@ public final class AdvancedVideoQualityMenuPatch {
listView.setSoundEffectsEnabled(false);
final var qualityItemMenuPosition = 4;
listView.performItemClick(null, qualityItemMenuPosition, 0);
} catch (Exception ex) {
Logger.printException(() -> "showAdvancedVideoQualityMenu failure", ex);
}
@@ -102,4 +91,13 @@ public final class AdvancedVideoQualityMenuPatch {
}
});
}
/**
* Injection point.
*
* Used to force the creation of the advanced menu item for the Shorts quality flyout.
*/
public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) {
return Settings.ADVANCED_VIDEO_QUALITY_MENU.get() || original;
}
}

View File

@@ -5,10 +5,9 @@ import static app.revanced.extension.shared.Utils.NetworkType;
import androidx.annotation.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import com.google.android.libraries.youtube.innertube.model.media.VideoQuality;
import java.util.Arrays;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
@@ -17,10 +16,29 @@ import app.revanced.extension.shared.settings.IntegerSetting;
import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.ShortsPlayerState;
import app.revanced.extension.youtube.videoplayer.VideoQualityDialogButton;
@SuppressWarnings("unused")
public class RememberVideoQualityPatch {
private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
/**
* Interface to use obfuscated methods.
*/
public interface VideoQualityMenuInterface {
void patch_setQuality(VideoQuality quality);
}
/**
* Video resolution of the automatic quality option..
*/
public static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
/**
* All quality names are the same for all languages.
* VideoQuality also has a resolution enum that can be used if needed.
*/
public static final String VIDEO_QUALITY_1080P_PREMIUM_NAME = "1080p Premium";
private static final IntegerSetting videoQualityWifi = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
private static final IntegerSetting videoQualityMobile = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
private static final IntegerSetting shortsQualityWifi = Settings.SHORTS_QUALITY_DEFAULT_WIFI;
@@ -29,46 +47,83 @@ public class RememberVideoQualityPatch {
private static boolean qualityNeedsUpdating;
/**
* If the user selected a new quality from the flyout menu,
* and {@link Settings#REMEMBER_VIDEO_QUALITY_LAST_SELECTED} is enabled.
*/
private static boolean userChangedDefaultQuality;
/**
* Index of the video quality chosen by the user from the flyout menu.
*/
private static int userSelectedQualityIndex;
/**
* The available qualities of the current video in human readable form: [1080, 720, 480]
* The available qualities of the current video.
*/
@Nullable
private static List<Integer> videoQualities;
private static VideoQuality[] currentQualities;
private static boolean shouldRememberVideoQuality() {
BooleanSetting preference = ShortsPlayerState.isOpen() ?
Settings.REMEMBER_SHORTS_QUALITY_LAST_SELECTED
/**
* The current quality of the video playing.
* This is always the actual quality even if Automatic quality is active.
*/
@Nullable
private static VideoQuality currentQuality;
/**
* The current VideoQualityMenuInterface, set during setVideoQuality.
*/
@Nullable
private static VideoQualityMenuInterface currentMenuInterface;
@Nullable
public static VideoQuality[] getCurrentQualities() {
return currentQualities;
}
@Nullable
public static VideoQuality getCurrentQuality() {
return currentQuality;
}
@Nullable
public static VideoQualityMenuInterface getCurrentMenuInterface() {
return currentMenuInterface;
}
public static boolean shouldRememberVideoQuality() {
BooleanSetting preference = ShortsPlayerState.isOpen()
? Settings.REMEMBER_SHORTS_QUALITY_LAST_SELECTED
: Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED;
return preference.get();
}
private static void changeDefaultQuality(int defaultQuality) {
public static int getDefaultQualityResolution() {
final boolean isShorts = ShortsPlayerState.isOpen();
IntegerSetting preference = Utils.getNetworkType() == NetworkType.MOBILE
? (isShorts ? shortsQualityMobile : videoQualityMobile)
: (isShorts ? shortsQualityWifi : videoQualityWifi);
return preference.get();
}
public static void saveDefaultQuality(int qualityResolution) {
final boolean shortPlayerOpen = ShortsPlayerState.isOpen();
String networkTypeMessage;
boolean useShortsPreference = ShortsPlayerState.isOpen();
IntegerSetting qualitySetting;
if (Utils.getNetworkType() == NetworkType.MOBILE) {
if (useShortsPreference) shortsQualityMobile.save(defaultQuality);
else videoQualityMobile.save(defaultQuality);
networkTypeMessage = str("revanced_remember_video_quality_mobile");
qualitySetting = shortPlayerOpen ? shortsQualityMobile : videoQualityMobile;
} else {
if (useShortsPreference) shortsQualityWifi.save(defaultQuality);
else videoQualityWifi.save(defaultQuality);
networkTypeMessage = str("revanced_remember_video_quality_wifi");
qualitySetting = shortPlayerOpen ? shortsQualityWifi : videoQualityWifi;
}
if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get())
if (qualitySetting.get() == qualityResolution) {
// User clicked the same video quality as the current video,
// or changed between 1080p Premium and non-Premium.
return;
}
qualitySetting.save(qualityResolution);
if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get()) {
String qualityLabel = qualityResolution + "p";
Utils.showToastShort(str(
useShortsPreference ? "revanced_remember_video_quality_toast_shorts" : "revanced_remember_video_quality_toast",
networkTypeMessage, (defaultQuality + "p")
));
shortPlayerOpen
? "revanced_remember_video_quality_toast_shorts"
: "revanced_remember_video_quality_toast",
networkTypeMessage,
qualityLabel)
);
}
}
/**
@@ -77,109 +132,133 @@ public class RememberVideoQualityPatch {
* @param qualities Video qualities available, ordered from largest to smallest, with index 0 being the 'automatic' value of -2
* @param originalQualityIndex quality index to use, as chosen by YouTube
*/
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
public static int setVideoQuality(VideoQuality[] qualities, VideoQualityMenuInterface menu, int originalQualityIndex) {
try {
boolean useShortsPreference = ShortsPlayerState.isOpen();
final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
? (useShortsPreference ? shortsQualityMobile : videoQualityMobile).get()
: (useShortsPreference ? shortsQualityWifi : videoQualityWifi).get();
Utils.verifyOnMainThread();
currentMenuInterface = menu;
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
final boolean availableQualitiesChanged = (currentQualities == null)
|| !Arrays.equals(currentQualities, qualities);
if (availableQualitiesChanged) {
currentQualities = qualities;
Logger.printDebug(() -> "VideoQualities: " + Arrays.toString(currentQualities));
}
VideoQuality updatedCurrentQuality = qualities[originalQualityIndex];
if (updatedCurrentQuality.patch_getResolution() != AUTOMATIC_VIDEO_QUALITY_VALUE &&
(currentQuality == null
|| !currentQuality.patch_getQualityName().equals(updatedCurrentQuality.patch_getQualityName()))) {
currentQuality = updatedCurrentQuality;
Logger.printDebug(() -> "Current quality changed to: " + updatedCurrentQuality);
VideoQualityDialogButton.updateButtonIcon(updatedCurrentQuality);
}
final int preferredQuality = getDefaultQualityResolution();
if (preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
return originalQualityIndex; // Nothing to do.
}
if (videoQualities == null || videoQualities.size() != qualities.length) {
videoQualities = new ArrayList<>(qualities.length);
for (Object streamQuality : qualities) {
for (Field field : streamQuality.getClass().getFields()) {
if (field.getType().isAssignableFrom(Integer.TYPE)
&& field.getName().length() <= 2) {
videoQualities.add(field.getInt(streamQuality));
}
}
}
// After changing videos the qualities can initially be for the prior video.
// So if the qualities have changed an update is needed.
qualityNeedsUpdating = true;
Logger.printDebug(() -> "VideoQualities: " + videoQualities);
}
if (userChangedDefaultQuality) {
userChangedDefaultQuality = false;
final int quality = videoQualities.get(userSelectedQualityIndex);
Logger.printDebug(() -> "User changed default quality to: " + quality);
changeDefaultQuality(quality);
return userSelectedQualityIndex;
}
if (!qualityNeedsUpdating) {
// After changing videos the qualities can initially be for the prior video.
// If the qualities have changed and the default is not auto then an update is needed.
if (!qualityNeedsUpdating && !availableQualitiesChanged) {
return originalQualityIndex;
}
qualityNeedsUpdating = false;
// Find the highest quality that is equal to or less than the preferred.
int qualityToUse = videoQualities.get(0); // first element is automatic mode
int qualityIndexToUse = 0;
int i = 0;
for (Integer quality : videoQualities) {
if (quality <= preferredQuality && qualityToUse < quality) {
qualityToUse = quality;
qualityIndexToUse = i;
for (VideoQuality quality : qualities) {
final int qualityResolution = quality.patch_getResolution();
if ((qualityResolution != AUTOMATIC_VIDEO_QUALITY_VALUE && qualityResolution <= preferredQuality)
// Use the lowest video quality if the default is lower than all available.
|| i == qualities.length - 1) {
final boolean qualityNeedsChange = (i != originalQualityIndex);
Logger.printDebug(() -> qualityNeedsChange
? "Changing video quality from: " + updatedCurrentQuality + " to: " + quality
: "Video is already the preferred quality: " + quality
);
// On first load of a new regular video, if the video is already the
// desired quality then the quality flyout will show 'Auto' (ie: Auto (720p)).
//
// To prevent user confusion, set the video index even if the
// quality is already correct so the UI picker will not display "Auto".
//
// Only change Shorts quality if the quality actually needs to change,
// because the "auto" option is not shown in the flyout
// and setting the same quality again can cause the Short to restart.
if (qualityNeedsChange || !ShortsPlayerState.isOpen()) {
menu.patch_setQuality(qualities[i]);
return i;
}
return originalQualityIndex;
}
i++;
}
// If the desired quality index is equal to the original index,
// then the video is already set to the desired default quality.
final int qualityToUseFinal = qualityToUse;
if (qualityIndexToUse == originalQualityIndex) {
// On first load of a new video, if the UI video quality flyout menu
// is not updated then it will still show 'Auto' (ie: Auto (480p)),
// even though it's already set to the desired resolution.
//
// To prevent confusion, set the video index anyways (even if it matches the existing index)
// as that will force the UI picker to not display "Auto".
Logger.printDebug(() -> "Video is already preferred quality: " + qualityToUseFinal);
} else {
Logger.printDebug(() -> "Changing video quality from: "
+ videoQualities.get(originalQualityIndex) + " to: " + qualityToUseFinal);
}
Method m = qInterface.getClass().getMethod(qIndexMethod, Integer.TYPE);
m.invoke(qInterface, qualityToUse);
return qualityIndexToUse;
} catch (Exception ex) {
Logger.printException(() -> "Failed to set quality", ex);
return originalQualityIndex;
Logger.printException(() -> "setVideoQuality failure", ex);
}
return originalQualityIndex;
}
/**
* Injection point.
* @param userSelectedQualityIndex Element index of {@link #currentQualities}.
*/
public static void userChangedShortsQuality(int userSelectedQualityIndex) {
try {
if (shouldRememberVideoQuality()) {
if (currentQualities == null) {
Logger.printDebug(() -> "Cannot save default quality, qualities is null");
return;
}
VideoQuality quality = currentQualities[userSelectedQualityIndex];
saveDefaultQuality(quality.patch_getResolution());
}
} catch (Exception ex) {
Logger.printException(() -> "userChangedShortsQuality failure", ex);
}
}
/**
* Injection point. Old quality menu.
* Injection point. Regular videos.
* @param videoResolution Human readable resolution: 480, 720, 1080.
*/
public static void userChangedQuality(int selectedQualityIndex) {
public static void userChangedQuality(int videoResolution) {
Utils.verifyOnMainThread();
if (shouldRememberVideoQuality()) {
userSelectedQualityIndex = selectedQualityIndex;
userChangedDefaultQuality = true;
saveDefaultQuality(videoResolution);
}
}
/**
* Injection point. New quality menu.
*/
public static void userChangedQualityInNewFlyout(int selectedQuality) {
if (!shouldRememberVideoQuality()) return;
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
}
/**
* Injection point.
*/
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
Utils.verifyOnMainThread();
Logger.printDebug(() -> "newVideoStarted");
currentQualities = null;
currentQuality = null;
currentMenuInterface = null;
qualityNeedsUpdating = true;
videoQualities = null;
// Hide the quality button until playback starts and the qualities are available.
VideoQualityDialogButton.updateButtonIcon(null);
}
/**
* Injection point. Fixes bad data used by YouTube.
*/
public static int fixVideoQualityResolution(String name, int quality) {
final int correctQuality = 480;
if (name.equals("480p") && quality != correctQuality) {
return correctQuality;
}
return quality;
}
}

View File

@@ -671,11 +671,9 @@ public class CustomPlaybackSpeedPatch {
*/
public static int getAdjustedBackgroundColor(boolean isHandleBar) {
final int baseColor = Utils.getDialogBackgroundColor();
float darkThemeFactor = isHandleBar ? 1.25f : 1.115f; // 1.25f for handleBar, 1.115f for others in dark theme.
float lightThemeFactor = isHandleBar ? 0.9f : 0.95f; // 0.9f for handleBar, 0.95f for others in light theme.
return Utils.isDarkModeEnabled()
? Utils.adjustColorBrightness(baseColor, darkThemeFactor) // Lighten for dark theme.
: Utils.adjustColorBrightness(baseColor, lightThemeFactor); // Darken for light theme.
final float darkThemeFactor = isHandleBar ? 1.25f : 1.115f; // 1.25f for handleBar, 1.115f for others in dark theme.
final float lightThemeFactor = isHandleBar ? 0.9f : 0.95f; // 0.9f for handleBar, 0.95f for others in light theme.
return Utils.adjustColorBrightness(baseColor, lightThemeFactor, darkThemeFactor);
}
}

View File

@@ -172,6 +172,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
public static final BooleanSetting OPEN_VIDEOS_FULLSCREEN_PORTRAIT = new BooleanSetting("revanced_open_videos_fullscreen_portrait", FALSE);
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
public static final BooleanSetting VIDEO_QUALITY_DIALOG_BUTTON = new BooleanSetting("revanced_video_quality_dialog_button", FALSE);
public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity", 100, true);
public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);

View File

@@ -333,10 +333,8 @@ class AbstractPreferenceSearchData<T extends Preference> {
return text;
}
final int baseColor = Utils.getAppBackgroundColor();
final int adjustedColor = Utils.isDarkModeEnabled()
? Utils.adjustColorBrightness(baseColor, 1.20f) // Lighten for dark theme.
: Utils.adjustColorBrightness(baseColor, 0.95f); // Darken for light theme.
final int adjustedColor = Utils.adjustColorBrightness(Utils.getAppBackgroundColor(),
0.95f, 1.20f);
BackgroundColorSpan highlightSpan = new BackgroundColorSpan(adjustedColor);
SpannableStringBuilder spannable = new SpannableStringBuilder(text);

View File

@@ -187,4 +187,56 @@ public class PlayerControlButton {
if (view != null) view.setVisibility(View.GONE);
isVisible = false;
}
}
/**
* Sets the icon of the button.
* @param resourceId Drawable identifier, or zero to hide the icon.
*/
public void setIcon(int resourceId) {
try {
View button = buttonRef.get();
if (button instanceof ImageView imageButton) {
imageButton.setImageResource(resourceId);
}
} catch (Exception ex) {
Logger.printException(() -> "setIcon failure", ex);
}
}
/**
* Starts an animation on the button.
* @param animation The animation to apply.
*/
public void startAnimation(Animation animation) {
try {
View button = buttonRef.get();
if (button != null) {
button.startAnimation(animation);
}
} catch (Exception ex) {
Logger.printException(() -> "startAnimation failure", ex);
}
}
/**
* Clears any animation on the button.
*/
public void clearAnimation() {
try {
View button = buttonRef.get();
if (button != null) {
button.clearAnimation();
}
} catch (Exception ex) {
Logger.printException(() -> "clearAnimation failure", ex);
}
}
/**
* Returns the View associated with this button.
* @return The button View.
*/
public View getView() {
return buttonRef.get();
}
}

View File

@@ -0,0 +1,482 @@
package app.revanced.extension.youtube.videoplayer;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.Utils.dipToPixels;
import static app.revanced.extension.youtube.patches.playback.quality.RememberVideoQualityPatch.AUTOMATIC_VIDEO_QUALITY_VALUE;
import static app.revanced.extension.youtube.patches.playback.quality.RememberVideoQualityPatch.VIDEO_QUALITY_1080P_PREMIUM_NAME;
import static app.revanced.extension.youtube.patches.playback.quality.RememberVideoQualityPatch.VideoQualityMenuInterface;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.libraries.youtube.innertube.model.media.VideoQuality;
import java.util.ArrayList;
import java.util.List;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.playback.quality.RememberVideoQualityPatch;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class VideoQualityDialogButton {
private static final int DRAWABLE_LD = getDrawableIdentifier("revanced_video_quality_dialog_button_ld");
private static final int DRAWABLE_SD = getDrawableIdentifier("revanced_video_quality_dialog_button_sd");
private static final int DRAWABLE_HD = getDrawableIdentifier("revanced_video_quality_dialog_button_hd");
private static final int DRAWABLE_FHD = getDrawableIdentifier("revanced_video_quality_dialog_button_fhd");
private static final int DRAWABLE_FHD_PLUS = getDrawableIdentifier("revanced_video_quality_dialog_button_fhd_plus");
private static final int DRAWABLE_QHD = getDrawableIdentifier("revanced_video_quality_dialog_button_qhd");
private static final int DRAWABLE_4K = getDrawableIdentifier("revanced_video_quality_dialog_button_4k");
private static final int DRAWABLE_UNKNOWN = getDrawableIdentifier("revanced_video_quality_dialog_button_unknown");
@Nullable
private static PlayerControlButton instance;
/**
* The current resource name of the button icon.
*/
private static int currentIconResource;
private static int getDrawableIdentifier(String resourceName) {
final int resourceId = Utils.getResourceIdentifier(resourceName, "drawable");
if (resourceId == 0) Logger.printException(() -> "Could not find resource: " + resourceName);
return resourceId;
}
/**
* Updates the button icon based on the current video quality.
*/
public static void updateButtonIcon(@Nullable VideoQuality quality) {
try {
Utils.verifyOnMainThread();
if (instance == null) return;
final int resolution = quality == null
? AUTOMATIC_VIDEO_QUALITY_VALUE // Video is still loading.
: quality.patch_getResolution();
final int iconResource = switch (resolution) {
case 144, 240, 360 -> DRAWABLE_LD;
case 480 -> DRAWABLE_SD;
case 720 -> DRAWABLE_HD;
case 1080 -> VIDEO_QUALITY_1080P_PREMIUM_NAME.equals(quality.patch_getQualityName())
? DRAWABLE_FHD_PLUS
: DRAWABLE_FHD;
case 1440 -> DRAWABLE_QHD;
case 2160 -> DRAWABLE_4K;
default -> DRAWABLE_UNKNOWN;
};
if (iconResource != currentIconResource) {
currentIconResource = iconResource;
Utils.runOnMainThreadDelayed(() -> {
if (iconResource != currentIconResource) {
Logger.printDebug(() -> "Ignoring stale button update to: " + quality);
return;
}
instance.setIcon(iconResource);
}, 100);
}
} catch (Exception ex) {
Logger.printException(() -> "updateButtonIcon failure", ex);
}
}
/**
* Injection point.
*/
public static void initializeButton(View controlsView) {
try {
instance = new PlayerControlButton(
controlsView,
"revanced_video_quality_dialog_button",
"revanced_video_quality_dialog_button_placeholder",
Settings.VIDEO_QUALITY_DIALOG_BUTTON::get,
view -> {
try {
showVideoQualityDialog(view.getContext());
} catch (Exception ex) {
Logger.printException(() -> "Video quality button onClick failure", ex);
}
},
view -> {
try {
VideoQuality[] qualities = RememberVideoQualityPatch.getCurrentQualities();
VideoQualityMenuInterface menu = RememberVideoQualityPatch.getCurrentMenuInterface();
if (qualities == null || menu == null) {
Logger.printDebug(() -> "Cannot reset quality, videoQualities is null");
return true;
}
// Reset to default quality.
final int defaultResolution = RememberVideoQualityPatch.getDefaultQualityResolution();
for (VideoQuality quality : qualities) {
final int resolution = quality.patch_getResolution();
if (resolution != AUTOMATIC_VIDEO_QUALITY_VALUE && resolution <= defaultResolution) {
Logger.printDebug(() -> "Resetting quality to: " + quality);
menu.patch_setQuality(quality);
return true;
}
}
// Existing hook cannot set default quality to auto.
// Instead show the quality dialog.
showVideoQualityDialog(view.getContext());
return true;
} catch (Exception ex) {
Logger.printException(() -> "Video quality button reset failure", ex);
}
return false;
}
);
// Set initial icon.
updateButtonIcon(RememberVideoQualityPatch.getCurrentQuality());
} catch (Exception ex) {
Logger.printException(() -> "initializeButton failure", ex);
}
}
/**
* Injection point.
*/
public static void setVisibilityImmediate(boolean visible) {
if (instance != null) {
instance.setVisibilityImmediate(visible);
}
}
/**
* Injection point.
*/
public static void setVisibility(boolean visible, boolean animated) {
if (instance != null) {
instance.setVisibility(visible, animated);
}
}
/**
* Shows a dialog with available video qualities, excluding Auto, with a title showing the current quality.
*/
private static void showVideoQualityDialog(Context context) {
try {
VideoQuality[] currentQualities = RememberVideoQualityPatch.getCurrentQualities();
VideoQuality currentQuality = RememberVideoQualityPatch.getCurrentQuality();
if (currentQualities == null || currentQuality == null) {
Logger.printDebug(() -> "Cannot show qualities dialog, videoQualities is null");
return;
}
if (currentQualities.length < 2) {
// Should never happen.
Logger.printException(() -> "Cannot show qualities dialog, no qualities available");
return;
}
VideoQualityMenuInterface menu = RememberVideoQualityPatch.getCurrentMenuInterface();
if (menu == null) {
Logger.printDebug(() -> "Cannot show qualities dialog, menu is null");
return;
}
// -1 adjustment for automatic quality at first index.
int listViewSelectedIndex = -1;
for (VideoQuality quality : currentQualities) {
if (quality == currentQuality) {
break;
}
listViewSelectedIndex++;
}
List<String> qualityLabels = new ArrayList<>(currentQualities.length - 1);
for (VideoQuality availableQuality : currentQualities) {
if (availableQuality.patch_getResolution() != AUTOMATIC_VIDEO_QUALITY_VALUE) {
qualityLabels.add(availableQuality.patch_getQualityName());
}
}
Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCanceledOnTouchOutside(true);
dialog.setCancelable(true);
final int dip4 = dipToPixels(4); // Height for handle bar.
final int dip5 = dipToPixels(5); // Padding for mainLayout.
final int dip6 = dipToPixels(6); // Bottom margin.
final int dip8 = dipToPixels(8); // Side padding.
final int dip16 = dipToPixels(16); // Left padding for ListView.
final int dip20 = dipToPixels(20); // Margin below handle.
final int dip40 = dipToPixels(40); // Width for handle bar.
LinearLayout mainLayout = new LinearLayout(context);
mainLayout.setOrientation(LinearLayout.VERTICAL);
mainLayout.setPadding(dip5, dip8, dip5, dip8);
ShapeDrawable background = new ShapeDrawable(new RoundRectShape(
Utils.createCornerRadii(12), null, null));
background.getPaint().setColor(Utils.getDialogBackgroundColor());
mainLayout.setBackground(background);
View handleBar = new View(context);
ShapeDrawable handleBackground = new ShapeDrawable(new RoundRectShape(
Utils.createCornerRadii(4), null, null));
final int baseColor = Utils.getDialogBackgroundColor();
final int adjustedHandleBarBackgroundColor = Utils.adjustColorBrightness(
baseColor, 0.9f, 1.25f);
handleBackground.getPaint().setColor(adjustedHandleBarBackgroundColor);
handleBar.setBackground(handleBackground);
LinearLayout.LayoutParams handleParams = new LinearLayout.LayoutParams(dip40, dip4);
handleParams.gravity = Gravity.CENTER_HORIZONTAL;
handleParams.setMargins(0, 0, 0, dip20);
handleBar.setLayoutParams(handleParams);
mainLayout.addView(handleBar);
// Create SpannableStringBuilder for formatted text.
SpannableStringBuilder spannableTitle = new SpannableStringBuilder();
String titlePart = str("video_quality_quick_menu_title");
String separatorPart = str("video_quality_title_seperator");
// Append title part with default foreground color.
spannableTitle.append(titlePart);
spannableTitle.setSpan(
new ForegroundColorSpan(Utils.getAppForegroundColor()),
0,
titlePart.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
spannableTitle.append(" "); // Space after title.
// Append separator part with adjusted title color.
int separatorStart = spannableTitle.length();
spannableTitle.append(separatorPart);
final int adjustedTitleForegroundColor = Utils.adjustColorBrightness(
Utils.getAppForegroundColor(), 1.6f, 0.6f);
spannableTitle.setSpan(
new ForegroundColorSpan(adjustedTitleForegroundColor),
separatorStart,
separatorStart + separatorPart.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
spannableTitle.append(" "); // Space after separator.
// Append quality label with adjusted title color.
final int qualityStart = spannableTitle.length();
spannableTitle.append(currentQuality.patch_getQualityName());
spannableTitle.setSpan(
new ForegroundColorSpan(adjustedTitleForegroundColor),
qualityStart,
qualityStart + currentQuality.patch_getQualityName().length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
// Add title with current quality.
TextView titleView = new TextView(context);
titleView.setText(spannableTitle);
titleView.setTextSize(16);
// Remove setTextColor since color is handled by SpannableStringBuilder.
LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
titleParams.setMargins(dip8, 0, 0, dip20);
titleView.setLayoutParams(titleParams);
mainLayout.addView(titleView);
ListView listView = new ListView(context);
CustomQualityAdapter adapter = new CustomQualityAdapter(context, qualityLabels);
adapter.setSelectedPosition(listViewSelectedIndex);
listView.setAdapter(adapter);
listView.setDivider(null);
listView.setPadding(dip16, 0, 0, 0);
listView.setOnItemClickListener((parent, view, which, id) -> {
try {
final int originalIndex = which + 1; // Adjust for automatic.
VideoQuality selectedQuality = currentQualities[originalIndex];
Logger.printDebug(() -> "User clicked on quality: " + selectedQuality);
if (RememberVideoQualityPatch.shouldRememberVideoQuality()) {
RememberVideoQualityPatch.saveDefaultQuality(selectedQuality.patch_getResolution());
}
// Don't update button icon now. Icon will update when the actual
// quality is changed by YT. This is needed to ensure the icon is correct
// if YT ignores changing from 1080p Premium to regular 1080p.
menu.patch_setQuality(selectedQuality);
dialog.dismiss();
} catch (Exception ex) {
Logger.printException(() -> "Video quality selection failure", ex);
}
});
LinearLayout.LayoutParams listViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
listViewParams.setMargins(0, 0, 0, dip5);
listView.setLayoutParams(listViewParams);
mainLayout.addView(listView);
LinearLayout wrapperLayout = new LinearLayout(context);
wrapperLayout.setOrientation(LinearLayout.VERTICAL);
wrapperLayout.setPadding(dip8, 0, dip8, 0);
wrapperLayout.addView(mainLayout);
dialog.setContentView(wrapperLayout);
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.BOTTOM;
params.y = dip6;
int portraitWidth = context.getResources().getDisplayMetrics().widthPixels;
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
portraitWidth = Math.min(
portraitWidth,
context.getResources().getDisplayMetrics().heightPixels);
}
params.width = portraitWidth;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);
window.setBackgroundDrawable(null);
}
final int fadeDurationFast = Utils.getResourceInteger("fade_duration_fast");
Animation slideInABottomAnimation = Utils.getResourceAnimation("slide_in_bottom");
slideInABottomAnimation.setDuration(fadeDurationFast);
mainLayout.startAnimation(slideInABottomAnimation);
// noinspection ClickableViewAccessibility
mainLayout.setOnTouchListener(new View.OnTouchListener() {
final float dismissThreshold = dipToPixels(100);
float touchY;
float translationY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchY = event.getRawY();
translationY = mainLayout.getTranslationY();
return true;
case MotionEvent.ACTION_MOVE:
final float deltaY = event.getRawY() - touchY;
if (deltaY >= 0) {
mainLayout.setTranslationY(translationY + deltaY);
}
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mainLayout.getTranslationY() > dismissThreshold) {
//noinspection ExtractMethodRecommender
final float remainingDistance = context.getResources().getDisplayMetrics().heightPixels
- mainLayout.getTop();
TranslateAnimation slideOut = new TranslateAnimation(
0, 0, mainLayout.getTranslationY(), remainingDistance);
slideOut.setDuration(fadeDurationFast);
slideOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
dialog.dismiss();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mainLayout.startAnimation(slideOut);
} else {
TranslateAnimation slideBack = new TranslateAnimation(
0, 0, mainLayout.getTranslationY(), 0);
slideBack.setDuration(fadeDurationFast);
mainLayout.startAnimation(slideBack);
mainLayout.setTranslationY(0);
}
return true;
default:
return false;
}
}
});
dialog.show();
} catch (Exception ex) {
Logger.printException(() -> "showVideoQualityDialog failure", ex);
}
}
private static class CustomQualityAdapter extends ArrayAdapter<String> {
private int selectedPosition = -1;
public CustomQualityAdapter(@NonNull Context context, @NonNull List<String> objects) {
super(context, 0, objects);
}
private void setSelectedPosition(int position) {
this.selectedPosition = position;
notifyDataSetChanged();
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
Utils.getResourceIdentifier("revanced_custom_list_item_checked", "layout"),
parent,
false
);
viewHolder = new ViewHolder();
viewHolder.checkIcon = convertView.findViewById(
Utils.getResourceIdentifier("revanced_check_icon", "id")
);
viewHolder.placeholder = convertView.findViewById(
Utils.getResourceIdentifier("revanced_check_icon_placeholder", "id")
);
viewHolder.textView = convertView.findViewById(
Utils.getResourceIdentifier("revanced_item_text", "id")
);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.textView.setText(getItem(position));
final boolean isSelected = position == selectedPosition;
viewHolder.checkIcon.setVisibility(isSelected ? View.VISIBLE : View.GONE);
viewHolder.placeholder.setVisibility(isSelected ? View.GONE : View.INVISIBLE);
return convertView;
}
private static class ViewHolder {
ImageView checkIcon;
View placeholder;
TextView textView;
}
}
}

View File

@@ -0,0 +1,8 @@
package com.google.android.libraries.youtube.innertube.model.media;
public abstract class VideoQuality implements Comparable<VideoQuality> {
public abstract String patch_getQualityName();
public abstract int patch_getResolution();
}

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.33.0-dev.5
version = 5.33.0-dev.11

View File

@@ -1664,6 +1664,10 @@ public final class app/revanced/patches/youtube/video/quality/VideoQualityPatchK
public static final fun getVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/video/quality/button/VideoQualityDialogButtonPatchKt {
public static final fun getVideoQualityButtonPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/video/speed/PlaybackSpeedPatchKt {
public static final fun getPlaybackSpeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

View File

@@ -3,6 +3,7 @@ package app.revanced.patches.nfctoolsse.misc.pro
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
@Deprecated("This patch no longer works and will soon be deleted.")
internal val isLicenseRegisteredFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
returns("Z")

View File

@@ -4,9 +4,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val unlockProPatch = bytecodePatch(
name = "Unlock pro",
) {
@Deprecated("This patch no longer works and will soon be deleted.")
val unlockProPatch = bytecodePatch{
compatibleWith("com.wakdev.apps.nfctools.se")
execute {

View File

@@ -11,7 +11,6 @@ val recyclerViewTreeHookPatch = bytecodePatch {
dependsOn(sharedExtensionPatch)
execute {
recyclerViewTreeObserverFingerprint.method.apply {
val insertIndex = recyclerViewTreeObserverFingerprint.patternMatch!!.startIndex + 1
val recyclerViewParameter = 2

View File

@@ -121,7 +121,7 @@ internal val subtitleButtonControllerFingerprint = fingerprint {
)
}
internal val newVideoQualityChangedFingerprint = fingerprint {
internal val videoQualityChangedFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
parameters("L")

View File

@@ -1,23 +1,27 @@
package app.revanced.patches.youtube.video.audio
import app.revanced.patcher.fingerprint
import app.revanced.util.containsLiteralInstruction
import com.android.tools.smali.dexlib2.AccessFlags
internal val streamingModelBuilderFingerprint = fingerprint {
internal val formatStreamModelToStringFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
strings("vprng")
returns("Ljava/lang/String;")
custom { method, classDef ->
method.name == "toString" && classDef.type ==
"Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
}
}
internal val menuItemAudioTrackFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters("L")
returns("V")
strings("menu_item_audio_track")
internal const val AUDIO_STREAM_IGNORE_DEFAULT_FEATURE_FLAG = 45666189L
internal val selectAudioStreamFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("L")
custom { method, _ ->
method.parameters.size > 2 // Method has a large number of parameters and may change.
&& method.parameters[1].type == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;"
&& method.containsLiteralInstruction(AUDIO_STREAM_IGNORE_DEFAULT_FEATURE_FLAG)
}
}
internal val audioStreamingTypeSelector = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returns("L")
strings("raw") // String is not unique
}

View File

@@ -5,22 +5,22 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.getReference
import app.revanced.util.findMethodFromToString
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.insertLiteralOverride
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@@ -37,6 +37,7 @@ val forceOriginalAudioPatch = bytecodePatch(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
versionCheckPatch
)
compatibleWith(
@@ -60,29 +61,25 @@ val forceOriginalAudioPatch = bytecodePatch(
)
)
fun Method.firstFormatStreamingModelCall(
returnType: String = "Ljava/lang/String;"
): MutableMethod {
val audioTrackIdIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
&& reference.returnType == returnType
}
return navigate(this).to(audioTrackIdIndex).stop()
// Disable feature flag that ignores the default track flag
// and instead overrides to the user region language.
if (is_20_07_or_greater) {
selectAudioStreamFingerprint.method.insertLiteralOverride(
AUDIO_STREAM_IGNORE_DEFAULT_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->ignoreDefaultAudioStream(Z)Z"
)
}
// Accessor methods of FormatStreamModel have no string constants and
// opcodes are identical to other methods in the same class,
// so must walk from another class that use the methods.
val isDefaultMethod = streamingModelBuilderFingerprint.originalMethod.firstFormatStreamingModelCall("Z")
val audioTrackIdMethod = menuItemAudioTrackFingerprint.originalMethod.firstFormatStreamingModelCall()
val audioTrackDisplayNameMethod = audioStreamingTypeSelector.originalMethod.firstFormatStreamingModelCall()
val formatStreamModelClass = proxy(classes.first {
it.type == audioTrackIdMethod.definingClass
}).mutableClass
val isDefaultAudioTrackMethod = formatStreamModelToStringFingerprint.originalMethod
.findMethodFromToString("isDefaultAudioTrack=")
val audioTrackDisplayNameMethod = formatStreamModelToStringFingerprint.originalMethod
.findMethodFromToString("audioTrackDisplayName=")
val audioTrackIdMethod = formatStreamModelToStringFingerprint.originalMethod
.findMethodFromToString("audioTrackId=")
formatStreamModelClass.apply {
proxy(classes.first {
it.type == audioTrackIdMethod.definingClass
}).mutableClass.apply {
// Add a new field to store the override.
val helperFieldName = "isDefaultAudioTrackOverride"
fields.add(
@@ -103,7 +100,7 @@ val forceOriginalAudioPatch = bytecodePatch(
// Add a helper method because the isDefaultAudioTrack() has only 2 registers and 3 are needed.
val helperMethodClass = type
val helperMethodName = "extension_isDefaultAudioTrack"
val helperMethodName = "patch_isDefaultAudioTrack"
val helperMethod = ImmutableMethod(
helperMethodClass,
helperMethodName,
@@ -143,7 +140,7 @@ val forceOriginalAudioPatch = bytecodePatch(
methods.add(helperMethod)
// Modify isDefaultAudioTrack() to call extension helper method.
isDefaultMethod.apply {
isDefaultAudioTrackMethod.apply {
val index = indexOfFirstInstructionOrThrow(Opcode.RETURN)
val register = getInstruction<OneRegisterInstruction>(index).registerA

View File

@@ -1,7 +1,7 @@
package app.revanced.patches.youtube.video.information
import app.revanced.patcher.fingerprint
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
import app.revanced.patches.youtube.shared.videoQualityChangedFingerprint
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@@ -110,7 +110,7 @@ internal val seekRelativeFingerprint = fingerprint {
}
/**
* Resolves with the class found in [newVideoQualityChangedFingerprint].
* Resolves with the class found in [videoQualityChangedFingerprint].
*/
internal val playbackSpeedMenuSpeedChangedFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
import app.revanced.patches.youtube.shared.videoQualityChangedFingerprint
import app.revanced.patches.youtube.video.playerresponse.Hook
import app.revanced.patches.youtube.video.playerresponse.addPlayerResponseMethodHook
import app.revanced.patches.youtube.video.playerresponse.playerResponseMethodHookPatch
@@ -263,7 +263,7 @@ val videoInformationPatch = bytecodePatch(
// Handle new playback speed menu.
playbackSpeedMenuSpeedChangedFingerprint.match(
newVideoQualityChangedFingerprint.originalClassDef,
videoQualityChangedFingerprint.originalClassDef,
).method.apply {
val index = indexOfFirstInstructionOrThrow(Opcode.IGET)

View File

@@ -68,7 +68,6 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
// region Patch for the old type of the video quality menu.
// Used for regular videos when spoofing to old app version,
// and for the Shorts quality flyout on newer app versions.
videoQualityMenuViewInflateFingerprint.let {
it.method.apply {
val checkCastIndex = it.patternMatch!!.endIndex
@@ -77,7 +76,7 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
addInstruction(
checkCastIndex + 1,
"invoke-static { v$listViewRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
"showAdvancedVideoQualityMenu(Landroid/widget/ListView;)V",
"addVideoQualityListMenuListener(Landroid/widget/ListView;)V",
)
}
}

View File

@@ -5,10 +5,25 @@ import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal const val YOUTUBE_VIDEO_QUALITY_CLASS_TYPE = "Lcom/google/android/libraries/youtube/innertube/model/media/VideoQuality;"
internal val videoQualityFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameters(
"I", // Resolution.
"Ljava/lang/String;", // Human readable resolution: "480p", "1080p Premium", etc
"Z",
"L"
)
custom { _, classDef ->
classDef.type == YOUTUBE_VIDEO_QUALITY_CLASS_TYPE
}
}
/**
* Matches with the class found in [videoQualitySetterFingerprint].
*/
internal val setQualityByIndexMethodClassFieldReferenceFingerprint = fingerprint {
internal val setVideoQualityFingerprint = fingerprint {
returns("V")
parameters("L")
opcodes(
@@ -23,6 +38,22 @@ internal val videoQualityItemOnClickParentFingerprint = fingerprint {
strings("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT")
}
/**
* Resolves to class found in [videoQualityItemOnClickFingerprint].
*/
internal val videoQualityItemOnClickFingerprint = fingerprint {
returns("V")
parameters(
"Landroid/widget/AdapterView;",
"Landroid/view/View;",
"I",
"J"
)
custom { method, _ ->
method.name == "onItemClick"
}
}
internal val videoQualitySetterFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
@@ -37,7 +68,6 @@ internal val videoQualitySetterFingerprint = fingerprint {
strings("menu_item_video_quality")
}
internal val videoQualityMenuOptionsFingerprint = fingerprint {
accessFlags(AccessFlags.STATIC)
returns("[L")

View File

@@ -3,8 +3,8 @@ package app.revanced.patches.youtube.video.quality
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.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference
@@ -12,15 +12,21 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
import app.revanced.patches.youtube.shared.videoQualityChangedFingerprint
import app.revanced.patches.youtube.video.information.onCreateHook
import app.revanced.patches.youtube.video.information.videoInformationPatch
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
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.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch;"
private const val EXTENSION_VIDEO_QUALITY_MENU_INTERFACE =
"Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch\$VideoQualityMenuInterface;"
val rememberVideoQualityPatch = bytecodePatch {
dependsOn(
@@ -61,81 +67,152 @@ val rememberVideoQualityPatch = bytecodePatch {
SwitchPreference("revanced_remember_video_quality_last_selected_toast")
))
/*
* The following code works by hooking the method which is called when the user selects a video quality
* to remember the last selected video quality.
*
* It also hooks the method which is called when the video quality to set is determined.
* Conveniently, at this point the video quality is overridden to the remembered playback speed.
*/
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
videoQualityFingerprint.let {
// Fix bad data used by YouTube.
it.method.addInstructions(
0,
"""
invoke-static { p2, p1 }, $EXTENSION_CLASS_DESCRIPTOR->fixVideoQualityResolution(Ljava/lang/String;I)I
move-result p1
"""
)
// Add methods to access obfuscated quality fields.
it.classDef.apply {
methods.add(
ImmutableMethod(
type,
"patch_getQualityName",
listOf(),
"Ljava/lang/String;",
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
null,
null,
MutableMethodImplementation(2),
).toMutable().apply {
// Only one string field.
val qualityNameField = fields.single { field ->
field.type == "Ljava/lang/String;"
}
addInstructions(
0,
"""
iget-object v0, p0, $qualityNameField
return-object v0
"""
)
}
)
methods.add(
ImmutableMethod(
type,
"patch_getResolution",
listOf(),
"I",
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
null,
null,
MutableMethodImplementation(2),
).toMutable().apply {
val resolutionField = fields.single { field ->
field.type == "I"
}
addInstructions(
0,
"""
iget v0, p0, $resolutionField
return v0
"""
)
}
)
}
}
// Inject a call to set the remembered quality once a video loads.
setQualityByIndexMethodClassFieldReferenceFingerprint.match(
videoQualitySetterFingerprint.originalClassDef,
setVideoQualityFingerprint.match(
videoQualitySetterFingerprint.originalClassDef
).let { match ->
// This instruction refers to the field with the type that contains the setQualityByIndex method.
// This instruction refers to the field with the type that contains the setQuality method.
val instructions = match.method.implementation!!.instructions
val getOnItemClickListenerClassReference =
val onItemClickListenerClassReference =
(instructions.elementAt(0) as ReferenceInstruction).reference
val getSetQualityByIndexMethodClassFieldReference =
(instructions.elementAt(1) as ReferenceInstruction).reference
val setQualityFieldReference =
((instructions.elementAt(1) as ReferenceInstruction).reference) as FieldReference
val setQualityByIndexMethodClassFieldReference =
getSetQualityByIndexMethodClassFieldReference as FieldReference
proxy(
classes.find { classDef ->
classDef.type == setQualityFieldReference.type
}!!
).mutableClass.apply {
// Add interface and helper methods to allow extension code to call obfuscated methods.
interfaces.add(EXTENSION_VIDEO_QUALITY_MENU_INTERFACE)
val setQualityByIndexMethodClass = classes
.find { classDef -> classDef.type == setQualityByIndexMethodClassFieldReference.type }!!
methods.add(
ImmutableMethod(
type,
"patch_setQuality",
listOf(
ImmutableMethodParameter(YOUTUBE_VIDEO_QUALITY_CLASS_TYPE, null, null)
),
"V",
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
null,
null,
MutableMethodImplementation(2),
).toMutable().apply {
val setQualityMenuIndexMethod = methods.single { method ->
method.parameterTypes.firstOrNull() == YOUTUBE_VIDEO_QUALITY_CLASS_TYPE
}
// Get the name of the setQualityByIndex method.
val setQualityByIndexMethod = setQualityByIndexMethodClass.methods
.find { method -> method.parameterTypes.first() == "I" }
?: throw PatchException("Could not find setQualityByIndex method")
addInstructions(
0,
"""
invoke-virtual { p0, p1 }, $setQualityMenuIndexMethod
return-void
"""
)
}
)
}
videoQualitySetterFingerprint.method.addInstructions(
0,
"""
# Get the object instance to invoke the setQualityByIndex method on.
iget-object v0, p0, $getOnItemClickListenerClassReference
iget-object v0, v0, $getSetQualityByIndexMethodClassFieldReference
# Get object instance to invoke setQuality method.
iget-object v0, p0, $onItemClickListenerClassReference
iget-object v0, v0, $setQualityFieldReference
# Get the method name.
const-string v1, "${setQualityByIndexMethod.name}"
# Set the quality.
# The first parameter is the array list of video qualities.
# The second parameter is the index of the selected quality.
# The register v0 stores the object instance to invoke the setQualityByIndex method on.
# The register v1 stores the name of the setQualityByIndex method.
invoke-static { p1, p2, v0, v1 }, $EXTENSION_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I
invoke-static { p1, v0, p2 }, $EXTENSION_CLASS_DESCRIPTOR->setVideoQuality([$YOUTUBE_VIDEO_QUALITY_CLASS_TYPE${EXTENSION_VIDEO_QUALITY_MENU_INTERFACE}I)I
move-result p2
""",
"""
)
}
// Inject a call to remember the selected quality.
videoQualityItemOnClickParentFingerprint.classDef.methods.find { it.name == "onItemClick" }
?.apply {
val listItemIndexParameter = 3
// Inject a call to remember the selected quality for Shorts.
videoQualityItemOnClickFingerprint.match(
videoQualityItemOnClickParentFingerprint.classDef
).method.addInstruction(
0,
"invoke-static { p3 }, $EXTENSION_CLASS_DESCRIPTOR->userChangedShortsQuality(I)V"
)
// Inject a call to remember the user selected quality for regular videos.
videoQualityChangedFingerprint.let {
it.method.apply {
val index = it.patternMatch!!.startIndex
val register = getInstruction<TwoRegisterInstruction>(index).registerA
addInstruction(
0,
"invoke-static { p$listItemIndexParameter }, " +
"$EXTENSION_CLASS_DESCRIPTOR->userChangedQuality(I)V",
index + 1,
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->userChangedQuality(I)V",
)
} ?: throw PatchException("Failed to find onItemClick method")
// Remember video quality if not using old layout menu.
newVideoQualityChangedFingerprint.method.apply {
val index = newVideoQualityChangedFingerprint.patternMatch!!.startIndex
val qualityRegister = getInstruction<TwoRegisterInstruction>(index).registerA
addInstruction(
index + 1,
"invoke-static { v$qualityRegister }, " +
"$EXTENSION_CLASS_DESCRIPTOR->userChangedQualityInNewFlyout(I)V",
)
}
}
}
}

View File

@@ -5,6 +5,7 @@ import app.revanced.patches.shared.misc.settings.preference.BasePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.video.quality.button.videoQualityButtonPatch
/**
* Video quality settings. Used to organize all speed related settings together.
@@ -19,6 +20,7 @@ val videoQualityPatch = bytecodePatch(
dependsOn(
rememberVideoQualityPatch,
advancedVideoQualityMenuPatch,
videoQualityButtonPatch,
)
compatibleWith(

View File

@@ -0,0 +1,64 @@
package app.revanced.patches.youtube.video.quality.button
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playercontrols.*
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.video.quality.rememberVideoQualityPatch
import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
private val videoQualityButtonResourcePatch = resourcePatch {
dependsOn(playerControlsResourcePatch)
execute {
copyResources(
"qualitybutton",
ResourceGroup(
"drawable",
"revanced_video_quality_dialog_button_ld.xml",
"revanced_video_quality_dialog_button_sd.xml",
"revanced_video_quality_dialog_button_hd.xml",
"revanced_video_quality_dialog_button_fhd.xml",
"revanced_video_quality_dialog_button_fhd_plus.xml",
"revanced_video_quality_dialog_button_qhd.xml",
"revanced_video_quality_dialog_button_4k.xml",
"revanced_video_quality_dialog_button_unknown.xml",
),
)
addBottomControl("qualitybutton")
}
}
private const val QUALITY_BUTTON_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/videoplayer/VideoQualityDialogButton;"
val videoQualityButtonPatch = bytecodePatch(
description = "Adds the option to display video quality dialog button in the video player.",
) {
dependsOn(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
rememberVideoQualityPatch,
videoQualityButtonResourcePatch,
playerControlsPatch,
)
execute {
addResources("youtube", "video.quality.button.videoQualityButtonPatch")
PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_video_quality_dialog_button"),
)
initializeBottomControl(QUALITY_BUTTON_CLASS_DESCRIPTOR)
injectVisibilityCheckCall(QUALITY_BUTTON_CLASS_DESCRIPTOR)
}
}

View File

@@ -32,7 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstructio
import com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
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.Reference
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.util.MethodUtil
import java.util.EnumSet
@@ -171,6 +174,79 @@ internal val Instruction.isBranchInstruction: Boolean
internal val Instruction.isReturnInstruction: Boolean
get() = this.opcode in returnOpcodes
/**
* Find the instruction index used for a toString() StringBuilder write of a given String name.
*
* @param fieldName The name of the field to find. Partial matches are allowed.
*/
private fun Method.findInstructionIndexFromToString(fieldName: String) : Int {
val stringIndex = indexOfFirstInstruction {
val reference = getReference<StringReference>()
reference?.string?.contains(fieldName) == true
}
if (stringIndex < 0) {
throw IllegalArgumentException("Could not find usage of string: '$fieldName'")
}
val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA
// Find use of the string with a StringBuilder.
val stringUsageIndex = indexOfFirstInstruction(stringIndex) {
val reference = getReference<MethodReference>()
reference?.definingClass == "Ljava/lang/StringBuilder;" &&
(this as? FiveRegisterInstruction)?.registerD == stringRegister
}
if (stringUsageIndex < 0) {
throw IllegalArgumentException("Could not find StringBuilder usage in: $this")
}
// Find the next usage of StringBuilder, which should be the desired field.
val fieldUsageIndex = indexOfFirstInstruction(stringUsageIndex + 1) {
val reference = getReference<MethodReference>()
reference?.definingClass == "Ljava/lang/StringBuilder;" && reference.name == "append"
}
if (fieldUsageIndex < 0) {
// Should never happen.
throw IllegalArgumentException("Could not find StringBuilder append usage in: $this")
}
val fieldUsageRegister = getInstruction<FiveRegisterInstruction>(fieldUsageIndex).registerD
// Look backwards up the method to find the instruction that sets the register.
var fieldSetIndex = indexOfFirstInstructionReversedOrThrow(fieldUsageIndex - 1) {
fieldUsageRegister == writeRegister
}
// If the field is a method call, then adjust from MOVE_RESULT to the method call.
val fieldSetOpcode = getInstruction(fieldSetIndex).opcode
if (fieldSetOpcode == MOVE_RESULT ||
fieldSetOpcode == MOVE_RESULT_WIDE ||
fieldSetOpcode == MOVE_RESULT_OBJECT) {
fieldSetIndex--
}
return fieldSetIndex
}
/**
* Find the method used for a toString() StringBuilder write of a given String name.
*
* @param fieldName The name of the field to find. Partial matches are allowed.
*/
context(BytecodePatchContext)
internal fun Method.findMethodFromToString(fieldName: String) : MutableMethod {
val methodUsageIndex = findInstructionIndexFromToString(fieldName)
return navigate(this).to(methodUsageIndex).stop()
}
/**
* Find the field used for a toString() StringBuilder write of a given String name.
*
* @param fieldName The name of the field to find. Partial matches are allowed.
*/
internal fun Method.findFieldFromToString(fieldName: String) : FieldReference {
val methodUsageIndex = findInstructionIndexFromToString(fieldName)
return getInstruction<ReferenceInstruction>(methodUsageIndex).getReference<FieldReference>()!!
}
/**
* Adds public [AccessFlags] and removes private and protected flags (if present).
*/
@@ -594,7 +670,7 @@ fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = indexOfF
/**
* Get the index of matching instruction,
* starting from and [startIndex] and searching down.
* starting from [startIndex] and searching down.
*
* @param startIndex Optional starting index to search down from. Searching includes the start index.
* @return The index of the instruction.
@@ -617,7 +693,7 @@ fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int = i
/**
* Get the index of matching instruction,
* starting from and [startIndex] and searching down.
* starting from [startIndex] and searching down.
*
* @param startIndex Optional starting index to search down from. Searching includes the start index.
* @return The index of the instruction.

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1465,6 +1465,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">الزر معروض. انقر مع الاستمرار لإعادة ضبط سرعة التشغيل إلى الوضع الافتراضي</string>
<string name="revanced_playback_speed_dialog_button_summary_off">لا يتم عرض الزر</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">عرض زر جودة الفيديو</string>
<string name="revanced_video_quality_dialog_button_summary_on">الزر معروض. انقر مع الاستمرار لإعادة تعيين الجودة إلى الافتراضي</string>
<string name="revanced_video_quality_dialog_button_summary_off">الزر غير معروض</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">قائمة سرعة التشغيل المخصصة</string>
<string name="revanced_custom_speed_menu_summary_on">يتم عرض قائمة سرعة التشغيل المخصصة</string>

View File

@@ -224,6 +224,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1464,6 +1464,8 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_playback_speed_dialog_button_summary_on">Düymə göstərilir. Oynatma sürətin standart olaraq qaytarmaq üçün toxunub saxla</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Düymə göstərilmir</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Fərdi oynatma sürəti siyahısı</string>
<string name="revanced_custom_speed_menu_summary_on">Fərdi sürət siyahısı göstərilir</string>

View File

@@ -1466,6 +1466,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Кнопка паказана. Націсніце і ўтрымлівайце, каб скінуць хуткасць прайгравання да стандартнай</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Кнопка не паказваецца</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Паказаць кнопку якасці відэа</string>
<string name="revanced_video_quality_dialog_button_summary_on">Кнопка паказана. Націсніце і ўтрымлівайце, каб скінуць якасць да па змаўчанні</string>
<string name="revanced_video_quality_dialog_button_summary_off">Кнопка не паказваецца</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Меню пользовательской скорости воспроизведения</string>
<string name="revanced_custom_speed_menu_summary_on">Меню пользовательской скорости отображается</string>

View File

@@ -1465,6 +1465,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Бутонът е показан. Докоснете и задръжте, за да върнете скоростта на възпроизвеждане към стойността по подразбиране</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Бутонът не е показан</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Покажи бутона за качество на видеото</string>
<string name="revanced_video_quality_dialog_button_summary_on">Бутонът е показан. Докоснете и задръжте, за да възстановите качеството до подразбиране</string>
<string name="revanced_video_quality_dialog_button_summary_off">Бутонът не е показан</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Менюто за потребителска скорост</string>
<string name="revanced_custom_speed_menu_summary_on">Менюто за потребителска скорост се показва</string>

View File

@@ -1461,6 +1461,11 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
<string name="revanced_playback_speed_dialog_button_summary_on">বোতামটি দেখানো হয়েছে। প্লেব্যাক স্পীড ডিফল্টে রিসেট করতে ট্যাপ করে ধরে রাখুন।</string>
<string name="revanced_playback_speed_dialog_button_summary_off">বোতাম প্রদর্শিত হয়নি</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">ভিডিও গুণমান বোতাম দেখান</string>
<string name="revanced_video_quality_dialog_button_summary_on">বোতামটি দেখানো হয়েছে। গুণমান ডিফল্টে রিসেট করতে ট্যাপ করে ধরে রাখুন।</string>
<string name="revanced_video_quality_dialog_button_summary_off">বোতামটি দেখানো হয়নি।</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">কাস্টম প্লেব্যাক গতি মেনু</string>
<string name="revanced_custom_speed_menu_summary_on">কাস্টম স্পিড মেনু দেখানো হচ্ছে</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1465,6 +1465,11 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Tlačítko je zobrazeno. Klepnutím a podržením obnovíte výchozí rychlost přehrávání</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Tlačítko se nezobrazuje</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Zobrazit tlačítko kvality videa</string>
<string name="revanced_video_quality_dialog_button_summary_on">Tlačítko je zobrazeno. Klepnutím a podržením obnovíte kvalitu na výchozí</string>
<string name="revanced_video_quality_dialog_button_summary_off">Tlačítko není zobrazeno.</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu vlastní rychlosti přehrávání</string>
<string name="revanced_custom_speed_menu_summary_on">Menu vlastní rychlosti se zobrazuje</string>

View File

@@ -1467,6 +1467,11 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Knappen vises. Tryk og hold for at nulstille afspilningshastigheden til standard.</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Knap vises ikke</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Vis videokvalitetsknap</string>
<string name="revanced_video_quality_dialog_button_summary_on">Knap vises. Tryk og hold nede for at nulstille kvaliteten til standard</string>
<string name="revanced_video_quality_dialog_button_summary_off">Knappen vises ikke</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Tilpasset afspilningshastighed menu</string>
<string name="revanced_custom_speed_menu_summary_on">Tilpasset hastighed menu er vist</string>

View File

@@ -1460,6 +1460,11 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w
<string name="revanced_playback_speed_dialog_button_summary_on">Die Schaltfläche wird angezeigt. Tippen und halten, um die Wiedergabegeschwindigkeit auf die Standardeinstellung zurückzusetzen.</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Button wird nicht angezeigt</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Videoqualität-Schaltfläche anzeigen</string>
<string name="revanced_video_quality_dialog_button_summary_on">Schaltfläche wird angezeigt. Tippen und halten, um die Qualität auf Standard zurückzusetzen</string>
<string name="revanced_video_quality_dialog_button_summary_off">Schaltfläche wird nicht angezeigt</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Benutzerdefiniertes Wiedergabegeschwindigkeitsmenü</string>
<string name="revanced_custom_speed_menu_summary_on">Benutzerdefiniertes Geschwindigkeitsmenü wird angezeigt</string>

View File

@@ -1464,6 +1464,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Το κουμπί εμφανίζεται. Πατήστε παρατεταμένα για επαναφορά της ταχύτητας αναπαραγωγής στην προεπιλογή</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Το κουμπί δεν εμφανίζεται</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Εμφάνιση κουμπιού αλλαγής ποιότητας βίντεο</string>
<string name="revanced_video_quality_dialog_button_summary_on">Το κουμπί εμφανίζεται. Πατήστε παρατεταμένα για επαναφορά της ποιότητας στην προεπιλογή</string>
<string name="revanced_video_quality_dialog_button_summary_off">Το κουμπί δεν εμφανίζεται</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Μενού προσαρμοσμένης ταχύτητας αναπαραγωγής</string>
<string name="revanced_custom_speed_menu_summary_on">Το μενού προσαρμοσμένης ταχύτητας αναπαραγωγής εμφανίζεται</string>

View File

@@ -1456,6 +1456,11 @@ Habilitar esto puede desbloquear calidades de vídeo más altas"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Se muestra el botón. Mantén pulsado para restablecer la velocidad de reproducción predeterminada</string>
<string name="revanced_playback_speed_dialog_button_summary_off">El botón no se muestra</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Mostrar botón de calidad de video</string>
<string name="revanced_video_quality_dialog_button_summary_on">Botón visible. Toca y mantén para restablecer la calidad a los valores predeterminados</string>
<string name="revanced_video_quality_dialog_button_summary_off">Botón no visible</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menú de velocidad de reproducción personalizada</string>
<string name="revanced_custom_speed_menu_summary_on">Menú de velocidad personalizado se muestra</string>

View File

@@ -1465,6 +1465,11 @@ Selle lubamine võib avada kõrgema video kvaliteedi"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Nupp on nähtaval. Puudutage ja hoidke all, et taastada taasesituse kiirus vaikeväärtusele</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Nuppi ei kuvata</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Näita video kvaliteedi nuppu</string>
<string name="revanced_video_quality_dialog_button_summary_on">Nupp on nähtaval. Kvaliteedi lähtestamiseks vaikeseadeteks puudutage ja hoidke</string>
<string name="revanced_video_quality_dialog_button_summary_off">Nuppu ei kuvata</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Kohandatud taasesituse kiiruse menüü</string>
<string name="revanced_custom_speed_menu_summary_on">Kohandatud kiiruse menüü kuvatakse</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -272,6 +272,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1465,10 +1465,15 @@ Tämä voi avata korkealaatuisemmat videot"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Painike näytetään. Napauta ja pidä pohjassa palauttaaksesi soiton nopeuden oletukseksi</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Painiketta ei näytetä</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Mukautettu toistonopeusvalikko</string>
<string name="revanced_custom_speed_menu_summary_on">Mukautettu nopeusvalikko näytetään</string>
<string name="revanced_custom_speed_menu_summary_off">Mukautettua nopeusvalikkoa ei näytetä</string>
<string name="revanced_restore_old_speed_menu_title">Palauta vanha toistonopeusvalikko</string>
<string name="revanced_restore_old_speed_menu_summary_on">Vanha nopeusvalikko näytetään</string>
<string name="revanced_restore_old_speed_menu_summary_off">Moderni nopeusvalikko näytetään</string>
<string name="revanced_custom_playback_speeds_title">Mukautetut toistonopeudet</string>
<string name="revanced_custom_playback_speeds_summary">Lisää tai muuta mukautettuja toistonopeuksia</string>
<string name="revanced_custom_playback_speeds_invalid">Mukautettujen nopeuksien tulee olla alle %s</string>

View File

@@ -1463,6 +1463,11 @@ Ang pagpapagana nito ay maaaring magbukas ng mas mataas na kalidad ng video"</st
<string name="revanced_playback_speed_dialog_button_summary_on">Ipinapakita ang button. I-tap at i-hold para i-reset ang bilis ng pag-playback sa default</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Hindi ipinapakita ang button</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Ipakita ang button ng kalidad ng video</string>
<string name="revanced_video_quality_dialog_button_summary_on">Nakalabas ang button. Pindutin nang matagal para ibalik sa default ang kalidad</string>
<string name="revanced_video_quality_dialog_button_summary_off">Hindi ipinapakita ang buton</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu ng pasadyang bilis ng pag-playback</string>
<string name="revanced_custom_speed_menu_summary_on">Ipinapakita ang menu ng pasadyang bilis</string>

View File

@@ -1466,6 +1466,11 @@ Activer cette option peut déverrouiller des qualités vidéo supérieures"</str
<string name="revanced_playback_speed_dialog_button_summary_on">Le bouton est affiché. Appuyez longuement dessus pour rétablir la vitesse de lecture par défaut.</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Le bouton n\'est pas affiché</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Afficher le bouton de qualité vidéo</string>
<string name="revanced_video_quality_dialog_button_summary_on">Le bouton est affiché. Appuyez longuement pour réinitialiser la qualité par défaut</string>
<string name="revanced_video_quality_dialog_button_summary_off">Le bouton n\'est pas affiché</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu de vitesse de lecture personnalisée</string>
<string name="revanced_custom_speed_menu_summary_on">Le menu de vitesse personnalisée est affiché</string>

View File

@@ -1465,6 +1465,11 @@ Is féidir le seo caighdeáin físeáin níos airde a dhíghlasáil"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Taispeántar an cnaipe. Tapáil agus coinnigh chun luas athsheinm a athshocrú go réamhshocrú</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Ní thaispeántar an cnaipe</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Taispeáin cnaipe cáilíochta físeáin</string>
<string name="revanced_video_quality_dialog_button_summary_on">Tá cnaipe le feiceáil. Tapáil agus coinnigh chun cáilíocht a athshocrú mar réamhshocrú</string>
<string name="revanced_video_quality_dialog_button_summary_off">Níl cnaipe le feiceáil</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Roghchlár luas athsheinm saincheaptha</string>
<string name="revanced_custom_speed_menu_summary_on">Taispeántar roghchlár luais saincheaptha</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1462,6 +1462,11 @@ Ez a beállítás lehetővé teszi a magasabb videóminőségek feloldását"</s
<string name="revanced_playback_speed_dialog_button_summary_on">A gomb látható. Tartsa lenyomva a lejátszási sebesség alapértelmezettre állításához</string>
<string name="revanced_playback_speed_dialog_button_summary_off">A gomb nem látható</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Videóminőség gomb megjelenítése</string>
<string name="revanced_video_quality_dialog_button_summary_on">A gomb látható. Tartsa lenyomva a minőséget az alapértelmezettre visszaállításához</string>
<string name="revanced_video_quality_dialog_button_summary_off">A gomb nem látható</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Egyedi lejátszási sebesség menü</string>
<string name="revanced_custom_speed_menu_summary_on">Megjelenik az egyéni sebesség menü</string>

View File

@@ -1466,6 +1466,11 @@ Mini-player-ը կարող է գրավվել էկրանից դուրս՝ դեպի
<string name="revanced_playback_speed_dialog_button_summary_on">Կոճակը ցուցադրվում է: Հպեք և պահեք՝ նվագարկման արագությունը լռելյայնի վերականգնելու համար</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Կոճակը չի ցուցադրվում</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Ցուցադրել տեսանյութի որակի կոճակը</string>
<string name="revanced_video_quality_dialog_button_summary_on">Կոճակը ցուցադրված է։ Սեղմեք և պահեք՝ որակը լռելյայն վիճակի վերականգնելու համար</string>
<string name="revanced_video_quality_dialog_button_summary_off">Կոճակը ցուցադրված չէ։</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Տեսանյութի արագության հարմարեցված մենյու</string>
<string name="revanced_custom_speed_menu_summary_on">Հարմարեցված արագության մենյուը ցուցադրվում է</string>

View File

@@ -1464,6 +1464,11 @@ Mengaktifkan ini dapat membuka kualitas video yang lebih tinggi"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Tombol ditampilkan. Ketuk dan tahan untuk mengatur ulang kecepatan pemutaran ke bawaan</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Tombol tidak ditampilkan</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Tampilkan tombol kualitas video</string>
<string name="revanced_video_quality_dialog_button_summary_on">Tombol ditampilkan. Ketuk dan tahan untuk mengatur ulang kualitas ke default</string>
<string name="revanced_video_quality_dialog_button_summary_off">Tombol tidak ditampilkan</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu kecepatan pemutaran khusus</string>
<string name="revanced_custom_speed_menu_summary_on">Menu kecepatan khusus ditampilkan</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1464,6 +1464,11 @@ Abilitare questa opzione può sbloccare qualità video più elevate"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Il pulsante è visualizzato. Tieni premuto per ripristinare la velocità di riproduzione predefinita</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Il pulsante non è visibile</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Mostra il pulsante qualità video</string>
<string name="revanced_video_quality_dialog_button_summary_on">Il pulsante è visibile. Tocca e tieni premuto per ripristinare la qualità predefinita.</string>
<string name="revanced_video_quality_dialog_button_summary_off">Il pulsante non è visibile.</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu di velocità di riproduzione personalizzato</string>
<string name="revanced_custom_speed_menu_summary_on">Il menu di velocità personalizzato è visibile</string>

View File

@@ -1467,6 +1467,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">הלחצן מוצג. יש להקיש ולהחזיק כדי לאפס את מהירות ההפעלה לברירת מחדל</string>
<string name="revanced_playback_speed_dialog_button_summary_off">הלחצן אינו מוצג</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">הצג כפתור איכות וידאו</string>
<string name="revanced_video_quality_dialog_button_summary_on">הלחצן מוצג. גע והחזק כדי לאפס את האיכות לברירת מחדל</string>
<string name="revanced_video_quality_dialog_button_summary_off">הלחצן אינו מוצג</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">תפריט מהירות הפעלה מותאם אישית</string>
<string name="revanced_custom_speed_menu_summary_on">תפריט מהירות מותאם אישית מוצג</string>

View File

@@ -475,9 +475,9 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_external_downloader_other_item">その他</string>
<string name="revanced_external_downloader_not_found_title">アプリがインストールされていません</string>
<string name="revanced_external_downloader_not_installed_warning">%s はインストールされていません。インストールしてください。</string>
<string name="revanced_external_downloader_package_not_found_warning">"パッケージ名 %s のインストール済みアプリが見つかりませんでした
<string name="revanced_external_downloader_package_not_found_warning">"パッケージ名%sのインストール済みアプリが見つかりませんでした
パッケージ名が正しいこと、およびアプリがインストールされていることを確認してください"</string>
パッケージ名が正しいこと、アプリがインストールされていることを確認してください"</string>
<string name="revanced_external_downloader_empty_warning">パッケージ名は空欄にはできません</string>
</patch>
<patch id="interaction.seekbar.disablePreciseSeekingGesturePatch">
@@ -1461,10 +1461,15 @@ Automotive レイアウト
<string name="revanced_remember_video_quality_toast_shorts">ショートの画質 (%1$s): %2$s</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">再生速度設定ボタンを表示する</string>
<string name="revanced_playback_speed_dialog_button_summary_on">ボタンオーバーレイに表示されます。長押しすると、再生速度がデフォルトの値にリセットされます</string>
<string name="revanced_playback_speed_dialog_button_title">再生速度設定ボタンを表示</string>
<string name="revanced_playback_speed_dialog_button_summary_on">ボタンオーバーレイに表示されます。長押しすると、再生速度がデフォルトの値にリセットされます</string>
<string name="revanced_playback_speed_dialog_button_summary_off">ボタンはオーバーレイに表示されません</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">画質設定ボタンを表示</string>
<string name="revanced_video_quality_dialog_button_summary_on">ボタンがオーバーレイに表示されます。長押しすると、画質がデフォルトの値にリセットされます</string>
<string name="revanced_video_quality_dialog_button_summary_off">ボタンはオーバーレイに表示されません</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">カスタム再生速度メニュー</string>
<string name="revanced_custom_speed_menu_summary_on">カスタム再生速度リストが再生速度メニューに表示されます</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -237,6 +237,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1472,6 +1472,11 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">버튼을 표시합니다\n\n• 버튼을 길게 누르면 동영상 재생 속도가 기본값으로 초기화됩니다</string>
<string name="revanced_playback_speed_dialog_button_summary_off">버튼을 표시하지 않습니다</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">동영상 화질 버튼 표시하기</string>
<string name="revanced_video_quality_dialog_button_summary_on">버튼을 표시합니다\n\n• 버튼을 길게 누르면 화질이 기본값으로 초기화됩니다</string>
<string name="revanced_video_quality_dialog_button_summary_off">버튼을 표시하지 않습니다</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">사용자 정의 동영상 재생 속도 활성화하기</string>
<string name="revanced_custom_speed_menu_summary_on">사용자 정의 동영상 재생 속도를 활성화합니다</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1464,6 +1464,11 @@ Gali būti atrakinta aukštesnės vaizdo įrašų kokybės, bet galite patirti v
<string name="revanced_playback_speed_dialog_button_summary_on">Mygtukas rodomas. Palieskite ir palaikykite, kad atkūrimo greitį nustatytumėte į numatytąjį.</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Mygtukas nerodomas</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Rodyti vaizdo kokybės mygtuką</string>
<string name="revanced_video_quality_dialog_button_summary_on">Mygtukas rodomas. Palaikykite nuspaudę, kad atstatytumėte kokybę į numatytąją</string>
<string name="revanced_video_quality_dialog_button_summary_off">Mygtukas nerodomas</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Tinkintas atkūrimo greičio meniu</string>
<string name="revanced_custom_speed_menu_summary_on">Tinkintas greičio meniu rodomas</string>

View File

@@ -1466,6 +1466,11 @@ Var tikt atbloķētas augstākas video kvalitātes, taču var rasties video atsk
<string name="revanced_playback_speed_dialog_button_summary_on">Poga ir redzama. Pieskarieties un turiet, lai atiestatītu atskaņošanas ātrumu uz noklusējuma</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Poga netiek rādīta</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Rādīt video kvalitātes pogu</string>
<string name="revanced_video_quality_dialog_button_summary_on">Poga tiek rādīta. Pieskarieties un turiet, lai atiestatītu kvalitāti uz noklusējuma</string>
<string name="revanced_video_quality_dialog_button_summary_off">Poga netiek rādīta</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Pielāgotas atskaņošanas ātruma izvēlne</string>
<string name="revanced_custom_speed_menu_summary_on">Pielāgotas ātruma izvēlne tiek rādīta</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -223,6 +223,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1463,6 +1463,11 @@ Het inschakelen hiervan kan hogere videokwaliteiten ontgrendelen"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">De knop wordt weergegeven. Tik en houd vast om de afspeelsnelheid terug te zetten naar de standaardwaarde</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Knop wordt niet weergegeven</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Toon videokwaliteitknop</string>
<string name="revanced_video_quality_dialog_button_summary_on">Knop wordt weergegeven. Tik en houd vast om de kwaliteit terug te zetten naar standaard</string>
<string name="revanced_video_quality_dialog_button_summary_off">Knop wordt niet weergegeven</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu voor aangepaste afspeelsnelheid</string>
<string name="revanced_custom_speed_menu_summary_on">Menu voor aangepaste snelheid wordt weergegeven</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1461,6 +1461,11 @@ Włączenie tego może odblokować wyższe jakości wideo"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Przycisk jest widoczny. Dotknij i przytrzymaj, aby zresetować prędkość odtwarzania do domyślnej</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Przycisk nie jest widoczny</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Pokaż przycisk jakości wideo</string>
<string name="revanced_video_quality_dialog_button_summary_on">Przycisk jest widoczny. Dotknij i przytrzymaj, aby zresetować jakość do wartości domyślnych</string>
<string name="revanced_video_quality_dialog_button_summary_off">Przycisk nie jest widoczny</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Niestandardowe menu prędkości odtwarzania</string>
<string name="revanced_custom_speed_menu_summary_on">Niestandardowe menu prędkości jest widoczne</string>

View File

@@ -1464,6 +1464,11 @@ Habilitar isso pode desbloquear qualidades de vídeo mais altas"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">O botão é exibido. Toque e mantenha pressionado para redefinir a velocidade de reprodução para o padrão</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Botão não está visível</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Mostrar botão de qualidade de vídeo</string>
<string name="revanced_video_quality_dialog_button_summary_on">O botão é exibido. Toque e segure para redefinir a qualidade para o padrão</string>
<string name="revanced_video_quality_dialog_button_summary_off">O botão não é exibido</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu de velocidade de reprodução personalizado</string>
<string name="revanced_custom_speed_menu_summary_on">O menu de velocidade personalizado é mostrado</string>

View File

@@ -1465,6 +1465,11 @@ Bật tính năng này có thể mở khóa chất lượng video cao hơn"</str
<string name="revanced_playback_speed_dialog_button_summary_on">O botão é mostrado. Toque e segure para redefinir a velocidade de reprodução para o padrão</string>
<string name="revanced_playback_speed_dialog_button_summary_off">O botão não está visível</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Mostrar botão de qualidade de vídeo</string>
<string name="revanced_video_quality_dialog_button_summary_on">O botão é exibido. Toque e segure para redefinir a qualidade para o padrão</string>
<string name="revanced_video_quality_dialog_button_summary_off">O botão não é exibido</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu personalizado de velocidade de reprodução</string>
<string name="revanced_custom_speed_menu_summary_on">O menu de velocidade personalizado é exibido</string>

View File

@@ -1464,6 +1464,11 @@ Activarea acestei opțiuni poate debloca calități video mai mari"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Butonul este afișat. Atingeți și mențineți apăsat pentru a reseta viteza de redare la cea implicită</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Butonul nu este afișat</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Afișați butonul de calitate video</string>
<string name="revanced_video_quality_dialog_button_summary_on">Butonul este afișat. Atingeți și mențineți apăsat pentru a reseta calitatea la valoarea implicită</string>
<string name="revanced_video_quality_dialog_button_summary_off">Butonul nu este afișat.</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Meniu de redare personalizat</string>
<string name="revanced_custom_speed_menu_summary_on">Meniul de viteză personalizat este afișat</string>

View File

@@ -1472,6 +1472,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Кнопка показана. Нажмите и удерживайте, чтобы сбросить скорость воспроизведения до значения по умолчанию</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Кнопка выбора скорости воспроизведения скрыта</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Показать кнопку качества видео</string>
<string name="revanced_video_quality_dialog_button_summary_on">Кнопка показана. Нажмите и удерживайте, чтобы сбросить качество до значения по умолчанию</string>
<string name="revanced_video_quality_dialog_button_summary_off">Кнопка выбора скорости воспроизведения скрыта</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Показать кастомное меню скорости</string>
<string name="revanced_custom_speed_menu_summary_on">Кастомное меню скорости воспроизведения показано</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1458,6 +1458,11 @@ Povolením tejto možnosti môžete odomknúť vyššie kvality videa"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Zobrazuje sa tlačidlo. Ťuknite a podržte, ak chcete obnoviť predvolenú rýchlosť prehrávania</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Tlačidlo nie je zobrazené</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Zobraziť tlačidlo kvality videa</string>
<string name="revanced_video_quality_dialog_button_summary_on">Tlačidlo sa zobrazí. Klepnite a podržte pre resetovanie kvality na predvolenú</string>
<string name="revanced_video_quality_dialog_button_summary_off">Tlačidlo sa nezobrazuje</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menu vlastnej rýchlosti prehrávania</string>
<string name="revanced_custom_speed_menu_summary_on">Menu vlastnej rýchlosti sa zobrazuje</string>

View File

@@ -1465,6 +1465,11 @@ Omogočanje tega lahko odklene višje kakovosti videa"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Gumb je prikazan. Dotaknite se ga in ga pridržite, da ponastavite hitrost predvajanja na privzeto.</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Gumb ni prikazan</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Prikaži gumb za kakovost videa</string>
<string name="revanced_video_quality_dialog_button_summary_on">Prikazan je gumb. Dotaknite se in držite, da ponastavite kakovost na privzeto</string>
<string name="revanced_video_quality_dialog_button_summary_off">Gumb ni prikazan</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Meni za nastavitev hitrosti predvajanja</string>
<string name="revanced_custom_speed_menu_summary_on">Meni za nastavitev hitrosti je prikazan</string>

View File

@@ -1463,6 +1463,11 @@ Aktivizimi i kësaj mund të zhbllokojë cilësi më të larta video"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Butoni shfaqet. Prekni dhe mbani për të rivendosur shpejtësinë e riprodhimit në atë të parazgjedhur</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Butoni nuk shfaqet</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Shfaq butonin e cilësisë së videos</string>
<string name="revanced_video_quality_dialog_button_summary_on">Butoni shfaqet. Prekni dhe mbani shtypur për të rivendosur cilësinë në parazgjedhur</string>
<string name="revanced_video_quality_dialog_button_summary_off">Butoni nuk shfaqet</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Menyja e shpejtësisë së përsëritjes së përshtatshme</string>
<string name="revanced_custom_speed_menu_summary_on">Menyja e shpejtësisë së përshtatshme shfaqet</string>

View File

@@ -1464,6 +1464,11 @@ Ako ovo omogućite, mogu biti otključani viši kvaliteti videa"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Dugme je prikazano. Dodirnite i zadržite da biste vratili brzinu reprodukcije na podrazumevanu vrednost</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Dugme dijaloga za brzinu nije prikazano</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Prikaži dugme za kvalitet video zapisa</string>
<string name="revanced_video_quality_dialog_button_summary_on">Dugme je prikazano. Dodirnite i zadržite za resetovanje kvaliteta na podrazumevano</string>
<string name="revanced_video_quality_dialog_button_summary_off">Dugme nije prikazano</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Meni prilagođene brzine reprodukcije</string>
<string name="revanced_custom_speed_menu_summary_on">Meni prilagođene brzine reprodukcije je prikazan</string>

View File

@@ -1467,6 +1467,11 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Дугме је приказано. Додирните и задржите да бисте вратили брзину репродукције на подразумевану вредност</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Дугме дијалога за брзину није приказано</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Прикажи дугме за квалитет видеа</string>
<string name="revanced_video_quality_dialog_button_summary_on">Дугме је приказано. Притисните и држите да бисте ресетовали квалитет на подразумевани</string>
<string name="revanced_video_quality_dialog_button_summary_off">Дугме није приказано</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Мени прилагођене брзине репродукције</string>
<string name="revanced_custom_speed_menu_summary_on">Мени прилагођене брзине репродукције је приказан</string>

View File

@@ -1464,6 +1464,11 @@ Om du aktiverar detta kan högre videokvaliteter låsas upp"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Knappen visas. Tryck länge för att återställa uppspelningshastigheten till standardhastigheten</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Knappen visas inte</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Visa videokvalitetsknapp</string>
<string name="revanced_video_quality_dialog_button_summary_on">Knappen visas. Tryck länge för att återställa kvaliteten till standardkvaliteten</string>
<string name="revanced_video_quality_dialog_button_summary_off">Knappen visas inte</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Anpassad meny för uppspelningshastighet</string>
<string name="revanced_custom_speed_menu_summary_on">Anpassad hastighetsmeny visas</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -1467,6 +1467,11 @@ User id ของคุณเหมือนกับรหัสผ่าน
<string name="revanced_playback_speed_dialog_button_summary_on">ปุ่มจะปรากฏขึ้น แตะค้างไว้เพื่อรีเซ็ตความเร็วในการเล่นเป็นค่าเริ่มต้น</string>
<string name="revanced_playback_speed_dialog_button_summary_off">ไม่แสดงปุ่ม</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">แสดงปุ่มคุณภาพวิดีโอ</string>
<string name="revanced_video_quality_dialog_button_summary_on">แสดงปุ่มแล้ว แตะค้างไว้เพื่อรีเซ็ตคุณภาพเป็นค่าเริ่มต้น</string>
<string name="revanced_video_quality_dialog_button_summary_off">ไม่ได้แสดงปุ่ม</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">เมนูกำหนดความเร็วในการเล่นแบบกำหนดเอง</string>
<string name="revanced_custom_speed_menu_summary_on">แสดงเมนูกำหนดความเร็ว</string>

View File

@@ -299,28 +299,28 @@ Bir Doodle şu anda bölgenizde gösteriliyorsa ve bu gizleme ayarııksa, a
<string name="revanced_hide_for_you_shelf_title">\'Sizin için\' rafını gizle</string>
<string name="revanced_hide_for_you_shelf_summary_on">Sizin İçin rafı gizli</string>
<string name="revanced_hide_for_you_shelf_summary_off">Sizin İçin rafı görünür</string>
<string name="revanced_hide_links_preview_title">Bağlantı önizlemesini gizle</string>
<string name="revanced_hide_links_preview_summary_on">Bağlantı önizlemesi gizli</string>
<string name="revanced_hide_links_preview_summary_off">Bağlantı önizlemesi görünür</string>
<string name="revanced_hide_links_preview_title">Bağlantı ön izlemesini gizle</string>
<string name="revanced_hide_links_preview_summary_on">Bağlantı ön izlemesi gizli</string>
<string name="revanced_hide_links_preview_summary_off">Bağlantı ön izlemesi görünür</string>
<string name="revanced_hide_members_shelf_title">Üyeler rafını gizle</string>
<string name="revanced_hide_members_shelf_summary_on">Üyeler rafı gizli</string>
<string name="revanced_hide_members_shelf_summary_off">Üyeler rafısteriliyor</string>
<string name="revanced_hide_members_shelf_summary_off">Üyeler rafırünür</string>
<!-- 'Visit Community' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_visit_community_button_title">\'Topluluğu Ziyaret Et\' düğmesini gizle</string>
<string name="revanced_hide_visit_community_button_summary_on">Topluluğu Ziyaret Et düğmesi gizli</string>
<string name="revanced_hide_visit_community_button_summary_off">Topluluğu Ziyaret Et düğmesi görünür</string>
<!-- 'Visit store' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_visit_store_button_title">Kanal sayfalarındaki \'Mağazayı ziyaret et\' düğmesini gizle</string>
<string name="revanced_hide_visit_store_button_summary_on">Mağazayı Ziyaret Et düğmesi gizli</string>
<string name="revanced_hide_visit_store_button_summary_off">Mağazayı Ziyaret Et düğmesi görünür</string>
<string name="revanced_hide_visit_store_button_title">\'Mağazayı ziyaret et\' düğmesini gizle</string>
<string name="revanced_hide_visit_store_button_summary_on">Mağazayı ziyaret et düğmesi gizli</string>
<string name="revanced_hide_visit_store_button_summary_off">Mağazayı ziyaret et düğmesi görünür</string>
<string name="revanced_comments_screen_title">Yorumlar</string>
<string name="revanced_comments_screen_summary">Yorumlar kısmı bileşenlerini gizle veya göster</string>
<string name="revanced_hide_comments_ai_chat_summary_title">Yapay zeka sohbet özetini gizle</string>
<string name="revanced_hide_comments_ai_chat_summary_summary_on">Yapay zeka sohbet özeti gizli</string>
<string name="revanced_hide_comments_ai_chat_summary_summary_off">Yapay zeka sohbet özeti gösteriliyor</string>
<string name="revanced_hide_comments_ai_summary_title">Yapay zeka yorumlar özetini gizle</string>
<string name="revanced_hide_comments_ai_summary_summary_on">Yapay zeka yorum özeti gizli</string>
<string name="revanced_hide_comments_ai_summary_summary_off">Yapay zeka yorum özeti gösteriliyor</string>
<string name="revanced_hide_comments_ai_chat_summary_summary_off">Yapay zeka sohbet özeti görünür</string>
<string name="revanced_hide_comments_ai_summary_title">Yapay zeka yorumların özetini gizle</string>
<string name="revanced_hide_comments_ai_summary_summary_on">Yapay zeka yorumların özeti gizli</string>
<string name="revanced_hide_comments_ai_summary_summary_off">Yapay zeka yorumların özeti görünür</string>
<string name="revanced_hide_comments_channel_guidelines_title">Kanal yönergelerini gizle</string>
<string name="revanced_hide_comments_channel_guidelines_summary_on">Kanal yönergeleri gizli</string>
<string name="revanced_hide_comments_channel_guidelines_summary_off">Kanal yönergeleri görünür</string>
@@ -342,7 +342,7 @@ Bir Doodle şu anda bölgenizde gösteriliyorsa ve bu gizleme ayarııksa, a
<string name="revanced_hide_comments_thanks_button_title">Teşekkürler düğmesini gizle</string>
<string name="revanced_hide_comments_thanks_button_summary_on">Teşekkürler düğmesi gizli</string>
<string name="revanced_hide_comments_thanks_button_summary_off">Teşekkürler düğmesi görünür</string>
<string name="revanced_hide_comments_timestamp_button_title">Zaman Damgası düğmesini gizle</string>
<string name="revanced_hide_comments_timestamp_button_title">Zaman damgası düğmesini gizle</string>
<string name="revanced_hide_comments_timestamp_button_summary_on">Zaman damgası düğmesi gizli</string>
<string name="revanced_hide_comments_timestamp_button_summary_off">Zaman damgası düğmesi görünür</string>
<string name="revanced_custom_filter_screen_title">Özel filtre</string>
@@ -555,43 +555,43 @@ Ekranın sağ tarafında dikey olarak kaydırarak sesi ayarlayın"</string>
<string name="revanced_hide_like_dislike_button_summary_on">Beğenme ve Beğenmeme düğmeleri gizli</string>
<string name="revanced_hide_like_dislike_button_summary_off">Beğenme ve Beğenmeme düğmeleri görünür</string>
<!-- 'Share' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_share_button_title">Paylaşmayı gizle</string>
<string name="revanced_hide_share_button_summary_on">Paylaşma düğmesi gizli</string>
<string name="revanced_hide_share_button_summary_off">Paylaşma düğmesi görünür</string>
<string name="revanced_hide_share_button_title">Paylaş\'ı gizle</string>
<string name="revanced_hide_share_button_summary_on">Paylaş düğmesi gizli</string>
<string name="revanced_hide_share_button_summary_off">Paylaş düğmesi görünür</string>
<!-- 'Stop ads' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_stop_ads_button_title">Reklamları Durdur\'u Gizle</string>
<string name="revanced_hide_stop_ads_button_summary_on">Reklamları durdur düğmesi gizlendi</string>
<string name="revanced_hide_stop_ads_button_summary_off">Reklamları durdur düğmesi gösterildi</string>
<string name="revanced_hide_stop_ads_button_title">Reklamları durdur\'u Gizle</string>
<string name="revanced_hide_stop_ads_button_summary_on">Reklamları durdur düğmesi gizli</string>
<string name="revanced_hide_stop_ads_button_summary_off">Reklamları durdur düğmesi görünür</string>
<!-- 'Report' should be translated with the same localized wording that YouTube displays.
This button usually appears only on live streams. -->
<string name="revanced_hide_report_button_title">Bildirmeyi gizle</string>
<string name="revanced_hide_report_button_summary_on">Bildirme düğmesi gizli</string>
<string name="revanced_hide_report_button_summary_off">Bildirme düğmesi görünür</string>
<string name="revanced_hide_report_button_title">Bildir\'i gizle</string>
<string name="revanced_hide_report_button_summary_on">Bildir düğmesi gizli</string>
<string name="revanced_hide_report_button_summary_off">Bildir düğmesi görünür</string>
<!-- 'Remix' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_remix_button_title">Remix düğmesini gizle</string>
<string name="revanced_hide_remix_button_title">Remix\'i gizle</string>
<string name="revanced_hide_remix_button_summary_on">Remix düğmesi gizli</string>
<string name="revanced_hide_remix_button_summary_off">Remix düğmesi görünür</string>
<!-- 'Download' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_download_button_title">İndirmeyi gizle</string>
<string name="revanced_hide_download_button_summary_on">İndirme düğmesi gizli</string>
<string name="revanced_hide_download_button_summary_off">İndirme düğmesi görünür</string>
<string name="revanced_hide_download_button_title">İndir\'i gizle</string>
<string name="revanced_hide_download_button_summary_on">İndir düğmesi gizli</string>
<string name="revanced_hide_download_button_summary_off">İndir düğmesi görünür</string>
<!-- 'Thanks' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_thanks_button_title">Teşekkürler düğmesini gizle</string>
<string name="revanced_hide_thanks_button_title">Teşekkürler\'i gizle</string>
<string name="revanced_hide_thanks_button_summary_on">Teşekkürler düğmesi gizli</string>
<string name="revanced_hide_thanks_button_summary_off">Teşekkürler düğmesi görünür</string>
<!-- 'Ask' should be translated with the same localized wording that YouTube displays.
This button only shows up if the user ip is from specific region such as the USA or EU. -->
<string name="revanced_hide_ask_button_title">\'Sor\'u gizle</string>
<string name="revanced_hide_ask_button_title">Sor\'u gizle</string>
<string name="revanced_hide_ask_button_summary_on">Sor düğmesi gizli</string>
<string name="revanced_hide_ask_button_summary_off">Sor düğmesi görünür</string>
<!-- 'Clip' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_clip_button_title">Klip düğmesini gizle</string>
<string name="revanced_hide_clip_button_title">Klip\'i gizle</string>
<string name="revanced_hide_clip_button_summary_on">Klip düğmesi gizli</string>
<string name="revanced_hide_clip_button_summary_off">Klip düğmesi görünür</string>
<!-- 'Save' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_save_button_title">Kaydet\'i Gizle</string>
<string name="revanced_hide_save_button_summary_on">Kaydet düğmesi gizlendi</string>
<string name="revanced_hide_save_button_summary_off">Kaydet düğmesi gösterildi</string>
<string name="revanced_hide_save_button_summary_on">Kaydet düğmesi gizli</string>
<string name="revanced_hide_save_button_summary_off">Kaydet düğmesi görünür</string>
</patch>
<patch id="layout.buttons.navigation.navigationButtonsPatch">
<string name="revanced_navigation_buttons_screen_title">Gezinme düğmeleri</string>
@@ -722,8 +722,8 @@ Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayar
</patch>
<patch id="layout.hide.fullscreenambientmode.disableFullscreenAmbientModePatch">
<string name="revanced_disable_fullscreen_ambient_mode_title">Tam ekranda ambiyans modunu devre dışı bırak</string>
<string name="revanced_disable_fullscreen_ambient_mode_summary_on">Tam ekranda ambiyans modu devre dışı</string>
<string name="revanced_disable_fullscreen_ambient_mode_summary_off">Tam ekranda ambiyans modu etkin</string>
<string name="revanced_disable_fullscreen_ambient_mode_summary_on">Ambiyans modu devre dışı</string>
<string name="revanced_disable_fullscreen_ambient_mode_summary_off">Ambiyans modu etkin</string>
</patch>
<patch id="layout.hide.infocards.hideInfocardsResourcePatch">
<string name="revanced_hide_info_cards_title">Bilgi kartlarını gizle</string>
@@ -736,13 +736,13 @@ Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayar
<string name="revanced_disable_rolling_number_animations_summary_off">Kayan sayı animasyonları etkin</string>
</patch>
<patch id="layout.hide.seekbar.hideSeekbarPatch">
<string name="revanced_hide_seekbar_title">Video oynatıcı kaydırma çubuğunu gizle</string>
<string name="revanced_hide_seekbar_summary_on">Video oynatıcısındaki zaman çubuğu gizli</string>
<string name="revanced_hide_seekbar_summary_off">Video oynatıcısındaki zaman çubuğu görünür</string>
<string name="revanced_hide_seekbar_title">Video oynatıcısı zaman çubuğunu gizle</string>
<string name="revanced_hide_seekbar_summary_on">Video oynatıcısı zaman çubuğu gizli</string>
<string name="revanced_hide_seekbar_summary_off">Video oynatıcısı zaman çubuğu görünür</string>
<!-- Seekbar shown inside video thumbnails found the home/feed/search/history. The seekbar shows the prior watch progress when the video was last open. -->
<string name="revanced_hide_seekbar_thumbnail_title">Video küçük resimleri kaydırma çubuğunu gizle</string>
<string name="revanced_hide_seekbar_thumbnail_summary_on">Video küçük resimleri kaydırma çubuğu gizli</string>
<string name="revanced_hide_seekbar_thumbnail_summary_off">Video küçük resimleri kaydırma çubuğu gösteriliyor</string>
<string name="revanced_hide_seekbar_thumbnail_title">Video kapak fotoğrafı zaman çubuğunu gizle</string>
<string name="revanced_hide_seekbar_thumbnail_summary_on">Video kapak fotoğrafı zaman çubuğu gizli</string>
<string name="revanced_hide_seekbar_thumbnail_summary_off">Video kapak fotoğrafı zaman çubuğu gösteriliyor</string>
</patch>
<patch id="layout.hide.shorts.hideShortsComponentsResourcePatch">
<string name="revanced_shorts_player_screen_title">Shorts oynatıcı</string>
@@ -751,22 +751,22 @@ Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayar
<string name="revanced_hide_shorts_home_title">Ana Sayfa akışında Shorts\'u gizle</string>
<string name="revanced_hide_shorts_home_summary_on">Ana Sayfa akışında ve ilgili videolarda gizli</string>
<string name="revanced_hide_shorts_home_summary_off">Ana Sayfa akışında ve ilgili videolarda görünür</string>
<string name="revanced_hide_shorts_search_title">Arama sonuçlarında Shorts videolarını gizle</string>
<string name="revanced_hide_shorts_search_title">Arama sonuçlarında Shorts\'u gizle</string>
<string name="revanced_hide_shorts_search_summary_on">Arama sonuçlarında gizli</string>
<string name="revanced_hide_shorts_search_summary_off">Arama sonuçlarında görünür</string>
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
<string name="revanced_hide_shorts_subscriptions_title">Abonelikler akışında Shorts\'u gizle</string>
<string name="revanced_hide_shorts_subscriptions_summary_on">Abonelikler akışında gizli</string>
<string name="revanced_hide_shorts_subscriptions_summary_off">Abonelikler akışında görünür</string>
<string name="revanced_hide_shorts_history_title">Shorts\'u izleme geçmişinde gizle</string>
<string name="revanced_hide_shorts_history_title">İzleme geçmişinde Shorts\'u gizle</string>
<string name="revanced_hide_shorts_history_summary_on">İzleme geçmişinde gizli</string>
<string name="revanced_hide_shorts_history_summary_off">İzleme geçmişinde görünür</string>
<string name="revanced_hide_shorts_super_thanks_button_title">Süper Teşekkürler düğmesini gizle</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_on">Süper Teşekkürler satın al düğmesi gizli</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_off">Süper Teşekkürler satın al düğmesi görünür</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_on">Süper Teşekkürler düğmesi gizli</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_off">Süper Teşekkürler düğmesi görünür</string>
<string name="revanced_hide_shorts_effect_button_title">Efekt düğmesini gizle</string>
<string name="revanced_hide_shorts_effect_button_summary_on">Efekt düğmesi gizli</string>
<string name="revanced_hide_shorts_effect_button_summary_off">Efekt düğmesi gösteriliyor</string>
<string name="revanced_hide_shorts_effect_button_summary_off">Efekt düğmesi görünür</string>
<string name="revanced_hide_shorts_green_screen_button_title">Yeşil ekran düğmesini gizle</string>
<string name="revanced_hide_shorts_green_screen_button_summary_on">Yeşil ekran düğmesi gizli</string>
<string name="revanced_hide_shorts_green_screen_button_summary_off">Yeşil ekran düğmesi görünür</string>
@@ -849,9 +849,9 @@ Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayar
<string name="revanced_hide_shorts_video_title_summary_on">Video başlığı gizli</string>
<string name="revanced_hide_shorts_video_title_summary_off">Video başlığı görünür</string>
<string name="revanced_hide_shorts_sound_metadata_label_title">Ses bilgisi etiketini gizle</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_on">Ses meta veri etiketi gizli</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_off">Ses meta veri etiketi görünür</string>
<string name="revanced_hide_shorts_full_video_link_label_title">Video bağlantı etiketini gizle</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_on">Ses bilgisi etiketi gizli</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_off">Ses bilgisi etiketi görünür</string>
<string name="revanced_hide_shorts_full_video_link_label_title">Video bağlantısı etiketini gizle</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_on">Video bağlantısı etiketi gizli</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_off">Video bağlantısı etiketi görünür</string>
<string name="revanced_hide_shorts_navigation_bar_title">Gezinme çubuğunu gizle</string>
@@ -864,12 +864,12 @@ Ses parçası menüsünü göstermek için 'Video akışlarını taklit et' ayar
Otomatik oynatma YouTube ayarlarından değiştirilebilir:
Ayarlar → Oynatma → Sonraki videoyu otomatik oynat"</string>
<string name="revanced_end_screen_suggested_video_summary_off">Bitiş ekranı önerilen videosu gösteriliyor</string>
<string name="revanced_end_screen_suggested_video_summary_off">Bitiş ekranı önerilen videosu görünür</string>
</patch>
<patch id="layout.hide.relatedvideooverlay.hideRelatedVideoOverlayPatch">
<string name="revanced_hide_related_videos_overlay_title">İlgili videolar bindirmesini gizle</string>
<string name="revanced_hide_related_videos_overlay_summary_on">Tam ekrandaki ilgili videolar bindirmesi gizli</string>
<string name="revanced_hide_related_videos_overlay_summary_off">Tam ekrandaki ilgili videolar bindirmesi görünür</string>
<string name="revanced_hide_related_videos_overlay_title">İlgili videolar katmanını gizle</string>
<string name="revanced_hide_related_videos_overlay_summary_on">Tam ekrandaki ilgili videolar katmanı gizli</string>
<string name="revanced_hide_related_videos_overlay_summary_off">Tam ekrandaki ilgili videolar katmanı görünür</string>
</patch>
<patch id="layout.hide.time.hideTimestampPatch">
<string name="revanced_hide_timestamp_title">Video zaman damgasını gizle</string>
@@ -894,7 +894,7 @@ Ayarlar → Oynatma → Sonraki videoyu otomatik oynat"</string>
<string name="revanced_open_videos_fullscreen_portrait_summary_off">Videolar tam ekranda açılmaz</string>
</patch>
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
<string name="revanced_player_overlay_opacity_title">Oynatıcı paneli opaklığı</string>
<string name="revanced_player_overlay_opacity_title">Oynatıcı katmanı opaklığı</string>
<string name="revanced_player_overlay_opacity_summary">0-100 arasında opaklık değeri, 0 şeffaftır</string>
<string name="revanced_player_overlay_opacity_invalid_toast">Oynatıcı katmanı opaklığı 0-100 arasında olmalıdır</string>
</patch>
@@ -984,13 +984,13 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet
<string name="revanced_sb_enable_auto_hide_skip_segment_button">Atlama düğmesini otomatik olarak gizle</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_on">Atlama düğmesi birkaç saniye sonra gizlenir</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_off">Atlama düğmesi bütün kısım boyunca gösterilir</string>
<string name="revanced_sb_auto_hide_skip_button_duration">Atla düğmesi süresi</string>
<string name="revanced_sb_auto_hide_skip_button_duration_sum">Atla ve öne çıkanlara atla düğmelerini otomatik olarak gizlemeden önce ne kadar süreyle göster</string>
<string name="revanced_sb_auto_hide_skip_button_duration">Atlama düğmesi süresi</string>
<string name="revanced_sb_auto_hide_skip_button_duration_sum">Atla ve vurguya atla düğmelerinin otomatik olarak gizlenmeden önce ne kadar süre gösterileceği</string>
<string name="revanced_sb_general_skiptoast">Atlamayı geri al bildirimini göster</string>
<string name="revanced_sb_general_skiptoast_sum_on">Bildirim, bir segment otomatik olarak atlandığında gösterilir. Atlamayı geri almak için bildirimine dokunun</string>
<string name="revanced_sb_general_skiptoast_sum_off">Toast gösterilmiyor</string>
<string name="revanced_sb_toast_on_skip_duration">Atlama toast süresi</string>
<string name="revanced_sb_toast_on_skip_duration_sum">Geri al atla bildirimini ne kadar süreyle göster</string>
<string name="revanced_sb_general_skiptoast_sum_on">Bir kısım otomatik olarak atlandığında bildirim gösterilir. Atlamayı geri almak için bildirime dokunun</string>
<string name="revanced_sb_general_skiptoast_sum_off">Bildirim gösterilmez</string>
<string name="revanced_sb_toast_on_skip_duration">Atlama bildirimi süresi</string>
<string name="revanced_sb_toast_on_skip_duration_sum">Atlamayı geri alma bildiriminin ne kadar süre gösterileceği</string>
<string name="revanced_sb_duration_1s">1 saniye</string>
<string name="revanced_sb_duration_2s">2 saniye</string>
<string name="revanced_sb_duration_3s">3 saniye</string>
@@ -1001,14 +1001,14 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet
<string name="revanced_sb_duration_8s">8 saniye</string>
<string name="revanced_sb_duration_9s">9 saniye</string>
<string name="revanced_sb_duration_10s">10 saniye</string>
<string name="revanced_sb_general_time_without">Kısımlar çıkarıldığında kalan video süresini göster</string>
<string name="revanced_sb_general_time_without_sum_on">Tüm segmentler çıkarıldıktan sonra video uzunluğu arama çubuğunda gösterilir</string>
<string name="revanced_sb_general_time_without_sum_off">Tam video uzunluğu gösterilir</string>
<string name="revanced_sb_general_time_without">Kısımlar olmadan video süresini göster</string>
<string name="revanced_sb_general_time_without_sum_on">Video süresi eksi bütün kısımların süresi zaman çubuğunda görünür</string>
<string name="revanced_sb_general_time_without_sum_off">Tam video süresi görünür</string>
<string name="revanced_sb_create_segment_category">Yeni kısım oluşturma</string>
<string name="revanced_sb_enable_create_segment">Yeni kısım oluşturma düğmesini göster</string>
<string name="revanced_sb_enable_create_segment_sum_on">Yeni kısım oluşturma düğmesi gösterilir</string>
<string name="revanced_sb_enable_create_segment_sum_off">Yeni kısım oluşturma düğmesi gösterilmez</string>
<string name="revanced_sb_general_adjusting">Yeni kısım oluştururken atlama süresi</string>
<string name="revanced_sb_general_adjusting">Yeni kısım oluştururkenki atlama süresi</string>
<string name="revanced_sb_general_adjusting_sum">Yeni bölüm oluştururkenki atlama düğmelerinin atlayacağı milisaniye miktarı</string>
<string name="revanced_sb_general_adjusting_invalid">Değer pozitif bir sayı olmalıdır</string>
<string name="revanced_sb_guidelines_preference_title">Yönergeleri görüntüle</string>
@@ -1018,10 +1018,10 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet
<string name="revanced_sb_guidelines_popup_already_read">Okudum</string>
<string name="revanced_sb_guidelines_popup_open">Göster</string>
<string name="revanced_sb_general">Genel</string>
<string name="revanced_sb_toast_on_connection_error_title">API kullanılamadığında bir tost bildirimi göster</string>
<string name="revanced_sb_toast_on_connection_error_summary_on">SponsorBlock kullanılamadığında tost bildirimi gösterilir</string>
<string name="revanced_sb_toast_on_connection_error_summary_off">SponsorBlock kullanılamadığında tost bildirimi gösterilmez</string>
<string name="revanced_sb_general_skipcount">Atlama sayısı izlemeyi etkinleştir</string>
<string name="revanced_sb_toast_on_connection_error_title">API kullanılamadığında bir bildirim göster</string>
<string name="revanced_sb_toast_on_connection_error_summary_on">SponsorBlock kullanılamadığında bir bildirim gösterilir</string>
<string name="revanced_sb_toast_on_connection_error_summary_off">SponsorBlock kullanılamadığında bildirim gösterilmez</string>
<string name="revanced_sb_general_skipcount">Atlama sayısı takibini etkinleştir</string>
<string name="revanced_sb_general_skipcount_sum_on">SponsorBlock liderlik tablosunun ne kadar zaman kazanıldığını bilmesini sağlar. Her bir kısım atlandığında liderlik tablosuna bir mesaj gönderilir</string>
<string name="revanced_sb_general_skipcount_sum_off">Atlama sayısı izleme etkin değil</string>
<string name="revanced_sb_general_min_duration">En az kısım süresi</string>
@@ -1103,7 +1103,7 @@ Kullanıcı kimliğiniz bir parola gibidir ve asla paylaşılmamalıdır.
<string name="revanced_sb_skip_seekbaronly">Zaman çubuğunda göster</string>
<string name="revanced_sb_skip_ignore">Devre dışı bırak</string>
<string name="revanced_sb_submit_failed_invalid">Kısım gönderilemedi: %s</string>
<string name="revanced_sb_submit_failed_timeout">SponsorBlock geçici olarak kullanılamıyor</string>
<string name="revanced_sb_submit_failed_timeout">SponsorBlock geçici olarak kapalı</string>
<string name="revanced_sb_submit_failed_unknown_error">Kısım gönderilemedi (durum: %1$d %2$s)</string>
<string name="revanced_sb_submit_failed_rate_limit">Kısım gönderilemiyor. Kullanıcı veya IP\'den çok fazla istek</string>
<string name="revanced_sb_submit_failed_forbidden">Kısım gönderilemiyor: %s</string>
@@ -1120,7 +1120,7 @@ Aynısı mevcut"</string>
<string name="revanced_sb_vote_upvote">Olumlu oy</string>
<string name="revanced_sb_vote_downvote">Olumsuz oy</string>
<string name="revanced_sb_vote_category">Kategori değiştir</string>
<string name="revanced_sb_vote_no_segments">Oylanılacak bir kısım yok</string>
<string name="revanced_sb_vote_no_segments">Oylanılacak kısım bulunmuyor</string>
<!-- A segment start and end time, such as "02:10 to 03:40". -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s - %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Kısım kategorisini seçin</string>
@@ -1218,7 +1218,7 @@ Daha sonra kapatılırsa, arayüz hatalarını önlemek için uygulama verilerin
<string name="revanced_change_start_page_entry_live">Canlı yayın</string>
<string name="revanced_change_start_page_entry_movies">Filmler</string>
<string name="revanced_change_start_page_entry_music">Müzik</string>
<string name="revanced_change_start_page_entry_news">Habercilik</string>
<string name="revanced_change_start_page_entry_news">Haberler</string>
<string name="revanced_change_start_page_entry_notifications">Bildirimler</string>
<string name="revanced_change_start_page_entry_playlists">Oynatma listeleri</string>
<string name="revanced_change_start_page_entry_search">Arama</string>
@@ -1228,7 +1228,7 @@ Daha sonra kapatılırsa, arayüz hatalarını önlemek için uygulama verilerin
<string name="revanced_change_start_page_entry_trending">Trendler</string>
<string name="revanced_change_start_page_entry_virtual_reality">Sanal Gerçeklik</string>
<string name="revanced_change_start_page_entry_watch_later">Daha sonra izle</string>
<string name="revanced_change_start_page_entry_your_clips">Sizin klipleriniz</string>
<string name="revanced_change_start_page_entry_your_clips">Klipleriniz</string>
<string name="revanced_change_start_page_always_title">Başlangıç sayfasını her zaman değiştir</string>
<string name="revanced_change_start_page_always_summary_on">"Başlangıç sayfası her zaman değiştirilir
@@ -1248,8 +1248,8 @@ Kısıtlama: Araç çubuğundaki geri düğmesini kullanmak işe yaramayabilir"<
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Shorts\'u otomatik oynat</string>
<string name="revanced_shorts_autoplay_summary_on">Sıradaki Shorts videosu otomatik olarak oynatılacak</string>
<string name="revanced_shorts_autoplay_summary_off">Aynı Shorts videosu sürekli döngü yapacak</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts otomatik oynatılacak</string>
<string name="revanced_shorts_autoplay_summary_off">Aynı Shorts videosu sürekli yeniden oynayacak</string>
<string name="revanced_shorts_autoplay_background_title">Arka planda Shorts\'u otomatik oynat</string>
<string name="revanced_shorts_autoplay_background_summary_on">Shorts arka planda otomatik oynatılacak</string>
<string name="revanced_shorts_autoplay_background_summary_off">Shorts arka planda döngüde olacak</string>
@@ -1472,11 +1472,16 @@ Bunu etkinleştirmek daha yüksek video kalitelerini açabilir"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Düğme görünür. Oynatma hızını varsayılana sıfırlamak için dokunup basılı tutun</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Düğme gösterilmez</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Video kalitesi düğmesini göster</string>
<string name="revanced_video_quality_dialog_button_summary_on">Düğme görünür. Kaliteyi varsayılana sıfırlamak için dokunup basılı tutun</string>
<string name="revanced_video_quality_dialog_button_summary_off">Düğme gösterilmez</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Özel oynatma hızı menüsü</string>
<string name="revanced_custom_speed_menu_summary_on">Özel oynatma hızı menüsü gösterilir</string>
<string name="revanced_custom_speed_menu_summary_off">Özel oynatma hızı menüsü gösterilmez</string>
<string name="revanced_restore_old_speed_menu_title">Eski oynatma hızı menüsünü geri yükle</string>
<string name="revanced_restore_old_speed_menu_title">Eski oynatma hızı menüsünü geri getir</string>
<string name="revanced_restore_old_speed_menu_summary_on">Eski hız menüsü gösterilir</string>
<string name="revanced_restore_old_speed_menu_summary_off">Modern hız menüsü gösterilir</string>
<string name="revanced_custom_playback_speeds_title">Özel oynatma hızları</string>
@@ -1490,10 +1495,10 @@ Bunu etkinleştirmek daha yüksek video kalitelerini açabilir"</string>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
<string name="revanced_remember_playback_speed_last_selected_title">Oynatma hızı değişikliklerini hatırla</string>
<string name="revanced_remember_playback_speed_last_selected_summary_on">Oynatma hızı değişiklikleri tüm videolara uygulanır</string>
<string name="revanced_remember_playback_speed_last_selected_summary_off">Oynatma hızı değişiklikleri yalnızca geçerli videoya uygulanır</string>
<string name="revanced_remember_playback_speed_last_selected_summary_off">Oynatma hızı değişiklikleri yalnızca mevcut videoya uygulanır</string>
<string name="revanced_remember_playback_speed_last_selected_toast_title">Oynatma hızı değişikliklerinde bildirim göster</string>
<string name="revanced_remember_playback_speed_last_selected_toast_summary_on">Varsayılan oynatma hızı değiştirildiğinde bir bildirim gösterilir</string>
<string name="revanced_remember_playback_speed_last_selected_toast_summary_off">Varsayılan oynatma hızı değiştirildiğinde bir bildirim gösterilmez.</string>
<string name="revanced_remember_playback_speed_last_selected_toast_summary_off">Varsayılan oynatma hızı değiştirildiğinde bir bildirim gösterilmez</string>
<string name="revanced_playback_speed_default_title">Varsayılan oynatma hızı</string>
<string name="revanced_remember_playback_speed_toast">Varsayılan hız %s olarak ayarlandı</string>
</patch>

View File

@@ -1464,13 +1464,18 @@ Second \"item\" text"</string>
<string name="revanced_playback_speed_dialog_button_summary_on">Кнопка показується. Натисніть і утримуйте, щоб відновити стандартну швидкість відтворення</string>
<string name="revanced_playback_speed_dialog_button_summary_off">Кнопка швидкості відтворення не показується</string>
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
<string name="revanced_video_quality_dialog_button_title">Кнопка якості відео</string>
<string name="revanced_video_quality_dialog_button_summary_on">Кнопка показується. Натисніть і утримуйте, щоб відновити стандартну якість</string>
<string name="revanced_video_quality_dialog_button_summary_off">Кнопка швидкості відтворення не показується</string>
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
<string name="revanced_custom_speed_menu_title">Користувацьке меню швидкості відтворення</string>
<string name="revanced_custom_speed_menu_summary_on">Користувацьке меню швидкості відтворення показується</string>
<string name="revanced_custom_speed_menu_summary_off">Користувацьке меню швидкості відтворення не показується</string>
<string name="revanced_restore_old_speed_menu_title">Відновити старе меню швидкості відтворення</string>
<string name="revanced_restore_old_speed_menu_summary_on">Показується старе меню швидкості</string>
<string name="revanced_restore_old_speed_menu_summary_off">Показується сучасне меню швидкості</string>
<string name="revanced_restore_old_speed_menu_summary_off">Показується новітнє меню швидкості</string>
<string name="revanced_custom_playback_speeds_title">Користувацькі швидкості відтворення</string>
<string name="revanced_custom_playback_speeds_summary">Додавання або зміна користувацьких швидкостей відтворення</string>
<string name="revanced_custom_playback_speeds_invalid">Користувацькі швидкості повинні бути менші ніж %s</string>

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

View File

@@ -222,6 +222,8 @@ Second \"item\" text"</string>
</patch>
<patch id="video.speed.button.playbackSpeedButtonPatch">
</patch>
<patch id="video.quality.button.videoQualityButtonPatch">
</patch>
<patch id="video.speed.custom.customPlaybackSpeedPatch">
</patch>
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">

Some files were not shown because too many files have changed in this diff Show More