How to "retime" a video with FunscriptToolbox

I’ve added a new functionality to the toolbox: a Video Retimer.

To be honest, it might be a bit of a niche/gimmicky feature, but I was curious, so I built it. It allows you to “retime” a video—selectively speeding up, slowing down, or cutting specific parts of a video file—while automatically keeping your associated .funscript and .srt files perfectly synchronized to the new video timeline.

Common Use Cases:

  • “Story Mode” creation: Compress long, non-action or dialog sequences (e.g., in JAV scenes) by fast-forwarding through them rather than cutting them out entirely.
  • Tightening action: Compress long pauses and breaks between funscript actions (e.g., positional transitions, cunnilingus).
  • Speed modulation: Manually slow down or speed up specific actions (e.g., slowing down a handjob sequence by 20%).

How it works (3 New Verbs):

  • retimer.generatecontrol (alias: retimer.gen): Takes a video alongside its .funscript and/or .srt files to generate a draft .control.srt file. This blueprint automatically maps out active blocks and gaps based on your existing subtitle and funscript timings. You should then adjust that file to your liking (removing, extending or merging block), adding specific speed for some parts, etc.
  • retimer.rendervideo (alias: retimer.render): Reads the .control.srt blueprint and renders a new version of the video applying the speed rules. It also creates an .offsets.json map and automatically synchronizes the original .funscript and .srt files to match the new timeline.
  • retimer.syncassets (alias: retimer.sync): A standalone command that uses an existing .offsets.json file to re-synchronize your .funscript and .srt files. This allows you to modify your original subtitles or scripts in the future and instantly generate a synced version without re-rendering the video.
CLI Parameters / Options

1. retimer.generatecontrol

  • --video: (Required) Path to the original video file.
  • --sub-padding-before / --sub-padding-after: Padding in seconds added around a subtitle block (Default: 0.5).
  • --sub-gap-threshold: Minimum gap in seconds before a gap is considered a break in the scene (Default: 8.0).
  • --sub-density-window / --sub-isolated-threshold: Calculates if a subtitle is “isolated”. Looks at a window of time (Default: 30.0s) and flags the subtitle if the text covers less than the threshold (Default: 10% or 0.10).
  • --fun-padding-before / --fun-padding-after: Padding in seconds added around a funscript action (Default: 1.0).
  • --fun-gap-threshold: Time threshold to merge funscript actions together into a single block (Default: 10.0).
  • --allow-overlaps: If false, subtitles will be trimmed/removed to prevent overlapping with funscript action blocks. If true, allows them to overlap (Default: false).
  • --override: Overwrite the .control.srt file if it already exists (Default: false).

2. retimer.rendervideo

  • --original-video: (Required) Original input video file.
  • --retimed-video: Output video file. Defaults to <input>.retimed.mp4.
  • --default-speed-controlled: Speed multiplier for sections covered by the blueprint (Default: 1.0).
  • --default-speed-uncontrolled: Base speed multiplier for gaps not covered by the blueprint (Default: 10.0).
  • --max-uncontrolled-duration: Maximum allowed output duration (in seconds) for a fast-forwarded gap. If the gap would take longer than this to play, the speed is dynamically increased to hit this target (Default: 30.0).
  • --micro-gap-threshold: Gaps smaller than this (in seconds) between controlled blocks are absorbed to prevent tiny framerate jumps (Default: 0.5).
  • --encoding-video: FFmpeg parameters for video encoding (Default: -c:v libx265 -crf 20 -tag:v hvc1).
  • --encoding-audio: FFmpeg parameters for audio encoding (Default: -c:a aac).

3. retimer.syncassets

  • --original-video: (Required) Path to the original video (used to find original .srt/.funscript sidecars).
  • --retimed-video: Path to the retimed video to dictate the output path of the newly synced files. Defaults to <original-video>.retimed.mp4.
  • --offsets-map: Path to the .offsets.json file. Defaults to <retimed-video>.offsets.json.
  • --sync-video: [NOT IMPLEMENTED YET] If true, compares the new original video audio signature with the one stored in the .offset.json file to prevent syncing to the wrong file.

Timeline Rules & Control Tags:
By default, any time segment covered by a block in the .control.srt blueprint is considered a “controlled” section and plays at normal speed (1.0x). Any time segment not covered by a block is considered an “uncontrolled” gap and is automatically fast-forwarded (defaulting to 10.0x speed). (Note: Both default speeds can be adjusted using CLI arguments).

When editing the generated .control.srt blueprint, you can override the behavior of any specific block by adding the following tags to the subtitle text:

  • {Speed: X.X}: Alters the playback speed of that specific block (e.g., {Speed: 0.8} to slow down to 80%, or {Speed: 5} to speed up 5x).
  • {Cut}: Completely removes that block of time from the rendered video. The script and subtitles will automatically drop actions in this window and shift everything else to maintain perfect sync.

The application binary can be found here: github releases

Examples found here:
3DSVR-0223 - Azusa Ichinose - My younger brother’s Hot Girlfriend Slipped Into Bed
DSVR-1721 - Hikaru Miyanishi - Nipples Insensitivity