diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt index 4a9a1724c..1c097fa49 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt @@ -16,7 +16,9 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch import app.revanced.patches.youtube.misc.fix.playback.fingerprints.* +import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -38,16 +40,21 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter SettingsPatch::class, AddResourcesPatch::class, UserAgentClientSpoofPatch::class, + // Required since iOS livestream fix partially enables background playback. + BackgroundPlaybackPatch::class, + PlayerTypeHookPatch::class, ], compatiblePackages = [ CompatiblePackage( "com.google.android.youtube", [ - "18.37.36", - "18.38.44", - "18.43.45", - "18.44.41", - "18.45.43", + // This patch works with these versions, + // but the dependent background playback patch does not. + // "18.37.36", + // "18.38.44", + // "18.43.45", + // "18.44.41", + // "18.45.43", "18.48.39", "18.49.37", "19.01.34", @@ -89,9 +96,9 @@ object SpoofClientPatch : BytecodePatch( // Video qualities missing. BuildRequestFingerprint, - // Watch history. - GetTrackingUriFingerprint, - ), + // Livestream audio only background playback. + PlayerResponseModelBackgroundAudioPlaybackFingerprint, + ) ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/spoof/SpoofClientPatch;" @@ -316,6 +323,23 @@ object SpoofClientPatch : BytecodePatch( // endregion + // region Fix livestream audio only background play if spoofing to iOS. + // This force enables audio background playback. + + PlayerResponseModelBackgroundAudioPlaybackFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, + """ + invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideBackgroundAudioPlayback()Z + move-result v0 + if-eqz v0, :do_not_override + return v0 + :do_not_override + nop + """ + ) + + // endregion + // Fix playback speed menu item if spoofing to iOS. CreatePlaybackSpeedMenuItemFingerprint.resultOrThrow().let { @@ -340,25 +364,6 @@ object SpoofClientPatch : BytecodePatch( // endregion - // Fix watch history if spoofing to iOS. - - GetTrackingUriFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val returnUrlIndex = it.scanResult.patternScanResult!!.endIndex - val urlRegister = getInstruction(returnUrlIndex).registerA - - addInstructions( - returnUrlIndex, - """ - invoke-static { v$urlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideTrackingUrl(Landroid/net/Uri;)Landroid/net/Uri; - move-result-object v$urlRegister - """ - ) - } - } - - // endregion - // region Fix video qualities missing, if spoofing to iOS by overriding the user agent. BuildRequestFingerprint.resultOrThrow().let { result -> diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/GetTrackingUriFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/GetTrackingUriFingerprint.kt deleted file mode 100644 index 328fb026f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/GetTrackingUriFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.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 - -internal object GetTrackingUriFingerprint : MethodFingerprint( - returnType = "Landroid/net/Uri;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.RETURN_OBJECT - ), - customFingerprint = { _, classDef -> - classDef.endsWith("TrackingUrlModel;") - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt new file mode 100644 index 000000000..afe153219 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.youtube.misc.fix.playback.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 + +internal object PlayerResponseModelBackgroundAudioPlaybackFingerprint : 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.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.GOTO, + Opcode.RETURN, + null, // Opcode.CONST_4 or Opcode.MOVE + Opcode.RETURN, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt index e74a3d11e..67a47c71d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt @@ -32,11 +32,12 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CompatiblePackage( "com.google.android.youtube", setOf( - "18.37.36", - "18.38.44", - "18.43.45", - "18.44.41", - "18.45.43", + // Patch supports these versions but ClientSpoof does not. + // "18.37.36", + // "18.38.44", + // "18.43.45", + // "18.44.41", + // "18.45.43", "18.48.39", "18.49.37", "19.01.34", diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index e13b9b65a..b002d5e70 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -1135,7 +1135,7 @@ This is because Crowdin requires temporarily flattening this file and removing t Client is not spoofed\n\nVideo playback may not work Turning off this setting may cause video playback issues. Spoof client to iOS - Client is currently spoofed to iOS\n\nSide effects include:\n• No HDR video\n• Higher video qualities may be missing\n• Live streams cannot play as audio only + Client is currently spoofed to iOS\n\nSide effects include:\n• HDR video may not be available\n• Watch history may not work Client is currently spoofed to Android VR\n\nSide effects include:\n• No HDR video\n• Kids videos do not playback\n• Paused videos can randomly resume\n• Low quality Shorts seekbar thumbnails\n• Download action button is hidden\n• End screen cards are hidden Spoof client thumbnails not available (API timed out) Spoof client thumbnails temporarily not available: %s