mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-04-29 22:24:27 +02:00
feat(YouTube - Remember video quality): Add separate Shorts default quality settings (#4543)
This commit is contained in:
parent
74ec83f964
commit
88142ab464
@ -158,16 +158,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
/**
|
/**
|
||||||
* Syncs all UI Preferences to any {@link Setting} they represent.
|
* Syncs all UI Preferences to any {@link Setting} they represent.
|
||||||
*/
|
*/
|
||||||
private void updatePreferenceScreen(@NonNull PreferenceScreen screen,
|
private void updatePreferenceScreen(@NonNull PreferenceGroup group,
|
||||||
boolean syncSettingValue,
|
boolean syncSettingValue,
|
||||||
boolean applySettingToPreference) {
|
boolean applySettingToPreference) {
|
||||||
// Alternatively this could iterate thru all Settings and check for any matching Preferences,
|
// Alternatively this could iterate thru all Settings and check for any matching Preferences,
|
||||||
// but there are many more Settings than UI preferences so it's more efficient to only check
|
// but there are many more Settings than UI preferences so it's more efficient to only check
|
||||||
// the Preferences.
|
// the Preferences.
|
||||||
for (int i = 0, prefCount = screen.getPreferenceCount(); i < prefCount; i++) {
|
for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) {
|
||||||
Preference pref = screen.getPreference(i);
|
Preference pref = group.getPreference(i);
|
||||||
if (pref instanceof PreferenceScreen) {
|
if (pref instanceof PreferenceGroup subGroup) {
|
||||||
updatePreferenceScreen((PreferenceScreen) pref, syncSettingValue, applySettingToPreference);
|
updatePreferenceScreen(subGroup, syncSettingValue, applySettingToPreference);
|
||||||
} else if (pref.hasKey()) {
|
} else if (pref.hasKey()) {
|
||||||
String key = pref.getKey();
|
String key = pref.getKey();
|
||||||
Setting<?> setting = Setting.getSettingFromPath(key);
|
Setting<?> setting = Setting.getSettingFromPath(key);
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package app.revanced.extension.shared.settings.preference;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.PreferenceCategory;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty preference category with no title, used to organize and group related preferences together.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
|
public class NoTitlePreferenceCategory extends PreferenceCategory {
|
||||||
|
public NoTitlePreferenceCategory(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoTitlePreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoTitlePreferenceCategory(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressLint("MissingSuperCall")
|
||||||
|
protected View onCreateView(ViewGroup parent) {
|
||||||
|
// Return an empty, zero-height view to eliminate spacing
|
||||||
|
return new View(getContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.shared.PlayerType;
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BackgroundPlaybackPatch {
|
public class BackgroundPlaybackPatch {
|
||||||
@ -23,16 +23,7 @@ public class BackgroundPlaybackPatch {
|
|||||||
// 7. Close the Short
|
// 7. Close the Short
|
||||||
// 8. Resume playing the regular video
|
// 8. Resume playing the regular video
|
||||||
// 9. Minimize the app (PIP should appear)
|
// 9. Minimize the app (PIP should appear)
|
||||||
if (!VideoInformation.lastVideoIdIsShort()) {
|
return !ShortsPlayerState.isOpen();
|
||||||
return true; // Definitely is not a Short.
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add better hook.
|
|
||||||
// Might be a Shorts, or might be a prior regular video on screen again after a Shorts was closed.
|
|
||||||
// This incorrectly prevents PIP if player is in WATCH_WHILE_MINIMIZED after closing a Shorts,
|
|
||||||
// But there's no way around this unless an additional hook is added to definitively detect
|
|
||||||
// the Shorts player is on screen. This use case is unusual anyways so it's not a huge concern.
|
|
||||||
return !PlayerType.getCurrent().isNoneHiddenOrMinimized();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.shared.PlayerType;
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class DisableAutoCaptionsPatch {
|
public class DisableAutoCaptionsPatch {
|
||||||
@ -14,7 +14,7 @@ public class DisableAutoCaptionsPatch {
|
|||||||
public static boolean autoCaptionsEnabled() {
|
public static boolean autoCaptionsEnabled() {
|
||||||
return Settings.AUTO_CAPTIONS.get()
|
return Settings.AUTO_CAPTIONS.get()
|
||||||
// Do not use auto captions for Shorts.
|
// Do not use auto captions for Shorts.
|
||||||
&& !PlayerType.getCurrent().isNoneHiddenOrSlidingMinimized();
|
&& ShortsPlayerState.isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.revanced.extension.youtube.shared.PlayerType;
|
import app.revanced.extension.youtube.shared.PlayerType;
|
||||||
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
import app.revanced.extension.youtube.shared.VideoState;
|
import app.revanced.extension.youtube.shared.VideoState;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -24,4 +27,26 @@ public class PlayerTypeHookPatch {
|
|||||||
|
|
||||||
VideoState.setFromString(youTubeVideoState.name());
|
VideoState.setFromString(youTubeVideoState.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*
|
||||||
|
* Add a listener to the shorts player overlay View.
|
||||||
|
* Triggered when a shorts player is attached or detached to Windows.
|
||||||
|
*
|
||||||
|
* @param view shorts player overlay (R.id.reel_watch_player).
|
||||||
|
*/
|
||||||
|
public static void onShortsCreate(View view) {
|
||||||
|
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onViewAttachedToWindow(@Nullable View v) {
|
||||||
|
ShortsPlayerState.setOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewDetachedFromWindow(@Nullable View v) {
|
||||||
|
ShortsPlayerState.setOpen(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,19 @@ import java.util.List;
|
|||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.Utils;
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
import app.revanced.extension.shared.settings.IntegerSetting;
|
import app.revanced.extension.shared.settings.IntegerSetting;
|
||||||
import app.revanced.extension.youtube.patches.VideoInformation;
|
import app.revanced.extension.youtube.patches.VideoInformation;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class RememberVideoQualityPatch {
|
public class RememberVideoQualityPatch {
|
||||||
private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
|
private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
|
||||||
private static final IntegerSetting wifiQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
|
private static final IntegerSetting videoQualityWifi = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
|
||||||
private static final IntegerSetting mobileQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
|
private static final IntegerSetting videoQualityMobile = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
|
||||||
|
private static final IntegerSetting shortsQualityWifi = Settings.SHORTS_QUALITY_DEFAULT_WIFI;
|
||||||
|
private static final IntegerSetting shortsQualityMobile = Settings.SHORTS_QUALITY_DEFAULT_MOBILE;
|
||||||
|
|
||||||
private static boolean qualityNeedsUpdating;
|
private static boolean qualityNeedsUpdating;
|
||||||
|
|
||||||
@ -41,17 +45,29 @@ public class RememberVideoQualityPatch {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static List<Integer> videoQualities;
|
private static List<Integer> videoQualities;
|
||||||
|
|
||||||
|
private 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) {
|
private static void changeDefaultQuality(int defaultQuality) {
|
||||||
String networkTypeMessage;
|
String networkTypeMessage;
|
||||||
|
boolean useShortsPreference = ShortsPlayerState.isOpen();
|
||||||
if (Utils.getNetworkType() == NetworkType.MOBILE) {
|
if (Utils.getNetworkType() == NetworkType.MOBILE) {
|
||||||
mobileQualitySetting.save(defaultQuality);
|
if (useShortsPreference) shortsQualityMobile.save(defaultQuality);
|
||||||
|
else videoQualityMobile.save(defaultQuality);
|
||||||
networkTypeMessage = str("revanced_remember_video_quality_mobile");
|
networkTypeMessage = str("revanced_remember_video_quality_mobile");
|
||||||
} else {
|
} else {
|
||||||
wifiQualitySetting.save(defaultQuality);
|
if (useShortsPreference) shortsQualityWifi.save(defaultQuality);
|
||||||
|
else videoQualityWifi.save(defaultQuality);
|
||||||
networkTypeMessage = str("revanced_remember_video_quality_wifi");
|
networkTypeMessage = str("revanced_remember_video_quality_wifi");
|
||||||
}
|
}
|
||||||
Utils.showToastShort(
|
Utils.showToastShort(str(
|
||||||
str("revanced_remember_video_quality_toast", networkTypeMessage, (defaultQuality + "p")));
|
useShortsPreference ? "revanced_remember_video_quality_toast_shorts" : "revanced_remember_video_quality_toast",
|
||||||
|
networkTypeMessage, (defaultQuality + "p")
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,9 +78,10 @@ public class RememberVideoQualityPatch {
|
|||||||
*/
|
*/
|
||||||
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
|
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
|
||||||
try {
|
try {
|
||||||
|
boolean useShortsPreference = ShortsPlayerState.isOpen();
|
||||||
final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
|
final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
|
||||||
? mobileQualitySetting.get()
|
? (useShortsPreference ? shortsQualityMobile : videoQualityMobile).get()
|
||||||
: wifiQualitySetting.get();
|
: (useShortsPreference ? shortsQualityWifi : videoQualityWifi).get();
|
||||||
|
|
||||||
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
|
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
|
||||||
return originalQualityIndex; // Nothing to do.
|
return originalQualityIndex; // Nothing to do.
|
||||||
@ -141,17 +158,17 @@ public class RememberVideoQualityPatch {
|
|||||||
* Injection point. Old quality menu.
|
* Injection point. Old quality menu.
|
||||||
*/
|
*/
|
||||||
public static void userChangedQuality(int selectedQualityIndex) {
|
public static void userChangedQuality(int selectedQualityIndex) {
|
||||||
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return;
|
if (shouldRememberVideoQuality()) {
|
||||||
|
|
||||||
userSelectedQualityIndex = selectedQualityIndex;
|
userSelectedQualityIndex = selectedQualityIndex;
|
||||||
userChangedDefaultQuality = true;
|
userChangedDefaultQuality = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point. New quality menu.
|
* Injection point. New quality menu.
|
||||||
*/
|
*/
|
||||||
public static void userChangedQualityInNewFlyout(int selectedQuality) {
|
public static void userChangedQualityInNewFlyout(int selectedQuality) {
|
||||||
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return;
|
if (!shouldRememberVideoQuality()) return;
|
||||||
|
|
||||||
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
|
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,13 @@ import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
|||||||
public class Settings extends BaseSettings {
|
public class Settings extends BaseSettings {
|
||||||
// Video
|
// Video
|
||||||
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
||||||
public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
|
|
||||||
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
|
||||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
|
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
|
||||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
|
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
|
||||||
|
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
||||||
|
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_shorts_quality_default_wifi", -2, true);
|
||||||
|
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_shorts_quality_default_mobile", -2, true);
|
||||||
|
public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE);
|
||||||
|
public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
|
||||||
// Speed
|
// Speed
|
||||||
public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true);
|
public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true);
|
||||||
public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE);
|
public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE);
|
||||||
|
@ -5,7 +5,7 @@ import app.revanced.extension.youtube.Event
|
|||||||
import app.revanced.extension.youtube.patches.VideoInformation
|
import app.revanced.extension.youtube.patches.VideoInformation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main player type.
|
* Regular player type.
|
||||||
*/
|
*/
|
||||||
enum class PlayerType {
|
enum class PlayerType {
|
||||||
/**
|
/**
|
||||||
@ -90,8 +90,6 @@ enum class PlayerType {
|
|||||||
* Does not include the first moment after a short is opened when a regular video is minimized on screen,
|
* Does not include the first moment after a short is opened when a regular video is minimized on screen,
|
||||||
* or while watching a short with a regular video present on a spoofed 16.x version of YouTube.
|
* or while watching a short with a regular video present on a spoofed 16.x version of YouTube.
|
||||||
* To include those situations instead use [isNoneHiddenOrMinimized].
|
* To include those situations instead use [isNoneHiddenOrMinimized].
|
||||||
*
|
|
||||||
* @see VideoInformation
|
|
||||||
*/
|
*/
|
||||||
fun isNoneOrHidden(): Boolean {
|
fun isNoneOrHidden(): Boolean {
|
||||||
return this == NONE || this == HIDDEN
|
return this == NONE || this == HIDDEN
|
||||||
@ -107,8 +105,11 @@ enum class PlayerType {
|
|||||||
* when spoofing to an old version this will return false even
|
* when spoofing to an old version this will return false even
|
||||||
* though a Short is being opened or is on screen (see [isNoneHiddenOrMinimized]).
|
* though a Short is being opened or is on screen (see [isNoneHiddenOrMinimized]).
|
||||||
*
|
*
|
||||||
|
* Instead of this method, consider using {@link ShortsPlayerState}
|
||||||
|
* which may work better for some situations.
|
||||||
|
*
|
||||||
* @return If nothing, a Short, or a regular video is sliding off screen to a dismissed or hidden state.
|
* @return If nothing, a Short, or a regular video is sliding off screen to a dismissed or hidden state.
|
||||||
* @see VideoInformation
|
* @see ShortsPlayerState
|
||||||
*/
|
*/
|
||||||
fun isNoneHiddenOrSlidingMinimized(): Boolean {
|
fun isNoneHiddenOrSlidingMinimized(): Boolean {
|
||||||
return isNoneOrHidden() || this == WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED
|
return isNoneOrHidden() || this == WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED
|
||||||
@ -125,9 +126,12 @@ enum class PlayerType {
|
|||||||
* Typically used to detect if a Short is playing when the player cannot be in a minimized state,
|
* Typically used to detect if a Short is playing when the player cannot be in a minimized state,
|
||||||
* such as the user interacting with a button or element of the player.
|
* such as the user interacting with a button or element of the player.
|
||||||
*
|
*
|
||||||
|
* Instead of this method, consider using {@link ShortsPlayerState}
|
||||||
|
* which may work better for some situations.
|
||||||
|
*
|
||||||
* @return If nothing, a Short, a regular video is sliding off screen to a dismissed or hidden state,
|
* @return If nothing, a Short, a regular video is sliding off screen to a dismissed or hidden state,
|
||||||
* a regular video is minimized (and a new video is not being opened).
|
* a regular video is minimized (and a new video is not being opened).
|
||||||
* @see VideoInformation
|
* @see ShortsPlayerState
|
||||||
*/
|
*/
|
||||||
fun isNoneHiddenOrMinimized(): Boolean {
|
fun isNoneHiddenOrMinimized(): Boolean {
|
||||||
return isNoneHiddenOrSlidingMinimized() || this == WATCH_WHILE_MINIMIZED
|
return isNoneHiddenOrSlidingMinimized() || this == WATCH_WHILE_MINIMIZED
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package app.revanced.extension.youtube.shared
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger
|
||||||
|
import app.revanced.extension.youtube.Event
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorts player state.
|
||||||
|
*/
|
||||||
|
class ShortsPlayerState {
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setOpen(open: Boolean) {
|
||||||
|
if (isOpen != open) {
|
||||||
|
Logger.printDebug { "ShortsPlayerState open changed to: $isOpen" }
|
||||||
|
isOpen = open
|
||||||
|
onChange(open)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var isOpen = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorts player state change listener.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
val onChange = Event<Boolean>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the Shorts player is currently open.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun isOpen(): Boolean {
|
||||||
|
return isOpen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ import org.w3c.dom.Element
|
|||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
abstract class BasePreference(
|
abstract class BasePreference(
|
||||||
val key: String? = null,
|
val key: String? = null,
|
||||||
val titleKey: String = "${key}_title",
|
val titleKey: String? = "${key}_title",
|
||||||
val summaryKey: String? = "${key}_summary",
|
val summaryKey: String? = "${key}_summary",
|
||||||
val icon: String? = null,
|
val icon: String? = null,
|
||||||
val layout: String? = null,
|
val layout: String? = null,
|
||||||
@ -35,7 +35,7 @@ abstract class BasePreference(
|
|||||||
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element =
|
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element =
|
||||||
ownerDocument.createElement(tag).apply {
|
ownerDocument.createElement(tag).apply {
|
||||||
key?.let { setAttribute("android:key", it) }
|
key?.let { setAttribute("android:key", it) }
|
||||||
setAttribute("android:title", "@string/${titleKey}")
|
titleKey?.let { setAttribute("android:title", "@string/${titleKey}") }
|
||||||
summaryKey?.let { addSummary(it) }
|
summaryKey?.let { addSummary(it) }
|
||||||
icon?.let {
|
icon?.let {
|
||||||
setAttribute("android:icon", it)
|
setAttribute("android:icon", it)
|
||||||
|
@ -17,7 +17,7 @@ import org.w3c.dom.Document
|
|||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
open class PreferenceCategory(
|
open class PreferenceCategory(
|
||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String? = "${key}_title",
|
||||||
icon: String? = null,
|
icon: String? = null,
|
||||||
layout: String? = null,
|
layout: String? = null,
|
||||||
sorting: Sorting = Sorting.BY_TITLE,
|
sorting: Sorting = Sorting.BY_TITLE,
|
||||||
|
@ -12,6 +12,8 @@ import app.revanced.patches.shared.misc.mapping.get
|
|||||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
|
||||||
@ -71,6 +73,15 @@ val spoofAppVersionPatch = bytecodePatch(
|
|||||||
addResources("youtube", "layout.spoofappversion.spoofAppVersionPatch")
|
addResources("youtube", "layout.spoofappversion.spoofAppVersionPatch")
|
||||||
|
|
||||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
|
// Group the switch and list preference together, since General menu is sorted by name
|
||||||
|
// and the preferences can be scattered apart with non English langauges.
|
||||||
|
PreferenceCategory(
|
||||||
|
key = null,
|
||||||
|
// The title does not show, but is used for sorting the group.
|
||||||
|
titleKey = "revanced_spoof_app_version_title",
|
||||||
|
sorting = Sorting.UNSORTED,
|
||||||
|
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||||
|
preferences = setOf(
|
||||||
SwitchPreference("revanced_spoof_app_version"),
|
SwitchPreference("revanced_spoof_app_version"),
|
||||||
if (is_19_17_or_greater) {
|
if (is_19_17_or_greater) {
|
||||||
ListPreference(
|
ListPreference(
|
||||||
@ -86,6 +97,8 @@ val spoofAppVersionPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a user really wants to spoof to very old versions with the latest app target
|
* If a user really wants to spoof to very old versions with the latest app target
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app.revanced.patches.youtube.misc.playertype
|
package app.revanced.patches.youtube.misc.playertype
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
|
import app.revanced.util.literal
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
@ -15,6 +16,12 @@ internal val playerTypeFingerprint = fingerprint {
|
|||||||
custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") }
|
custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val reelWatchPagerFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("Landroid/view/View;")
|
||||||
|
literal { reelWatchPlayerId }
|
||||||
|
}
|
||||||
|
|
||||||
internal val videoStateFingerprint = fingerprint {
|
internal val videoStateFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returns("V")
|
returns("V")
|
||||||
|
@ -4,15 +4,34 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patcher.patch.resourcePatch
|
||||||
|
import app.revanced.patches.shared.misc.mapping.get
|
||||||
|
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||||
|
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||||
|
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.ReferenceInstruction
|
||||||
|
|
||||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
|
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
|
||||||
|
|
||||||
|
internal var reelWatchPlayerId = -1L
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val playerTypeHookResourcePatch = resourcePatch {
|
||||||
|
dependsOn(resourceMappingPatch)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
reelWatchPlayerId = resourceMappings["id", "reel_watch_player"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val playerTypeHookPatch = bytecodePatch(
|
val playerTypeHookPatch = bytecodePatch(
|
||||||
description = "Hook to get the current player type and video playback state.",
|
description = "Hook to get the current player type and video playback state.",
|
||||||
) {
|
) {
|
||||||
dependsOn(sharedExtensionPatch)
|
dependsOn(sharedExtensionPatch, playerTypeHookResourcePatch)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
playerTypeFingerprint.method.addInstruction(
|
playerTypeFingerprint.method.addInstruction(
|
||||||
@ -20,6 +39,17 @@ val playerTypeHookPatch = bytecodePatch(
|
|||||||
"invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V",
|
"invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
reelWatchPagerFingerprint.method.apply {
|
||||||
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(reelWatchPlayerId)
|
||||||
|
val registerIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
|
val viewRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
registerIndex + 1,
|
||||||
|
"invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR->onShortsCreate(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
videoStateFingerprint.method.apply {
|
videoStateFingerprint.method.apply {
|
||||||
val endIndex = videoStateFingerprint.patternMatch!!.endIndex
|
val endIndex = videoStateFingerprint.patternMatch!!.endIndex
|
||||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||||
@ -29,7 +59,7 @@ val playerTypeHookPatch = bytecodePatch(
|
|||||||
"""
|
"""
|
||||||
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
|
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
|
||||||
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
|
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
|
||||||
""",
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,6 +323,7 @@ object PreferenceScreen : BasePreferenceScreen() {
|
|||||||
val VIDEO = Screen(
|
val VIDEO = Screen(
|
||||||
key = "revanced_settings_screen_12_video",
|
key = "revanced_settings_screen_12_video",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
|
sorting = Sorting.BY_KEY,
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun commit(screen: PreferenceScreenPreference) {
|
override fun commit(screen: PreferenceScreenPreference) {
|
||||||
|
@ -8,8 +8,11 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
|
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
|
||||||
@ -29,6 +32,7 @@ val rememberVideoQualityPatch = bytecodePatch(
|
|||||||
dependsOn(
|
dependsOn(
|
||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
|
playerTypeHookPatch,
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
addResourcesPatch,
|
addResourcesPatch,
|
||||||
)
|
)
|
||||||
@ -49,19 +53,42 @@ val rememberVideoQualityPatch = bytecodePatch(
|
|||||||
addResources("youtube", "video.quality.rememberVideoQualityPatch")
|
addResources("youtube", "video.quality.rememberVideoQualityPatch")
|
||||||
|
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
SwitchPreference("revanced_remember_video_quality_last_selected"),
|
// Keep the preferences organized together.
|
||||||
ListPreference(
|
PreferenceCategory(
|
||||||
key = "revanced_video_quality_default_wifi",
|
key = "revanced_01_video_key", // Dummy key to force the quality preferences first.
|
||||||
summaryKey = null,
|
titleKey = null,
|
||||||
entriesKey = "revanced_video_quality_default_entries",
|
sorting = Sorting.UNSORTED,
|
||||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||||
),
|
preferences = setOf(
|
||||||
ListPreference(
|
ListPreference(
|
||||||
key = "revanced_video_quality_default_mobile",
|
key = "revanced_video_quality_default_mobile",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
entriesKey = "revanced_video_quality_default_entries",
|
entriesKey = "revanced_video_quality_default_entries",
|
||||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||||
),
|
),
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_video_quality_default_wifi",
|
||||||
|
summaryKey = null,
|
||||||
|
entriesKey = "revanced_video_quality_default_entries",
|
||||||
|
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||||
|
),
|
||||||
|
SwitchPreference("revanced_remember_video_quality_last_selected"),
|
||||||
|
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_shorts_quality_default_mobile",
|
||||||
|
summaryKey = null,
|
||||||
|
entriesKey = "revanced_video_quality_default_entries",
|
||||||
|
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||||
|
),
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_shorts_quality_default_wifi",
|
||||||
|
summaryKey = null,
|
||||||
|
entriesKey = "revanced_video_quality_default_entries",
|
||||||
|
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||||
|
),
|
||||||
|
SwitchPreference("revanced_remember_shorts_quality_last_selected")
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
package app.revanced.patches.youtube.video.speed
|
package app.revanced.patches.youtube.video.speed
|
||||||
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
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.speed.button.playbackSpeedButtonPatch
|
import app.revanced.patches.youtube.video.speed.button.playbackSpeedButtonPatch
|
||||||
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
||||||
import app.revanced.patches.youtube.video.speed.remember.rememberPlaybackSpeedPatch
|
import app.revanced.patches.youtube.video.speed.remember.rememberPlaybackSpeedPatch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speed menu settings. Used to organize all speed related settings together.
|
||||||
|
*/
|
||||||
|
internal val settingsMenuVideoSpeedGroup = mutableSetOf<BasePreference>()
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val playbackSpeedPatch = bytecodePatch(
|
val playbackSpeedPatch = bytecodePatch(
|
||||||
name = "Playback speed",
|
name = "Playback speed",
|
||||||
@ -26,6 +35,18 @@ val playbackSpeedPatch = bytecodePatch(
|
|||||||
"19.45.38",
|
"19.45.38",
|
||||||
"19.46.42",
|
"19.46.42",
|
||||||
"19.47.53",
|
"19.47.53",
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalize {
|
||||||
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
|
PreferenceCategory(
|
||||||
|
key = "revanced_zz_key", // Dummy key to force the speed settings last.
|
||||||
|
titleKey = null,
|
||||||
|
sorting = Sorting.UNSORTED,
|
||||||
|
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||||
|
preferences = settingsMenuVideoSpeedGroup
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
|||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
|
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
|
||||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
|
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.patches.youtube.video.speed.settingsMenuVideoSpeedGroup
|
||||||
import app.revanced.util.*
|
import app.revanced.util.*
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
@ -71,13 +71,18 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
|||||||
execute {
|
execute {
|
||||||
addResources("youtube", "video.speed.custom.customPlaybackSpeedPatch")
|
addResources("youtube", "video.speed.custom.customPlaybackSpeedPatch")
|
||||||
|
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
settingsMenuVideoSpeedGroup.addAll(
|
||||||
|
listOf(
|
||||||
SwitchPreference("revanced_custom_speed_menu"),
|
SwitchPreference("revanced_custom_speed_menu"),
|
||||||
TextPreference("revanced_custom_playback_speeds", inputType = InputType.TEXT_MULTI_LINE),
|
TextPreference(
|
||||||
|
"revanced_custom_playback_speeds",
|
||||||
|
inputType = InputType.TEXT_MULTI_LINE
|
||||||
|
),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
settingsMenuVideoSpeedGroup.add(
|
||||||
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
|
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.*
|
import app.revanced.patches.youtube.video.information.*
|
||||||
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
||||||
|
import app.revanced.patches.youtube.video.speed.settingsMenuVideoSpeedGroup
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
@ -30,8 +30,8 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch {
|
|||||||
execute {
|
execute {
|
||||||
addResources("youtube", "video.speed.remember.rememberPlaybackSpeedPatch")
|
addResources("youtube", "video.speed.remember.rememberPlaybackSpeedPatch")
|
||||||
|
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
settingsMenuVideoSpeedGroup.addAll(
|
||||||
SwitchPreference("revanced_remember_playback_speed_last_selected"),
|
listOf(
|
||||||
ListPreference(
|
ListPreference(
|
||||||
key = "revanced_playback_speed_default",
|
key = "revanced_playback_speed_default",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
@ -39,6 +39,8 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch {
|
|||||||
entriesKey = null,
|
entriesKey = null,
|
||||||
entryValuesKey = null,
|
entryValuesKey = null,
|
||||||
),
|
),
|
||||||
|
SwitchPreference("revanced_remember_playback_speed_last_selected")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
|
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
|
||||||
|
@ -1373,15 +1373,22 @@ Enabling this can unlock higher video qualities"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_screen_title">Video quality</string>
|
||||||
<string name="revanced_video_quality_default_entry_1">Auto</string>
|
<string name="revanced_video_quality_default_entry_1">Auto</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Remember video quality changes</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Remember video quality changes</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Quality changes apply to all videos</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Quality changes apply to all videos</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Quality changes only apply to the current video</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Quality changes only apply to the current video</string>
|
||||||
<string name="revanced_video_quality_default_wifi_title">Default video quality on Wi-Fi network</string>
|
<string name="revanced_video_quality_default_wifi_title">Default video quality on Wi-Fi network</string>
|
||||||
<string name="revanced_video_quality_default_mobile_title">Default video quality on mobile network</string>
|
<string name="revanced_video_quality_default_mobile_title">Default video quality on mobile network</string>
|
||||||
|
<string name="revanced_remember_shorts_quality_last_selected_title">Remember Shorts quality changes</string>
|
||||||
|
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Quality changes apply to all Shorts videos</string>
|
||||||
|
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Quality changes only apply to the current Shorts video</string>
|
||||||
|
<string name="revanced_shorts_quality_default_wifi_title">Default Shorts quality on Wi-Fi network</string>
|
||||||
|
<string name="revanced_shorts_quality_default_mobile_title">Default Shorts quality on mobile network</string>
|
||||||
<string name="revanced_remember_video_quality_mobile">mobile</string>
|
<string name="revanced_remember_video_quality_mobile">mobile</string>
|
||||||
<string name="revanced_remember_video_quality_wifi">wifi</string>
|
<string name="revanced_remember_video_quality_wifi">wifi</string>
|
||||||
<string name="revanced_remember_video_quality_toast">Changed default %1$s quality to: %2$s</string>
|
<string name="revanced_remember_video_quality_toast">Changed default %1$s quality to: %2$s</string>
|
||||||
|
<string name="revanced_remember_video_quality_toast_shorts">Changed Shorts %1$s quality to: %2$s</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
<string name="revanced_playback_speed_dialog_button_title">Show speed dialog button</string>
|
<string name="revanced_playback_speed_dialog_button_title">Show speed dialog button</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user