feat(YouTube - Fullscreen components): Add Enter fullscreen mode setting

This commit is contained in:
inotia00 2025-01-03 21:54:27 +09:00
parent 428047b725
commit 1f95e07e7a
6 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,67 @@
package app.revanced.extension.youtube.patches.player;
import androidx.annotation.NonNull;
import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.Utils;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType;
import app.revanced.extension.youtube.utils.VideoUtils;
@SuppressWarnings("unused")
public class EnterFullscreenPatch {
private static volatile boolean isForeground = true;
@NonNull
private static String videoId = "";
/**
* Injection point.
*/
public static void onAppBackgrounded() {
isForeground = false;
}
/**
* Injection point.
*/
public static void onAppForegrounded() {
isForeground = true;
}
/**
* Injection point.
*/
public static void enterFullscreen(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName,
@NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle,
final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) {
try {
if (!Settings.ENTER_FULLSCREEN.get()) {
return;
}
PlayerType playerType = PlayerType.getCurrent();
// 1. The user opened the video while playing a video in the feed.
// 2. This is a valid request, so the videoId is not saved.
if (playerType == PlayerType.INLINE_MINIMAL) {
return;
}
if (videoId.equals(newlyLoadedVideoId)) {
return;
}
videoId = newlyLoadedVideoId;
// 1. User clicks home button in [PlayerType.WATCH_WHILE_MAXIMIZED], thus entering audio only mode.
// 2. PlayerType is still [PlayerType.WATCH_WHILE_MAXIMIZED].
// 3. Next video starts in audio only mode, then returns to foreground mode.
// 4. Enters fullscreen for a moment and then returns.
// We can prevent this by checking if the app is in the foreground.
if (playerType == PlayerType.WATCH_WHILE_MAXIMIZED && isForeground) {
// It works without delay, but in this case sometimes portrait videos have landscape orientation.
Utils.runOnMainThreadDelayed(VideoUtils::enterFullscreenMode, 250L);
}
} catch (Exception ex) {
Logger.printException(() -> "enterFullscreen failure", ex);
}
}
}

View File

@ -335,6 +335,7 @@ public class Settings extends BaseSettings {
// PreferenceScreen: Player - Fullscreen // PreferenceScreen: Player - Fullscreen
public static final BooleanSetting DISABLE_ENGAGEMENT_PANEL = new BooleanSetting("revanced_disable_engagement_panel", FALSE, true); public static final BooleanSetting DISABLE_ENGAGEMENT_PANEL = new BooleanSetting("revanced_disable_engagement_panel", FALSE, true);
public static final BooleanSetting ENTER_FULLSCREEN = new BooleanSetting("revanced_enter_fullscreen", FALSE);
public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED); public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED);
public static final BooleanSetting SHOW_VIDEO_TITLE_SECTION = new BooleanSetting("revanced_show_video_title_section", TRUE, true, parent(DISABLE_ENGAGEMENT_PANEL)); public static final BooleanSetting SHOW_VIDEO_TITLE_SECTION = new BooleanSetting("revanced_show_video_title_section", TRUE, true, parent(DISABLE_ENGAGEMENT_PANEL));
public static final BooleanSetting HIDE_AUTOPLAY_PREVIEW = new BooleanSetting("revanced_hide_autoplay_preview", FALSE, true); public static final BooleanSetting HIDE_AUTOPLAY_PREVIEW = new BooleanSetting("revanced_hide_autoplay_preview", FALSE, true);

View File

@ -18,6 +18,10 @@ lateinit var onConfigurationChangedMethod: MutableMethod
private set private set
lateinit var onCreateMethod: MutableMethod lateinit var onCreateMethod: MutableMethod
private set private set
lateinit var onStartMethod: MutableMethod
private set
lateinit var onStopMethod: MutableMethod
private set
private lateinit var constructorMethod: MutableMethod private lateinit var constructorMethod: MutableMethod
private lateinit var onBackPressedMethod: MutableMethod private lateinit var onBackPressedMethod: MutableMethod
@ -45,6 +49,9 @@ fun baseMainActivityResolvePatch(
// set onConfigurationChanged method // set onConfigurationChanged method
onConfigurationChangedMethod = getMainActivityMethod("onConfigurationChanged") onConfigurationChangedMethod = getMainActivityMethod("onConfigurationChanged")
onStartMethod = getMainActivityMethod("onStart")
onStopMethod = getMainActivityMethod("onStop")
} }
} }

View File

