feat(YouTube - Hide player overlay buttons): Add in app setting for "Hide player control buttons background" (#5147)

This commit is contained in:
Nuckyz
2025-06-08 15:04:58 -03:00
committed by GitHub
parent 1d46ad0b6a
commit dd8afa2b07
6 changed files with 78 additions and 30 deletions

View File

@ -1,6 +1,7 @@
package app.revanced.extension.youtube.patches;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import app.revanced.extension.shared.Logger;
@ -58,6 +59,22 @@ public final class HidePlayerOverlayButtonsPatch {
});
}
/**
* Injection point.
*/
public static void hidePlayerControlButtonsBackground(View rootView) {
try {
if (!Settings.HIDE_PLAYER_CONTROL_BUTTONS_BACKGROUND.get()) {
return;
}
// Each button is an ImageView with a background set to another drawable.
removeImageViewsBackgroundRecursive(rootView);
} catch (Exception ex) {
Logger.printException(() -> "removePlayerControlButtonsBackground failure", ex);
}
}
private static void hideView(View parentView, int resourceId) {
View nextPreviousButton = parentView.findViewById(resourceId);
@ -69,4 +86,16 @@ public final class HidePlayerOverlayButtonsPatch {
Logger.printDebug(() -> "Hiding previous/next button");
Utils.hideViewByRemovingFromParentUnderCondition(true, nextPreviousButton);
}
private static void removeImageViewsBackgroundRecursive(View currentView) {
if (currentView instanceof ImageView imageView) {
imageView.setBackground(null);
}
if (currentView instanceof ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
removeImageViewsBackgroundRecursive(viewGroup.getChildAt(i));
}
}
}
}

View File

@ -135,6 +135,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
public static final BooleanSetting HIDE_PLAYER_CONTROL_BUTTONS_BACKGROUND = new BooleanSetting("revanced_hide_player_control_buttons_background", FALSE, true);
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE);
public static final BooleanSetting HIDE_CHANNEL_MEMBER_SHELF = new BooleanSetting("revanced_hide_channel_member_shelf", TRUE);
public static final BooleanSetting HIDE_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_community_guidelines", TRUE);

View File

@ -2,6 +2,7 @@ package app.revanced.patches.youtube.layout.buttons.overlay
import app.revanced.patcher.fingerprint
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
internal val playerControlsPreviousNextOverlayTouchFingerprint = fingerprint {
@ -20,3 +21,10 @@ internal val mediaRouteButtonFingerprint = fingerprint {
methodDef.definingClass.endsWith("/MediaRouteButton;") && methodDef.name == "setVisibility"
}
}
internal val inflateControlsGroupLayoutStubFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters()
returns("V")
literal { controlsButtonGroupLayoutStub }
}

View File

@ -28,6 +28,8 @@ internal var playerControlPreviousButtonTouchArea = -1L
private set
internal var playerControlNextButtonTouchArea = -1L
private set
internal var controlsButtonGroupLayoutStub = -1L
private set
private val hidePlayerOverlayButtonsResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
@ -35,6 +37,7 @@ private val hidePlayerOverlayButtonsResourcePatch = resourcePatch {
execute {
playerControlPreviousButtonTouchArea = resourceMappings["id", "player_control_previous_button_touch_area"]
playerControlNextButtonTouchArea = resourceMappings["id", "player_control_next_button_touch_area"]
controlsButtonGroupLayoutStub = resourceMappings["id", "youtube_controls_button_group_layout_stub"]
}
}
@ -43,7 +46,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val hidePlayerOverlayButtonsPatch = bytecodePatch(
name = "Hide player overlay buttons",
description = "Adds options to hide the player Cast, Autoplay, Captions, and Previous & Next buttons.",
description = "Adds options to hide the player Cast, Autoplay, Captions, Previous & Next buttons, and the player " +
"control buttons background.",
) {
dependsOn(
sharedExtensionPatch,
@ -72,6 +76,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
SwitchPreference("revanced_hide_cast_button"),
SwitchPreference("revanced_hide_captions_button"),
SwitchPreference("revanced_hide_autoplay_button"),
SwitchPreference("revanced_hide_player_control_buttons_background"),
)
// region Hide player next/previous button.
@ -147,5 +152,32 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
}
// endregion
// region Hide player control buttons background.
inflateControlsGroupLayoutStubFingerprint.method.apply {
val controlsButtonGroupLayoutStubResIdConstIndex =
indexOfFirstLiteralInstructionOrThrow(controlsButtonGroupLayoutStub)
val inflateControlsGroupLayoutStubIndex =
indexOfFirstInstruction(controlsButtonGroupLayoutStubResIdConstIndex) {
getReference<MethodReference>()?.name == "inflate"
}
val freeRegister = findFreeRegister(inflateControlsGroupLayoutStubIndex)
val hidePlayerControlButtonsBackgroundDescriptor =
"$EXTENSION_CLASS_DESCRIPTOR->hidePlayerControlButtonsBackground(Landroid/view/View;)V"
addInstructions(
inflateControlsGroupLayoutStubIndex + 1,
"""
# Move the inflated layout to a temporary register.
# The result of the inflate method is by default not moved to a register after the method is called.
move-result-object v$freeRegister
invoke-static { v$freeRegister }, $hidePlayerControlButtonsBackgroundDescriptor
"""
)
}
// endregion
}
}

View File

@ -1,37 +1,12 @@
package app.revanced.patches.youtube.layout.player.background
import app.revanced.patcher.patch.resourcePatch
import app.revanced.util.doRecursively
import org.w3c.dom.Element
import app.revanced.patches.youtube.layout.buttons.overlay.hidePlayerOverlayButtonsPatch
@Suppress("unused")
@Deprecated("Functionality added to hidePlayerOverlayButtonsPatch", ReplaceWith("hidePlayerOverlayButtonsPatch"))
val playerControlsBackgroundPatch = resourcePatch(
name = "Remove player controls background",
description = "Removes the dark background surrounding the video player controls.",
use = false,
description = "Removes the dark background surrounding the video player control buttons.",
) {
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.47.53",
"20.07.39",
"20.12.46",
)
)
execute {
document("res/drawable/player_button_circle_background.xml").use { document ->
document.doRecursively node@{ node ->
if (node !is Element) return@node
node.getAttributeNode("android:color")?.let { attribute ->
attribute.textContent = "@android:color/transparent"
}
}
}
}
dependsOn(hidePlayerOverlayButtonsPatch)
}

View File

@ -743,6 +743,9 @@ To show the Audio track menu, change \'Spoof video streams\' to iOS TV"</string>
<string name="revanced_hide_autoplay_button_title">Hide Autoplay button</string>
<string name="revanced_hide_autoplay_button_summary_on">Autoplay button is hidden</string>
<string name="revanced_hide_autoplay_button_summary_off">Autoplay button is shown</string>
<string name="revanced_hide_player_control_buttons_background_title">Hide player control buttons background</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Player control buttons background is hidden</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Player control buttons background is shown</string>
</patch>
<patch id="layout.hide.endscreencards.hideEndscreenCardsResourcePatch">
<string name="revanced_hide_endscreen_cards_title">Hide end screen cards</string>