feat(YouTube/Seekbar components): add Replace time stamp action settings

This commit is contained in:
inotia00 2024-05-02 04:59:08 +09:00
parent 9e93427d11
commit c91a08675e
10 changed files with 107 additions and 78 deletions

View File

@ -106,7 +106,7 @@ object LayoutComponentsPatch : BaseBytecodePatch(
1,
"const/4 p1, 0x0"
)
// endregion
// region patch for hide account menu

View File

@ -20,6 +20,7 @@ import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerp
import app.revanced.patches.youtube.utils.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.utils.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.utils.fingerprints.TotalTimeFingerprint
import app.revanced.patches.youtube.utils.flyoutmenu.FlyoutMenuHookPatch
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarColorizedBarPlayedColorDark
@ -50,6 +51,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
description = "Adds options to hide or change components related to player.",
dependencies = setOf(
DrawableColorPatch::class,
FlyoutMenuHookPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class,
VideoInformationPatch::class

View File

@ -0,0 +1,81 @@
package app.revanced.patches.youtube.utils.flyoutmenu
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.utils.flyoutmenu.fingerprints.PlaybackRateBottomSheetClassFingerprint
import app.revanced.patches.youtube.utils.flyoutmenu.fingerprints.VideoQualityBottomSheetClassFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.addFieldAndInstructions
import app.revanced.util.resultOrThrow
@Patch(
description = "Hooks YouTube to open the playback speed or video quality flyout menu in the integration.",
dependencies = [SharedResourceIdPatch::class]
)
object FlyoutMenuHookPatch : BytecodePatch(
setOf(
PlaybackRateBottomSheetClassFingerprint,
VideoQualityBottomSheetClassFingerprint
)
) {
private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/utils/VideoUtils;"
override fun execute(context: BytecodeContext) {
val videoUtilsMutableClass = context.findClass(
INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR
)!!.mutableClass
PlaybackRateBottomSheetClassFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val playbackRateBottomSheetBuilderMethodName =
it.mutableClass.methods.find { method -> method.parameters.isEmpty() && method.returnType == "V" }
?.name
?: throw PatchException("Could not find PlaybackRateBottomSheetBuilderMethod")
val smaliInstructions =
"""
if-eqz v0, :ignore
invoke-virtual {v0}, $definingClass->$playbackRateBottomSheetBuilderMethodName()V
:ignore
return-void
"""
videoUtilsMutableClass.addFieldAndInstructions(
context,
"showPlaybackSpeedFlyoutMenu",
"playbackRateBottomSheetClass",
definingClass,
smaliInstructions,
true
)
}
}
VideoQualityBottomSheetClassFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val smaliInstructions =
"""
if-eqz v0, :ignore
const/4 v1, 0x1
invoke-virtual {v0, v1}, $definingClass->$name(Z)V
:ignore
return-void
"""
videoUtilsMutableClass.addFieldAndInstructions(
context,
"showVideoQualityFlyoutMenu",
"videoQualityBottomSheetClass",
definingClass,
smaliInstructions,
true
)
}
}
}
}

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.utils.flyoutpanel.fingerprints
package app.revanced.patches.youtube.utils.flyoutmenu.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -0,0 +1,13 @@
package app.revanced.patches.youtube.utils.flyoutmenu.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VideoQualityUnavailableAnnouncement
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object VideoQualityBottomSheetClassFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Z"),
literalSupplier = { VideoQualityUnavailableAnnouncement }
)

View File

@ -1,73 +0,0 @@
package app.revanced.patches.youtube.utils.flyoutpanel
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patches.youtube.utils.flyoutpanel.fingerprints.PlaybackRateBottomSheetClassFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableField
@Patch(description = "Hooks YouTube to open the playback speed flyout panel in the integration.")
object PlaybackSpeedFlyoutPanelHookPatch : BytecodePatch(
setOf(PlaybackRateBottomSheetClassFingerprint)
) {
private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/utils/VideoUtils;"
override fun execute(context: BytecodeContext) {
PlaybackRateBottomSheetClassFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val playbackRateBottomSheetClass = definingClass
val playbackRateBottomSheetBuilderMethodName =
it.mutableClass.methods.find { method -> method.parameters.isEmpty() && method.returnType == "V" }
?.name
?: throw PatchException("Could not find PlaybackRateBottomSheetBuilderMethod")
// set playback rate bottom sheet class
addInstruction(
0,
"sput-object p0, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->playbackRateBottomSheetClass:$playbackRateBottomSheetClass"
)
val videoUtilsMutableClass = context.findClass(
INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR
)!!.mutableClass
videoUtilsMutableClass.methods.single { method ->
method.name == "showPlaybackSpeedFlyoutMenu"
}.apply {
// add playback rate bottom sheet class
videoUtilsMutableClass.staticFields.add(
ImmutableField(
definingClass,
"playbackRateBottomSheetClass",
playbackRateBottomSheetClass,
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
// call playback rate bottom sheet method
addInstructionsWithLabels(
0, """
sget-object v0, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->playbackRateBottomSheetClass:$playbackRateBottomSheetClass
if-eqz v0, :ignore
invoke-virtual {v0}, $playbackRateBottomSheetClass->$playbackRateBottomSheetBuilderMethodName()V
:ignore
return-void
"""
)
}
}
}
}
}

