From bf982e8d7765c2a89a5475b6db8b203a3ac4ddf9 Mon Sep 17 00:00:00 2001 From: aliernfrog <45766489+aliernfrog@users.noreply.github.com> Date: Sat, 31 Dec 2022 20:48:40 +0300 Subject: [PATCH] feat(youtube): `copy-video-url` patch (#1402) --- .../annotation/CopyVideoUrlCompatibility.kt | 13 ++++ .../patch/CopyVideoUrlBytecodePatch.kt | 49 ++++++++++++ .../patch/CopyVideoUrlResourcePatch.kt | 62 ++++++++++++++++ .../bytecode/patch/DownloadsBytecodePatch.kt | 14 +--- .../patch/VideoInformationPatch.kt | 8 +- .../drawable/revanced_yt_copy.xml | 51 +++++++++++++ .../drawable/revanced_yt_copy_timestamp.xml | 74 +++++++++++++++++++ .../youtube_controls_bottom_ui_container.xml | 5 ++ 8 files changed, 264 insertions(+), 12 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt create mode 100644 src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml create mode 100644 src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml create mode 100644 src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt new file mode 100644 index 00000000..50396a80 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.interaction.copyvideourl.annotation + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [ + Package("com.google.android.youtube", arrayOf("17.49.37")) + ] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class CopyVideoUrlCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt new file mode 100644 index 00000000..c015612a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt @@ -0,0 +1,49 @@ +package app.revanced.patches.youtube.interaction.copyvideourl.bytecode.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.youtube.interaction.copyvideourl.annotation.CopyVideoUrlCompatibility +import app.revanced.patches.youtube.interaction.copyvideourl.resource.patch.CopyVideoUrlResourcePatch +import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch +import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch + +@Patch +@Name("copy-video-url") +@Description("Adds buttons in player to copy video links.") +@DependsOn([ + CopyVideoUrlResourcePatch::class, + PlayerControlsBytecodePatch::class, + VideoInformationPatch::class +]) +@CopyVideoUrlCompatibility +@Version("0.0.1") +class CopyVideoUrlBytecodePatch : BytecodePatch() { + private companion object { + const val INTEGRATIONS_PACKAGE = "Lapp/revanced/integrations" + const val INTEGRATIONS_PLAYER_PACKAGE = "$INTEGRATIONS_PACKAGE/videoplayer" + val BUTTONS_DESCRIPTORS = listOf( + "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlButton;", + "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlTimestampButton;" + ) + } + + override fun execute(context: BytecodeContext): PatchResult { + + // Initialize buttons and inject visibility control + BUTTONS_DESCRIPTORS.forEach { descriptor -> + val initializeButtonDescriptor = "$descriptor->initializeButton(Ljava/lang/Object;)V" + val visibilityDescriptor = "$descriptor->changeVisibility(Z)V" + PlayerControlsBytecodePatch.initializeControl(initializeButtonDescriptor) + PlayerControlsBytecodePatch.injectVisibilityCheckCall(visibilityDescriptor) + } + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt new file mode 100644 index 00000000..5cebcb3f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt @@ -0,0 +1,62 @@ +package app.revanced.patches.youtube.interaction.copyvideourl.resource.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.interaction.copyvideourl.annotation.CopyVideoUrlCompatibility +import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch +import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch +import app.revanced.util.resources.ResourceUtils +import app.revanced.util.resources.ResourceUtils.copyResources + +@Name("copy-video-url-resource") +@Description("Makes necessary changes to resources for copy video link buttons.") +@DependsOn([BottomControlsResourcePatch::class, FixLocaleConfigErrorPatch::class, SettingsPatch::class]) +@CopyVideoUrlCompatibility +@Version("0.0.1") +class CopyVideoUrlResourcePatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( + PreferenceScreen( + "revanced_copy_video_url", + StringResource("revanced_copy_video_url_title", "Copy video URL settings"), + listOf( + SwitchPreference( + "revanced_copy_video_url", + StringResource("revanced_copy_video_url_enabled_title", "Show copy video URL button"), + true, + StringResource("revanced_copy_video_url_enabled_summary_on", "Button is shown, click to copy video URL without timestamp"), + StringResource("revanced_copy_video_url_enabled_summary_off", "Button is not shown") + ), + SwitchPreference( + "revanced_copy_video_url_timestamp", + StringResource("revanced_copy_video_url_timestamp_enabled_title", "Show copy timestamp URL button"), + true, + StringResource("revanced_copy_video_url_timestamp_enabled_summary_on", "Button is shown, click to copy video URL with timestamp"), + StringResource("revanced_copy_video_url_timestamp_enabled_summary_off", "Button is not shown") + ) + ), + StringResource("revanced_copy_video_url_summary", "Settings related to copy URL buttons in video player") + ) + ) + + context.copyResources("copyvideourl", ResourceUtils.ResourceGroup( + resourceDirectoryName = "drawable", + "revanced_yt_copy.xml", + "revanced_yt_copy_timestamp.xml" + )) + + BottomControlsResourcePatch.addControls("copyvideourl/host/layout/${BottomControlsResourcePatch.TARGET_RESOURCE_NAME}") + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt index c5e6ba0c..244dbead 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt @@ -12,11 +12,11 @@ import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility import app.revanced.patches.youtube.interaction.downloads.resource.patch.DownloadsResourcePatch import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch +import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch @Patch @Name("downloads") -@DependsOn([DownloadsResourcePatch::class, PlayerControlsBytecodePatch::class, VideoIdPatch::class]) +@DependsOn([DownloadsResourcePatch::class, PlayerControlsBytecodePatch::class, VideoInformationPatch::class]) @Description("Enables downloading music and videos from YouTube.") @DownloadsCompatibility @Version("0.0.1") @@ -29,7 +29,7 @@ class DownloadsBytecodePatch : BytecodePatch() { initialize the control */ - val initializeDownloadsDescriptor = "$classDescriptor->initializeDownloadButton(Ljava/lang/Object;)V" + val initializeDownloadsDescriptor = "$classDescriptor->initializeButton(Ljava/lang/Object;)V" PlayerControlsBytecodePatch.initializeControl(initializeDownloadsDescriptor) /* @@ -39,14 +39,6 @@ class DownloadsBytecodePatch : BytecodePatch() { val changeVisibilityDescriptor = "$classDescriptor->changeVisibility(Z)V" PlayerControlsBytecodePatch.injectVisibilityCheckCall(changeVisibilityDescriptor) - /* - add code to change to update the video id - */ - - val setVideoIdDescriptor = - "L$integrationsPackage/patches/downloads/DownloadsPatch;->setVideoId(Ljava/lang/String;)V" - VideoIdPatch.injectCall(setVideoIdDescriptor) - return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt index 4df446b1..99708eb4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt @@ -20,6 +20,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility import app.revanced.patches.youtube.misc.video.information.fingerprints.* +import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.builder.MutableMethodImplementation import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -31,7 +32,7 @@ import org.jf.dexlib2.util.MethodUtil @Description("Hooks YouTube to get information about the current playing video.") @VideoInformationCompatibility @Version("0.0.1") -@DependsOn([IntegrationsPatch::class]) +@DependsOn([IntegrationsPatch::class, VideoIdPatch::class]) class VideoInformationPatch : BytecodePatch( listOf( PlayerInitFingerprint, @@ -94,6 +95,11 @@ class VideoInformationPatch : BytecodePatch( } } + /* + Inject call for video id + */ + VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") + /* Set the video time method */ diff --git a/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml b/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml new file mode 100644 index 00000000..14d05a97 --- /dev/null +++ b/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml b/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml new file mode 100644 index 00000000..57964725 --- /dev/null +++ b/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml b/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml new file mode 100644 index 00000000..97ec1740 --- /dev/null +++ b/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml @@ -0,0 +1,5 @@ + + + + +