Skip to content

Commit

Permalink
feat(YouTube Music - Player components): Add `Player background prima…
Browse files Browse the repository at this point in the history
…ry color` and `Player background secondary color` settings
  • Loading branch information
inotia00 authored and anddea committed Feb 11, 2025
1 parent 34d5631 commit 37131e0
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.revanced.extension.music.patches.player;

import static app.revanced.extension.shared.utils.StringRef.str;
import static app.revanced.extension.shared.utils.Utils.hideViewByRemovingFromParentUnderCondition;
import static app.revanced.extension.shared.utils.Utils.hideViewUnderCondition;
import static app.revanced.extension.shared.utils.Utils.isSDKAbove;
Expand All @@ -11,11 +12,14 @@
import org.apache.commons.lang3.ArrayUtils;

import java.lang.ref.WeakReference;
import java.util.Arrays;

import app.revanced.extension.music.settings.Settings;
import app.revanced.extension.music.shared.VideoType;
import app.revanced.extension.music.utils.VideoUtils;
import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.Utils;

@SuppressWarnings({"unused", "SpellCheckingInspection"})
public class PlayerPatch {
Expand All @@ -29,6 +33,10 @@ public class PlayerPatch {
Settings.DISABLE_PLAYER_GESTURE.get();
private static final boolean ENABLE_SWIPE_TO_DISMISS_MINIPLAYER =
Settings.ENABLE_SWIPE_TO_DISMISS_MINIPLAYER.get();
private static final boolean ENABLE_ZEN_MODE =
Settings.ENABLE_ZEN_MODE.get();
private static final boolean ENABLE_ZEN_MODE_PODCAST =
Settings.ENABLE_ZEN_MODE_PODCAST.get();
private static final boolean HIDE_DOUBLE_TAP_OVERLAY_FILTER =
Settings.HIDE_DOUBLE_TAP_OVERLAY_FILTER.get();
private static final boolean HIDE_FULLSCREEN_SHARE_BUTTON =
Expand All @@ -37,13 +45,45 @@ public class PlayerPatch {
Settings.HIDE_SONG_VIDEO_TOGGLE.get();
private static final boolean RESTORE_OLD_COMMENTS_POPUP_PANELS =
Settings.RESTORE_OLD_COMMENTS_POPUP_PANELS.get();
private static final boolean SETTINGS_INITIALIZED =
Settings.SETTINGS_INITIALIZED.get();

private static final int MUSIC_VIDEO_GREY_BACKGROUND_COLOR = 0xFF404040;
private static final int MUSIC_VIDEO_ORIGINAL_BACKGROUND_COLOR = 0xFF030303;
private static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY =
Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY;
private static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY =
Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY;

private static final int ZEN_MODE_BACKGROUND_COLOR = 0xFF404040;
private static final int MUSIC_VIDEO_BACKGROUND_COLOR = 0xFF030303;

private static final int[] MUSIC_VIDEO_GRADIENT_COLORS = {MUSIC_VIDEO_BACKGROUND_COLOR, MUSIC_VIDEO_BACKGROUND_COLOR};
private static final int[] ZEN_MODE_GRADIENT_COLORS = {ZEN_MODE_BACKGROUND_COLOR, ZEN_MODE_BACKGROUND_COLOR};
private static final int[] customColorGradient = new int[2];
private static boolean colorInitalized = false;

private static WeakReference<View> previousButtonViewRef = new WeakReference<>(null);
private static WeakReference<View> nextButtonViewRef = new WeakReference<>(null);

static {
if (CHANGE_PLAYER_BACKGROUND_COLOR)
loadPlayerbackgroundColor();
}

private static void loadPlayerbackgroundColor() {
try {
customColorGradient[0] = Color.parseColor(CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.get());
customColorGradient[1] = Color.parseColor(CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.get());
colorInitalized = true;
} catch (Exception ex) {
Utils.showToastShort(str("revanced_custom_player_background_invalid_toast"));
Utils.showToastShort(str("revanced_extended_reset_to_default_toast"));
CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.resetToDefault();
CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.resetToDefault();

loadPlayerbackgroundColor();
}
}

public static boolean addMiniPlayerNextButton(boolean original) {
return !ADD_MINIPLAYER_NEXT_BUTTON && original;
}
Expand All @@ -52,10 +92,20 @@ public static boolean changeMiniPlayerColor() {
return Settings.CHANGE_MINIPLAYER_COLOR.get();
}

public static int changePlayerBackgroundColor(int originalColor) {
return CHANGE_PLAYER_BACKGROUND_COLOR && originalColor != MUSIC_VIDEO_GREY_BACKGROUND_COLOR
? Color.BLACK
: originalColor;
public static int[] changePlayerBackgroundColor(int[] colors) {
if (Arrays.equals(MUSIC_VIDEO_GRADIENT_COLORS, colors)) {
final VideoType videoType = VideoType.getCurrent();
final boolean isZenMode = ENABLE_ZEN_MODE &&
(videoType.isMusicVideo() || (videoType.isPodCast() && ENABLE_ZEN_MODE_PODCAST));
if (isZenMode) {
return ZEN_MODE_GRADIENT_COLORS;
}
}
if (CHANGE_PLAYER_BACKGROUND_COLOR && colorInitalized) {
return customColorGradient;
}

return colors;
}

public static boolean disableMiniPlayerGesture() {
Expand Down Expand Up @@ -137,9 +187,10 @@ public static Object enableSwipeToDismissMiniPlayer(Object object) {
}

public static int enableZenMode(int originalColor) {
if (Settings.ENABLE_ZEN_MODE.get() && originalColor == MUSIC_VIDEO_ORIGINAL_BACKGROUND_COLOR) {
if (Settings.ENABLE_ZEN_MODE_PODCAST.get() || !VideoType.getCurrent().isPodCast()) {
return MUSIC_VIDEO_GREY_BACKGROUND_COLOR;
if (ENABLE_ZEN_MODE && originalColor == MUSIC_VIDEO_BACKGROUND_COLOR) {
final VideoType videoType = VideoType.getCurrent();
if (videoType.isMusicVideo() || (videoType.isPodCast() && ENABLE_ZEN_MODE_PODCAST)) {
return ZEN_MODE_BACKGROUND_COLOR;
}
}
return originalColor;
Expand All @@ -162,9 +213,9 @@ public static int hideFullscreenShareButton(int original) {
}

public static void setShuffleState(Enum<?> shuffleState) {
if (!Settings.REMEMBER_SHUFFLE_SATE.get())
return;
Settings.ALWAYS_SHUFFLE.save(shuffleState.ordinal() == 1);
if (Settings.REMEMBER_SHUFFLE_SATE.get()) {
Settings.ALWAYS_SHUFFLE.save(shuffleState.ordinal() == 1);
}
}

public static void shuffleTracks() {
Expand Down Expand Up @@ -199,14 +250,13 @@ public static boolean restoreOldCommentsPopUpPanels() {
}

public static boolean restoreOldCommentsPopUpPanels(boolean original) {
if (!Settings.SETTINGS_INITIALIZED.get()) {
return original;
}
return !RESTORE_OLD_COMMENTS_POPUP_PANELS && original;
return SETTINGS_INITIALIZED
? !RESTORE_OLD_COMMENTS_POPUP_PANELS && original
: original;
}

public static boolean restoreOldPlayerBackground(boolean original) {
if (!Settings.SETTINGS_INITIALIZED.get()) {
if (!SETTINGS_INITIALIZED) {
return original;
}
if (!isSDKAbove(23)) {
Expand All @@ -220,7 +270,7 @@ public static boolean restoreOldPlayerBackground(boolean original) {
}

public static boolean restoreOldPlayerLayout(boolean original) {
if (!Settings.SETTINGS_INITIALIZED.get()) {
if (!SETTINGS_INITIALIZED) {
return original;
}
return !Settings.RESTORE_OLD_PLAYER_LAYOUT.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,14 @@ public class Settings extends BaseSettings {
public static final BooleanSetting ADD_MINIPLAYER_PREVIOUS_BUTTON = new BooleanSetting("revanced_add_miniplayer_previous_button", TRUE, true);
public static final BooleanSetting CHANGE_MINIPLAYER_COLOR = new BooleanSetting("revanced_change_miniplayer_color", TRUE);
public static final BooleanSetting CHANGE_PLAYER_BACKGROUND_COLOR = new BooleanSetting("revanced_change_player_background_color", FALSE, true);
public static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY = new StringSetting("revanced_custom_player_background_color_primary", "#000000", true);
public static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY = new StringSetting("revanced_custom_player_background_color_secondary", "#000000", true);
public static final BooleanSetting DISABLE_MINIPLAYER_GESTURE = new BooleanSetting("revanced_disable_miniplayer_gesture", FALSE, true);
public static final BooleanSetting DISABLE_PLAYER_GESTURE = new BooleanSetting("revanced_disable_player_gesture", FALSE, true);
public static final BooleanSetting ENABLE_FORCED_MINIPLAYER = new BooleanSetting("revanced_enable_forced_miniplayer", TRUE);
public static final BooleanSetting ENABLE_SWIPE_TO_DISMISS_MINIPLAYER = new BooleanSetting("revanced_enable_swipe_to_dismiss_miniplayer", TRUE, true);
public static final BooleanSetting ENABLE_ZEN_MODE = new BooleanSetting("revanced_enable_zen_mode", FALSE);
public static final BooleanSetting ENABLE_ZEN_MODE_PODCAST = new BooleanSetting("revanced_enable_zen_mode_podcast", FALSE);
public static final BooleanSetting ENABLE_ZEN_MODE = new BooleanSetting("revanced_enable_zen_mode", FALSE, true);
public static final BooleanSetting ENABLE_ZEN_MODE_PODCAST = new BooleanSetting("revanced_enable_zen_mode_podcast", FALSE, true);
public static final BooleanSetting HIDE_COMMENT_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_comment_channel_guidelines", TRUE);
public static final BooleanSetting HIDE_DOUBLE_TAP_OVERLAY_FILTER = new BooleanSetting("revanced_hide_double_tap_overlay_filter", FALSE, true);
public static final BooleanSetting HIDE_COMMENT_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comment_timestamp_and_emoji_buttons", FALSE);
Expand Down Expand Up @@ -261,6 +263,8 @@ public class Settings extends BaseSettings {
CHANGE_START_PAGE.key,
CUSTOM_FILTER_STRINGS.key,
CUSTOM_PLAYBACK_SPEEDS.key,
CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.key,
CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.key,
DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE.key,
ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE.key,
EXTERNAL_DOWNLOADER_PACKAGE_NAME.key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static app.revanced.extension.music.settings.Settings.CHANGE_START_PAGE;
import static app.revanced.extension.music.settings.Settings.CUSTOM_FILTER_STRINGS;
import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYBACK_SPEEDS;
import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY;
import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY;
import static app.revanced.extension.music.settings.Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE;
import static app.revanced.extension.music.settings.Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE;
import static app.revanced.extension.music.settings.Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME;
Expand Down Expand Up @@ -139,6 +141,8 @@ public void onCreate(Bundle savedInstanceState) {
if (settings.equals(BYPASS_IMAGE_REGION_RESTRICTIONS_DOMAIN)
|| settings.equals(CUSTOM_FILTER_STRINGS)
|| settings.equals(CUSTOM_PLAYBACK_SPEEDS)
|| settings.equals(CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY)
|| settings.equals(CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY)
|| settings.equals(ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE)
|| settings.equals(HIDE_ACCOUNT_MENU_FILTER_STRINGS)
|| settings.equals(RETURN_YOUTUBE_USERNAME_YOUTUBE_DATA_API_V3_DEVELOPER_KEY)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import app.revanced.patches.music.utils.resourceid.topEnd
import app.revanced.patches.music.utils.resourceid.topStart
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
import app.revanced.patches.music.utils.settings.addPreferenceWithIntent
import app.revanced.patches.music.utils.settings.addSwitchPreference
import app.revanced.patches.music.utils.settings.settingsPatch
import app.revanced.patches.music.utils.videotype.videoTypeHookPatch
Expand All @@ -48,6 +49,7 @@ import app.revanced.util.addStaticFieldToExtension
import app.revanced.util.adoptChild
import app.revanced.util.cloneMutable
import app.revanced.util.doRecursively
import app.revanced.util.findInstructionIndicesReversed
import app.revanced.util.findMethodOrThrow
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
import app.revanced.util.fingerprint.injectLiteralInstructionViewCall
Expand Down Expand Up @@ -391,7 +393,7 @@ val playerComponentsPatch = bytecodePatch(

// endregion

// region patch for color match player and black player background
// region patch for color match player, change player background and enable zen mode (6.35+)

val (
colorMathPlayerMethodParameter,
Expand All @@ -406,17 +408,19 @@ val playerComponentsPatch = bytecodePatch(

// black player background
val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT)
val targetMethod = getWalkerMethod(invokeDirectIndex)
val insertIndex = targetMethod.indexOfFirstInstructionOrThrow(Opcode.IF_NE)

targetMethod.addInstructions(
insertIndex, """
invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor(I)I
move-result p1
invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor(I)I
move-result p2
"""
)
getWalkerMethod(invokeDirectIndex).apply {
val index = indexOfFirstInstructionOrThrow(Opcode.FILLED_NEW_ARRAY)
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA

addInstructions(
index + 2, """
invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor([I)[I
move-result-object v$register
"""
)
}

Triple(
parameters,
getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference,
Expand All @@ -438,7 +442,6 @@ val playerComponentsPatch = bytecodePatch(
}.forEach { method ->
method.apply {
val freeRegister = implementation!!.registerCount - parameters.size - 3

val invokeDirectIndex =
indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_DIRECT)
val invokeDirectReference =
Expand Down Expand Up @@ -472,6 +475,16 @@ val playerComponentsPatch = bytecodePatch(
"revanced_change_player_background_color",
"false"
)
addPreferenceWithIntent(
CategoryType.PLAYER,
"revanced_custom_player_background_color_primary",
"revanced_change_player_background_color"
)
addPreferenceWithIntent(
CategoryType.PLAYER,
"revanced_custom_player_background_color_secondary",
"revanced_change_player_background_color"
)

// endregion

Expand Down Expand Up @@ -708,7 +721,7 @@ val playerComponentsPatch = bytecodePatch(

// endregion

// region patch for enable zen mode
// region patch for enable zen mode (~ 6.34)

// this method is used for old player background (deprecated since YT Music v6.34.51)
zenModeFingerprint.matchOrNull(miniPlayerConstructorFingerprint)?.let {
Expand All @@ -728,20 +741,6 @@ val playerComponentsPatch = bytecodePatch(
}
} // no exception

switchToggleColorFingerprint.methodOrThrow(miniPlayerConstructorFingerprint).apply {
val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT)
val walkerMethod = getWalkerMethod(invokeDirectIndex)

walkerMethod.addInstructions(
0, """
invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I
move-result p1
invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I
move-result p2
"""
)
}

addSwitchPreference(
CategoryType.PLAYER,
"revanced_enable_zen_mode",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,27 +95,6 @@ fun indexOfSpannableStringInstruction(method: Method) = method.indexOfFirstInstr
getReference<MethodReference>()?.toString() == SPANNABLE_STRING_REFERENCE
}

internal val startVideoInformerFingerprint = legacyFingerprint(
name = "startVideoInformerFingerprint",
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID
),
strings = listOf("pc"),
customFingerprint = { method, _ ->
method.implementation
?.instructions
?.withIndex()
?.filter { (_, instruction) ->
instruction.opcode == Opcode.CONST_STRING
}
?.map { (index, _) -> index }
?.size == 1
}
)

internal val videoLengthFingerprint = legacyFingerprint(
name = "videoLengthFingerprint",
returnType = "V",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.extension.Constants.PATCHES_PATH
import app.revanced.patches.shared.startVideoInformerFingerprint
import app.revanced.util.fingerprint.methodOrThrow

private const val EXTENSION_CLASS_DESCRIPTOR =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@ package app.revanced.patches.shared.captions
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

internal val startVideoInformerFingerprint = legacyFingerprint(
name = "startVideoInformerFingerprint",
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID
),
strings = listOf("pc"),
customFingerprint = { method, _ ->
method.implementation
?.instructions
?.withIndex()
?.filter { (_, instruction) ->
instruction.opcode == Opcode.CONST_STRING
}
?.map { (index, _) -> index }
?.size == 1
}
)

internal val storyboardRendererDecoderRecommendedLevelFingerprint = legacyFingerprint(
name = "storyboardRendererDecoderRecommendedLevelFingerprint",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,6 @@ fun indexOfSpannedCharSequenceInstruction(method: Method) =
reference.returnType == "Ljava/lang/CharSequence;"
}

internal val engagementPanelBuilderFingerprint = legacyFingerprint(
name = "engagementPanelBuilderFingerprint",
returnType = "L",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
parameters = listOf("L", "L", "Z", "Z"),
strings = listOf(
"EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.",
"[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called."
)
)

internal val layoutConstructorFingerprint = legacyFingerprint(
name = "layoutConstructorFingerprint",
returnType = "V",
Expand Down

0 comments on commit 37131e0

Please sign in to comment.