npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

smooth-video-warp

v0.1.1

Published

Smoothly compress long stretches of video into short, watchable time warps.

Readme

smooth-video-warp

Smoothly compress long stretches of video into short, watchable time warps.

smooth-video-warp takes a video clip and compresses it to a requested duration while:

  • starting at normal playback speed
  • accelerating smoothly
  • reaching maximum speed at the midpoint
  • decelerating symmetrically
  • finishing at normal playback speed

Rather than abruptly switching from 1× to some arbitrary fast-forward speed, smooth-video-warp calculates the piecewise constant jerk required to fit the complete source video into the requested target duration.

The result is a smooth, symmetric time warp suitable for software demonstrations, AI agent workflows, builds, renders and other recordings where elapsed work should remain visible without making the viewer wait for it.

1× ─────╮
         ╰───────────────╮
                          ╰── peak ──╮
                                     ╰───────────────╮
                                                      ╰───── 1×

The video is not cut.

Time is compressed.


Example

Given a 37 minute 15 second recording:

37m 15s = 2235 seconds

compress it to 18 seconds:

smooth-video-warp agent-working.mp4 --duration 18 --output agent-working.warped.mp4

smooth-video-warp probes the source duration and calculates the warp required to satisfy the requested target duration exactly. It prints a report:

Source duration:     37m 15.000s
Target duration:     18.000s
Average speed:       124.1667×
Peak speed:          247.3333×
Jerk:                12.164609 s⁻²

and, because --output was given, writes the warped video to agent-working.warped.mp4.

Playback begins at:

1.00×

accelerates continuously to:

247.33×

at the midpoint then follows the exact reverse profile back to:

1.00×

at the end.

The caller does not choose the peak playback speed or jerk.

They fall out of the source duration, requested target duration and warp model.


Installation

Requirements

Runtime requirements:

  • Node.js
  • FFmpeg
  • ffprobe

ffmpeg and ffprobe must be available on the system PATH.

Check with:

node --version
ffmpeg -version
ffprobe -version

npm

npm install -g smooth-video-warp

This installs the:

smooth-video-warp

binary.


Usage

smooth-video-warp <input> --duration <seconds> [--output <path>] [--samples <n>] [--fps <rate>]

--duration specifies the desired duration of the warped output in seconds, and is the only required option. The entire input file is warped.

smooth-video-warp only prints the report unless --output <path> is given. Without --output, no file is written — the command reports the source duration, target duration, average speed, peak speed and jerk, and exits. With --output <path>, the warped video is rendered and written to exactly that path.

# report only — nothing is written
smooth-video-warp agent-working.mp4 --duration 18

# render the warped video to the given path
smooth-video-warp agent-working.mp4 --duration 18 --output agent-working.warped.mp4

--samples and --fps only affect rendering and are refused if --output is not given:

  • --samples <n> — how many source frames are averaged together per output frame (default 64).
  • --fps <rate> — the output frame rate, as a decimal (30) or exact rational (30000/1001). Defaults to the source's own frame rate.

smooth-video-warp deliberately does not provide timeline editing. If only part of a longer recording should be compressed, split that section into its own video first.

For example:

presentation.mp4
        │
        ├── normal section
        │
        ├── agent-working.mp4   ← warp this
        │
        └── normal section

Then:

smooth-video-warp agent-working.mp4 --duration 12 --output agent-working.warped.mp4

The resulting warped clip can be placed back into the presentation using the editor of your choice.


The warp model

smooth-video-warp uses a symmetric piecewise constant-jerk motion profile.

The easiest way to understand the maths is to treat:

source video time as position

and:

output video time as time

Let:

D = source duration
T = target duration
t = current output time
x(t) = source timestamp displayed at output time t
v(t) = instantaneous playback speed
a(t) = acceleration of playback speed
j(t) = jerk

Then:

$$ v(t)=x'(t) $$

$$ a(t)=x''(t) $$

and:

