Repository navigation
[Feature]: Raise the 16x playback-speed cap (frame-seek preview + offline audio for fast segments) #79
Description
Search existing issues
- I have searched the existing issues
Is your feature request related to a problem?
Speed regions are currently capped at 16× (MAX_PLAYBACK_SPEED = 16 in src/components/video-editor/types.ts). For long recordings this is limiting: condensing a 2-hour capture into a short timelapse segment needs far more than 16× (at 16× a 2 h 11 m recording still takes ~8 minutes). Desktop editors commonly allow much more: CapCut desktop goes to 100×, Premiere Pro's Speed/Duration dialog to 10,000 % (100×), Final Cut Pro accepts arbitrary custom rates.
I dug into why the cap exists, and it is not arbitrary — it is a hard Chromium engine limit, but one that only binds two of the three speed-handling paths:
-
Chromium hard-caps
HTMLMediaElement.playbackRateto[0.0625, 16]. Verified on the exact engine Openscreen ships (Electron, Chromium 146):v.playbackRate = 16 → ok v.playbackRate = 16.1 → NotSupportedError: Failed to set the 'playbackRate' property on 'HTMLMediaElement': The provided playback rate (16.1) is not in the supported playback range. -
Two paths assign the region speed directly to
playbackRate, so they inherit the cap:- Editor preview:
videoEventHandlers.ts(video.playbackRate = activeSpeedRegion.speed), plus the webcam element and supplemental audio inVideoPlayback.tsx. - Export audio:
audioEncoder.ts→renderPitchPreservedTimelineAudio()plays the timeline in real time through a hidden<audio>element (forpreservesPitch) and captures it withMediaRecorder. Anything above 16× would throw.
- Editor preview:
-
The export video path is already unlimited.
streamingDecoder.tsretimes frames offline (sourceTime = segmentStart + (frameIndex / fps) × speed), so 100× video export works today — it is only fenced off by the UI cap.
There is also a practical preview constraint noted in types.ts ("above 16× the decoder can't keep up and the playhead stalls"), which any solution needs to respect: real-time decode at 16× of a 60 fps recording is already ~960 fps.
Describe the solution you'd like
Raise the cap to 100× (the de-facto industry ceiling — ffmpeg's atempo audio filter, Premiere's audio time remapping, and CapCut all cap at 100) by taking the two playbackRate-bound paths off the real-time engine for fast segments:
-
Preview, segments > 16×: rAF-driven seek stepping. Instead of letting the media element play, advance the playhead by
speed × Δtper animation frame and setvideo.currentTimeto the target. Visually this is the fast-slideshow behaviour native NLEs show at extreme rates. The existing native-playback path stays untouched for ≤ 16× segments, so today's smooth preview is not affected. -
Export audio, segments > 16×: drop real-time capture.
- Phase 1 (pragmatic): render silence for > 16× segments. At those rates audio carries no usable information anyway, and this matches what users get from timelapse features elsewhere. Segments ≤ 16× keep the current pitch-preserved real-time path.
- Phase 2 (optional follow-up): offline pitch-preserved time-stretch (WSOLA) in a worker fed by
AudioDecoder, reusing the streaming infrastructure from fix: stream large local recordings so the editor and export don't exhaust memory #74. This would give real audio up to 100× and, as a bonus, could eventually replace the real-time capture path entirely (audio export would no longer take output-duration wall-clock time).
-
UI: raise
MAX_PLAYBACK_SPEEDto 100, keep the preset list as is, and let the custom-speed input accept up to 100. Optionally hint in the speed popover that > 16× segments preview as frame-stepping and export with silenced (Phase 1) audio.
Describe alternatives you've considered
- Keep 16×: simplest, but condensing long recordings is a core screen-recording use case, and the video half of the work is already done.
- WebAudio
AudioBufferSourceNode.playbackRate: no pitch preservation and requires decoding the full track into memory, which conflicts with the large-recording streaming work from fix: stream large local recordings so the editor and export don't exhaust memory #74. - A "timelapse" toggle instead of higher speeds: avoids the audio question entirely, but a unified speed control up to 100× is more discoverable and matches user expectations from other editors.
Additional context
Comparison of caps elsewhere:
| Tool | Max speed | Approach |
|---|---|---|
| CapCut desktop | 100× | offline retiming, offline audio stretch |
| Premiere Pro | 10,000 % (time remapping 20,000 %) | offline; audio remap capped at 100× |
| Final Cut Pro | arbitrary custom | offline |
| ffmpeg | video unlimited (setpts); atempo 0.5–100 |
offline |
| Openscreen today | 16× | real-time playbackRate |
The pattern across tools: video retiming is effectively unlimited, ~100× is the recognised ceiling for meaningful audio, and every tool that exceeds 16× does so by not driving a real-time media element.
Activity
EtienneLescot commentedon Jul 7, 2026
@rainyflash seems a good idea to me.
would you be up to making a PR?
rainyflash commentedon Jul 7, 2026
Thanks @EtienneLescot — yes, happy to take this on.
I'll put up the full implementation: the ≤16× path stays exactly as it is today (native
playbackRate), and only faster segments switch to offline handling — frame-seek preview stepping plus offline pitch-preserved audio time-stretch — with the UI cap raised to 100×. I'll ping you here when it's ready for review.rainyflash commentedon Jul 8, 2026
PR is up: #80.
It keeps the ≤16× paths exactly as they are and only switches faster segments to offline handling — frame-seek preview stepping plus an offline pitch-preserved (WSOLA) audio time-stretch — with the custom-speed input cap raised to 100×. Video export already retimed offline with no ceiling, so that part needed no change.
Verified end-to-end (preview stepping + offline audio export) on macOS and Windows. Happy to adjust anything in review.
github-actions commentedon Jul 11, 2026
Fixed by #80 and merged into
main.This change is assigned to the
Next Releaserelease milestone and is not necessarily available in the latest downloadable desktop release yet. It is currently marked asstatus: pending releaseuntil a packaged release containing it is published.feat: raise playback-speed cap to 100x
EtienneLescot commentedon Jul 15, 2026
Moved into
v1.7.0as part of the pre-release cut.revert(speed): restore the 100x playback cap
revert(speed): restore the 100x playback cap
revert(speed): restore the 100x playback cap
revert(speed): restore the 100x playback cap