mirror of
https://github.com/SoPat712/YTLitePlus.git
synced 2025-10-30 12:33:57 -04:00
195 lines
8.5 KiB
Plaintext
195 lines
8.5 KiB
Plaintext
//
|
|
// YTHFSTweak.x
|
|
//
|
|
// Created by Joshua Seltzer on 12/5/22.
|
|
//
|
|
//
|
|
|
|
#import "YTHFSHeaders.h"
|
|
#import "YTHFSPrefsManager.h"
|
|
|
|
@interface YTPlayerViewController (YTHFS)
|
|
|
|
// the long press gesture that will be created and added to the player view
|
|
@property (nonatomic, retain) UILongPressGestureRecognizer *YTHFSLongPressGesture;
|
|
|
|
// switch between the user-selected playback rate and the normal playback rate, invoked either via the hold gesture or
|
|
// automatically when the video starts (dependent on settings)
|
|
- (void)YTHFSSwitchPlaybackRate;
|
|
|
|
@end
|
|
|
|
// define some non-configurable defaults for the long press gesture
|
|
#define kYTHFSNormalPlaybackRate 1.0
|
|
#define kYTHFSNumTouchesRequired 1
|
|
#define kYTHFSAllowableMovement 50
|
|
|
|
// the static variables to keep track of the settings which shall persist until the YTPlayerViewController is recreated
|
|
static CGFloat sYTHFSTogglePlaybackRate;
|
|
static BOOL sYTHFSHapticFeedbackEnabled;
|
|
static BOOL sYTHFSAutoApplyRateEnabled;
|
|
|
|
// enum to define the direction of the playback rate feedback indicator
|
|
typedef enum YTHFSFeedbackDirection : NSInteger {
|
|
kYTHFSFeedbackDirectionForward,
|
|
kYTHFSFeedbackDirectionBackward
|
|
} YTHFSFeedbackDirection;
|
|
|
|
%hook YTWatchLayerViewController
|
|
|
|
// invoked when the player view controller is either created or destroyed
|
|
- (void)watchController:(YTWatchController *)watchController didSetPlayerViewController:(YTPlayerViewController *)playerViewController
|
|
{
|
|
if (playerViewController) {
|
|
// grab the state of the settings for this instance of the player view controller
|
|
sYTHFSTogglePlaybackRate = [YTHFSPrefsManager togglePlaybackRate];
|
|
sYTHFSHapticFeedbackEnabled = [YTHFSPrefsManager hapticFeedbackEnabled];
|
|
|
|
// check to see if the toggle rate should automatically be applied when the video starts
|
|
sYTHFSAutoApplyRateEnabled = [YTHFSPrefsManager autoApplyRateEnabled];
|
|
|
|
// add a long press gesture to configure the playback rate
|
|
if ([YTHFSPrefsManager holdGestureEnabled]) {
|
|
// check to see if the long press gesture is already created
|
|
if (!playerViewController.YTHFSLongPressGesture) {
|
|
playerViewController.YTHFSLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:playerViewController
|
|
action:@selector(YTHFSHandleLongPressGesture:)];
|
|
playerViewController.YTHFSLongPressGesture.numberOfTouchesRequired = kYTHFSNumTouchesRequired;
|
|
playerViewController.YTHFSLongPressGesture.allowableMovement = kYTHFSAllowableMovement;
|
|
[playerViewController.playerView addGestureRecognizer:playerViewController.YTHFSLongPressGesture];
|
|
}
|
|
|
|
// update the minimum press duration with whatever the user set in the settings
|
|
playerViewController.YTHFSLongPressGesture.minimumPressDuration = [YTHFSPrefsManager holdDuration];
|
|
}
|
|
}
|
|
|
|
%orig;
|
|
}
|
|
|
|
%end
|
|
|
|
%hook YTPlayerViewController
|
|
|
|
// the long press gesture that will be created and added to the player view
|
|
%property (nonatomic, retain) UILongPressGestureRecognizer *YTHFSLongPressGesture;
|
|
|
|
%new
|
|
- (void)YTHFSHandleLongPressGesture:(UILongPressGestureRecognizer *)longPressGestureRecognizer
|
|
{
|
|
if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan && [self.contentVideoPlayerOverlay isKindOfClass:objc_getClass("YTMainAppVideoPlayerOverlayViewController")]) {
|
|
YTMainAppVideoPlayerOverlayViewController *overlayViewController = (YTMainAppVideoPlayerOverlayViewController *)self.contentVideoPlayerOverlay;
|
|
if (overlayViewController.isVarispeedAvailable) {
|
|
[self YTHFSSwitchPlaybackRate];
|
|
}
|
|
}
|
|
}
|
|
|
|
%new
|
|
- (void)YTHFSSwitchPlaybackRate
|
|
{
|
|
NSString *feedbackTitle = nil;
|
|
YTHFSFeedbackDirection feedbackDirection = kYTHFSFeedbackDirectionForward;
|
|
CGFloat currentPlaybackRate = [self currentPlaybackRateForVarispeedSwitchController:self.varispeedController];
|
|
if (currentPlaybackRate != sYTHFSTogglePlaybackRate) {
|
|
// change to the toggle rate if the current playback rate is any other speed
|
|
[self varispeedSwitchController:self.varispeedController didSelectRate:sYTHFSTogglePlaybackRate];
|
|
feedbackTitle = [YTHFSPrefsManager playbackRateStringForValue:sYTHFSTogglePlaybackRate];
|
|
if (currentPlaybackRate > sYTHFSTogglePlaybackRate) {
|
|
feedbackDirection = kYTHFSFeedbackDirectionBackward;
|
|
}
|
|
} else {
|
|
// otherwise switch back to the default rate
|
|
[self varispeedSwitchController:self.varispeedController didSelectRate:kYTHFSNormalPlaybackRate];
|
|
feedbackTitle = [YTHFSPrefsManager localizedStringForKey:@"NORMAL" withDefaultValue:@"Normal"];
|
|
if (currentPlaybackRate > kYTHFSNormalPlaybackRate) {
|
|
feedbackDirection = kYTHFSFeedbackDirectionBackward;
|
|
}
|
|
}
|
|
|
|
// if the overlay controls are displayed, ensure to hide them before displaying the visual indicator
|
|
if (![self arePlayerControlsHidden] && [self.contentVideoPlayerOverlay isKindOfClass:objc_getClass("YTMainAppVideoPlayerOverlayViewController")]) {
|
|
YTMainAppVideoPlayerOverlayViewController *overlayViewController = (YTMainAppVideoPlayerOverlayViewController *)self.contentVideoPlayerOverlay;
|
|
[overlayViewController hidePlayerControlsAnimated:YES];
|
|
}
|
|
|
|
// trigger the double tap to seek view to visibly indicate that the playback rate has changed
|
|
if ([self.playerView.overlayView isKindOfClass:objc_getClass("YTMainAppVideoPlayerOverlayView")]) {
|
|
YTMainAppVideoPlayerOverlayView *overlayView = (YTMainAppVideoPlayerOverlayView *)self.playerView.overlayView;
|
|
[overlayView.doubleTapToSeekView showCenteredSeekFeedbackWithTitle:feedbackTitle direction:feedbackDirection];
|
|
}
|
|
|
|
// fire off haptic feedback to indicate that the playback rate changed (only applies to supported devices if enabled)
|
|
if (sYTHFSHapticFeedbackEnabled) {
|
|
UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init];
|
|
[feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess];
|
|
feedbackGenerator = nil;
|
|
}
|
|
}
|
|
|
|
// invoked when a video (or ad) is activated inside the player
|
|
- (void)playbackController:(id)localPlaybackController didActivateVideo:(id)singleVideoController withPlaybackData:(id)playbackData
|
|
{
|
|
%orig;
|
|
|
|
if (sYTHFSAutoApplyRateEnabled && [self.contentVideoPlayerOverlay isKindOfClass:objc_getClass("YTMainAppVideoPlayerOverlayViewController")]) {
|
|
YTMainAppVideoPlayerOverlayViewController *overlayViewController = (YTMainAppVideoPlayerOverlayViewController *)self.contentVideoPlayerOverlay;
|
|
if (overlayViewController.isVarispeedAvailable) {
|
|
// regardless of the current playback rate, at this point we know that the toggle rate will be applied
|
|
sYTHFSAutoApplyRateEnabled = NO;
|
|
|
|
// compare whether or not the current playback rate is what the user selected and if not, change to it now
|
|
if ([self currentPlaybackRateForVarispeedSwitchController:self.varispeedController] != sYTHFSTogglePlaybackRate) {
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
[self YTHFSSwitchPlaybackRate];
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
// remove and destroy the gesture recognizer if it exists
|
|
if (self.YTHFSLongPressGesture) {
|
|
[self.playerView removeGestureRecognizer:self.YTHFSLongPressGesture];
|
|
self.YTHFSLongPressGesture = nil;
|
|
}
|
|
|
|
%orig;
|
|
}
|
|
|
|
%end
|
|
|
|
%hook YTMainAppVideoPlayerOverlayView
|
|
|
|
// override the long press gesture recognizer that is used to invoke the seek gesture
|
|
- (void)setSeekAnywhereLongPressGestureRecognizer:(UILongPressGestureRecognizer *)longPressGestureRecognizer
|
|
{
|
|
if (![YTHFSPrefsManager holdGestureEnabled]) {
|
|
%orig;
|
|
}
|
|
}
|
|
|
|
// override the pan gesture recognizer that is used to invoke the seek gesture
|
|
- (void)setSeekAnywherePanGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognzier
|
|
{
|
|
if (![YTHFSPrefsManager holdGestureEnabled]) {
|
|
%orig;
|
|
}
|
|
}
|
|
|
|
// override the long press gesture recognizer that is used to invoke the seek gesture (introduced with YouTube 18.05.2)
|
|
- (void)setLongPressGestureRecognizer:(UILongPressGestureRecognizer *)longPressGestureRecognizer
|
|
{
|
|
if (![YTHFSPrefsManager holdGestureEnabled]) {
|
|
%orig;
|
|
}
|
|
}
|
|
|
|
%end
|
|
|
|
%ctor {
|
|
// ensure that the default preferences are available
|
|
[YTHFSPrefsManager registerDefaults];
|
|
} |