Add smoothing, improve seek, adjust sensitivity

This commit is contained in:
Bryce Hackel
2024-08-25 20:38:59 -07:00
parent aa5300f54f
commit 6aa1f62140

View File

@@ -668,6 +668,7 @@ BOOL isTabSelected = NO;
* for each zone. The zones are horizontal sections that divide the player into * for each zone. The zones are horizontal sections that divide the player into
* 3 equal parts. The choices are volume, brightness, seek, and disabled. * 3 equal parts. The choices are volume, brightness, seek, and disabled.
* There is also a deadzone that can be configured in the settings. * There is also a deadzone that can be configured in the settings.
* There are 4 logical states: initial, changed in deadzone, changed, end.
*/ */
%new %new
- (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { - (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer {
@@ -676,7 +677,7 @@ BOOL isTabSelected = NO;
// Variables for storing initial values to be adjusted // Variables for storing initial values to be adjusted
static float initialVolume; static float initialVolume;
static float initialBrightness; static float initialBrightness;
static CGFloat currentTime; static CGFloat initialTime;
// Flag to determine if the pan gesture is valid // Flag to determine if the pan gesture is valid
static BOOL isValidHorizontalPan = NO; static BOOL isValidHorizontalPan = NO;
// Variable to store the section of the screen the gesture is in // Variable to store the section of the screen the gesture is in
@@ -687,6 +688,10 @@ BOOL isTabSelected = NO;
static CGFloat deadzoneStartingXTranslation; static CGFloat deadzoneStartingXTranslation;
// Variable to track the X translation of the pan gesture after exiting the deadzone // Variable to track the X translation of the pan gesture after exiting the deadzone
static CGFloat adjustedTranslationX; static CGFloat adjustedTranslationX;
// Variable used to smooth out the X translation
static CGFloat smoothedTranslationX = 0;
// Constant for the filter constant to change responsiveness
static const CGFloat filterConstant = 0.1;
// Constant for the deadzone radius that can be changed in the settings // Constant for the deadzone radius that can be changed in the settings
static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone"); static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone");
// Constant for the sensitivity factor that can be changed in the settings // Constant for the sensitivity factor that can be changed in the settings
@@ -714,7 +719,7 @@ BOOL isTabSelected = NO;
/***** Helper functions for adjusting player state *****/ /***** Helper functions for adjusting player state *****/
// Helper function to adjust brightness // Helper function to adjust brightness
void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) {
float brightnessSensitivityFactor = 2.0; float brightnessSensitivityFactor = 3;
float newBrightness = initialBrightness + ((translationX / 1000.0) * sensitivityFactor * brightnessSensitivityFactor); float newBrightness = initialBrightness + ((translationX / 1000.0) * sensitivityFactor * brightnessSensitivityFactor);
newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0); newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0);
[[UIScreen mainScreen] setBrightness:newBrightness]; [[UIScreen mainScreen] setBrightness:newBrightness];
@@ -722,7 +727,7 @@ BOOL isTabSelected = NO;
// Helper function to adjust volume // Helper function to adjust volume
void (^adjustVolume)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialVolume) { void (^adjustVolume)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialVolume) {
float volumeSensitivityFactor = 2.0; float volumeSensitivityFactor = 3.0;
float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor); float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor);
newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); newVolume = fmaxf(fminf(newVolume, 1.0), 0.0);
// https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4
@@ -733,18 +738,25 @@ BOOL isTabSelected = NO;
}; };
// Helper function to adjust seek time // Helper function to adjust seek time
// void (^adjustSeek)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat currentTime) { void (^adjustSeek)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialTime) {
// // Calculate a seek fraction based on the horizontal translation // Get the location in view for the current video time
// CGFloat totalDuration = self.currentVideoTotalMediaTime; CGFloat totalTime = self.currentVideoTotalMediaTime;
// CGFloat viewWidth = self.view.bounds.size.width; CGFloat videoFraction = initialTime / totalTime;
// CGFloat seekFraction = (translationX / viewWidth); CGFloat initialTimeXPosition = scrubXForScrubRange(videoFraction);
// // Calculate the new seek time based on the calculated offset // Calculate the new seek X position
// CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive
// seekFraction = sensitivityFactor * seekFraction; CGFloat newSeekXPosition = initialTimeXPosition + translationX * sensitivityFactor;
// CGFloat seekTime = currentTime + totalDuration * seekFraction; // Create a CGPoint using this new X position
// // Seek to the new time CGPoint newSeekPoint = CGPointMake(newSeekXPosition, 0);
// [playerBarController inlinePlayerBarContainerView:playerBar didFineScrubToTime:seekTime]; // Send this to a seek method in the player bar controller
// }; [playerBarController didScrbToPoint:newSeekPoint];
};
// Helper function to smooth out the X translation
CGFloat (^applyLowPassFilter)(CGFloat) = ^(CGFloat newTranslation) {
smoothedTranslationX = filterConstant * newTranslation + (1 - filterConstant) * smoothedTranslationX;
return smoothedTranslationX;
};
/***** Helper functions for running the selected gesture *****/ /***** Helper functions for running the selected gesture *****/
// Helper function to run any setup for the selected gesture mode // Helper function to run any setup for the selected gesture mode
@@ -754,18 +766,15 @@ BOOL isTabSelected = NO;
// Handle the setup based on the selected mode // Handle the setup based on the selected mode
switch (selectedGestureMode) { switch (selectedGestureMode) {
case GestureModeVolume: case GestureModeVolume:
// Store initial volume value
initialVolume = [[AVAudioSession sharedInstance] outputVolume]; initialVolume = [[AVAudioSession sharedInstance] outputVolume];
break; break;
case GestureModeBrightness: case GestureModeBrightness:
// Store the initial brightness value
initialBrightness = [UIScreen mainScreen].brightness; initialBrightness = [UIScreen mainScreen].brightness;
break; break;
case GestureModeSeek: case GestureModeSeek:
// Store the current time value initialTime = self.currentVideoMediaTime;
currentTime = self.currentVideoMediaTime;
// Start a seek action // Start a seek action
[playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; [playerBarController startScrubbing];
break; break;
case GestureModeDisabled: case GestureModeDisabled:
// Do nothing if the gesture is disabled // Do nothing if the gesture is disabled
@@ -793,8 +802,7 @@ BOOL isTabSelected = NO;
adjustBrightness(adjustedTranslationX, initialBrightness); adjustBrightness(adjustedTranslationX, initialBrightness);
break; break;
case GestureModeSeek: case GestureModeSeek:
// adjustSeek(adjustedTranslationX, currentTime); adjustSeek(adjustedTranslationX, initialTime);
[playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer];
break; break;
case GestureModeDisabled: case GestureModeDisabled:
// Do nothing if the gesture is disabled // Do nothing if the gesture is disabled
@@ -820,7 +828,7 @@ BOOL isTabSelected = NO;
case GestureModeBrightness: case GestureModeBrightness:
break; break;
case GestureModeSeek: case GestureModeSeek:
[playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; [playerBarController endScrubbingForSeekSource:0];
break; break;
case GestureModeDisabled: case GestureModeDisabled:
break; break;
@@ -907,6 +915,8 @@ BOOL isTabSelected = NO;
if (isValidHorizontalPan) { if (isValidHorizontalPan) {
// Adjust the X translation based on the value hit after exiting the deadzone // Adjust the X translation based on the value hit after exiting the deadzone
adjustedTranslationX = translation.x - deadzoneStartingXTranslation; adjustedTranslationX = translation.x - deadzoneStartingXTranslation;
// Smooth the translation value
adjustedTranslationX = applyLowPassFilter(adjustedTranslationX);
// Pass the adjusted translation to the selected gesture // Pass the adjusted translation to the selected gesture
switch (gestureSection) { switch (gestureSection) {
case GestureSectionTop: case GestureSectionTop:
@@ -925,26 +935,25 @@ BOOL isTabSelected = NO;
} }
} }
} }
if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
if (isValidHorizontalPan) { // Handle the gesture end state by running the selected gesture mode's end action
// Handle the gesture based on the identified section if (panGestureRecognizer.state == UIGestureRecognizerStateEnded && isValidHorizontalPan) {
switch (gestureSection) { switch (gestureSection) {
case GestureSectionTop: case GestureSectionTop:
runSelectedGestureEnded(@"playerGestureTopSelection"); runSelectedGestureEnded(@"playerGestureTopSelection");
break; break;
case GestureSectionMiddle: case GestureSectionMiddle:
runSelectedGestureEnded(@"playerGestureMiddleSelection"); runSelectedGestureEnded(@"playerGestureMiddleSelection");
break; break;
case GestureSectionBottom: case GestureSectionBottom:
runSelectedGestureEnded(@"playerGestureBottomSelection"); runSelectedGestureEnded(@"playerGestureBottomSelection");
break; break;
default: default:
break; break;
}
// Provide haptic feedback upon successful gesture recognition
// [feedbackGenerator prepare];
// [feedbackGenerator impactOccurred];
} }
// Provide haptic feedback upon successful gesture recognition
// [feedbackGenerator prepare];
// [feedbackGenerator impactOccurred];
} }
} }