From 2e4f9053cca3397d9bb7d4486bb7264ca31de163 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 26 Apr 2024 07:05:55 +0900 Subject: [PATCH] feat(YouTube/Video playback): add `Replace software AV1 codec` and `Reject software AV1 codec response` settings --- .../video/playback/VideoPlaybackPatch.kt | 52 +++++++++++++++++++ .../fingerprints/AV1CodecFingerprint.kt | 18 +++++++ .../ByteBufferArrayFingerprint.kt | 21 ++++++++ .../ByteBufferArrayParentFingerprint.kt | 11 ++++ .../youtube/settings/host/values/strings.xml | 10 +++- .../youtube/settings/xml/revanced_prefs.xml | 6 ++- 6 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/AV1CodecFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayParentFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt index 0d07e4c13..d7c3e71ff 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt @@ -21,6 +21,9 @@ import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPa import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch.speedSelectionInsertMethod +import app.revanced.patches.youtube.video.playback.fingerprints.AV1CodecFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.ByteBufferArrayFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.ByteBufferArrayParentFingerprint import app.revanced.patches.youtube.video.playback.fingerprints.DeviceDimensionsModelToStringFingerprint import app.revanced.patches.youtube.video.playback.fingerprints.HDRCapabilityFingerprint import app.revanced.patches.youtube.video.playback.fingerprints.PlaybackSpeedChangedFromRecyclerViewFingerprint @@ -29,6 +32,7 @@ import app.revanced.patches.youtube.video.playback.fingerprints.QualityChangedFr import app.revanced.patches.youtube.video.playback.fingerprints.QualitySetterFingerprint import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.util.getReference +import app.revanced.util.getStringInstructionIndex import app.revanced.util.getTargetIndex import app.revanced.util.indexOfFirstInstruction import app.revanced.util.patch.BaseBytecodePatch @@ -58,6 +62,8 @@ object VideoPlaybackPatch : BaseBytecodePatch( ), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( + AV1CodecFingerprint, + ByteBufferArrayParentFingerprint, DeviceDimensionsModelToStringFingerprint, HDRCapabilityFingerprint, PlaybackSpeedChangedFromRecyclerViewFingerprint, @@ -72,6 +78,8 @@ object VideoPlaybackPatch : BaseBytecodePatch( "$COMPONENTS_PATH/PlaybackSpeedMenuFilter;" private const val VIDEO_QUALITY_MENU_FILTER_CLASS_DESCRIPTOR = "$COMPONENTS_PATH/VideoQualityMenuFilter;" + private const val INTEGRATIONS_AV1_CODEC_CLASS_DESCRIPTOR = + "$VIDEO_PATH/AV1CodecPatch;" private const val INTEGRATIONS_CUSTOM_PLAYBACK_SPEED_CLASS_DESCRIPTOR = "$VIDEO_PATH/CustomPlaybackSpeedPatch;" private const val INTEGRATIONS_HDR_VIDEO_CLASS_DESCRIPTOR = @@ -256,6 +264,50 @@ object VideoPlaybackPatch : BaseBytecodePatch( // endregion + // region patch for disable AV1 codec + + // replace av1 codec + + AV1CodecFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = getStringInstructionIndex("video/av01") + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$insertRegister}, $INTEGRATIONS_AV1_CODEC_CLASS_DESCRIPTOR->replaceCodec(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$insertRegister + """ + ) + } + + SettingsPatch.addPreference( + arrayOf( + "SETTINGS: REPLACE_AV1_CODEC" + ) + ) + } // for compatibility with old versions, no exceptions are raised. + + // reject av1 codec response + + ByteBufferArrayParentFingerprint.resultOrThrow().classDef.let { classDef -> + ByteBufferArrayFingerprint.also { it.resolve(context, classDef) }.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $INTEGRATIONS_AV1_CODEC_CLASS_DESCRIPTOR->rejectResponse(I)I + move-result v$insertRegister + """ + ) + } + } + } + + // endregion + /** * Add settings */ diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/AV1CodecFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/AV1CodecFingerprint.kt new file mode 100644 index 000000000..30442651b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/AV1CodecFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.video.playback.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.util.containsWideLiteralInstructionIndex +import com.android.tools.smali.dexlib2.AccessFlags + +internal object AV1CodecFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + returnType = "L", + strings = listOf("AtomParsers", "video/av01"), + customFingerprint = handler@{ methodDef, _ -> + if (methodDef.returnType == "Ljava/util/List;") + return@handler false + + methodDef.containsWideLiteralInstructionIndex(1987076931) + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayFingerprint.kt new file mode 100644 index 000000000..8a7a46c88 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.youtube.video.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 ByteBufferArrayFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "I", + parameters = emptyList(), + opcodes = listOf( + Opcode.SHL_INT_LIT8, + Opcode.SHL_INT_LIT8, + Opcode.OR_INT_2ADDR, + Opcode.SHL_INT_LIT8, + Opcode.OR_INT_2ADDR, + Opcode.OR_INT_2ADDR, + Opcode.RETURN + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayParentFingerprint.kt new file mode 100644 index 000000000..d9e7803af --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/ByteBufferArrayParentFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.video.playback.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object ByteBufferArrayParentFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, + returnType = "C", + parameters = listOf("Ljava/nio/charset/Charset;", "[C") +) diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 98fcbbe73..ca40787d3 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -985,8 +985,6 @@ Limitation: Official headers in search results will be hidden." Enable shorts default playback speed Default playback speed applies to Shorts. Default playback speed does not apply to Shorts. - Spoof device dimensions - Spoofs the device dimensions in order to unlock higher video qualities that may not be available on your device. Skipped preloaded buffer. Skip preloaded buffer "Skip preloaded buffer at video start to bypass default video quality enforcement delay. @@ -996,6 +994,14 @@ Limitation: Official headers in search results will be hidden." Show a toast when skipped Toast is shown. Toast is not shown. + Spoof device dimensions + Spoofs the device dimensions in order to unlock higher video qualities that may not be available on your device. + Replace software AV1 codec + Replace software AV1 codec with VP9 codec. + Reject software AV1 codec response + "Forcefully rejects the software AV1 codec response. +After about 20 seconds of buffering, switches to different codec." + Fallback process causes about 20 seconds of buffering. Changing default speed to %s. Changing default mobile data quality to %s. Failed to set video quality. diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index f0ed8bdda..65ae7310c 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -467,9 +467,13 @@ - + PREFERENCE_SCREEN: VIDEO --> + +