fix(YouTube - Playback speed): Allow long press 2x speed when using custom playback speeds (#3990)

This commit is contained in:
LisoUseInAIKyrios
2024-11-27 01:12:46 +04:00
committed by GitHub
parent d3a2fb17f1
commit 79a543a574
4 changed files with 88 additions and 63 deletions

View File

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

View File

@ -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<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
setPlaybackSpeedMethodReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference as MethodReference
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference as FieldReference
setPlaybackSpeedContainerClassFieldReference =
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ)
getInstruction<ReferenceInstruction>(indexOfFirstInstructionOrThrow(Opcode.IF_EQZ) - 1).reference as FieldReference
setPlaybackSpeedMethod =
proxy(classes.first { it.type == setPlaybackSpeedMethodReference.definingClass })
.mutableClass.methods.first { it.name == setPlaybackSpeedMethodReference.name }
setPlaybackSpeedMethodIndex = 0
}
// Handle new playback speed menu.
@ -195,6 +202,7 @@ val videoInformationPatch = bytecodePatch(
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
}
videoSpeedChangedHook(EXTENSION_CLASS_DESCRIPTOR, "videoSpeedChanged")
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
}
}
@ -295,9 +303,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 for any reason _except when the user manually selects a new speed_.
*/
fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) =
setPlaybackSpeedMethod.addInstruction(
setPlaybackSpeedMethodIndex++,
"invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V"
)
/**
* Hook the video speed selected by the user.
@ -312,4 +325,4 @@ fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: S
speedSelectionInsertIndex++,
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
)
}
}