feat(video-information): hook video time

This commit is contained in:
oSumAtrIX 2022-11-05 06:24:07 +01:00
parent 98eaf9c3f2
commit 6aa0ca9556
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
2 changed files with 45 additions and 28 deletions

View File

@ -9,14 +9,17 @@ import java.lang.reflect.Method;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
/** /**
* Hooking class for the player controller. * Hooking class for the current playing video.
*/ */
public final class PlayerControllerPatch { public final class VideoInformation {
private static final String SEEK_METHOD_NAME = "seekTo"; private static final String SEEK_METHOD_NAME = "seekTo";
private static WeakReference<Object> playerController; private static WeakReference<Object> playerController;
private static Method seekMethod; private static Method seekMethod;
private static long videoLength = 1; private static long videoLength = 1;
private static long videoTime = -1;
/** /**
* Hook into PlayerController.onCreate() method. * Hook into PlayerController.onCreate() method.
@ -26,26 +29,36 @@ public final class PlayerControllerPatch {
public static void playerController_onCreateHook(final Object thisRef) { public static void playerController_onCreateHook(final Object thisRef) {
playerController = new WeakReference<>(thisRef); playerController = new WeakReference<>(thisRef);
videoLength = 1; videoLength = 1;
videoTime = -1;
try { try {
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE); seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
seekMethod.setAccessible(true); seekMethod.setAccessible(true);
} catch (NoSuchMethodException ex) { } catch (NoSuchMethodException ex) {
LogHelper.debug(PlayerControllerPatch.class, "Failed to initialize: " + ex.getMessage()); LogHelper.debug(VideoInformation.class, "Failed to initialize: " + ex.getMessage());
} }
} }
/** /**
* Set the current video length. * Set the video length.
* *
* @param length The length of the video in milliseconds. * @param length The length of the video in milliseconds.
*/ */
public static void setCurrentVideoLength(final long length) { public static void setVideoLength(final long length) {
LogHelper.debug(PlayerControllerPatch.class, "Setting current video length to " + length); LogHelper.debug(VideoInformation.class, "Setting current video length to " + length);
videoLength = length; videoLength = length;
} }
/**
* Set the video time.
*
* @param time The time of the video in milliseconds.
*/
public static void setVideoTime(final long time) {
LogHelper.debug(VideoInformation.class, "Current video time " + time);
videoTime = time;
}
/** /**
* Seek on the current video. * Seek on the current video.
* *
@ -54,15 +67,15 @@ public final class PlayerControllerPatch {
public static void seekTo(final long millisecond) { public static void seekTo(final long millisecond) {
new Handler(Looper.getMainLooper()).post(() -> { new Handler(Looper.getMainLooper()).post(() -> {
if (seekMethod == null) { if (seekMethod == null) {
LogHelper.debug(PlayerControllerPatch.class, "seekMethod was null"); LogHelper.debug(VideoInformation.class, "seekMethod was null");
return; return;
} }
try { try {
LogHelper.debug(PlayerControllerPatch.class, "Seeking to " + millisecond); LogHelper.debug(VideoInformation.class, "Seeking to " + millisecond);
seekMethod.invoke(playerController.get(), millisecond); seekMethod.invoke(playerController.get(), millisecond);
} catch (Exception ex) { } catch (Exception ex) {
LogHelper.debug(PlayerControllerPatch.class, "Failed to seek: " + ex.getMessage()); LogHelper.debug(VideoInformation.class, "Failed to seek: " + ex.getMessage());
} }
}); });
} }
@ -70,9 +83,18 @@ public final class PlayerControllerPatch {
/** /**
* Get the length of the current video playing. * Get the length of the current video playing.
* *
* @return The length of the video in milliseconds. * @return The length of the video in milliseconds. 1 if not set yet.
*/ */
public static long getCurrentVideoLength() { public static long getCurrentVideoLength() {
return videoLength; return videoLength;
}
/**
* Get the time of the current video playing.
*
* @return The time of the video in milliseconds. -1 if not set yet.
*/
public static long getVideoTime() {
return videoTime;
} }
} }

View File

