From 851bca7ef787a266b0b749287b02740a0b055d0f Mon Sep 17 00:00:00 2001 From: Sami Alaoui <4ndroidgeek@gmail.com> Date: Tue, 11 Jun 2024 18:31:48 +0100 Subject: [PATCH 1/6] fix(YouTube - SponsorBlock/VideoInformation): implement MDX seekTo command to fix skipping while casted to a TV --- .../youtube/patches/VideoInformation.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index 8cf525f3c7..b91c169b69 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -23,7 +23,9 @@ public final class VideoInformation { private static final String SHORTS_PLAYER_PARAMETERS = "8AEB"; private static WeakReference playerControllerRef; + private static WeakReference mdxPlayerDirectorRef; private static Method seekMethod; + private static Method mdxSeekMethod; @NonNull private static String videoId = ""; @@ -59,6 +61,23 @@ public static void initialize(@NonNull Object playerController) { } } + /** + * Injection point. + * + * @param mdxPlayerDirector MDX player director object (casting mode). + */ + public static void initializeMdx(@NonNull Object mdxPlayerDirector) { + try { + mdxPlayerDirectorRef = new WeakReference<>(Objects.requireNonNull(mdxPlayerDirector)); + + mdxSeekMethod = mdxPlayerDirector.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE); + mdxSeekMethod.setAccessible(true); + + } catch (Exception ex) { + Logger.printException(() -> "Failed to initialize", ex); + } + } + /** * Injection point. * @@ -178,8 +197,22 @@ public static boolean seekTo(final long seekTime) { } Logger.printDebug(() -> "Seeking to " + adjustedSeekTime); + + // Try calling the seekTo method of the MDX player director first (called when casting to a big screen device). + // The difference has to be at least 1000ms to avoid infinite skip loops (the seekTo Lounge API command only supports seconds). + if (adjustedSeekTime - videoTime >= 1000) { + try { + mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); + } catch (Exception ex) { + Logger.printInfo(() -> "Failed to seek (MDX)", ex); + } + } else { + Logger.printDebug(() -> "Skipping seekTo for MDX because of a small relative value (" + (seekTime - videoTime) + "ms)."); + } + //noinspection DataFlowIssue return (Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime); + } catch (Exception ex) { Logger.printException(() -> "Failed to seek", ex); return false; From 23a3f0c5f5dc28f23b175ee2c7642a374b3c75f5 Mon Sep 17 00:00:00 2001 From: Sami Alaoui <4ndroidgeek@gmail.com> Date: Wed, 12 Jun 2024 03:10:46 +0100 Subject: [PATCH 2/6] Apply code review suggestions fix(YouTube - SponsorBlock): Skip segments when casting #655 --- .../youtube/patches/VideoInformation.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index b91c169b69..13450fd8e3 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -74,7 +74,7 @@ public static void initializeMdx(@NonNull Object mdxPlayerDirector) { mdxSeekMethod.setAccessible(true); } catch (Exception ex) { - Logger.printException(() -> "Failed to initialize", ex); + Logger.printException(() -> "Failed to initialize MDX", ex); } } @@ -198,21 +198,30 @@ public static boolean seekTo(final long seekTime) { Logger.printDebug(() -> "Seeking to " + adjustedSeekTime); - // Try calling the seekTo method of the MDX player director first (called when casting to a big screen device). + try { + //noinspection DataFlowIssue + if ((Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime)) { + return true; + } + } catch (Exception ex) { + Logger.printInfo(() -> "seekTo method call failed", ex); + } + + // Try calling the seekTo method of the MDX player director (called when casting) if the player controller one failed. // The difference has to be at least 1000ms to avoid infinite skip loops (the seekTo Lounge API command only supports seconds). - if (adjustedSeekTime - videoTime >= 1000) { + if (Math.abs(adjustedSeekTime - videoTime) >= 1000) { try { - mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); + //noinspection DataFlowIssue + return (Boolean) mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); } catch (Exception ex) { - Logger.printInfo(() -> "Failed to seek (MDX)", ex); + Logger.printInfo(() -> "seekTo (MDX) method call failed", ex); + return false; } } else { Logger.printDebug(() -> "Skipping seekTo for MDX because of a small relative value (" + (seekTime - videoTime) + "ms)."); + return false; } - //noinspection DataFlowIssue - return (Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime); - } catch (Exception ex) { Logger.printException(() -> "Failed to seek", ex); return false; From 1e3788d3076aa3210d781a65dd119a0f477aaf8a Mon Sep 17 00:00:00 2001 From: Sami Alaoui <4ndroidgeek@gmail.com> Date: Thu, 13 Jun 2024 14:04:06 +0100 Subject: [PATCH 3/6] fix(YouTube - VideoInformation): Improve seekTo conditions for MDX --- .../integrations/youtube/patches/VideoInformation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index 13450fd8e3..8525ce9ff7 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -208,8 +208,8 @@ public static boolean seekTo(final long seekTime) { } // Try calling the seekTo method of the MDX player director (called when casting) if the player controller one failed. - // The difference has to be at least 1000ms to avoid infinite skip loops (the seekTo Lounge API command only supports seconds). - if (Math.abs(adjustedSeekTime - videoTime) >= 1000) { + // The difference has to be a different second mark in order to avoid infinite skip loops (as the Lounge API only supports seconds). + if (Math.abs(adjustedSeekTime/1000 - videoTime/1000) >= 1) { try { //noinspection DataFlowIssue return (Boolean) mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); From c1ab3b1ceb54e67052ee258ecdae08ab9e57c833 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Thu, 4 Jul 2024 00:21:39 +0400 Subject: [PATCH 4/6] Update app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java Co-authored-by: oSumAtrIX --- .../revanced/integrations/youtube/patches/VideoInformation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index 8525ce9ff7..e7d8700931 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -72,7 +72,6 @@ public static void initializeMdx(@NonNull Object mdxPlayerDirector) { mdxSeekMethod = mdxPlayerDirector.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE); mdxSeekMethod.setAccessible(true); - } catch (Exception ex) { Logger.printException(() -> "Failed to initialize MDX", ex); } From 1c6f469c831089cad769f354a76cd6e26deeca05 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Thu, 4 Jul 2024 00:22:58 +0400 Subject: [PATCH 5/6] Update app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Hoàng Gia Bảo <70064328+YT-Advanced@users.noreply.github.com> --- .../youtube/patches/VideoInformation.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index e7d8700931..fe740c37a5 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -208,16 +208,15 @@ public static boolean seekTo(final long seekTime) { // Try calling the seekTo method of the MDX player director (called when casting) if the player controller one failed. // The difference has to be a different second mark in order to avoid infinite skip loops (as the Lounge API only supports seconds). - if (Math.abs(adjustedSeekTime/1000 - videoTime/1000) >= 1) { - try { - //noinspection DataFlowIssue - return (Boolean) mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); - } catch (Exception ex) { - Logger.printInfo(() -> "seekTo (MDX) method call failed", ex); - return false; - } - } else { - Logger.printDebug(() -> "Skipping seekTo for MDX because of a small relative value (" + (seekTime - videoTime) + "ms)."); + if ((adjustedSeekTime / 1000) == (videoTime / 1000)) { + Logger.printDebug(() -> String.format("Skipping seekTo for MDX because of a small relative value (%d ms).", adjustedSeekTime - videoTime)); + return false; + } + try { + //noinspection DataFlowIssue + return (Boolean) mdxSeekMethod.invoke(mdxPlayerDirectorRef.get(), adjustedSeekTime); + } catch (Exception ex) { + Logger.printInfo(() -> "seekTo (MDX) method call failed", ex); return false; } From 17612e9c05052d378bfef95abcdd430376438041 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Thu, 4 Jul 2024 00:35:31 +0400 Subject: [PATCH 6/6] fix warnings, add some comments. --- .../integrations/youtube/patches/VideoInformation.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index fe740c37a5..5ef230400b 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -201,15 +201,17 @@ public static boolean seekTo(final long seekTime) { //noinspection DataFlowIssue if ((Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime)) { return true; - } + } // Else the video is loading or changing videos, or video is casting to a different device. } catch (Exception ex) { Logger.printInfo(() -> "seekTo method call failed", ex); } - // Try calling the seekTo method of the MDX player director (called when casting) if the player controller one failed. - // The difference has to be a different second mark in order to avoid infinite skip loops (as the Lounge API only supports seconds). + // Try calling the seekTo method of the MDX player director (called when casting). + // The difference has to be a different second mark in order to avoid infinite skip loops + // as the Lounge API only supports seconds. if ((adjustedSeekTime / 1000) == (videoTime / 1000)) { - Logger.printDebug(() -> String.format("Skipping seekTo for MDX because of a small relative value (%d ms).", adjustedSeekTime - videoTime)); + Logger.printDebug(() -> "Skipping seekTo for MDX because seek time is too small (" + + (adjustedSeekTime - videoTime) + "ms)"); return false; } try {