11package app.revanced.patches.tiktok.interaction.speed
22
33import app.revanced.patcher.data.BytecodeContext
4+ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
45import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
6+ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
57import app.revanced.patcher.patch.BytecodePatch
8+ import app.revanced.patcher.patch.PatchException
69import app.revanced.patcher.patch.annotation.CompatiblePackage
710import app.revanced.patcher.patch.annotation.Patch
8- import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
9- import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint
11+ import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint
12+ import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint
13+ import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint
1014import app.revanced.util.exception
15+ import app.revanced.util.getReference
1116import app.revanced.util.indexOfFirstInstruction
12- import com.android.tools.smali.dexlib2.Opcode
13- import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
17+ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
1418import com.android.tools.smali.dexlib2.iface.reference.MethodReference
1519
1620@Patch(
1721 name = " Playback speed" ,
18- description = " Enables the playback speed option for all videos." ,
22+ description = " Enables the playback speed option for all videos and " +
23+ " retains the speed configurations in between videos." ,
1924 compatiblePackages = [
2025 CompatiblePackage (" com.ss.android.ugc.trill" , [" 32.5.3" ]),
2126 CompatiblePackage (" com.zhiliaoapp.musically" , [" 32.5.3" ])
2227 ]
2328)
2429@Suppress(" unused" )
25- object PlaybackSpeedPatch : BytecodePatch(setOf(SpeedControlParentFingerprint )) {
30+ object PlaybackSpeedPatch : BytecodePatch(
31+ setOf(
32+ GetSpeedFingerprint ,
33+ OnRenderFirstFrameFingerprint ,
34+ SetSpeedFingerprint
35+ )
36+ ) {
2637 override fun execute (context : BytecodeContext ) {
27- SpeedControlParentFingerprint .result?.mutableMethod?.apply {
28- val targetMethodCallIndex = indexOfFirstInstruction {
29- if (opcode == Opcode .INVOKE_STATIC ) {
30- val paramsTypes = ((this as Instruction35c ).reference as MethodReference ).parameterTypes
31- paramsTypes.size == 1 && paramsTypes[0 ].contains(" /Aweme;" )
32- } else false
33- }
38+ SetSpeedFingerprint .result?.let { onVideoSwiped ->
39+ // Remember the playback speed of the current video.
40+ GetSpeedFingerprint .result?.mutableMethod?.apply {
41+ val injectIndex = indexOfFirstInstruction { getReference<MethodReference >()?.returnType == " F" } + 2
42+ val register = getInstruction<Instruction11x >(injectIndex - 1 ).registerA
3443
35- val isSpeedEnableMethod = context
36- .toMethodWalker(this )
37- .nextMethod(targetMethodCallIndex, true )
38- .getMethod() as MutableMethod
44+ addInstruction(
45+ injectIndex,
46+ " invoke-static { v$register }," +
47+ " Lapp/revanced/tiktok/speed/SpeedPatch;->rememberPlaybackSpeed(F)V"
48+ )
49+ } ? : throw GetSpeedFingerprint .exception
3950
40- isSpeedEnableMethod.addInstructions(
51+ // By default, the playback speed will reset to 1.0 at the start of each video.
52+ // Instead, override it with the desired playback speed.
53+ OnRenderFirstFrameFingerprint .result?.mutableMethod?.addInstructions(
4154 0 ,
4255 """
43- const/4 v0, 0x1
44- return v0
56+ # Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
57+ const/4 v0, 0x1
58+ invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String;
59+ move-result-object v0
60+
61+ # Model of current video retrieved using getCurrentAweme method.
62+ invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme;
63+ move-result-object v1
64+
65+ # Desired playback speed retrieved using getPlaybackSpeed method.
66+ invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getPlaybackSpeed()F
67+ move-result-object v2
68+ invoke-static { v0, v1, v2 }, ${onVideoSwiped.method}
69+ """
70+ ) ? : throw OnRenderFirstFrameFingerprint .exception
71+
72+ // Force enable the playback speed option for all videos.
73+ onVideoSwiped.mutableClass.methods.find { method -> method.returnType == " Z" }?.addInstructions(
74+ 0 ,
4575 """
46- )
47- } ? : throw SpeedControlParentFingerprint .exception
76+ const/4 v0, 0x1
77+ return v0
78+ """
79+ ) ? : throw PatchException (" Failed to force enable the playback speed option." )
80+ } ? : throw SetSpeedFingerprint .exception
4881 }
49- }
82+ }
0 commit comments