mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-13 05:37:40 +02:00
feat(YouTube Music - Disable music video in album): Add redirection option
This commit is contained in:
@ -1,20 +1,58 @@
|
|||||||
package app.revanced.extension.music.patches.misc;
|
package app.revanced.extension.music.patches.misc;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.GuardedBy;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import app.revanced.extension.music.patches.misc.requests.PipedRequester;
|
import app.revanced.extension.music.patches.misc.requests.PipedRequester;
|
||||||
import app.revanced.extension.music.settings.Settings;
|
import app.revanced.extension.music.settings.Settings;
|
||||||
|
import app.revanced.extension.music.shared.VideoInformation;
|
||||||
import app.revanced.extension.music.utils.VideoUtils;
|
import app.revanced.extension.music.utils.VideoUtils;
|
||||||
import app.revanced.extension.shared.utils.Logger;
|
import app.revanced.extension.shared.utils.Logger;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class AlbumMusicVideoPatch {
|
public class AlbumMusicVideoPatch {
|
||||||
private static final String YOUTUBE_MUSIC_ALBUM_PREFIX = "OLAK";
|
|
||||||
|
public enum RedirectType {
|
||||||
|
REDIRECT_DISMISS(true),
|
||||||
|
REDIRECT(false),
|
||||||
|
ON_CLICK_DISMISS(true),
|
||||||
|
ON_CLICK(false),
|
||||||
|
ON_LONG_CLICK_DISMISS(true),
|
||||||
|
ON_LONG_CLICK(false);
|
||||||
|
|
||||||
|
public final boolean dismissQueue;
|
||||||
|
|
||||||
|
RedirectType(boolean dismissQueue) {
|
||||||
|
this.dismissQueue = dismissQueue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final RedirectType REDIRECT_TYPE =
|
||||||
|
Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE.get();
|
||||||
|
|
||||||
private static final boolean DISABLE_MUSIC_VIDEO_IN_ALBUM =
|
private static final boolean DISABLE_MUSIC_VIDEO_IN_ALBUM =
|
||||||
Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM.get();
|
Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM.get();
|
||||||
|
|
||||||
|
private static final boolean DISMISS_QUEUE =
|
||||||
|
DISABLE_MUSIC_VIDEO_IN_ALBUM && REDIRECT_TYPE.dismissQueue;
|
||||||
|
|
||||||
|
private static final boolean REDIRECT =
|
||||||
|
REDIRECT_TYPE == RedirectType.REDIRECT || REDIRECT_TYPE == RedirectType.REDIRECT_DISMISS;
|
||||||
|
|
||||||
|
private static final boolean ON_CLICK =
|
||||||
|
REDIRECT_TYPE == RedirectType.ON_CLICK || REDIRECT_TYPE == RedirectType.ON_CLICK_DISMISS;
|
||||||
|
|
||||||
|
private static final boolean ON_LONG_CLICK =
|
||||||
|
REDIRECT_TYPE == RedirectType.ON_LONG_CLICK || REDIRECT_TYPE == RedirectType.ON_LONG_CLICK_DISMISS;
|
||||||
|
|
||||||
|
private static final String YOUTUBE_MUSIC_ALBUM_PREFIX = "OLAK";
|
||||||
|
|
||||||
private static final AtomicBoolean isVideoLaunched = new AtomicBoolean(false);
|
private static final AtomicBoolean isVideoLaunched = new AtomicBoolean(false);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -23,6 +61,16 @@ public class AlbumMusicVideoPatch {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private static volatile String currentVideoId = "";
|
private static volatile String currentVideoId = "";
|
||||||
|
|
||||||
|
@GuardedBy("itself")
|
||||||
|
private static final Map<String, String> lastVideoIds = new LinkedHashMap<>() {
|
||||||
|
private static final int NUMBER_OF_LAST_VIDEO_IDS_TO_TRACK = 5;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry eldest) {
|
||||||
|
return size() > NUMBER_OF_LAST_VIDEO_IDS_TO_TRACK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
@ -41,7 +89,7 @@ public class AlbumMusicVideoPatch {
|
|||||||
}
|
}
|
||||||
playerResponseVideoId = videoId;
|
playerResponseVideoId = videoId;
|
||||||
|
|
||||||
// Fetch from piped instances.
|
// Fetch Piped instance.
|
||||||
PipedRequester.fetchRequestIfNeeded(videoId, playlistId, playlistIndex);
|
PipedRequester.fetchRequestIfNeeded(videoId, playlistId, playlistIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,13 +104,10 @@ public class AlbumMusicVideoPatch {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentVideoId = videoId;
|
currentVideoId = videoId;
|
||||||
|
checkVideo(videoId);
|
||||||
// If the user is using a not fast enough internet connection, there will be a slight delay.
|
|
||||||
// Otherwise, the video may open repeatedly.
|
|
||||||
VideoUtils.runOnMainThreadDelayed(() -> openOfficialMusicIfNeeded(videoId), 750);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void openOfficialMusicIfNeeded(@NonNull String videoId) {
|
private static void checkVideo(@NonNull String videoId) {
|
||||||
try {
|
try {
|
||||||
PipedRequester request = PipedRequester.getRequestForVideoId(videoId);
|
PipedRequester request = PipedRequester.getRequestForVideoId(videoId);
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
@ -72,13 +117,46 @@ public class AlbumMusicVideoPatch {
|
|||||||
if (songId == null) {
|
if (songId == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
synchronized (lastVideoIds) {
|
||||||
|
if (lastVideoIds.put(videoId, songId) == null) {
|
||||||
|
Logger.printDebug(() -> "Official song found, videoId: " + videoId + ", songId: " + songId);
|
||||||
|
if (REDIRECT) {
|
||||||
|
openMusic(songId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "check failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It is handled by YouTube Music's internal code.
|
/**
|
||||||
// There is a slight delay before the dismiss request is reflected.
|
* Injection point.
|
||||||
VideoUtils.dismissQueue();
|
*/
|
||||||
|
public static boolean openMusic() {
|
||||||
|
if (DISABLE_MUSIC_VIDEO_IN_ALBUM && ON_CLICK) {
|
||||||
|
try {
|
||||||
|
String videoId = VideoInformation.getVideoId();
|
||||||
|
synchronized (lastVideoIds) {
|
||||||
|
String songId = lastVideoIds.get(videoId);
|
||||||
|
if (songId != null) {
|
||||||
|
openMusic(songId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "openMusic failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void openMusic(@NonNull String songId) {
|
||||||
|
try {
|
||||||
|
if (DISMISS_QUEUE) {
|
||||||
|
VideoUtils.dismissQueue();
|
||||||
|
}
|
||||||
|
|
||||||
// Every time a new video is opened, a snack bar appears indicating that the account has been switched.
|
|
||||||
// To prevent this, hide the snack bar while a new video is opening.
|
|
||||||
isVideoLaunched.compareAndSet(false, true);
|
isVideoLaunched.compareAndSet(false, true);
|
||||||
|
|
||||||
// The newly opened video is not a music video.
|
// The newly opened video is not a music video.
|
||||||
@ -87,12 +165,33 @@ public class AlbumMusicVideoPatch {
|
|||||||
playerResponseVideoId = songId;
|
playerResponseVideoId = songId;
|
||||||
currentVideoId = songId;
|
currentVideoId = songId;
|
||||||
VideoUtils.openInYouTubeMusic(songId);
|
VideoUtils.openInYouTubeMusic(songId);
|
||||||
}, 750);
|
}, 500);
|
||||||
|
|
||||||
// If a new video is opened, the snack bar will be shown.
|
|
||||||
VideoUtils.runOnMainThreadDelayed(() -> isVideoLaunched.compareAndSet(true, false), 1500);
|
VideoUtils.runOnMainThreadDelayed(() -> isVideoLaunched.compareAndSet(true, false), 1500);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "openOfficialMusicIfNeeded failure", ex);
|
Logger.printException(() -> "openMusic failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void setAudioVideoSwitchToggleOnLongClickListener(View view) {
|
||||||
|
if (DISABLE_MUSIC_VIDEO_IN_ALBUM && ON_LONG_CLICK) {
|
||||||
|
view.setOnLongClickListener(v -> {
|
||||||
|
try {
|
||||||
|
String videoId = VideoInformation.getVideoId();
|
||||||
|
synchronized (lastVideoIds) {
|
||||||
|
String songId = lastVideoIds.get(videoId);
|
||||||
|
if (songId != null) {
|
||||||
|
openMusic(songId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "onLongClickListener failure", ex);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,10 +199,7 @@ public class AlbumMusicVideoPatch {
|
|||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static boolean hideSnackBar() {
|
public static boolean hideSnackBar() {
|
||||||
if (!DISABLE_MUSIC_VIDEO_IN_ALBUM) {
|
return DISABLE_MUSIC_VIDEO_IN_ALBUM && isVideoLaunched.get();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isVideoLaunched.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import static app.revanced.extension.music.sponsorblock.objects.CategoryBehaviou
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import app.revanced.extension.music.patches.misc.AlbumMusicVideoPatch.RedirectType;
|
||||||
import app.revanced.extension.music.patches.misc.client.AppClient.ClientType;
|
import app.revanced.extension.music.patches.misc.client.AppClient.ClientType;
|
||||||
import app.revanced.extension.music.patches.utils.PatchStatus;
|
import app.revanced.extension.music.patches.utils.PatchStatus;
|
||||||
import app.revanced.extension.music.sponsorblock.SponsorBlockSettings;
|
import app.revanced.extension.music.sponsorblock.SponsorBlockSettings;
|
||||||
@ -179,6 +180,7 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting DISABLE_CAIRO_SPLASH_ANIMATION = new BooleanSetting("revanced_disable_cairo_splash_animation", FALSE, true);
|
public static final BooleanSetting DISABLE_CAIRO_SPLASH_ANIMATION = new BooleanSetting("revanced_disable_cairo_splash_animation", FALSE, true);
|
||||||
public static final BooleanSetting DISABLE_DRC_AUDIO = new BooleanSetting("revanced_disable_drc_audio", FALSE, true);
|
public static final BooleanSetting DISABLE_DRC_AUDIO = new BooleanSetting("revanced_disable_drc_audio", FALSE, true);
|
||||||
public static final BooleanSetting DISABLE_MUSIC_VIDEO_IN_ALBUM = new BooleanSetting("revanced_disable_music_video_in_album", FALSE, true);
|
public static final BooleanSetting DISABLE_MUSIC_VIDEO_IN_ALBUM = new BooleanSetting("revanced_disable_music_video_in_album", FALSE, true);
|
||||||
|
public static final EnumSetting<RedirectType> DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE = new EnumSetting<>("revanced_disable_music_video_in_album_redirect_type", RedirectType.REDIRECT_DISMISS, true);
|
||||||
public static final BooleanSetting ENABLE_OPUS_CODEC = new BooleanSetting("revanced_enable_opus_codec", FALSE, true);
|
public static final BooleanSetting ENABLE_OPUS_CODEC = new BooleanSetting("revanced_enable_opus_codec", FALSE, true);
|
||||||
public static final BooleanSetting SETTINGS_IMPORT_EXPORT = new BooleanSetting("revanced_extended_settings_import_export", FALSE, false);
|
public static final BooleanSetting SETTINGS_IMPORT_EXPORT = new BooleanSetting("revanced_extended_settings_import_export", FALSE, false);
|
||||||
public static final BooleanSetting SPOOF_CLIENT = new BooleanSetting("revanced_spoof_client", FALSE, true);
|
public static final BooleanSetting SPOOF_CLIENT = new BooleanSetting("revanced_spoof_client", FALSE, true);
|
||||||
@ -248,6 +250,7 @@ public class Settings extends BaseSettings {
|
|||||||
CHANGE_START_PAGE.key,
|
CHANGE_START_PAGE.key,
|
||||||
CUSTOM_FILTER_STRINGS.key,
|
CUSTOM_FILTER_STRINGS.key,
|
||||||
CUSTOM_PLAYBACK_SPEEDS.key,
|
CUSTOM_PLAYBACK_SPEEDS.key,
|
||||||
|
DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE.key,
|
||||||
EXTERNAL_DOWNLOADER_PACKAGE_NAME.key,
|
EXTERNAL_DOWNLOADER_PACKAGE_NAME.key,
|
||||||
HIDE_ACCOUNT_MENU_FILTER_STRINGS.key,
|
HIDE_ACCOUNT_MENU_FILTER_STRINGS.key,
|
||||||
SB_API_URL.key,
|
SB_API_URL.key,
|
||||||
|
@ -4,6 +4,7 @@ import static app.revanced.extension.music.settings.Settings.BYPASS_IMAGE_REGION
|
|||||||
import static app.revanced.extension.music.settings.Settings.CHANGE_START_PAGE;
|
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_FILTER_STRINGS;
|
||||||
import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYBACK_SPEEDS;
|
import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYBACK_SPEEDS;
|
||||||
|
import static app.revanced.extension.music.settings.Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE;
|
||||||
import static app.revanced.extension.music.settings.Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME;
|
import static app.revanced.extension.music.settings.Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME;
|
||||||
import static app.revanced.extension.music.settings.Settings.HIDE_ACCOUNT_MENU_FILTER_STRINGS;
|
import static app.revanced.extension.music.settings.Settings.HIDE_ACCOUNT_MENU_FILTER_STRINGS;
|
||||||
import static app.revanced.extension.music.settings.Settings.OPEN_DEFAULT_APP_SETTINGS;
|
import static app.revanced.extension.music.settings.Settings.OPEN_DEFAULT_APP_SETTINGS;
|
||||||
@ -160,9 +161,11 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
|
|||||||
Logger.printDebug(() -> "Failed to find the right value: " + dataString);
|
Logger.printDebug(() -> "Failed to find the right value: " + dataString);
|
||||||
}
|
}
|
||||||
} else if (settings instanceof EnumSetting<?> enumSetting) {
|
} else if (settings instanceof EnumSetting<?> enumSetting) {
|
||||||
if (settings.equals(RETURN_YOUTUBE_USERNAME_DISPLAY_FORMAT)
|
if (settings.equals(DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE)
|
||||||
|
|| settings.equals(RETURN_YOUTUBE_USERNAME_DISPLAY_FORMAT)
|
||||||
|| settings.equals(SPOOF_CLIENT_TYPE)
|
|| settings.equals(SPOOF_CLIENT_TYPE)
|
||||||
|| settings.equals(SPOOF_STREAMING_DATA_TYPE)) {
|
|| settings.equals(SPOOF_STREAMING_DATA_TYPE)
|
||||||
|
) {
|
||||||
ResettableListPreference.showDialog(mActivity, enumSetting, 0);
|
ResettableListPreference.showDialog(mActivity, enumSetting, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package app.revanced.patches.music.misc.album
|
|||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.dismiss.dismissQueueHookPatch
|
import app.revanced.patches.music.utils.dismiss.dismissQueueHookPatch
|
||||||
@ -9,13 +10,21 @@ 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.patch.PatchList.DISABLE_MUSIC_VIDEO_IN_ALBUM
|
||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
|
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.addSwitchPreference
|
||||||
import app.revanced.patches.music.utils.settings.settingsPatch
|
import app.revanced.patches.music.utils.settings.settingsPatch
|
||||||
import app.revanced.patches.music.video.information.videoIdHook
|
import app.revanced.patches.music.video.information.videoIdHook
|
||||||
import app.revanced.patches.music.video.information.videoInformationPatch
|
import app.revanced.patches.music.video.information.videoInformationPatch
|
||||||
import app.revanced.patches.music.video.playerresponse.hookPlayerResponse
|
import app.revanced.patches.music.video.playerresponse.hookPlayerResponse
|
||||||
import app.revanced.patches.music.video.playerresponse.playerResponseMethodHookPatch
|
import app.revanced.patches.music.video.playerresponse.playerResponseMethodHookPatch
|
||||||
|
import app.revanced.util.findMethodOrThrow
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"$MISC_PATH/AlbumMusicVideoPatch;"
|
"$MISC_PATH/AlbumMusicVideoPatch;"
|
||||||
@ -64,11 +73,50 @@ val albumMusicVideoPatch = bytecodePatch(
|
|||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
// region patch for setOnClick / setOnLongClick listener
|
||||||
|
|
||||||
|
audioVideoSwitchToggleConstructorFingerprint.methodOrThrow().apply {
|
||||||
|
val onClickListenerIndex = indexOfAudioVideoSwitchSetOnClickListenerInstruction(this)
|
||||||
|
val viewRegister = getInstruction<FiveRegisterInstruction>(onClickListenerIndex).registerC
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
onClickListenerIndex + 1,
|
||||||
|
"invoke-static { v$viewRegister }, " +
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->setAudioVideoSwitchToggleOnLongClickListener(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
|
||||||
|
val onClickListenerSyntheticIndex = indexOfFirstInstructionReversedOrThrow(onClickListenerIndex) {
|
||||||
|
opcode == Opcode.INVOKE_DIRECT &&
|
||||||
|
getReference<MethodReference>()?.name == "<init>"
|
||||||
|
}
|
||||||
|
val onClickListenerSyntheticClass = (getInstruction<ReferenceInstruction>(onClickListenerSyntheticIndex).reference as MethodReference).definingClass
|
||||||
|
|
||||||
|
findMethodOrThrow(onClickListenerSyntheticClass) {
|
||||||
|
name == "onClick"
|
||||||
|
}.addInstructionsWithLabels(
|
||||||
|
0, """
|
||||||
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->openMusic()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :ignore
|
||||||
|
return-void
|
||||||
|
:ignore
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
addSwitchPreference(
|
addSwitchPreference(
|
||||||
CategoryType.MISC,
|
CategoryType.MISC,
|
||||||
"revanced_disable_music_video_in_album",
|
"revanced_disable_music_video_in_album",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
|
addPreferenceWithIntent(
|
||||||
|
CategoryType.MISC,
|
||||||
|
"revanced_disable_music_video_in_album_redirect_type",
|
||||||
|
"revanced_disable_music_video_in_album"
|
||||||
|
)
|
||||||
|
|
||||||
updatePatchStatus(DISABLE_MUSIC_VIDEO_IN_ALBUM)
|
updatePatchStatus(DISABLE_MUSIC_VIDEO_IN_ALBUM)
|
||||||
|
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
package app.revanced.patches.music.misc.album
|
package app.revanced.patches.music.misc.album
|
||||||
|
|
||||||
import app.revanced.util.fingerprint.legacyFingerprint
|
import app.revanced.util.fingerprint.legacyFingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.or
|
import app.revanced.util.or
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
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 audioVideoSwitchToggleConstructorFingerprint = legacyFingerprint(
|
||||||
|
name = "audioVideoSwitchToggleConstructorFingerprint",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
returnType = "V",
|
||||||
|
opcodes = listOf(Opcode.INVOKE_DIRECT),
|
||||||
|
customFingerprint = { method, _ ->
|
||||||
|
indexOfAudioVideoSwitchSetOnClickListenerInstruction(method) >= 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun indexOfAudioVideoSwitchSetOnClickListenerInstruction(method: Method) =
|
||||||
|
method.indexOfFirstInstruction {
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||||
|
getReference<MethodReference>()?.toString() == "Lcom/google/android/apps/youtube/music/player/AudioVideoSwitcherToggleView;->setOnClickListener(Landroid/view/View${'$'}OnClickListener;)V"
|
||||||
|
}
|
||||||
|
|
||||||
internal val snackBarParentFingerprint = legacyFingerprint(
|
internal val snackBarParentFingerprint = legacyFingerprint(
|
||||||
name = "snackBarParentFingerprint",
|
name = "snackBarParentFingerprint",
|
||||||
|
@ -14,6 +14,22 @@
|
|||||||
<item>FEmusic_library_landing</item>
|
<item>FEmusic_library_landing</item>
|
||||||
<item>FEmusic_library_corpus_artists</item>
|
<item>FEmusic_library_corpus_artists</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="revanced_disable_music_video_in_album_redirect_type_entries">
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_redirect_dismiss</item>
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_redirect</item>
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_on_click_dismiss</item>
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_on_click</item>
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_on_long_click_dismiss</item>
|
||||||
|
<item>@string/revanced_disable_music_video_in_album_redirect_type_entry_on_long_click</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="revanced_disable_music_video_in_album_redirect_type_entry_values">
|
||||||
|
<item>REDIRECT_DISMISS</item>
|
||||||
|
<item>REDIRECT</item>
|
||||||
|
<item>ON_CLICK_DISMISS</item>
|
||||||
|
<item>ON_CLICK</item>
|
||||||
|
<item>ON_LONG_CLICK_DISMISS</item>
|
||||||
|
<item>ON_LONG_CLICK</item>
|
||||||
|
</string-array>
|
||||||
<string-array name="revanced_extended_settings_import_export_entries">
|
<string-array name="revanced_extended_settings_import_export_entries">
|
||||||
<item>@string/revanced_extended_settings_export_as_file</item>
|
<item>@string/revanced_extended_settings_export_as_file</item>
|
||||||
<item>@string/revanced_extended_settings_import_as_file</item>
|
<item>@string/revanced_extended_settings_import_as_file</item>
|
||||||
|
@ -423,9 +423,17 @@ Click to see how to issue a API key."</string>
|
|||||||
<string name="revanced_disable_music_video_in_album_title">Disable music video in album</string>
|
<string name="revanced_disable_music_video_in_album_title">Disable music video in album</string>
|
||||||
<string name="revanced_disable_music_video_in_album_summary">"When a non-premium user plays a song included in an album, the music video is sometimes played instead of the official song.
|
<string name="revanced_disable_music_video_in_album_summary">"When a non-premium user plays a song included in an album, the music video is sometimes played instead of the official song.
|
||||||
|
|
||||||
If such a music video is detected playing, it is redirected to the official song.
|
Find the official song if a music video is detected playing from an album.
|
||||||
|
|
||||||
A piped instance is used, but the API may not be available in some regions."</string>
|
• Powered by Piped Instance API."</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_title">Redirection type</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_summary">Specifies how to redirect to official song.</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_redirect_dismiss">Redirect (Dismiss queue)</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_redirect">Redirect</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_on_click_dismiss">Tap Audio / Video toggle (Dismiss queue)</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_on_click">Tap Audio / Video toggle</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_on_long_click_dismiss">Tap and hold Audio / Video toggle (Dismiss queue)</string>
|
||||||
|
<string name="revanced_disable_music_video_in_album_redirect_type_entry_on_long_click">Tap and hold Audio / Video toggle</string>
|
||||||
<string name="revanced_enable_debug_logging_title">Enable debug logging</string>
|
<string name="revanced_enable_debug_logging_title">Enable debug logging</string>
|
||||||
<string name="revanced_enable_debug_logging_summary">Prints the debug log.</string>
|
<string name="revanced_enable_debug_logging_summary">Prints the debug log.</string>
|
||||||
<string name="revanced_enable_debug_buffer_logging_title">Enable debug buffer logging</string>
|
<string name="revanced_enable_debug_buffer_logging_title">Enable debug buffer logging</string>
|
||||||
|
Reference in New Issue
Block a user