@ -19,7 +19,7 @@ import java.util.Arrays;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import app.revanced.integrations.patches.PlayerControllerPatch; import app.revanced.integrations.patches.VideoInformation;
import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.sponsorblock.objects.SponsorSegment; import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
import app.revanced.integrations.sponsorblock.requests.SBRequester; import app.revanced.integrations.sponsorblock.requests.SBRequester;
@ -102,20 +102,18 @@ public class PlayerController {
} }
sponsorSegmentsOfCurrentVideo = segments; sponsorSegmentsOfCurrentVideo = segments;
// new Handler(Looper.getMainLooper()).post(findAndSkipSegmentRunnable); // new Handler(Looper.getMainLooper()).post(findAndSkipSegmentRunnable);
} }
/**
* Called when it's time to update the UI with new second, about once per second, only when playing, also in background public static void setVideoTime(long millis) {
*/
public static void setCurrentVideoTime(long millis) {
LogHelper.debug(PlayerController.class, "setCurrentVideoTime: current video time: " + millis); LogHelper.debug(PlayerController.class, "setCurrentVideoTime: current video time: " + millis);
if (!SettingsEnum.SB_ENABLED.getBoolean()) return; if (!SettingsEnum.SB_ENABLED.getBoolean()) return;
lastKnownVideoTime = millis; lastKnownVideoTime = millis;
if (millis <= 0) return; if (millis <= 0) return;
//findAndSkipSegment(false); //findAndSkipSegment(false);
if (millis == PlayerControllerPatch.getCurrentVideoLength()) { if (millis == VideoInformation.getCurrentVideoLength()) {
SponsorBlockUtils.hideShieldButton(); SponsorBlockUtils.hideShieldButton();
SponsorBlockUtils.hideVoteButton(); SponsorBlockUtils.hideVoteButton();
return; return;
@ -187,22 +185,19 @@ public class PlayerController {
}).start(); }).start();
} }
/** public static void setHighPrecisionVideoTime(final long millis) {
* Called very high frequency (once every about 100ms), also in background. It sometimes triggers when a video is paused (couple times in the row with the same value) if ((millis < lastKnownVideoTime && lastKnownVideoTime >= VideoInformation.getCurrentVideoLength()) || millis == 0) {
*/
public static void setCurrentVideoTimeHighPrecision(final long millis) {
if ((millis < lastKnownVideoTime && lastKnownVideoTime >= PlayerControllerPatch.getCurrentVideoLength()) || millis == 0) {
SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again
SponsorBlockUtils.showVoteButton(); SponsorBlockUtils.showVoteButton();
} }
if (lastKnownVideoTime > 0) { if (lastKnownVideoTime > 0) {
lastKnownVideoTime = millis; lastKnownVideoTime = millis;
} else } else
setCurrentVideoTime(millis); setVideoTime(millis);
} }
public static long getCurrentVideoLength() { public static long getCurrentVideoLength() {
return PlayerControllerPatch.getCurrentVideoLength(); return VideoInformation.getCurrentVideoLength();
} }
public static long getLastKnownVideoTime() { public static long getLastKnownVideoTime() {
@ -296,7 +291,7 @@ public class PlayerController {
final float absoluteLeft = sponsorBarLeft; final float absoluteLeft = sponsorBarLeft;
final float absoluteRight = sponsorBarRight; final float absoluteRight = sponsorBarRight;
final float tmp1 = 1f / (float) PlayerControllerPatch.getCurrentVideoLength() * (absoluteRight - absoluteLeft); final float tmp1 = 1f / (float) VideoInformation.getCurrentVideoLength() * (absoluteRight - absoluteLeft);
for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) {
float left = segment.start * tmp1 + absoluteLeft; float left = segment.start * tmp1 + absoluteLeft;
float right = segment.end * tmp1 + absoluteLeft; float right = segment.end * tmp1 + absoluteLeft;
@ -330,7 +325,7 @@ public class PlayerController {
try { try {
LogHelper.debug(PlayerController.class, "Skipping to millis=" + finalMillisecond); LogHelper.debug(PlayerController.class, "Skipping to millis=" + finalMillisecond);
lastKnownVideoTime = finalMillisecond; lastKnownVideoTime = finalMillisecond;
PlayerControllerPatch.seekTo(finalMillisecond); VideoInformation.seekTo(finalMillisecond);
} catch (Exception e) { } catch (Exception e) {
LogHelper.printException(PlayerController.class, "Cannot skip to millisecond", e); LogHelper.printException(PlayerController.class, "Cannot skip to millisecond", e);
} }