mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-13 05:37:40 +02:00
feat(YouTube - Shorts components): Add Open Shorts in regular player
setting
This commit is contained in:
@ -16,9 +16,11 @@ import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import app.revanced.extension.shared.utils.Logger;
|
||||
import app.revanced.extension.shared.utils.ResourceUtils;
|
||||
import app.revanced.extension.shared.utils.Utils;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
import app.revanced.extension.youtube.utils.VideoUtils;
|
||||
import kotlin.Unit;
|
||||
@ -216,4 +218,38 @@ public class ShortsPatch {
|
||||
return !Settings.RESTORE_SHORTS_OLD_PLAYER_LAYOUT.get();
|
||||
}
|
||||
|
||||
public static boolean openShortInRegularPlayer(String videoId) {
|
||||
try {
|
||||
if (!Settings.OPEN_SHORTS_IN_REGULAR_PLAYER.get()) {
|
||||
return false; // Default unpatched behavior.
|
||||
}
|
||||
|
||||
if (videoId.isEmpty()) {
|
||||
// Shorts was opened using launcher app shortcut.
|
||||
//
|
||||
// This check will not detect if the Shorts app shortcut is used
|
||||
// while the app is running in the background (instead the regular player is opened).
|
||||
// To detect that the hooked method map parameter can be checked
|
||||
// if integer key 'com.google.android.apps.youtube.app.endpoint.flags'
|
||||
// has bitmask 16 set.
|
||||
//
|
||||
// This use case seems unlikely if the user has the Shorts
|
||||
// set to open in the regular player, so it's ignored as
|
||||
// checking the map makes the patch more complicated.
|
||||
Logger.printDebug(() -> "Ignoring Short with no videoId");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.SHORTS) {
|
||||
return false; // Always use Shorts player for the Shorts nav button.
|
||||
}
|
||||
|
||||
VideoUtils.openVideo(videoId, true);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "openShortInRegularPlayer failure", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -433,6 +433,7 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting HIDE_SHORTS_SHELF_HISTORY = new BooleanSetting("revanced_hide_shorts_shelf_history", TRUE);
|
||||
public static final EnumSetting<ShortsLoopBehavior> CHANGE_SHORTS_BACKGROUND_REPEAT_STATE = new EnumSetting<>("revanced_change_shorts_background_repeat_state", ShortsLoopBehavior.UNKNOWN);
|
||||
public static final EnumSetting<ShortsLoopBehavior> CHANGE_SHORTS_REPEAT_STATE = new EnumSetting<>("revanced_change_shorts_repeat_state", ShortsLoopBehavior.UNKNOWN);
|
||||
public static final BooleanSetting OPEN_SHORTS_IN_REGULAR_PLAYER = new BooleanSetting("revanced_open_shorts_in_regular_player", FALSE);
|
||||
|
||||
// PreferenceScreen: Shorts - Shorts player components
|
||||
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
|
||||
|
@ -21,6 +21,7 @@ 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
|
||||
import kotlin.collections.listOf
|
||||
|
||||
internal val bottomSheetMenuListBuilderFingerprint = legacyFingerprint(
|
||||
name = "bottomSheetMenuListBuilderFingerprint",
|
||||
@ -187,3 +188,40 @@ internal val shortsFullscreenFeatureFingerprint = legacyFingerprint(
|
||||
literals = listOf(FULLSCREEN_FEATURE_FLAG),
|
||||
)
|
||||
|
||||
// Pre 19.25
|
||||
internal val shortsPlaybackIntentLegacyFingerprint = legacyFingerprint(
|
||||
name = "shortsPlaybackIntentLegacyFingerprint",
|
||||
returnType = "V",
|
||||
parameters = listOf(
|
||||
"L",
|
||||
"Ljava/util/Map;",
|
||||
"J",
|
||||
"Ljava/lang/String;",
|
||||
"Z",
|
||||
"Ljava/util/Map;"
|
||||
),
|
||||
strings = listOf(
|
||||
// None of these strings are unique.
|
||||
"com.google.android.apps.youtube.app.endpoint.flags",
|
||||
"ReelWatchFragmentArgs",
|
||||
"reels_fragment_descriptor"
|
||||
)
|
||||
)
|
||||
|
||||
internal val shortsPlaybackIntentFingerprint = legacyFingerprint(
|
||||
name = "shortsPlaybackIntentFingerprint",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf(
|
||||
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;",
|
||||
"Ljava/util/Map;",
|
||||
"J",
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
strings = listOf(
|
||||
// None of these strings are unique.
|
||||
"com.google.android.apps.youtube.app.endpoint.flags",
|
||||
"ReelWatchFragmentArgs",
|
||||
"reels_fragment_descriptor"
|
||||
)
|
||||
)
|
||||
|
@ -62,6 +62,9 @@ import app.revanced.patches.youtube.utils.toolbar.hookToolBar
|
||||
import app.revanced.patches.youtube.utils.toolbar.toolBarHookPatch
|
||||
import app.revanced.patches.youtube.video.information.hookShortsVideoInformation
|
||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||
import app.revanced.patches.youtube.video.playbackstart.PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.video.playbackstart.playbackStartDescriptorPatch
|
||||
import app.revanced.patches.youtube.video.playbackstart.playbackStartVideoIdReference
|
||||
import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId
|
||||
import app.revanced.patches.youtube.video.videoid.videoIdPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
@ -569,6 +572,8 @@ val shortsComponentPatch = bytecodePatch(
|
||||
shortsToolBarPatch,
|
||||
|
||||
lithoFilterPatch,
|
||||
navigationBarHookPatch,
|
||||
playbackStartDescriptorPatch,
|
||||
playerTypeHookPatch,
|
||||
sharedResourceIdPatch,
|
||||
textComponentPatch,
|
||||
@ -874,6 +879,47 @@ val shortsComponentPatch = bytecodePatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region patch for open Shorts in regular player
|
||||
|
||||
fun extensionInstructions(playbackStartRegister: Int, freeRegister: Int) =
|
||||
"""
|
||||
invoke-virtual { v$playbackStartRegister }, $playbackStartVideoIdReference
|
||||
move-result-object v$freeRegister
|
||||
invoke-static { v$freeRegister }, $SHORTS_CLASS_DESCRIPTOR->openShortInRegularPlayer(Ljava/lang/String;)Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :disabled
|
||||
return-void
|
||||
:disabled
|
||||
nop
|
||||
"""
|
||||
|
||||
if (!is_19_25_or_greater) {
|
||||
shortsPlaybackIntentLegacyFingerprint.methodOrThrow().apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.returnType == PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR
|
||||
}
|
||||
val freeRegister = getInstruction<FiveRegisterInstruction>(index).registerC
|
||||
val playbackStartRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||
|
||||
addInstructionsWithLabels(
|
||||
index + 2,
|
||||
extensionInstructions(playbackStartRegister, freeRegister)
|
||||
)
|
||||
}
|
||||
|
||||
return@execute
|
||||
}
|
||||
|
||||
shortsPlaybackIntentFingerprint.methodOrThrow().addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
move-object/from16 v0, p1
|
||||
${extensionInstructions(0, 1)}
|
||||
"""
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
addLithoFilter(BUTTON_FILTER_CLASS_DESCRIPTOR)
|
||||
addLithoFilter(SHELF_FILTER_CLASS_DESCRIPTOR)
|
||||
addLithoFilter(RETURN_YOUTUBE_CHANNEL_NAME_FILTER_CLASS_DESCRIPTOR)
|
||||
|
@ -1318,6 +1318,9 @@ Info:
|
||||
<string name="revanced_change_shorts_repeat_state_entry_default">Default</string>
|
||||
<string name="revanced_change_shorts_repeat_state_entry_pause">Pause</string>
|
||||
<string name="revanced_change_shorts_repeat_state_entry_repeat">Repeat</string>
|
||||
<string name="revanced_open_shorts_in_regular_player_title">Open Shorts in regular player</string>
|
||||
<string name="revanced_open_shorts_in_regular_player_summary_on">Open Shorts in the regular player.</string>
|
||||
<string name="revanced_open_shorts_in_regular_player_summary_off">Do not open Shorts in the regular player.</string>
|
||||
|
||||
<!-- PreferenceScreen: Shorts, PreferenceCategory: Shorts, PreferenceScreen: Shorts player -->
|
||||
<string name="revanced_preference_screen_shorts_player_title">Shorts player</string>
|
||||
|
@ -653,7 +653,8 @@
|
||||
<ListPreference android:entries="@array/revanced_change_shorts_repeat_state_entries" android:title="@string/revanced_change_shorts_background_repeat_state_title" android:key="revanced_change_shorts_background_repeat_state" android:entryValues="@array/revanced_change_shorts_repeat_state_entry_values" />SETTINGS: SHORTS_REPEAT_STATE_BACKGROUND -->
|
||||
|
||||
<!-- SETTINGS: SHORTS_COMPONENTS
|
||||
<ListPreference android:entries="@array/revanced_change_shorts_repeat_state_entries" android:title="@string/revanced_change_shorts_repeat_state_title" android:key="revanced_change_shorts_repeat_state" android:entryValues="@array/revanced_change_shorts_repeat_state_entry_values" />SETTINGS: SHORTS_COMPONENTS -->
|
||||
<ListPreference android:entries="@array/revanced_change_shorts_repeat_state_entries" android:title="@string/revanced_change_shorts_repeat_state_title" android:key="revanced_change_shorts_repeat_state" android:entryValues="@array/revanced_change_shorts_repeat_state_entry_values" />
|
||||
<SwitchPreference android:title="@string/revanced_open_shorts_in_regular_player_title" android:key="revanced_open_shorts_in_regular_player" android:summaryOn="@string/revanced_open_shorts_in_regular_player_summary_on" android:summaryOff="@string/revanced_open_shorts_in_regular_player_summary_off" />SETTINGS: SHORTS_COMPONENTS -->
|
||||
|
||||
<!-- PREFERENCE_SCREEN: SHORTS
|
||||
</PreferenceScreen>PREFERENCE_SCREEN: SHORTS -->
|
||||
|
Reference in New Issue
Block a user