Skip to content
This repository has been archived by the owner on Oct 26, 2024. It is now read-only.

fix(YouTube - SponsorBlock): Skip segments when casting #655

Merged
merged 6 commits into from
Jul 10, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public final class VideoInformation {
private static final String SHORTS_PLAYER_PARAMETERS = "8AEB";

private static WeakReference<Object> playerControllerRef;
private static WeakReference<Object> mdxPlayerDirectorRef;
private static Method seekMethod;
private static Method mdxSeekMethod;

@NonNull
private static String videoId = "";
Expand Down Expand Up @@ -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);

LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception ex) {
Logger.printException(() -> "Failed to initialize MDX", ex);
}
}

/**
* Injection point.
*
Expand Down Expand Up @@ -178,8 +197,31 @@ public static boolean seekTo(final long seekTime) {
}

Logger.printDebug(() -> "Seeking to " + adjustedSeekTime);
//noinspection DataFlowIssue
return (Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime);

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 (Math.abs(adjustedSeekTime - videoTime) >= 1000) {
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
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).");
return false;
}

LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception ex) {
Logger.printException(() -> "Failed to seek", ex);
return false;
Expand Down
Loading