@ -11,6 +11,8 @@ import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.litho.addLithoFilter import app.revanced.patches.shared.litho.addLithoFilter
import app.revanced.patches.shared.litho.lithoFilterPatch import app.revanced.patches.shared.litho.lithoFilterPatch
import app.revanced.patches.shared.mainactivity.onConfigurationChangedMethod import app.revanced.patches.shared.mainactivity.onConfigurationChangedMethod
import app.revanced.patches.shared.mainactivity.onStartMethod
import app.revanced.patches.shared.mainactivity.onStopMethod
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.extension.Constants.PATCH_STATUS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
@ -31,6 +33,7 @@ import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.patches.youtube.utils.youtubeControlsOverlayFingerprint import app.revanced.patches.youtube.utils.youtubeControlsOverlayFingerprint
import app.revanced.patches.youtube.video.information.hookBackgroundPlayVideoInformation
import app.revanced.patches.youtube.video.information.videoEndMethod import app.revanced.patches.youtube.video.information.videoEndMethod
import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.patches.youtube.video.information.videoInformationPatch
import app.revanced.util.Utils.printWarn import app.revanced.util.Utils.printWarn
@ -54,6 +57,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/QuickActionFilter;" "$COMPONENTS_PATH/QuickActionFilter;"
private const val EXTENSION_ENTER_FULLSCREEN_CLASS_DESCRIPTOR =
"$PLAYER_PATH/EnterFullscreenPatch;"
private const val EXTENSION_EXIT_FULLSCREEN_CLASS_DESCRIPTOR = private const val EXTENSION_EXIT_FULLSCREEN_CLASS_DESCRIPTOR =
"$PLAYER_PATH/ExitFullscreenPatch;" "$PLAYER_PATH/ExitFullscreenPatch;"
@ -118,6 +124,22 @@ val fullscreenComponentsPatch = bytecodePatch(
// endregion // endregion
// region patch for enter fullscreen
mapOf(
onStartMethod to "onAppForegrounded",
onStopMethod to "onAppBackgrounded"
).forEach { (method, name) ->
method.addInstruction(
0,
"invoke-static {}, $EXTENSION_ENTER_FULLSCREEN_CLASS_DESCRIPTOR->$name()V"
)
}
hookBackgroundPlayVideoInformation("$EXTENSION_ENTER_FULLSCREEN_CLASS_DESCRIPTOR->enterFullscreen(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V")
// endregion
// region patch for exit fullscreen // region patch for exit fullscreen
videoEndMethod.apply { videoEndMethod.apply {

View File

@ -923,6 +923,11 @@ Settings → Autoplay → Autoplay next video"</string>
<string name="revanced_disable_engagement_panel_title">Disable engagement panel</string> <string name="revanced_disable_engagement_panel_title">Disable engagement panel</string>
<string name="revanced_disable_engagement_panel_summary_on">Engagement panel is disabled.</string> <string name="revanced_disable_engagement_panel_summary_on">Engagement panel is disabled.</string>
<string name="revanced_disable_engagement_panel_summary_off">Engagement panel is enabled.</string> <string name="revanced_disable_engagement_panel_summary_off">Engagement panel is enabled.</string>
<string name="revanced_enter_fullscreen_title">Enter fullscreen mode when video starts</string>
<string name="revanced_enter_fullscreen_summary_on">"Enter fullscreen mode when the video starts.
Limitation: Does not work if the player is minimized, in PiP mode, or in the background.</string>
<string name="revanced_enter_fullscreen_summary_off">Do not enter fullscreen mode when the video starts.</string>
<string name="revanced_exit_fullscreen_title">Exit fullscreen mode at end of video</string> <string name="revanced_exit_fullscreen_title">Exit fullscreen mode at end of video</string>
<string name="revanced_exit_fullscreen_entry_1">Disabled</string> <string name="revanced_exit_fullscreen_entry_1">Disabled</string>
<string name="revanced_exit_fullscreen_entry_2">Portrait</string> <string name="revanced_exit_fullscreen_entry_2">Portrait</string>

View File

@ -397,6 +397,7 @@
<!-- SETTINGS: FULLSCREEN_COMPONENTS <!-- SETTINGS: FULLSCREEN_COMPONENTS
<PreferenceScreen android:title="@string/revanced_preference_screen_fullscreen_title" android:key="revanced_preference_screen_fullscreen" android:summary="@string/revanced_preference_screen_fullscreen_summary"> <PreferenceScreen android:title="@string/revanced_preference_screen_fullscreen_title" android:key="revanced_preference_screen_fullscreen" android:summary="@string/revanced_preference_screen_fullscreen_summary">
<SwitchPreference android:title="@string/revanced_disable_engagement_panel_title" android:key="revanced_disable_engagement_panel" android:summaryOn="@string/revanced_disable_engagement_panel_summary_on" android:summaryOff="@string/revanced_disable_engagement_panel_summary_off" /> <SwitchPreference android:title="@string/revanced_disable_engagement_panel_title" android:key="revanced_disable_engagement_panel" android:summaryOn="@string/revanced_disable_engagement_panel_summary_on" android:summaryOff="@string/revanced_disable_engagement_panel_summary_off" />
<SwitchPreference android:title="@string/revanced_enter_fullscreen_title" android:key="revanced_enter_fullscreen" android:summaryOn="@string/revanced_enter_fullscreen_summary_on" android:summaryOff="@string/revanced_enter_fullscreen_summary_off" />
<ListPreference android:entries="@array/revanced_exit_fullscreen_entries" android:title="@string/revanced_exit_fullscreen_title" android:key="revanced_exit_fullscreen" android:entryValues="@array/revanced_exit_fullscreen_entry_values" /> <ListPreference android:entries="@array/revanced_exit_fullscreen_entries" android:title="@string/revanced_exit_fullscreen_title" android:key="revanced_exit_fullscreen" android:entryValues="@array/revanced_exit_fullscreen_entry_values" />
<SwitchPreference android:title="@string/revanced_show_video_title_section_title" android:key="revanced_show_video_title_section" android:summary="@string/revanced_show_video_title_section_summary" /> <SwitchPreference android:title="@string/revanced_show_video_title_section_title" android:key="revanced_show_video_title_section" android:summary="@string/revanced_show_video_title_section_summary" />
<SwitchPreference android:title="@string/revanced_hide_autoplay_preview_title" android:key="revanced_hide_autoplay_preview" android:summaryOn="@string/revanced_hide_autoplay_preview_summary_on" android:summaryOff="@string/revanced_hide_autoplay_preview_summary_off" /> <SwitchPreference android:title="@string/revanced_hide_autoplay_preview_title" android:key="revanced_hide_autoplay_preview" android:summaryOn="@string/revanced_hide_autoplay_preview_summary_on" android:summaryOff="@string/revanced_hide_autoplay_preview_summary_off" />