fix(YouTube): When clicking on timestamps in comments, playback speed sometimes changes to 1.0x (unpatched YouTube bug)

This commit is contained in:
inotia00
2024-12-21 13:49:59 +09:00
parent d89491ef15
commit 20eaad51d8
4 changed files with 130 additions and 0 deletions

View File

@ -0,0 +1,42 @@
package app.revanced.patches.youtube.utils.fix.playbackspeed
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionReversed
import app.revanced.util.or
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
/**
* This fingerprint is compatible with YouTube 17.34.36 ~ 19.50.40.
*
* This method is usually used to set the initial speed (1.0x) when playback starts from the feed.
* For some reason, in the latest YouTube, it is invoked even after the video has already started.
*/
internal val playbackSpeedInFeedsFingerprint = legacyFingerprint(
name = "playbackSpeedInFeedsFingerprint",
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),
opcodes = listOf(
Opcode.IGET,
Opcode.MUL_INT_LIT16,
Opcode.IGET_WIDE,
Opcode.CONST_WIDE_16,
Opcode.CMP_LONG,
Opcode.IF_EQZ,
Opcode.IF_LEZ,
Opcode.SUB_LONG_2ADDR,
),
customFingerprint = { method, _ ->
indexOfGetPlaybackSpeedInstruction(method) >= 0
}
)
fun indexOfGetPlaybackSpeedInstruction(method: Method) =
method.indexOfFirstInstructionReversed {
opcode == Opcode.IGET &&
getReference<FieldReference>()?.type == "F"
}

View File

@ -0,0 +1,60 @@
package app.revanced.patches.youtube.utils.fix.playbackspeed
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
private const val EXTENSION_CLASS_DESCRIPTOR =
"$UTILS_PATH/PlaybackSpeedWhilePlayingPatch;"
val playbackSpeedWhilePlayingPatch = bytecodePatch(
description = "playbackSpeedWhilePlayingPatch"
) {
dependsOn(
sharedExtensionPatch,
playerTypeHookPatch,
versionCheckPatch,
)
execute {
if (!is_19_34_or_greater) {
return@execute
}
/**
* There is an issue where sometimes when you click on a comment in a video and press the back button or click on the timestamp of the comment, the playback speed will change to 1.0x.
*
* This can be reproduced on unpatched YouTube 19.34.42+ by following these steps:
* 1. After the video starts, manually change the playback speed to something other than 1.0x.
* 2. If enough time has passed since the video started, open the comments panel.
* 3. Click on a comment and press the back button, or click on the timestamp of the comment.
* 4. Sometimes the playback speed will change to 1.0x.
*
* This is an issue that Google should fix, but it is not that hard to fix, so it has been implemented in the patch.
*/
playbackSpeedInFeedsFingerprint.methodOrThrow().apply {
val freeRegister = implementation!!.registerCount - parameters.size - 2
val playbackSpeedIndex = indexOfGetPlaybackSpeedInstruction(this)
val playbackSpeedRegister = getInstruction<TwoRegisterInstruction>(playbackSpeedIndex).registerA
val jumpIndex = indexOfFirstInstructionOrThrow(playbackSpeedIndex, Opcode.RETURN_VOID)
addInstructionsWithLabels(
playbackSpeedIndex + 1, """
invoke-static { v$playbackSpeedRegister }, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedChanged(F)Z
move-result v$freeRegister
if-nez v$freeRegister, :do_not_change
""", ExternalLabel("do_not_change", getInstruction(jumpIndex))
)
}
}
}

View File

@ -15,6 +15,7 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
import app.revanced.patches.youtube.utils.fix.cairo.cairoSettingsPatch
import app.revanced.patches.youtube.utils.fix.playbackspeed.playbackSpeedWhilePlayingPatch
import app.revanced.patches.youtube.utils.fix.splash.darkModeSplashScreenPatch
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
import app.revanced.patches.youtube.utils.patch.PatchList.SETTINGS_FOR_YOUTUBE
@ -122,6 +123,7 @@ val settingsPatch = resourcePatch(
settingsBytecodePatch,
cairoSettingsPatch,
darkModeSplashScreenPatch,
playbackSpeedWhilePlayingPatch,
)
val insertPosition = stringOption(