feat(YouTube Music): Add Disable music video in album patch https://github.com/inotia00/ReVanced_Extended/issues/2568

This commit is contained in:
inotia00
2025-01-03 20:04:50 +09:00
parent 1da2664513
commit 8ab67bc6ef
12 changed files with 549 additions and 0 deletions

View File

@ -0,0 +1,85 @@
package app.revanced.patches.music.misc.album
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.dismiss.dismissQueueHookPatch
import app.revanced.patches.music.utils.extension.Constants.MISC_PATH
import app.revanced.patches.music.utils.patch.PatchList.DISABLE_MUSIC_VIDEO_IN_ALBUM
import app.revanced.patches.music.utils.playservice.is_7_03_or_greater
import app.revanced.patches.music.utils.playservice.versionCheckPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
import app.revanced.patches.music.utils.settings.addSwitchPreference
import app.revanced.patches.music.utils.settings.settingsPatch
import app.revanced.patches.music.video.information.videoIdHook
import app.revanced.patches.music.video.information.videoInformationPatch
import app.revanced.util.fingerprint.methodOrThrow
private const val EXTENSION_CLASS_DESCRIPTOR =
"$MISC_PATH/AlbumMusicVideoPatch;"
@Suppress("unused")
val albumMusicVideoPatch = bytecodePatch(
DISABLE_MUSIC_VIDEO_IN_ALBUM.title,
DISABLE_MUSIC_VIDEO_IN_ALBUM.summary,
false,
) {
compatibleWith(COMPATIBLE_PACKAGE)
dependsOn(
settingsPatch,
dismissQueueHookPatch,
videoInformationPatch,
versionCheckPatch,
)
execute {
// region hook player response
val fingerprint = if (is_7_03_or_greater) {
playerParameterBuilderFingerprint
} else {
playerParameterBuilderLegacyFingerprint
}
fingerprint.methodOrThrow().addInstruction(
0,
"invoke-static {p1, p4, p5}, $EXTENSION_CLASS_DESCRIPTOR->newPlayerResponse(Ljava/lang/String;Ljava/lang/String;I)V"
)
// endregion
// region hook video id
videoIdHook("$EXTENSION_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
// endregion
// region patch for hide snack bar
snackBarParentFingerprint.methodOrThrow().addInstructionsWithLabels(
0, """
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->hideSnackBar()Z
move-result v0
if-eqz v0, :hide
return-void
:hide
nop
"""
)
// endregion
addSwitchPreference(
CategoryType.MISC,
"revanced_disable_music_video_in_album",
"false"
)
updatePatchStatus(DISABLE_MUSIC_VIDEO_IN_ALBUM)
}
}

View File

@ -0,0 +1,69 @@
package app.revanced.patches.music.misc.album
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.or
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* For targets 7.03 and later.
*/
internal val playerParameterBuilderFingerprint = legacyFingerprint(
name = "playerParameterBuilderFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "L",
parameters = listOf(
"Ljava/lang/String;", // VideoId.
"[B",
"Ljava/lang/String;", // Player parameters proto buffer.
"Ljava/lang/String;", // PlaylistId.
"I", // PlaylistIndex.
"I",
"L",
"Ljava/util/Set;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"L",
"Z",
"Z",
"Z", // Appears to indicate if the video id is being opened or is currently playing.
),
strings = listOf("psps")
)
/**
* For targets 7.02 and earlier.
*/
internal val playerParameterBuilderLegacyFingerprint = legacyFingerprint(
name = "playerParameterBuilderLegacyFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "L",
parameters = listOf(
"Ljava/lang/String;", // VideoId.
"[B",
"Ljava/lang/String;", // Player parameters proto buffer.
"Ljava/lang/String;", // PlaylistId.
"I", // PlaylistIndex.
"I",
"Ljava/util/Set;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"L",
"Z",
"Z", // Appears to indicate if the video id is being opened or is currently playing.
),
opcodes = listOf(
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE
)
)
internal val snackBarParentFingerprint = legacyFingerprint(
name = "snackBarParentFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L"),
strings = listOf("No suitable parent found from the given view. Please provide a valid view.")
)

View File

@ -0,0 +1,42 @@
package app.revanced.patches.music.utils.dismiss
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.music.utils.extension.Constants.EXTENSION_PATH
import app.revanced.util.addStaticFieldToExtension
import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.getWalkerMethod
private const val EXTENSION_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$EXTENSION_PATH/utils/VideoUtils;"
@Suppress("unused")
val dismissQueueHookPatch = bytecodePatch(
description = "dismissQueueHookPatch"
) {
execute {
dismissQueueFingerprint.methodOrThrow().apply {
val dismissQueueIndex = indexOfDismissQueueInstruction(this)
getWalkerMethod(dismissQueueIndex).apply {
val smaliInstructions =
"""
if-eqz v0, :ignore
invoke-virtual {v0}, $definingClass->$name()V
:ignore
return-void
"""
addStaticFieldToExtension(
EXTENSION_VIDEO_UTILS_CLASS_DESCRIPTOR,
"dismissQueue",
"dismissQueueClass",
definingClass,
smaliInstructions
)
}
}
}
}

View File

@ -0,0 +1,24 @@
package app.revanced.patches.music.utils.dismiss
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val dismissQueueFingerprint = legacyFingerprint(
name = "dismissQueueFingerprint",
returnType = "V",
parameters = listOf("L"),
customFingerprint = { method, _ ->
method.name == "handleDismissWatchEvent" &&
indexOfDismissQueueInstruction(method) >= 0
}
)
internal fun indexOfDismissQueueInstruction(method: Method) =
method.indexOfFirstInstruction {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.definingClass?.endsWith("/MppWatchWhileLayout;") == true
}

View File

@ -57,6 +57,10 @@ internal enum class PatchList(
"Disable dislike redirection",
"Adds an option to disable redirection to the next track when clicking the Dislike button."
),
DISABLE_MUSIC_VIDEO_IN_ALBUM(
"Disable music video in album",
"Adds option to redirect music videos from albums."
),
ENABLE_OPUS_CODEC(
"Enable OPUS codec",
"Adds an options to enable the OPUS audio codec if the player response includes."

View File

@ -11,6 +11,8 @@ var is_6_36_or_greater = false
private set
var is_6_42_or_greater = false
private set
var is_7_03_or_greater = false
private set
var is_7_06_or_greater = false
private set
var is_7_13_or_greater = false
@ -43,6 +45,7 @@ val versionCheckPatch = resourcePatch(
is_6_27_or_greater = 234412000 <= playStoreServicesVersion
is_6_36_or_greater = 240399000 <= playStoreServicesVersion
is_6_42_or_greater = 240999000 <= playStoreServicesVersion
is_7_03_or_greater = 242199000 <= playStoreServicesVersion
is_7_06_or_greater = 242499000 <= playStoreServicesVersion
is_7_13_or_greater = 243199000 <= playStoreServicesVersion
is_7_17_or_greater = 243530000 <= playStoreServicesVersion