$$ j(t)=x'''(t) $$

A playback speed of:

$$ v(t)=7.32 $$

therefore means:

Speed ×7.32

and:

$$ x(t)=6324.043 $$

means the source timestamp is:

Time 01h 45m 24.043s

Why jerk?

An abrupt fast-forward might do this:

1× → 100×

Playback speed changes instantaneously.

A simple speed ramp improves this, but can still introduce sudden changes in acceleration.

smooth-video-warp instead controls jerk: the rate at which acceleration changes.

Its playback speed therefore behaves more like an elevator or train:

normal speed
     ↓
acceleration begins gently
     ↓
acceleration increases
     ↓
acceleration decreases
     ↓
maximum speed
     ↓
deceleration increases
     ↓
deceleration decreases
     ↓
normal speed

The source timestamp, playback speed and acceleration remain continuous throughout the warp.

Jerk itself is piecewise constant and changes sign at defined points in the profile.


Jerk profile

Define:

$$ q=\frac{T}{4} $$

The complete warp consists of three constant-jerk regions:

$$ j(t)= \begin{cases} +J & 0 \leq t < q \ -J & q \leq t < 3q \ +J & 3q \leq t \leq T \end{cases} $$

Conceptually:

jerk

 +J  ──────────┐                 ┌──────────
               │                 │
  0            │                 │
               │                 │
 -J            └─────────────────┘

      0       T/4      T/2     3T/4       T

This produces a triangular acceleration profile.

During the first quarter:

acceleration: 0 → maximum
speed:        1× → increasing

During the second quarter:

acceleration: maximum → 0
speed:        increasing → maximum

At the midpoint:

acceleration: 0
speed:        maximum

The second half is the exact mirror image.

At the end:

acceleration: 0
speed:        1×

Calculating the required jerk

The central constraint is:

$$ x(T)=D $$

The complete source duration must fit exactly into the requested output duration.

For this jerk profile:

$$ D=T+\frac{JT^3}{32} $$

Solving for (J):

$$ \boxed{ J=\frac{32(D-T)}{T^3} } $$

This is why the user does not need to specify a jerk value.

Given:

source duration
target duration

there is a specific jerk magnitude required by this profile.

For compression:

$$ D>T $$

and therefore:

$$ J>0 $$

If:

$$ D=T $$

then:

$$ J=0 $$

and the video simply remains at normal speed.

smooth-video-warp is a compression tool and does not use this model for slow motion where:

$$ T>D $$

A --duration longer than the source duration is refused.


Peak playback speed

The maximum playback speed occurs exactly halfway through the output:

$$ t=\frac{T}{2} $$

For the constant-jerk profile:

$$ v_{\text{peak}}

1+\frac{JT^2}{16} $$

Substituting the calculated jerk gives:

$$ \boxed{ v_{\text{peak}}

2\frac{D}{T}-1 } $$

Define the average compression ratio:

$$ R=\frac{D}{T} $$

Then:

$$ \boxed{ v_{\text{peak}}=2R-1 } $$

So a clip requiring an average playback speed of:

124.1667×

has a peak speed of:

247.3333×

The peak is not an independently configurable parameter.

It is a consequence of the requested compression.


Quarter-point speed

At:

$$ t=\frac{T}{4} $$

the playback speed is:

$$ v(T/4)

1+\frac{JT^2}{32} $$

Substituting (J):

$$ \boxed{ v(T/4)=\frac{D}{T} } $$

So the playback speed one quarter of the way through the output is exactly the average compression ratio.

By symmetry the same is true at:

$$ t=\frac{3T}{4} $$

For the 37m 15s → 18s example:

t = 0%      speed =   1.0000×
t = 25%     speed = 124.1667×
t = 50%     speed = 247.3333×
t = 75%     speed = 124.1667×
t = 100%    speed =   1.0000×

Source timestamp mapping

The warp needs to answer one fundamental question for every output frame:

At this output time, what point in the original video should be displayed?

That is:

$$ x(t) $$

First quarter

For:

$$ 0 \leq t \leq q $$

where:

$$ q=T/4 $$

the source timestamp is:

$$ \boxed{ x(t)

t+\frac{Jt^3}{6} } $$

Playback speed is:

$$ \boxed{ v(t)

1+\frac{Jt^2}{2} } $$

and acceleration is:

$$ a(t)=Jt $$


Middle half

For:

$$ q < t < 3q $$

define:

$$ u=t-q $$

At the first quarter:

$$ x_q=q+\frac{Jq^3}{6} $$

and:

$$ v_q=1+\frac{Jq^2}{2} $$

The source timestamp is then:

$$ \boxed{ x(t)

x_q + v_qu + \frac{Jq}{2}u^2

\frac{J}{6}u^3 } $$

Playback speed is:

$$ \boxed{ v(t)

v_q + Jqu

\frac{J}{2}u^2 } $$

Acceleration is:

$$ a(t)=Jq-Ju $$

Acceleration reaches zero exactly at:

$$ t=T/2 $$

which is where playback speed reaches its maximum.


Final quarter

The warp is symmetric.

For:

$$ 3q \leq t \leq T $$

the source timestamp can therefore be calculated from the first quarter:

$$ \boxed{ x(t)=D-x(T-t) } $$

and:

$$ \boxed{ v(t)=v(T-t) } $$

This guarantees:

$$ x(0)=0 $$

$$ x(T)=D $$

$$ v(0)=1 $$

$$ v(T)=1 $$

and:

$$ x(t)+x(T-t)=D $$


Example: 37m 15s → 18s

Given:

$$ D=2235 $$

and:

$$ T=18 $$

the average compression ratio is:

$$ R=\frac{2235}{18}=124.1666667 $$

The required jerk is:

$$ J= \frac{32(2235-18)}{18^3} $$

giving:

$$ \boxed{ J=12.1646090535\ s^{-2} } $$

Peak playback speed is:

$$ 2(124.1666667)-1 $$

giving:

$$ \boxed{ 247.3333333\times } $$

Some points on the resulting warp are:

| Output time | Source timestamp | Speed | | ----------: | ---------------: | ------: | | 0.000s | 00m 00.000s | ×1.00 | | 1.000s | 00m 03.027s | ×7.08 | | 2.000s | 00m 18.219s | ×25.33 | | 4.500s | 03m 09.250s | ×124.17 | | 9.000s | 18m 37.500s | ×247.33 | | 13.500s | 34m 05.750s | ×124.17 | | 16.000s | 36m 56.781s | ×25.33 | | 17.000s | 37m 11.973s | ×7.08 | | 18.000s | 37m 15.000s | ×1.00 |

The source video is consumed slowly near the beginning and end then extremely rapidly around the middle.

That is intentional.


Frame mapping

The mathematical warp is continuous.

Video is not.

A video consists of discrete frames.

For an output frame rate (F), output frame (n) corresponds approximately to:

$$ t_n=\frac{n}{F} $$

The desired source timestamp for that frame is:

$$ s_n=x(t_n) $$

and the instantaneous playback multiplier is:

$$ r_n=v(t_n) $$

Conceptually:

output frame 0
    ↓
output time 0.000s
    ↓
source time 0.000s
    ↓
source frame near 0.000s

output frame 1
    ↓
output time 0.033s
    ↓
source time x(0.033)
    ↓
source frame near that timestamp

...

output frame n
    ↓
output time n / fps
    ↓
source time x(n / fps)

At low playback speeds, most source frames survive.

At very high playback speeds, large numbers of source frames are skipped.

For example, around:

247×

roughly one source frame out of every 247 can appear in an output with the same frame rate.

This is expected.

The purpose of the warp is to compress elapsed source time rather than preserve every source frame.

Each output frame is a blend of several nearby source frames rather than a single selected one — --samples controls how many.


Rendering pipeline

Conceptually:

input.mp4
    │
    ▼
ffprobe
    │
    ├── duration
    ├── frame information
    └── media information
    │
    ▼
warp calculation
    │
    ├── required jerk
    ├── average speed
    ├── peak speed
    └── source-time mapping
    │
    ▼
FFmpeg
    │
    ├── decode source
    ├── select and blend source frames
    ├── rebuild output timestamps
    └── encode output
    │
    ▼
--output path

Audio

The initial scope is video warping.

Input audio is not copied unchanged into the warped output because it would immediately become unsynchronised with the video.

Narration, music or other presentation audio can be added when the warped clip is incorporated into the final edit.


Input assumptions

smooth-video-warp is aimed primarily at screen recordings and similar demonstration footage.

Constant-frame-rate input is the primary target.

Variable-frame-rate media may require additional handling and is not part of the current compatibility guarantee.

The tool requires a valid video stream whose duration can be determined by ffprobe.


Validation

The following must hold before a warp is attempted:

source duration > 0
target duration > 0
target duration <= source duration

If:

target duration == source duration

the calculated jerk is zero and playback remains at 1×.

If:

target duration > source duration

the request represents slow motion rather than compression and is refused.

The tool also fails clearly if:

  • the input file does not exist
  • the input cannot be probed
  • no usable video stream exists
  • FFmpeg is unavailable
  • ffprobe is unavailable
  • the requested output cannot be encoded

Design principles

Target duration is the user intent

The primary input is:

Make this clip this long.

The user should not need to guess an appropriate peak playback speed.

They should not need to tune acceleration.

They should not need to tune jerk.

The tool calculates those values.

source duration
        +
target duration
        ↓
required jerk
        ↓
warp curve
        ↓
peak speed
        ↓
frame schedule

Preserve the process

A hard cut answers:

What happened after the wait?

A warp also shows:

Something continued happening during the wait.

This is useful when the passage of work itself provides context or credibility.


Smooth entry and exit

The transition from normal playback into the warp should feel intentional rather than like a playback glitch.

Likewise, the viewer should arrive back at normal speed smoothly before important content resumes.


Remain small

smooth-video-warp does one thing:

Smoothly compress an entire video clip to a requested duration.

It is not intended to become a general-purpose video editor.

The scope does not include:

  • timeline editing
  • arbitrary trimming
  • sequencing multiple clips
  • presentation assembly
  • titles
  • transitions between clips
  • music
  • narration
  • general audio editing
  • slow motion
  • arbitrary speed-keyframe editing
  • manual animation curves

Those concerns belong in other tools.


Why?

Long-running processes are common in recorded technical demonstrations:

  • AI agents reasoning
  • AI agents writing code
  • builds
  • tests
  • package installation
  • compilation
  • rendering
  • data processing
  • deployment
  • long-running commands

Showing these in real time is boring.

Removing them completely with a hard cut can make a demonstration feel disjointed or hide the fact that work actually occurred.

Constant fast-forward is better, but jumping instantly between normal speed and extreme playback speed is visually abrupt.

smooth-video-warp provides another option:

1×
 ↓
smooth acceleration
 ↓
very fast
 ↓
smooth deceleration
 ↓
1×

The viewer sees that time passed.

They see the process continue.

They just don't have to wait for it.