mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 09:36:08 +00:00
feat(player): raise the playback speed ceiling off YouTube's limit
A single speed ladder fed both players, so the 2x cap that YouTube's iframe API enforces also applied to Bunny and R2, which are plain <video> elements the browser will play far faster. Pick the ladder per provider: YouTube keeps 0.25x-2x, the native ones go up to 16x, where Chrome and Firefox clamp playbackRate. The picker labels everything past 4x as "no audio", since that is where the browsers stop pitch-correcting and drop the audio track.
This commit is contained in:
@@ -6,11 +6,15 @@ import {
|
||||
getFrameStepLabel,
|
||||
getFrameStepSeconds,
|
||||
getPlayheadPercent,
|
||||
getSpeedOptionsForProvider,
|
||||
isTypingTarget,
|
||||
normalizeFrameRate,
|
||||
NATIVE_SPEED_OPTIONS,
|
||||
resolvePlayerShortcut,
|
||||
resolveSkipAmount,
|
||||
SILENT_ABOVE_SPEED,
|
||||
timeFromClientX,
|
||||
YOUTUBE_SPEED_OPTIONS,
|
||||
} from '@/components/video-page/hooks/video-player-utils';
|
||||
|
||||
const SPEEDS = [0.25, 0.5, 1, 1.5, 2];
|
||||
@@ -215,6 +219,34 @@ describe('getAdjacentPlaybackSpeed', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSpeedOptionsForProvider', () => {
|
||||
it('caps YouTube at 2x, since its iframe API ignores anything faster', () => {
|
||||
expect(getSpeedOptionsForProvider('youtube')).toBe(YOUTUBE_SPEED_OPTIONS);
|
||||
expect(Math.max(...YOUTUBE_SPEED_OPTIONS)).toBe(2);
|
||||
});
|
||||
|
||||
it('lets the <video> providers run up to the browser ceiling', () => {
|
||||
for (const provider of ['bunny', 'r2', undefined, null]) {
|
||||
expect(getSpeedOptionsForProvider(provider)).toBe(NATIVE_SPEED_OPTIONS);
|
||||
}
|
||||
expect(NATIVE_SPEED_OPTIONS).toContain(3);
|
||||
// 16 is where Chrome and Firefox clamp `playbackRate`; anything past it throws.
|
||||
expect(Math.max(...NATIVE_SPEED_OPTIONS)).toBe(16);
|
||||
});
|
||||
|
||||
it('marks the rates the browser plays without audio', () => {
|
||||
expect(SILENT_ABOVE_SPEED).toBe(4);
|
||||
expect(NATIVE_SPEED_OPTIONS.filter((speed) => speed > SILENT_ABOVE_SPEED)).toEqual([6, 8, 16]);
|
||||
expect(YOUTUBE_SPEED_OPTIONS.every((speed) => speed <= SILENT_ABOVE_SPEED)).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps both ladders ascending so the arrow-key stepping stays monotonic', () => {
|
||||
for (const ladder of [YOUTUBE_SPEED_OPTIONS, NATIVE_SPEED_OPTIONS]) {
|
||||
expect([...ladder].sort((a, b) => a - b)).toEqual(ladder);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolvePlayerShortcut', () => {
|
||||
it('maps the play/pause, seek, mute and fullscreen keys', () => {
|
||||
expect(resolvePlayerShortcut({ code: 'Space' })).toBe('toggle-play');
|
||||
|
||||
Reference in New Issue
Block a user