Skip to content

Commit

Permalink
fix(YouTube - Spoof client): Fix background playback issue with lives…
Browse files Browse the repository at this point in the history
…tream on iOS clients
  • Loading branch information
inotia00 authored and Francesco146 committed Aug 7, 2024
1 parent f0cefa8 commit 0ef9a65
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -67,6 +76,9 @@ object SpoofClientPatch : BaseBytecodePatch(
CreatePlayerRequestBodyWithVersionReleaseFingerprint,
UserAgentHeaderBuilderFingerprint,

// Background playback in live stream.
BackgroundPlaybackPlayerResponseFingerprint,

// Player gesture config.
PlayerGestureConfigSyntheticFingerprint,

Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
),
)

0 comments on commit 0ef9a65

Please sign in to comment.