Skip to content

Commit

Permalink
fix(YouTube - Playback speed): Allow long press 2x speed when using a…
Browse files Browse the repository at this point in the history
… default playback speed
  • Loading branch information
LisoUseInAIKyrios committed Nov 26, 2024
1 parent 03fa88c commit 1f7b3fc
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ public static void setPlayerResponseVideoId(@NonNull String videoId, boolean isS
}
}

/**
* 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.
Expand All @@ -137,10 +147,10 @@ public static void userSelectedPlaybackSpeed(float userSelectedPlaybackSpeed) {
* <b> Used exclusively by {@link RememberPlaybackSpeedPatch} </b>
*/
public static void overridePlaybackSpeed(float speedOverride) {
if (playbackSpeed != speedOverride) {
Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
playbackSpeed = speedOverride;
}
if (speedOverride <= 0) throw new IllegalArgumentException("Invalid speed override: " + speedOverride);

Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
playbackSpeed = speedOverride;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ public final class RememberPlaybackSpeedPatch {

private static final long TOAST_DELAY_MILLISECONDS = 750;

private static volatile boolean newVideoStarted;

private static long lastTimeSpeedChanged;

/**
* Injection point.
*/
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
Logger.printDebug(() -> "newVideoStarted");
VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get());
try {
Logger.printDebug(() -> "newVideoStarted");
newVideoStarted = true;
} catch (Exception ex) {
Logger.printException(() -> "newVideoStarted failure", ex);
}
}

/**
Expand All @@ -29,42 +35,56 @@ public static void newVideoStarted(VideoInformation.PlaybackController ignoredPl
* @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);

// 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;
}

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);
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;

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);

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;
}

}
}
1 change: 1 addition & 0 deletions patches/api/patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,7 @@ public final class app/revanced/patches/youtube/video/information/VideoInformati
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 videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
public static final fun videoVideoSpeedChanged (Ljava/lang/String;Ljava/lang/String;)V
}

public abstract class app/revanced/patches/youtube/video/playerresponse/Hook {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ 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
private set
Expand Down Expand Up @@ -176,10 +180,15 @@ val videoInformationPatch = bytecodePatch(
legacySpeedSelectionValueRegister =
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA

val setPlaybackSpeedClassReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference as MethodReference
setPlaybackSpeedMethod = proxy(classes.first { it.type == setPlaybackSpeedClassReference.definingClass })
.mutableClass.methods.first { it.name == setPlaybackSpeedClassReference.name }
setPlaybackSpeedMethodIndex = 0

setPlaybackSpeedMethodReference = setPlaybackSpeedClassReference.toString()
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
setPlaybackSpeedMethodReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
setPlaybackSpeedContainerClassFieldReference =
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ)
}
Expand All @@ -195,6 +204,7 @@ val videoInformationPatch = bytecodePatch(
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
}

videoVideoSpeedChanged(EXTENSION_CLASS_DESCRIPTOR, "videoSpeedChanged")
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
}
}
Expand Down Expand Up @@ -295,9 +305,14 @@ fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
"$targetMethodClass->$targetMethodName(J)V",
)

private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction)
.reference.toString()
/**
* Hook when the video speed is changed, either by the user or any other reason.
*/
fun videoVideoSpeedChanged(targetMethodClass: String, targetMethodName: String) =
setPlaybackSpeedMethod.addInstruction(
setPlaybackSpeedMethodIndex++,
"invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V"
)

/**
* Hook the video speed selected by the user.
Expand All @@ -313,3 +328,7 @@ fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: S
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
)
}

private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction)
.reference.toString()

0 comments on commit 1f7b3fc

Please sign in to comment.