How YTLite Speed Control Works: A Deep Dive into YouTube's Playback Speed Tweaks
YTLite combines a custom hold-to-speed gesture with automatic default rate selection to give users fine-grained control over YouTube playback speed without relying on the native UI.
YTLite is an open-source iOS tweak that modifies the YouTube app to unlock advanced playback features. Understanding how YTLite speed control works requires examining its dual-mode architecture: a temporary speed boost triggered by a long-press gesture, and a persistent default rate applied automatically when videos load. Both features are implemented through Objective-C runtime hooks in the tweak's main source file.
The Two Speed Control Modes in YTLite
YTLite provides complementary approaches to speed management. Users can choose one or both depending on their viewing habits.
Hold-to-Speed: Temporary Rate Changes via Gesture
The hold-to-speed feature allows temporary speed changes while a finger remains pressed on the video player. This is implemented through a custom UILongPressGestureRecognizer injected into the player overlay.
Configuration and storage: Users select their preferred speed in Settings → Hold to speed. The choice is stored as speedIndex in YTLUserDefaults with a default value of 1 (Disabled). The available speeds are defined in a hardcoded array:
@[@0, @2.0, @0.25, @0.5, @0.75, @1.0, @1.25, @1.5, @1.75, @2.0, @3.0, @4.0, @5.0]
Index 0 serves as a sentinel for "Disabled," while index 1 (2.0) satisfies the native speed-master UI without being user-selectable.
Runtime implementation: In YTLite.x, the tweak hooks YTMainAppVideoPlayerOverlayView to inject the gesture recognizer:
%hook YTMainAppVideoPlayerOverlayView
- (void)setSeekAnywherePanGestureRecognizer:(id)arg1 {
if (ytlInt(@"speedIndex") == 0) return %orig; // Disabled: skip injection
UILongPressGestureRecognizer *longPress =
[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(speedmasterYtLite:)];
longPress.minimumPressDuration = 0.3;
[self addGestureRecognizer:longPress];
}
%new
- (void)speedmasterYtLite:(UILongPressGestureRecognizer *)gesture {
YTInlinePlayerScrubUserEducationView *edu = self.scrubUserEducationView;
manageSpeedmasterYTLite(gesture, self.delegate, edu);
}
%end
The helper function manageSpeedmasterYTLite handles state transitions:
static void manageSpeedmasterYTLite(UILongPressGestureRecognizer *gesture,
YTMainAppVideoPlayerOverlayViewController *delegate,
YTInlinePlayerScrubUserEducationView *edu) {
NSArray *speedLabels = @[@0, @2.0, @0.25, @0.5, @0.75, @1.0,
@1.25, @1.5, @1.75, @2.0, @3.0, @4.0, @5.0];
if (gesture.state == UIGestureRecognizerStateBegan) {
rateBeforeSpeedmaster = delegate.currentPlaybackRate;
[delegate setPlaybackRate:[speedLabels[ytlInt(@"speedIndex")] floatValue]];
[edu setVisible:YES];
} else if (gesture.state == UIGestureRecognizerStateEnded) {
[delegate setPlaybackRate:rateBeforeSpeedmaster];
[edu setVisible:NO];
}
}
The native YTSpeedmasterController is also hooked to redirect its long-press behavior to the same helper, ensuring consistency when the native speed-master UI is present.
Default Playback Rate: Automatic Speed on Video Load
The default playback rate feature automatically applies a user-selected speed whenever a new video begins playback. This eliminates the need to manually adjust speed for every video.
Configuration and storage: The setting is stored as autoSpeedIndex in YTLUserDefaults with a default of 3 (representing 1.0×). The speed array for this feature omits the sentinel values:
@[@0.25, @0.5, @0.75, @1.0, @1.25, @1.5, @1.75, @2.0, @3.0, @4.0, @5.0]
Runtime implementation: The feature hooks YTPlayerViewController to inject the speed change after video load:
%hook YTPlayerViewController
- (void)loadWithPlayerTransition:(id)arg1 playbackConfig:(id)arg2 {
%orig;
[self performSelector:@selector(setAutoSpeed) withObject:nil afterDelay:0.5];
}
%new
- (void)setAutoSpeed {
NSArray *speedLabels = @[@0.25, @0.5, @0.75, @1.0, @1.25,
@1.5, @1.75, @2.0, @3.0, @4.0, @5.0];
YTMainAppVideoPlayerOverlayViewController *ov =
(YTMainAppVideoPlayerOverlayViewController *)self.activeVideoPlayerOverlay;
[ov setPlaybackRate:[speedLabels[ytlInt(@"autoSpeedIndex")] floatValue]];
}
%end
The 0.5-second delay ensures the player overlay is fully initialized before the speed change is applied.
Key Implementation Files in the YTLite Repository
| File | Purpose | Key Components |
|---|---|---|
YTLite.x |
Core speed control implementation | speedmasterYtLite:, setAutoSpeed, manageSpeedmasterYTLite |
Settings.x |
User interface for speed selection | Speed picker UI, ytlSetInt calls for speedIndex and autoSpeedIndex |
Utils/YTLUserDefaults.m |
Default configuration values | Registration of speedIndex and autoSpeedIndex with default values |
The extra speed options (2.5×–5×) are implemented in a separate hook of YTVarispeedSwitchController, extending the native speed selection UI when the corresponding toggle is enabled.
Summary
-
YTLite speed control operates through two independent but complementary mechanisms: a hold-to-speed gesture for temporary changes and a default playback rate applied automatically on video load.
-
Both features rely on runtime injection into YouTube's native player classes (
YTMainAppVideoPlayerOverlayView,YTPlayerViewController) using the Logos hooking framework. -
Configuration persists through a custom
YTLUserDefaultswrapper, withspeedIndexcontrolling the gesture andautoSpeedIndexcontrolling the startup speed. -
The implementation reuses a centralized helper function (
manageSpeedmasterYTLite) to keep gesture handling consistent across native and injected interfaces.
Frequently Asked Questions
What speeds are available in YTLite's speed control?
YTLite supports playback rates from 0.25× to 5.0×, including granular options like 0.75×, 1.25×, and 1.75× that are often missing from native YouTube controls. The hold-to-speed feature additionally includes a special 2.0× entry at index 1 to satisfy the native speed-master UI's internal validation.
How does YTLite's hold-to-speed gesture differ from YouTube's native speed controls?
The hold-to-speed gesture in YTLite is a temporary speed change that only applies while the user maintains pressure on the screen. YouTube's native speed controls require navigating through menus and apply a persistent change until manually adjusted. YTLite's implementation also allows higher maximum speeds (up to 5×) than the native app typically permits.
Does YTLite remember the last speed I used?
YTLite provides two independent memory mechanisms: the hold-to-speed feature remembers your chosen speed index for the gesture, while the default playback rate feature remembers a separate speed that's applied automatically when each video loads. Neither automatically adapts based on your last-used speed in a session; both require explicit configuration through the Settings interface.
Where is the speed control configuration stored in YTLite?
Speed preferences are stored in NSUserDefaults through the YTLUserDefaults wrapper class in Utils/YTLUserDefaults.m. The keys are speedIndex (for hold-to-speed, default 1) and autoSpeedIndex (for default playback rate, default 3). These values persist across app launches and are registered with defaults on first initialization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →