Skip to content

Commit 0ef9a65

Browse files
inotia00Francesco146
authored andcommitted
fix(YouTube - Spoof client): Fix background playback issue with livestream on iOS clients
1 parent f0cefa8 commit 0ef9a65

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofClientPatch.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ package app.revanced.patches.youtube.utils.fix.client
33
import app.revanced.patcher.data.BytecodeContext
44
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
55
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
6+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
67
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
78
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
89
import app.revanced.patcher.extensions.or
910
import app.revanced.patcher.patch.PatchException
1011
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
12+
import app.revanced.patcher.util.smali.ExternalLabel
1113
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint
1214
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfModelInstruction
15+
import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch
1316
import app.revanced.patches.youtube.utils.compatibility.Constants
1417
import app.revanced.patches.youtube.utils.fingerprints.PlaybackRateBottomSheetBuilderFingerprint
18+
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BackgroundPlaybackPlayerResponseFingerprint
1519
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildInitPlaybackRequestFingerprint
1620
import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildPlayerRequestURIFingerprint
1721
import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlaybackSpeedMenuItemFingerprint
@@ -24,6 +28,7 @@ import app.revanced.patches.youtube.utils.fix.client.fingerprints.SetPlayerReque
2428
import app.revanced.patches.youtube.utils.fix.client.fingerprints.UserAgentHeaderBuilderFingerprint
2529
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
2630
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
31+
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
2732
import app.revanced.patches.youtube.utils.settings.SettingsPatch
2833
import app.revanced.patches.youtube.utils.storyboard.StoryboardHookPatch
2934
import app.revanced.patches.youtube.video.information.VideoInformationPatch
@@ -50,6 +55,10 @@ object SpoofClientPatch : BaseBytecodePatch(
5055
name = "Spoof client",
5156
description = "Adds options to spoof the client to allow video playback.",
5257
dependencies = setOf(
58+
// Required to fix background playback issue of live stream on iOS client.
59+
BackgroundPlaybackPatch::class,
60+
PlayerTypeHookPatch::class,
61+
5362
PlayerResponseMethodHookPatch::class,
5463
SettingsPatch::class,
5564
VideoInformationPatch::class,
@@ -67,6 +76,9 @@ object SpoofClientPatch : BaseBytecodePatch(
6776
CreatePlayerRequestBodyWithVersionReleaseFingerprint,
6877
UserAgentHeaderBuilderFingerprint,
6978

79+
// Background playback in live stream.
80+
BackgroundPlaybackPlayerResponseFingerprint,
81+
7082
// Player gesture config.
7183
PlayerGestureConfigSyntheticFingerprint,
7284

@@ -379,6 +391,30 @@ object SpoofClientPatch : BaseBytecodePatch(
379391

380392
// endregion
381393

394+
// region fix background playback in live stream, if spoofing to iOS
395+
396+
/**
397+
* If the return value of this method is true, background playback is always enabled.
398+
*
399+
* If [BackgroundPlaybackPatch] is excluded, there may be unintended behavior.
400+
* Therefore, [BackgroundPlaybackPatch] must be included.
401+
*
402+
* Also, [PlayerTypeHookPatch] is required to disable background playback in Shorts.
403+
*/
404+
BackgroundPlaybackPlayerResponseFingerprint.resultOrThrow().mutableMethod.apply {
405+
addInstructionsWithLabels(
406+
0, """
407+
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceEnableBackgroundPlayback()Z
408+
move-result v0
409+
if-eqz v0, :disabled
410+
const/4 v0, 0x1
411+
return v0
412+
""", ExternalLabel("disabled", getInstruction(0))
413+
)
414+
}
415+
416+
// endregion
417+
382418
// region append spoof info.
383419

384420
NerdsStatsVideoFormatBuilderFingerprint.resultOrThrow().mutableMethod.apply {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package app.revanced.patches.youtube.utils.fix.client.fingerprints
2+
3+
import app.revanced.patcher.extensions.or
4+
import app.revanced.patcher.fingerprint.MethodFingerprint
5+
import com.android.tools.smali.dexlib2.AccessFlags
6+
import com.android.tools.smali.dexlib2.Opcode
7+
8+
/**
9+
* On iOS clients, this method always returns false in live streams.
10+
*
11+
* This fingerprint seems to break easily because there are many [Opcode] patterns, but it is not.
12+
* This fingerprint has been tested on all versions from YouTube 17.34.36 to YouTube 19.29.42.
13+
*/
14+
internal object BackgroundPlaybackPlayerResponseFingerprint : MethodFingerprint(
15+
returnType = "Z",
16+
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
17+
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
18+
opcodes = listOf(
19+
Opcode.CONST_4,
20+
Opcode.IF_EQZ,
21+
Opcode.INVOKE_INTERFACE,
22+
Opcode.MOVE_RESULT_OBJECT,
23+
Opcode.IF_EQZ,
24+
Opcode.INVOKE_INTERFACE,
25+
Opcode.MOVE_RESULT_OBJECT,
26+
Opcode.INVOKE_STATIC,
27+
Opcode.MOVE_RESULT,
28+
Opcode.IF_EQZ,
29+
Opcode.INVOKE_INTERFACE,
30+
Opcode.MOVE_RESULT,
31+
Opcode.CONST_4,
32+
Opcode.IF_EQZ,
33+
Opcode.INVOKE_INTERFACE,
34+
Opcode.MOVE_RESULT_OBJECT,
35+
Opcode.INVOKE_VIRTUAL,
36+
Opcode.MOVE_RESULT,
37+
Opcode.IF_NEZ,
38+
Opcode.GOTO,
39+
Opcode.RETURN,
40+
null, // Opcode.CONST_4 or Opcode.MOVE
41+
Opcode.RETURN,
42+
),
43+
)

0 commit comments

Comments
 (0)