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

Commit

Permalink
fix(YouTube - SponsorBlock): Skip segments when casting
Browse files Browse the repository at this point in the history
  • Loading branch information
inotia00 authored and Francesco146 committed Jul 14, 2024
1 parent 80b8058 commit 6d2d33d
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class AlwaysRepeatPatch {
* @return video is repeated.
*/
public static boolean alwaysRepeat() {
return alwaysRepeatEnabled() && VideoInformation.overrideVideoTime(0);
return alwaysRepeatEnabled() && VideoInformation.seekTo(0);
}

public static boolean alwaysRepeatEnabled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ private static void reloadVideo(final long videoLength) {
final long lastVideoTime = VideoInformation.getVideoTime();
final float playbackSpeed = VideoInformation.getPlaybackSpeed();
final long speedAdjustedTimeThreshold = (long) (playbackSpeed * 300);
VideoInformation.overrideVideoTime(videoLength);
VideoInformation.overrideVideoTime(lastVideoTime + speedAdjustedTimeThreshold);
VideoInformation.seekTo(videoLength);
VideoInformation.seekTo(lastVideoTime + speedAdjustedTimeThreshold);

if (!Settings.SKIP_PRELOADED_BUFFER_TOAST.get())
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import app.revanced.integrations.shared.utils.Logger;
import app.revanced.integrations.shared.utils.Utils;
Expand All @@ -23,11 +26,17 @@ public final class VideoInformation {
private static final float DEFAULT_YOUTUBE_PLAYBACK_SPEED = 1.0f;
private static final int DEFAULT_YOUTUBE_VIDEO_QUALITY = -2;
private static final String DEFAULT_YOUTUBE_VIDEO_QUALITY_STRING = getString("quality_auto");
private static final String SEEK_METHOD_NAME = "seekTo";
/**
* Prefix present in all Short player parameters signature.
*/
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 channelId = "";
@NonNull
Expand Down Expand Up @@ -65,13 +74,39 @@ public final class VideoInformation {

/**
* Injection point.
*
* @param playerController player controller object.
*/
public static void initialize() {
videoLength = 0;
videoTime = -1;
public static void initialize(@NonNull Object playerController) {
try {
playerControllerRef = new WeakReference<>(Objects.requireNonNull(playerController));
videoTime = -1;
videoLength = 0;
playbackSpeed = DEFAULT_YOUTUBE_PLAYBACK_SPEED;

seekMethod = playerController.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
seekMethod.setAccessible(true);
} catch (Exception ex) {
Logger.printException(() -> "Failed to initialize", ex);
}
}

/**
* 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 MDX", ex);
}
}

@Deprecated
public static boolean seekTo(final long seekTime) {
return seekTo(seekTime, getVideoLength());
}
Expand All @@ -89,10 +124,34 @@ public static boolean seekTo(final long seekTime) {
public static boolean seekTo(final long seekTime, final long videoLength) {
Utils.verifyOnMainThread();
try {
final long videoTime = getVideoTime();
final long adjustedSeekTime = getAdjustedSeekTime(seekTime, videoLength);

Logger.printDebug(() -> "Seeking to " + getFormattedTimeStamp(adjustedSeekTime));
return overrideVideoTime(adjustedSeekTime);
try {
//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).
// 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(() -> "Skipping seekTo for MDX because seek time is too small ("
+ (adjustedSeekTime - videoTime) + "ms)");
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;
}
} catch (Exception ex) {
Logger.printException(() -> "Failed to seek", ex);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public static void clearData() {
* Injection point.
* Initializes SponsorBlock when the video player starts playing a new video.
*/
public static void initialize() {
public static void initialize(@NonNull Object ignoredPlayerController) {
try {
Utils.verifyOnMainThread();
SponsorBlockSettings.initialize();
Expand Down

0 comments on commit 6d2d33d

Please sign in to comment.