diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/VideoInformation.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/VideoInformation.java index 6b64ade12..6df9a9095 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/VideoInformation.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/VideoInformation.java @@ -1,14 +1,14 @@ package app.revanced.extension.youtube.patches; import androidx.annotation.NonNull; -import app.revanced.extension.youtube.patches.playback.speed.RememberPlaybackSpeedPatch; -import app.revanced.extension.youtube.shared.VideoState; -import app.revanced.extension.shared.Logger; -import app.revanced.extension.shared.Utils; import java.lang.ref.WeakReference; import java.util.Objects; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.youtube.shared.VideoState; + /** * Hooking class for the current playing video. * @noinspection unused @@ -120,6 +120,16 @@ public final class VideoInformation { } } + /** + * Injection point. + */ + public static void videoSpeedChanged(float currentVideoSpeed) { + if (playbackSpeed != currentVideoSpeed) { + Logger.printDebug(() -> "Video speed changed: " + currentVideoSpeed); + playbackSpeed = currentVideoSpeed; + } + } + /** * Injection point. * Called when user selects a playback speed. @@ -131,18 +141,6 @@ public final class VideoInformation { playbackSpeed = userSelectedPlaybackSpeed; } - /** - * Overrides the current playback speed. - *
- * Used exclusively by {@link RememberPlaybackSpeedPatch}
- */
- public static void overridePlaybackSpeed(float speedOverride) {
- if (playbackSpeed != speedOverride) {
- Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
- playbackSpeed = speedOverride;
- }
- }
-
/**
* Injection point.
*
diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java
index 3c504df5d..a6c86477c 100644
--- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java
+++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java
@@ -12,6 +12,8 @@ public final class RememberPlaybackSpeedPatch {
private static final long TOAST_DELAY_MILLISECONDS = 750;
+ private static volatile boolean newVideoStarted;
+
private static long lastTimeSpeedChanged;
/**
@@ -19,7 +21,7 @@ public final class RememberPlaybackSpeedPatch {
*/
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
Logger.printDebug(() -> "newVideoStarted");
- VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get());
+ newVideoStarted = true;
}
/**
@@ -29,42 +31,56 @@ public final class RememberPlaybackSpeedPatch {
* @param playbackSpeed The playback speed the user selected
*/
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
- if (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);
+ try {
+ if (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);
- // 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;
+ // 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;
- final float finalPlaybackSpeed = playbackSpeed;
- Utils.runOnMainThreadDelayed(() -> {
- if (lastTimeSpeedChanged != now) {
- // The user made additional speed adjustments and this call is outdated.
- return;
- }
+ final float finalPlaybackSpeed = playbackSpeed;
+ Utils.runOnMainThreadDelayed(() -> {
+ if (lastTimeSpeedChanged != now) {
+ // The user made additional speed adjustments and this call is outdated.
+ return;
+ }
- if (Settings.PLAYBACK_SPEED_DEFAULT.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.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
+ if (Settings.PLAYBACK_SPEED_DEFAULT.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.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
- Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
- }, TOAST_DELAY_MILLISECONDS);
+ Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
+ }, TOAST_DELAY_MILLISECONDS);
+ }
+ } catch (Exception ex) {
+ Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex);
}
}
/**
* Injection point.
- * Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed
+ * Overrides the video speed. Called after video loads,
+ * and immediately after the user selects a different playback speed.
*/
public static float getPlaybackSpeedOverride() {
- return VideoInformation.getPlaybackSpeed();
+ if (newVideoStarted) {
+ newVideoStarted = false;
+
+ final float defaultSpeed = Settings.PLAYBACK_SPEED_DEFAULT.get();
+ if (defaultSpeed > 0) {
+ return defaultSpeed;
+ }
+ }
+
+ return -2.0f;
}
-}
+}
\ No newline at end of file
diff --git a/patches/api/patches.api b/patches/api/patches.api
index 89368b943..2ba4d9a4e 100644
--- a/patches/api/patches.api
+++ b/patches/api/patches.api
@@ -1370,11 +1370,9 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt {
}
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
- public static final fun getSetPlaybackSpeedClassFieldReference ()Ljava/lang/String;
- public static final fun getSetPlaybackSpeedContainerClassFieldReference ()Ljava/lang/String;
- public static final fun getSetPlaybackSpeedMethodReference ()Ljava/lang/String;
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
+ public static final fun videoSpeedChangedHook (Ljava/lang/String;Ljava/lang/String;)V
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
}
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 a44e371bf..a22934d1c 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
@@ -20,13 +20,13 @@ import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.builder.BuilderInstruction
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@@ -57,12 +57,16 @@ private lateinit var speedSelectionInsertMethod: MutableMethod
private var speedSelectionInsertIndex = -1
private var speedSelectionValueRegister = -1
+// Change playback speed method.
+private lateinit var setPlaybackSpeedMethod: MutableMethod
+private var setPlaybackSpeedMethodIndex = -1
+
// Used by other patches.
-lateinit var setPlaybackSpeedContainerClassFieldReference: String
+internal lateinit var setPlaybackSpeedContainerClassFieldReference: FieldReference
private set
-lateinit var setPlaybackSpeedClassFieldReference: String
+internal lateinit var setPlaybackSpeedClassFieldReference: FieldReference
private set
-lateinit var setPlaybackSpeedMethodReference: String
+internal lateinit var setPlaybackSpeedMethodReference: MethodReference
private set
val videoInformationPatch = bytecodePatch(
@@ -164,24 +168,27 @@ val videoInformationPatch = bytecodePatch(
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
/*
- * Hook the user playback speed selection
+ * Hook the user playback speed selection.
*/
onPlaybackSpeedItemClickFingerprint.method.apply {
- val speedSelectionMethodInstructions = implementation!!.instructions
- val speedSelectionValueInstructionIndex = speedSelectionMethodInstructions.indexOfFirst {
- it.opcode == Opcode.IGET
- }
+ val speedSelectionValueInstructionIndex = indexOfFirstInstructionOrThrow(Opcode.IGET)
+
legacySpeedSelectionInsertMethod = this
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
legacySpeedSelectionValueRegister =
getInstruction