View File

@ -93,6 +93,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var TotalTime = -1L
var TouchArea = -1L
var VideoQualityBottomSheet = -1L
var VideoQualityUnavailableAnnouncement = -1L
var VoiceSearch = -1L
var YouTubeControlsOverlaySubtitleButton = -1L
var YtOutlinePiPWhite = -1L
@ -181,6 +182,7 @@ object SharedResourceIdPatch : ResourcePatch() {
TotalTime = getId(STRING, "total_time")
TouchArea = getId(ID, "touch_area")
VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
VideoQualityUnavailableAnnouncement = getId(STRING, "video_quality_unavailable_announcement")
VoiceSearch = getId(ID, "voice_search")
YouTubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button")
YtOutlinePiPWhite = getId(DRAWABLE, "yt_outline_picture_in_picture_white_24")

View File

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
import app.revanced.patches.youtube.utils.fingerprints.QualityMenuViewInflateFingerprint
import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint
import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch
import app.revanced.patches.youtube.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch
import app.revanced.patches.youtube.utils.flyoutmenu.FlyoutMenuHookPatch
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
@ -52,8 +52,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
dependencies = setOf(
BottomSheetRecyclerViewPatch::class,
CustomPlaybackSpeedPatch::class,
FlyoutMenuHookPatch::class,
LithoFilterPatch::class,
PlaybackSpeedFlyoutPanelHookPatch::class,
PlayerTypeHookPatch::class,
SettingsPatch::class,
ShortsPlaybackPatch::class,

View File

@ -816,6 +816,9 @@ Please download %2$s from the website."</string>
<string name="revanced_append_time_stamp_information_type_title">Append information type</string>
<string name="revanced_append_time_stamp_information_type_summary_on">Append video quality.</string>
<string name="revanced_append_time_stamp_information_type_summary_off">Append playback speed.</string>
<string name="revanced_replace_time_stamp_action_title">Replace time stamp action</string>
<string name="revanced_replace_time_stamp_action_summary_on">Tap to open playback speed or video quality flyout menu.</string>
<string name="revanced_replace_time_stamp_action_summary_off">Tap to show the remaining time.</string>
<string name="revanced_enable_custom_seekbar_color_title">Enable custom seekbar color</string>
<string name="revanced_enable_custom_seekbar_color_summary_on">Custom seekbar color is enabled.</string>
<string name="revanced_enable_custom_seekbar_color_summary_off">Custom seekbar color is disabled.</string>

View File

@ -346,7 +346,8 @@
<!-- SETTINGS: SEEKBAR_COMPONENTS
<PreferenceScreen android:title="@string/revanced_preference_screen_seekbar_title" android:key="revanced_preference_screen_seekbar" android:summary="@string/revanced_preference_screen_seekbar_summary">
<SwitchPreference android:title="@string/revanced_append_time_stamp_information_title" android:key="revanced_append_time_stamp_information" android:defaultValue="true" android:summaryOn="@string/revanced_append_time_stamp_information_summary_on" android:summaryOff="@string/revanced_append_time_stamp_information_summary_off" />
<SwitchPreference android:title="@string/revanced_append_time_stamp_information_type_title" android:key="revanced_append_time_stamp_information_type" android:defaultValue="true" android:summaryOn="@string/revanced_append_time_stamp_information_type_summary_on" android:summaryOff="@string/revanced_append_time_stamp_information_type_summary_off" android:dependency="revanced_append_time_stamp_information" />
<SwitchPreference android:title="@string/revanced_append_time_stamp_information_type_title" android:key="revanced_append_time_stamp_information_type" android:defaultValue="true" android:summaryOn="@string/revanced_append_time_stamp_information_type_summary_on" android:summaryOff="@string/revanced_append_time_stamp_information_type_summary_off" />
<SwitchPreference android:title="@string/revanced_replace_time_stamp_action_title" android:key="revanced_replace_time_stamp_action" android:defaultValue="true" android:summaryOn="@string/revanced_replace_time_stamp_action_summary_on" android:summaryOff="@string/revanced_replace_time_stamp_action_summary_off" />
<SwitchPreference android:title="@string/revanced_enable_custom_seekbar_color_title" android:key="revanced_enable_custom_seekbar_color" android:defaultValue="false" android:summaryOn="@string/revanced_enable_custom_seekbar_color_summary_on" android:summaryOff="@string/revanced_enable_custom_seekbar_color_summary_off" />
<app.revanced.integrations.shared.settings.preference.ResettableEditTextPreference android:title="@string/revanced_custom_seekbar_color_value_title" android:key="revanced_custom_seekbar_color_value" android:summary="@string/revanced_custom_seekbar_color_value_summary" android:defaultValue="#FF0000" android:hint="#FF0000" android:inputType="text" />
<SwitchPreference android:title="@string/revanced_enable_seekbar_tapping_title" android:key="revanced_enable_seekbar_tapping" android:defaultValue="true" android:summaryOn="@string/revanced_enable_seekbar_tapping_summary_on" android:summaryOff="@string/revanced_enable_seekbar_tapping_summary_off" />