fix(YouTube/Spoof client): fix background playback issue with livestream on iOS clients https://github.com/inotia00/ReVanced_Extended/issues/2290

This commit is contained in:
inotia00 2024-08-04 13:21:11 +09:00
parent 0330f97c4f
commit dde5331ba9
2 changed files with 79 additions and 0 deletions

View File

@ -3,15 +3,19 @@ package app.revanced.patches.youtube.utils.fix.client
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfModelInstruction
import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch
import app.revanced.patches.youtube.utils.compatibility.Constants
import app.revanced.patches.youtube.utils.fingerprints.PlaybackRateBottomSheetBuilderFingerprint
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BackgroundPlaybackPlayerResponseFingerprint
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildInitPlaybackRequestFingerprint
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildPlayerRequestURIFingerprint
import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlaybackSpeedMenuItemFingerprint
@ -24,6 +28,7 @@ import app.revanced.patches.youtube.utils.fix.client.fingerprints.SetPlayerReque
import app.revanced.patches.youtube.utils.fix.client.fingerprints.UserAgentHeaderBuilderFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.storyboard.StoryboardHookPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch
@ -50,6 +55,10 @@ object SpoofClientPatch : BaseBytecodePatch(
name = "Spoof client",
description = "Adds options to spoof the client to allow video playback.",
dependencies = setOf(
// Required to fix background playback issue of live stream on iOS client.
BackgroundPlaybackPatch::class,
PlayerTypeHookPatch::class,
PlayerResponseMethodHookPatch::class,
SettingsPatch::class,
VideoInformationPatch::class,
@ -67,6 +76,9 @@ object SpoofClientPatch : BaseBytecodePatch(
CreatePlayerRequestBodyWithVersionReleaseFingerprint,
UserAgentHeaderBuilderFingerprint,
// Background playback in live stream.
BackgroundPlaybackPlayerResponseFingerprint,
// Player gesture config.
PlayerGestureConfigSyntheticFingerprint,
@ -379,6 +391,30 @@ object SpoofClientPatch : BaseBytecodePatch(
// endregion
// region fix background playback in live stream, if spoofing to iOS
/**
* If the return value of this method is true, background playback is always enabled.
*
* If [BackgroundPlaybackPatch] is excluded, there may be unintended behavior.
* Therefore, [BackgroundPlaybackPatch] must be included.
*
* Also, [PlayerTypeHookPatch] is required to disable background playback in Shorts.
*/
BackgroundPlaybackPlayerResponseFingerprint.resultOrThrow().mutableMethod.apply {
addInstructionsWithLabels(
0, """
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceEnableBackgroundPlayback()Z
move-result v0
if-eqz v0, :disabled
const/4 v0, 0x1
return v0
""", ExternalLabel("disabled", getInstruction(0))
)
}
// endregion
// region append spoof info.
NerdsStatsVideoFormatBuilderFingerprint.resultOrThrow().mutableMethod.apply {

View File

@ -0,0 +1,43 @@
package app.revanced.patches.youtube.utils.fix.client.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* On iOS clients, this method always returns false in live streams.
*
* This fingerprint seems to break easily because there are many [Opcode] patterns, but it is not.
* This fingerprint has been tested on all versions from YouTube 17.34.36 to YouTube 19.29.42.
*/
internal object BackgroundPlaybackPlayerResponseFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
opcodes = listOf(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.RETURN,
null, // Opcode.CONST_4 or Opcode.MOVE
Opcode.RETURN,
),
)