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 @@
+
+
+
+
+