diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java index 9b76a935c..7dfdf27e8 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java @@ -296,6 +296,11 @@ public final class CustomActionsPatch { true ) ), + SPEED_DIALOG( + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, + "yt_outline_play_arrow_half_circle_black_24", + () -> VideoUtils.showPlaybackSpeedDialog(contextRef.get()) + ), REPEAT_STATE( Settings.SHORTS_CUSTOM_ACTIONS_REPEAT_STATE, "yt_outline_arrow_repeat_1_black_24", diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java index 71f5dd9d6..8cf4980d1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java @@ -1,17 +1,10 @@ package app.revanced.extension.youtube.patches.video; -import static app.revanced.extension.shared.utils.StringRef.str; - -import app.revanced.extension.shared.utils.Logger; -import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") public class AV1CodecPatch { - private static final int LITERAL_VALUE_AV01 = 1635135811; - private static final int LITERAL_VALUE_DOLBY_VISION = 1685485123; private static final String VP9_CODEC = "video/x-vnd.on2.vp9"; - private static long lastTimeResponse = 0; /** * Replace the SW AV01 codec to VP9 codec. @@ -22,32 +15,4 @@ public class AV1CodecPatch { public static String replaceCodec(String original) { return Settings.REPLACE_AV1_CODEC.get() ? VP9_CODEC : original; } - - /** - * Replace the SW AV01 codec request with a Dolby Vision codec request. - * This request is invalid, so it falls back to codecs other than AV01. - *

- * Limitation: Fallback process causes about 15-20 seconds of buffering. - * - * @param literalValue literal value of the codec - */ - public static int rejectResponse(int literalValue) { - if (!Settings.REJECT_AV1_CODEC.get()) - return literalValue; - - Logger.printDebug(() -> "Response: " + literalValue); - - if (literalValue != LITERAL_VALUE_AV01) - return literalValue; - - final long currentTime = System.currentTimeMillis(); - - // Ignore the invoke within 20 seconds. - if (currentTime - lastTimeResponse > 20000) { - lastTimeResponse = currentTime; - Utils.showToastShort(str("revanced_reject_av1_codec_toast")); - } - - return LITERAL_VALUE_DOLBY_VISION; - } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java index 5211c6a47..7ad27b152 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java @@ -3,39 +3,73 @@ package app.revanced.extension.youtube.patches.video; import static app.revanced.extension.shared.utils.StringRef.str; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.apache.commons.lang3.BooleanUtils; +import app.revanced.extension.shared.settings.BooleanSetting; +import app.revanced.extension.shared.settings.FloatSetting; import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.utils.PatchStatus; import app.revanced.extension.youtube.patches.video.requests.MusicRequest; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; import app.revanced.extension.youtube.whitelist.Whitelist; @SuppressWarnings("unused") public class PlaybackSpeedPatch { + private static final FloatSetting DEFAULT_PLAYBACK_SPEED = + Settings.DEFAULT_PLAYBACK_SPEED; + private static final FloatSetting DEFAULT_PLAYBACK_SPEED_SHORTS = + Settings.DEFAULT_PLAYBACK_SPEED_SHORTS; + private static final boolean DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = Settings.DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC.get(); private static final long TOAST_DELAY_MILLISECONDS = 750; private static long lastTimeSpeedChanged; + private static float lastSelectedPlaybackSpeed = 1.0f; + + private static volatile String channelId = ""; + private static volatile String videoId = ""; private static boolean isLiveStream; + private static volatile String channelIdShorts = ""; + private static volatile String videoIdShorts = ""; + private static boolean isLiveStreamShorts; + /** * Injection point. */ public static void newVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { - isLiveStream = newlyLoadedLiveStreamValue; - Logger.printDebug(() -> "newVideoStarted: " + newlyLoadedVideoId); + if (isShorts()) { + channelIdShorts = newlyLoadedChannelId; + videoIdShorts = newlyLoadedVideoId; + isLiveStreamShorts = newlyLoadedLiveStreamValue; - final float defaultPlaybackSpeed = getDefaultPlaybackSpeed(newlyLoadedChannelId, newlyLoadedVideoId); - Logger.printDebug(() -> "overridePlaybackSpeed: " + defaultPlaybackSpeed); + Logger.printDebug(() -> "newVideoStarted: " + newlyLoadedVideoId); + } else { + channelId = newlyLoadedChannelId; + videoId = newlyLoadedVideoId; + isLiveStream = newlyLoadedLiveStreamValue; - VideoInformation.overridePlaybackSpeed(defaultPlaybackSpeed); + Logger.printDebug(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); + } + } + + /** + * Injection point. + */ + public static void newShortsVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, + @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, + final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { + channelIdShorts = newlyLoadedChannelId; + videoIdShorts = newlyLoadedVideoId; + isLiveStreamShorts = newlyLoadedLiveStreamValue; + + Logger.printInfo(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); } /** @@ -65,17 +99,34 @@ public class PlaybackSpeedPatch { /** * Injection point. */ - public static float getPlaybackSpeedInShorts(final float playbackSpeed) { - if (VideoInformation.lastPlayerResponseIsShort() && - Settings.ENABLE_DEFAULT_PLAYBACK_SPEED_SHORTS.get() - ) { - float defaultPlaybackSpeed = getDefaultPlaybackSpeed(VideoInformation.getChannelId(), null); - Logger.printDebug(() -> "overridePlaybackSpeed in Shorts: " + defaultPlaybackSpeed); + public static float getPlaybackSpeed(float playbackSpeed) { + boolean isShorts = isShorts(); + String currentChannelId = isShorts ? channelIdShorts : channelId; + String currentVideoId = isShorts ? videoIdShorts : videoId; + boolean currentVideoIsLiveStream = isShorts ? isLiveStreamShorts : isLiveStream; + boolean currentVideoIsWhitelisted = Whitelist.isChannelWhitelistedPlaybackSpeed(currentChannelId); + boolean currentVideoIsMusic = !isShorts && isMusic(); - return defaultPlaybackSpeed; + if (currentVideoIsLiveStream || currentVideoIsWhitelisted || currentVideoIsMusic) { + Logger.printDebug(() -> "changing playback speed to: 1.0"); + VideoInformation.setPlaybackSpeed(1.0f); + return 1.0f; } - return playbackSpeed; + float defaultPlaybackSpeed = isShorts ? DEFAULT_PLAYBACK_SPEED_SHORTS.get() : DEFAULT_PLAYBACK_SPEED.get(); + + if (defaultPlaybackSpeed < 0) { + float finalPlaybackSpeed = isShorts ? playbackSpeed : lastSelectedPlaybackSpeed; + VideoInformation.overridePlaybackSpeed(finalPlaybackSpeed); + Logger.printDebug(() -> "changing playback speed to: " + finalPlaybackSpeed); + return finalPlaybackSpeed; + } else { + if (isShorts) { + VideoInformation.setPlaybackSpeed(defaultPlaybackSpeed); + } + Logger.printDebug(() -> "changing playback speed to: " + defaultPlaybackSpeed); + return defaultPlaybackSpeed; + } } /** @@ -86,51 +137,61 @@ public class PlaybackSpeedPatch { */ public static void userSelectedPlaybackSpeed(float playbackSpeed) { try { - if (PatchStatus.RememberPlaybackSpeed() && - Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) { - // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x - // then the menu will allow increasing without bounds but the max speed is - // still capped to under 8.0x. - playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f); + boolean isShorts = isShorts(); + if (PatchStatus.RememberPlaybackSpeed()) { + BooleanSetting rememberPlaybackSpeedLastSelectedSetting = isShorts + ? Settings.REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED + : Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED; + FloatSetting playbackSpeedSetting = isShorts + ? DEFAULT_PLAYBACK_SPEED_SHORTS + : DEFAULT_PLAYBACK_SPEED; + BooleanSetting showToastSetting = isShorts + ? Settings.REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED_TOAST + : Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST; - // Prevent toast spamming if using the 0.05x adjustments. - // Show exactly one toast after the user stops interacting with the speed menu. - final long now = System.currentTimeMillis(); - lastTimeSpeedChanged = now; + if (rememberPlaybackSpeedLastSelectedSetting.get()) { + // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x + // then the menu will allow increasing without bounds but the max speed is + // still capped to under 8.0x. + playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f); - final float finalPlaybackSpeed = playbackSpeed; - Utils.runOnMainThreadDelayed(() -> { - if (lastTimeSpeedChanged != now) { - // The user made additional speed adjustments and this call is outdated. - return; - } + // Prevent toast spamming if using the 0.05x adjustments. + // Show exactly one toast after the user stops interacting with the speed menu. + final long now = System.currentTimeMillis(); + lastTimeSpeedChanged = now; - if (Settings.DEFAULT_PLAYBACK_SPEED.get() == finalPlaybackSpeed) { - // User changed to a different speed and immediately changed back. - // Or the user is going past 8.0x in the glitched out 0.05x menu. - return; - } - Settings.DEFAULT_PLAYBACK_SPEED.save(finalPlaybackSpeed); + final float finalPlaybackSpeed = playbackSpeed; + Utils.runOnMainThreadDelayed(() -> { + if (lastTimeSpeedChanged != now) { + // The user made additional speed adjustments and this call is outdated. + return; + } + if (playbackSpeedSetting.get() == finalPlaybackSpeed) { + // User changed to a different speed and immediately changed back. + // Or the user is going past 8.0x in the glitched out 0.05x menu. + return; + } + playbackSpeedSetting.save(finalPlaybackSpeed); - if (!Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST.get()) { - return; - } - Utils.showToastShort(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x"))); - }, TOAST_DELAY_MILLISECONDS); + if (showToastSetting.get()) { + Utils.showToastShort(str(isShorts ? "revanced_remember_playback_speed_toast_shorts" : "revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x"))); + } + }, TOAST_DELAY_MILLISECONDS); + } + } else if (!isShorts){ + lastSelectedPlaybackSpeed = playbackSpeed; } } catch (Exception ex) { Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex); } } - private static float getDefaultPlaybackSpeed(@NonNull String channelId, @Nullable String videoId) { - return (isLiveStream || Whitelist.isChannelWhitelistedPlaybackSpeed(channelId) || isMusic(videoId)) - ? 1.0f - : Settings.DEFAULT_PLAYBACK_SPEED.get(); + private static boolean isShorts() { + return !ShortsPlayerState.getCurrent().isClosed(); } - private static boolean isMusic(@Nullable String videoId) { - if (DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC && videoId != null) { + private static boolean isMusic() { + if (DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC && !videoId.isEmpty()) { try { MusicRequest request = MusicRequest.getRequestForVideoId(videoId); final boolean isMusic = request != null && BooleanUtils.toBoolean(request.getStream()); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java index 45d84038c..d4769d084 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java @@ -9,13 +9,16 @@ import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; +import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; @SuppressWarnings("unused") public class VideoQualityPatch { private static final int DEFAULT_YOUTUBE_VIDEO_QUALITY = -2; - private static final IntegerSetting mobileQualitySetting = Settings.DEFAULT_VIDEO_QUALITY_MOBILE; - private static final IntegerSetting wifiQualitySetting = Settings.DEFAULT_VIDEO_QUALITY_WIFI; + private static final IntegerSetting shortsQualityMobile = Settings.DEFAULT_VIDEO_QUALITY_MOBILE_SHORTS; + private static final IntegerSetting shortsQualityWifi = Settings.DEFAULT_VIDEO_QUALITY_WIFI_SHORTS; + private static final IntegerSetting videoQualityMobile = Settings.DEFAULT_VIDEO_QUALITY_MOBILE; + private static final IntegerSetting videoQualityWifi = Settings.DEFAULT_VIDEO_QUALITY_WIFI; @NonNull public static String videoId = ""; @@ -35,12 +38,11 @@ public class VideoQualityPatch { public static void newVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { - if (PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL) - return; - if (videoId.equals(newlyLoadedVideoId)) - return; - videoId = newlyLoadedVideoId; - setVideoQuality(Settings.SKIP_PRELOADED_BUFFER.get() ? 250 : 750); + if (PlayerType.getCurrent() != PlayerType.INLINE_MINIMAL && + !videoId.equals(newlyLoadedVideoId)) { + videoId = newlyLoadedVideoId; + setVideoQuality(750); + } } /** @@ -53,42 +55,67 @@ public class VideoQualityPatch { ); } - private static void setVideoQuality(final long delayMillis) { - final int defaultQuality = Utils.getNetworkType() == Utils.NetworkType.MOBILE - ? mobileQualitySetting.get() - : wifiQualitySetting.get(); + private static void setVideoQuality(long delayMillis) { + boolean isShorts = isShorts(); + IntegerSetting defaultQualitySetting = Utils.getNetworkType() == Utils.NetworkType.MOBILE + ? isShorts ? shortsQualityMobile : videoQualityMobile + : isShorts ? shortsQualityWifi : videoQualityWifi; - if (defaultQuality == DEFAULT_YOUTUBE_VIDEO_QUALITY) - return; + int defaultQuality = defaultQualitySetting.get(); - Utils.runOnMainThreadDelayed(() -> { - final int qualityToUseFinal = VideoInformation.getAvailableVideoQuality(defaultQuality); - Logger.printDebug(() -> "Changing video quality to: " + qualityToUseFinal); - VideoInformation.overrideVideoQuality(qualityToUseFinal); - }, delayMillis - ); + if (defaultQuality != DEFAULT_YOUTUBE_VIDEO_QUALITY) { + Utils.runOnMainThreadDelayed(() -> { + final int qualityToUseFinal = VideoInformation.getAvailableVideoQuality(defaultQuality); + Logger.printDebug(() -> "Changing video quality to: " + qualityToUseFinal); + VideoInformation.overrideVideoQuality(qualityToUseFinal); + }, delayMillis + ); + } } private static void userSelectedVideoQuality(final int defaultQuality) { - if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) - return; - if (defaultQuality == DEFAULT_YOUTUBE_VIDEO_QUALITY) - return; + if (defaultQuality != DEFAULT_YOUTUBE_VIDEO_QUALITY) { + boolean isShorts = isShorts(); + final Utils.NetworkType networkType = Utils.getNetworkType(); + String networkTypeMessage = networkType == Utils.NetworkType.MOBILE + ? str("revanced_remember_video_quality_mobile") + : str("revanced_remember_video_quality_wifi"); - final Utils.NetworkType networkType = Utils.getNetworkType(); + if (isShorts) { + if (Settings.REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED.get()) { + IntegerSetting defaultQualitySetting = networkType == Utils.NetworkType.MOBILE + ? shortsQualityMobile + : shortsQualityWifi; - switch (networkType) { - case NONE -> { - Utils.showToastShort(str("revanced_remember_video_quality_none")); - return; + defaultQualitySetting.save(defaultQuality); + + if (Settings.REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED_TOAST.get()) { + Utils.showToastShort(str( + "revanced_remember_video_quality_toast_shorts", + networkTypeMessage, (defaultQuality + "p") + )); + } + } + } else { + if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) { + IntegerSetting defaultQualitySetting = networkType == Utils.NetworkType.MOBILE + ? videoQualityMobile + : videoQualityWifi; + + defaultQualitySetting.save(defaultQuality); + + if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get()) { + Utils.showToastShort(str( + "revanced_remember_video_quality_toast", + networkTypeMessage, (defaultQuality + "p") + )); + } + } } - case MOBILE -> mobileQualitySetting.save(defaultQuality); - default -> wifiQualitySetting.save(defaultQuality); } + } - if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get()) - return; - - Utils.showToastShort(str("revanced_remember_video_quality_" + networkType.getName(), defaultQuality + "p")); + private static boolean isShorts() { + return !ShortsPlayerState.getCurrent().isClosed(); } } \ No newline at end of file diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index ae6f3fea3..da959b002 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -498,12 +498,13 @@ public class Settings extends BaseSettings { public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL = new BooleanSetting("revanced_shorts_custom_actions_copy_video_url", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_shorts_custom_actions_external_downloader", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO = new BooleanSetting("revanced_shorts_custom_actions_open_video", FALSE, true); + public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG = new BooleanSetting("revanced_shorts_custom_actions_speed_dialog", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_REPEAT_STATE = new BooleanSetting("revanced_shorts_custom_actions_repeat_state", FALSE, true); public static final BooleanSetting ENABLE_SHORTS_CUSTOM_ACTIONS_FLYOUT_MENU = new BooleanSetting("revanced_enable_shorts_custom_actions_flyout_menu", FALSE, true, - parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); + parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); public static final BooleanSetting ENABLE_SHORTS_CUSTOM_ACTIONS_TOOLBAR = new BooleanSetting("revanced_enable_shorts_custom_actions_toolbar", FALSE, true, - parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); + parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); // Experimental Flags public static final BooleanSetting ENABLE_TIME_STAMP = new BooleanSetting("revanced_enable_shorts_time_stamp", FALSE, true); @@ -550,30 +551,38 @@ public class Settings extends BaseSettings { public static final FloatSetting SWIPE_BRIGHTNESS_VALUE = new FloatSetting("revanced_swipe_brightness_value", -1.0f, false, false); - // PreferenceScreen: Video - public static final FloatSetting DEFAULT_PLAYBACK_SPEED = new FloatSetting("revanced_default_playback_speed", -2.0f); - public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE = new IntegerSetting("revanced_default_video_quality_mobile", -2); - public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI = new IntegerSetting("revanced_default_video_quality_wifi", -2); + // PreferenceScreen: Video - Codec public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE, true); + public static final BooleanSetting DISABLE_VP9_CODEC = new BooleanSetting("revanced_disable_vp9_codec", FALSE, true); + public static final BooleanSetting REPLACE_AV1_CODEC = new BooleanSetting("revanced_replace_av1_codec", FALSE, true); + + // PreferenceScreen: Video - Playback speed + public static final FloatSetting DEFAULT_PLAYBACK_SPEED = new FloatSetting("revanced_default_playback_speed", -2.0f); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", TRUE); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_LAST_SELECTED)); + public static final FloatSetting DEFAULT_PLAYBACK_SPEED_SHORTS = new FloatSetting("revanced_default_playback_speed_shorts", -2.0f); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_shorts_last_selected", TRUE); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_shorts_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED)); public static final BooleanSetting ENABLE_CUSTOM_PLAYBACK_SPEED = new BooleanSetting("revanced_enable_custom_playback_speed", FALSE, true); public static final BooleanSetting CUSTOM_PLAYBACK_SPEED_MENU_TYPE = new BooleanSetting("revanced_custom_playback_speed_menu_type", FALSE, parent(ENABLE_CUSTOM_PLAYBACK_SPEED)); public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds", "0.25\n0.5\n0.75\n1.0\n1.25\n1.5\n1.75\n2.0\n2.25\n2.5", true, parent(ENABLE_CUSTOM_PLAYBACK_SPEED)); - public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", TRUE); - public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_LAST_SELECTED)); + + // PreferenceScreen: Video - Video quality + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE = new IntegerSetting("revanced_default_video_quality_mobile", -2); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI = new IntegerSetting("revanced_default_video_quality_wifi", -2); public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", TRUE); public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_last_selected_toast", TRUE, parent(REMEMBER_VIDEO_QUALITY_LAST_SELECTED)); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE_SHORTS = new IntegerSetting("revanced_default_video_quality_mobile_shorts", -2, true); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI_SHORTS = new IntegerSetting("revanced_default_video_quality_wifi_shorts", -2, true); + public static final BooleanSetting REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_shorts_last_selected", TRUE); + public static final BooleanSetting REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_shorts_last_selected_toast", TRUE, parent(REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED)); public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE, true); - // Experimental Flags - public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = new BooleanSetting("revanced_disable_default_playback_speed_music", FALSE, true); - public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC_TYPE = new BooleanSetting("revanced_disable_default_playback_speed_music_type", FALSE, true, parent(DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC)); - public static final BooleanSetting ENABLE_DEFAULT_PLAYBACK_SPEED_SHORTS = new BooleanSetting("revanced_enable_default_playback_speed_shorts", FALSE); public static final BooleanSetting SKIP_PRELOADED_BUFFER = new BooleanSetting("revanced_skip_preloaded_buffer", FALSE, true, "revanced_skip_preloaded_buffer_user_dialog_message"); public static final BooleanSetting SKIP_PRELOADED_BUFFER_TOAST = new BooleanSetting("revanced_skip_preloaded_buffer_toast", TRUE); public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true); - public static final BooleanSetting DISABLE_VP9_CODEC = new BooleanSetting("revanced_disable_vp9_codec", FALSE, true); - public static final BooleanSetting REPLACE_AV1_CODEC = new BooleanSetting("revanced_replace_av1_codec", FALSE, true); - public static final BooleanSetting REJECT_AV1_CODEC = new BooleanSetting("revanced_reject_av1_codec", FALSE, true); + public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = new BooleanSetting("revanced_disable_default_playback_speed_music", FALSE, true); + public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC_TYPE = new BooleanSetting("revanced_disable_default_playback_speed_music_type", FALSE, true, parent(DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC)); // PreferenceScreen: Miscellaneous public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 34ebdb184..d183dbae2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -10,6 +10,7 @@ import static app.revanced.extension.shared.utils.Utils.getChildView; import static app.revanced.extension.shared.utils.Utils.isSDKAbove; import static app.revanced.extension.shared.utils.Utils.showToastShort; import static app.revanced.extension.youtube.settings.Settings.DEFAULT_PLAYBACK_SPEED; +import static app.revanced.extension.youtube.settings.Settings.DEFAULT_PLAYBACK_SPEED_SHORTS; import static app.revanced.extension.youtube.settings.Settings.HIDE_PREVIEW_COMMENT; import static app.revanced.extension.youtube.settings.Settings.HIDE_PREVIEW_COMMENT_TYPE; @@ -119,7 +120,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } else { Setting.privateSetValueFromString(setting, listPreference.getValue()); } - if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { + if (setting.equals(DEFAULT_PLAYBACK_SPEED) || setting.equals(DEFAULT_PLAYBACK_SPEED_SHORTS)) { listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); } @@ -310,7 +311,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } else if (preference instanceof EditTextPreference editTextPreference) { editTextPreference.setText(setting.get().toString()); } else if (preference instanceof ListPreference listPreference) { - if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { + if (setting.equals(DEFAULT_PLAYBACK_SPEED) || setting.equals(DEFAULT_PLAYBACK_SPEED_SHORTS)) { listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java index dfd02e7a7..e4cc256bf 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java @@ -46,6 +46,7 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { NavigationPreferenceLinks(); RYDPreferenceLinks(); SeekBarPreferenceLinks(); + ShortsPreferenceLinks(); SpeedOverlayPreferenceLinks(); QuickActionsPreferenceLinks(); TabletLayoutLinks(); @@ -186,6 +187,19 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { ); } + /** + * Enable/Disable Preference related to Shorts settings + */ + private static void ShortsPreferenceLinks() { + if (!PatchStatus.RememberPlaybackSpeed()) { + enableDisablePreferences( + true, + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG + ); + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG.save(false); + } + } + /** * Enable/Disable Preference related to Speed overlay settings */ diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index 9df7bb1f6..6d8d407c4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -202,6 +202,7 @@ public class VideoUtils extends IntentUtils { new AlertDialog.Builder(context) .setSingleChoiceItems(playbackSpeedEntries, index, (mDialog, mIndex) -> { final float selectedPlaybackSpeed = Float.parseFloat(playbackSpeedEntryValues[mIndex] + "f"); + VideoInformation.setPlaybackSpeed(selectedPlaybackSpeed); VideoInformation.overridePlaybackSpeed(selectedPlaybackSpeed); userSelectedPlaybackSpeed(selectedPlaybackSpeed); mDialog.dismiss(); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index 52683bdd5..824364d2b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableClass @@ -26,6 +25,7 @@ import app.revanced.patches.youtube.video.playerresponse.playerResponseMethodHoo import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId import app.revanced.patches.youtube.video.videoid.hookVideoId import app.revanced.patches.youtube.video.videoid.videoIdPatch +import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.addStaticFieldToExtension import app.revanced.util.cloneMutable import app.revanced.util.findMethodOrThrow @@ -94,6 +94,8 @@ private var mdxConstructorInsertIndex = -1 private lateinit var videoTimeConstructorMethod: MutableMethod private var videoTimeConstructorInsertIndex = 2 +private lateinit var setPlaybackSpeedMethodReference: MethodReference + // Used by other patches. internal lateinit var speedSelectionInsertMethod: MutableMethod internal lateinit var videoEndMethod: MutableMethod @@ -396,12 +398,13 @@ val videoInformationPatch = bytecodePatch( Opcode.IGET_OBJECT ) val setPlaybackSpeedContainerClassFieldReference = - getInstruction(setPlaybackSpeedContainerClassFieldIndex).reference.toString() + getInstruction(setPlaybackSpeedContainerClassFieldIndex).reference val setPlaybackSpeedClassFieldReference = - getInstruction(speedSelectionValueInstructionIndex + 1).reference.toString() - val setPlaybackSpeedMethodReference = - getInstruction(speedSelectionValueInstructionIndex + 2).reference.toString() + getInstruction(speedSelectionValueInstructionIndex + 1).reference + + setPlaybackSpeedMethodReference = + getInstruction(speedSelectionValueInstructionIndex + 2).reference as MethodReference // add override playback speed method it.classDef.methods.add( @@ -450,41 +453,93 @@ val videoInformationPatch = bytecodePatch( } } - playbackSpeedClassFingerprint.matchOrThrow().let { result -> - result.method.apply { - val index = result.patternMatch!!.endIndex - val register = getInstruction(index).registerA - val playbackSpeedClass = this.returnType - - // set playback speed class - replaceInstruction( - index, - "sput-object v$register, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass" - ) - addInstruction( - index + 1, - "return-object v$register" - ) + videoIdFingerprintShorts.matchOrThrow().let { + it.method.apply { + val shortsPlaybackSpeedClassField = it.classDef.fields.find { field -> + field.type == setPlaybackSpeedMethodReference.definingClass + } ?: throw PatchException("Failed to find hook field") val smaliInstructions = """ if-eqz v0, :ignore - invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V + invoke-virtual {v0, p0}, $definingClass->overridePlaybackSpeed(F)V :ignore return-void - """ + """ addStaticFieldToExtension( EXTENSION_CLASS_DESCRIPTOR, "overridePlaybackSpeed", - "playbackSpeedClass", - playbackSpeedClass, - smaliInstructions, - false + "playbackSpeedShortsClass", + definingClass, + smaliInstructions + ) + + // add override playback speed method + it.classDef.methods.add( + ImmutableMethod( + definingClass, + "overridePlaybackSpeed", + listOf(ImmutableMethodParameter("F", annotations, null)), + "V", + AccessFlags.PUBLIC or AccessFlags.PUBLIC, + annotations, + null, + ImmutableMethodImplementation( + 3, """ + # Check if the playback speed is not auto (-2.0f) + const/4 v0, 0x0 + cmpg-float v0, v2, v0 + if-lez v0, :ignore + + # Get the container class field. + iget-object v0, v1, $shortsPlaybackSpeedClassField + + # For some reason, in YouTube 19.44.39 this value is sometimes null. + if-eqz v0, :ignore + + # Invoke setPlaybackSpeed on that class. + invoke-virtual {v0, v2}, $setPlaybackSpeedMethodReference + + :ignore + return-void + """.toInstructions(), null, null + ) + ).toMutable() ) } } + playbackSpeedClassFingerprint.methodOrThrow().apply { + val index = indexOfFirstInstructionOrThrow(Opcode.RETURN_OBJECT) + val register = getInstruction(index).registerA + val playbackSpeedClass = this.returnType + + // set playback speed class + addInstructionsAtControlFlowLabel( + index, + "sput-object v$register, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass" + ) + + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V + return-void + :ignore + nop + """ + + addStaticFieldToExtension( + EXTENSION_CLASS_DESCRIPTOR, + "overridePlaybackSpeed", + "playbackSpeedClass", + playbackSpeedClass, + smaliInstructions, + false + ) + } + /** * Hook current video quality */ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt index 0b8282018..53abb9489 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt @@ -20,29 +20,6 @@ internal val av1CodecFingerprint = legacyFingerprint( } ) -internal val byteBufferArrayFingerprint = legacyFingerprint( - name = "byteBufferArrayFingerprint", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "I", - parameters = emptyList(), - opcodes = listOf( - Opcode.SHL_INT_LIT8, - Opcode.SHL_INT_LIT8, - Opcode.OR_INT_2ADDR, - Opcode.SHL_INT_LIT8, - Opcode.OR_INT_2ADDR, - Opcode.OR_INT_2ADDR, - Opcode.RETURN - ) -) - -internal val byteBufferArrayParentFingerprint = legacyFingerprint( - name = "byteBufferArrayParentFingerprint", - accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, - returnType = "C", - parameters = listOf("Ljava/nio/charset/Charset;", "[C") -) - internal val deviceDimensionsModelToStringFingerprint = legacyFingerprint( name = "deviceDimensionsModelToStringFingerprint", returnType = "L", @@ -77,17 +54,26 @@ internal val playbackSpeedChangedFromRecyclerViewFingerprint = legacyFingerprint } ) -internal val playbackSpeedInitializeFingerprint = legacyFingerprint( - name = "playbackSpeedInitializeFingerprint", - returnType = "F", - accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, +internal val loadVideoParamsFingerprint = legacyFingerprint( + name = "loadVideoParamsFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, parameters = listOf("L"), opcodes = listOf( - Opcode.IGET, - Opcode.RETURN + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IPUT, + Opcode.INVOKE_INTERFACE, ) ) +internal val loadVideoParamsParentFingerprint = legacyFingerprint( + name = "loadVideoParamsParentFingerprint", + returnType = "Z", + parameters = listOf("J"), + strings = listOf("LoadVideoParams.playerListener = null") +) + internal val qualityChangedFromRecyclerViewFingerprint = legacyFingerprint( name = "qualityChangedFromRecyclerViewFingerprint", returnType = "L", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt index 895d7b505..41ed6bdcd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt @@ -24,8 +24,8 @@ import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverP import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch -import app.revanced.patches.youtube.utils.videoEndFingerprint import app.revanced.patches.youtube.video.information.hookBackgroundPlayVideoInformation +import app.revanced.patches.youtube.video.information.hookShortsVideoInformation import app.revanced.patches.youtube.video.information.hookVideoInformation import app.revanced.patches.youtube.video.information.onCreateHook import app.revanced.patches.youtube.video.information.speedSelectionInsertMethod @@ -44,6 +44,7 @@ import app.revanced.util.indexOfFirstStringInstructionOrThrow import app.revanced.util.updatePatchStatus import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -158,21 +159,30 @@ val videoPlaybackPatch = bytecodePatch( } } - playbackSpeedInitializeFingerprint.matchOrThrow(videoEndFingerprint).let { + loadVideoParamsFingerprint.matchOrThrow(loadVideoParamsParentFingerprint).let { it.method.apply { - val insertIndex = it.patternMatch!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA + val targetIndex = it.patternMatch!!.endIndex + val targetReference = getInstruction(targetIndex).reference as MethodReference - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeedInShorts(F)F - move-result v$insertRegister - """ - ) + findMethodOrThrow(definingClass) { + name == targetReference.name + }.apply { + val insertIndex = implementation!!.instructions.lastIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeed(F)F + move-result v$insertRegister + """ + ) + } } } hookBackgroundPlayVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") + hookShortsVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newShortsVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") + hookVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") hookPlayerResponseVideoId("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->fetchMusicRequest(Ljava/lang/String;Z)V") updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "RememberPlaybackSpeed") @@ -294,25 +304,6 @@ val videoPlaybackPatch = bytecodePatch( settingArray += "SETTINGS: REPLACE_AV1_CODEC" } - // reject av1 codec response - - byteBufferArrayFingerprint.matchOrThrow(byteBufferArrayParentFingerprint).let { - it.method.apply { - val insertIndex = it.patternMatch!!.endIndex - val insertRegister = - getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $EXTENSION_AV1_CODEC_CLASS_DESCRIPTOR->rejectResponse(I)I - move-result v$insertRegister - """ - ) - } - } - - // endregion - // region patch for disable VP9 codec vp9CapabilityFingerprint.methodOrThrow().apply { diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 0b04f7072..783bc9185 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1646,6 +1646,10 @@ Press and hold the More button to show the Custom actions dialog." Show open video menu Open video menu is shown. Open video menu is hidden. + Speed dialog + Show speed dialog menu + Speed dialog menu is shown. + Speed dialog menu is hidden. Repeat state Show repeat state menu Repeat state menu is shown. @@ -1763,12 +1767,45 @@ No margins on top and bottom of player." Video - Default playback speed - Default video quality on mobile network - Default video quality on Wi-Fi network + + Codec Disable HDR video HDR video is disabled. HDR video is enabled. + Disable VP9 codec + "VP9 codec is disabled. + +Info: +• Maximum resolution is 1080p. +• Video playback will use more internet data than VP9. +• VP9 codec is still used for HDR video." + VP9 codec is enabled. + Replace software AV1 codec + Replaces the software AV1 codec with the VP9 codec. + + + Playback speed + Default playback speed + Remember playback speed changes + Playback speed changes apply to all videos. + Playback speed changes only apply to the current video. + Show a toast + A toast will be shown when changing the default playback speed. + A toast will not be shown when changing the default playback speed. + + Default playback speed on Shorts + Remember playback speed changes on Shorts + "Playback speed changes apply to all Shorts. + +Info: +• The only way to change the playback speed in the Shorts player is to use the 'Speed ​​dialog' in 'Custom actions'. +• If you didn't include the 'Shorts components' patch, this wouldn't be available." + Playback speed changes only apply to the current Short. + Show a toast + A toast will be shown when changing the default playback speed on Shorts. + A toast will not be shown when changing the default playback speed on Shorts. + Changed default playback speed to: %s. + Changed default Shorts playback speed to: %s. Enable custom playback speed Custom playback speed is enabled. Custom playback speed is disabled. @@ -1777,30 +1814,34 @@ No margins on top and bottom of player." Old style flyout menu is used. Edit custom playback speeds Add or change available playback speeds. - Remember playback speed changes - Playback speed changes apply to all videos. - Playback speed changes only apply to the current video. - Show a toast - A toast will be shown when changing the default playback speed. - A toast will not be shown when changing the default playback speed. + Custom speeds must be less than %sx. + Invalid custom playback speeds. + + + Video quality + Default video quality on mobile network + Default video quality on Wi-Fi network Remember video quality changes Quality changes apply to all videos. Quality changes only apply to the current video. Show a toast A toast will be shown when changing the default video quality. A toast will not be shown when changing the default video quality. + Default Shorts quality on mobile network + Default Shorts quality on Wi-Fi network + Remember Shorts quality changes + Quality changes apply to all Shorts. + Quality changes only apply to the current Short. + Show a toast + A toast will be shown when changing the default Shorts quality. + A toast will not be shown when changing the default Shorts quality. + mobile + wifi + Changed default %1$s quality to: %2$s. + Changed Shorts %1$s quality to: %2$s. Restore old video quality menu Old video quality menu is shown. Old video quality menu is not shown. - Disable playback speed for music - Default playback speed is disabled for music. - Default playback speed is enabled for music. - Validate using categories - Default playback speed is disabled if the video category is Music. - Default playback speed is disabled for videos playable on YouTube Music. - Enable Shorts default playback speed - Default playback speed applies to Shorts. - Default playback speed does not apply to Shorts. Skipped preloaded buffer. Skip preloaded buffer "Skips the preloaded buffer at the start of videos to immediately apply the default video quality. @@ -1814,26 +1855,18 @@ Info: Toast is not shown. Spoof device dimensions "Spoofs the device dimensions to the maximum value. -High quality may be unlocked on some videos that require high device dimensions, but not all videos." - Disable VP9 codec - "VP9 codec is disabled. -• Maximum resolution is 1080p. -• Video playback will use more internet data than VP9. -• VP9 codec is still used for HDR video." - VP9 codec is enabled. - Replace software AV1 codec - Replaces the software AV1 codec with the VP9 codec. - Reject software AV1 codec response - "Forcefully rejects the software AV1 codec response. -A different codec will be applied after about 20 seconds of buffering." - Fallback process causes about 20 seconds of buffering. - Changing default speed to %s. - Changing default mobile data quality to %s. - Failed to set video quality. - Changing default Wi-Fi quality to %s. - Custom speeds must be less than %sx. - Invalid custom playback speeds. +Info: +• High quality may be unlocked on some videos that require high device dimensions, but not all videos. +• This setting is not available if 'Spoof streaming data' is turned on." + + + Disable playback speed for music + Default playback speed is disabled for music. + Default playback speed is enabled for music. + Validate using categories + Default playback speed is disabled if the video category is Music. + Default playback speed is disabled for videos playable on YouTube Music. diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index f857250e9..3b906b092 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -639,6 +639,7 @@ + SETTINGS: SHORTS_CUSTOM_ACTIONS_SHARED --> @@ -730,32 +731,44 @@