Video judder with mixed frame rates: Timeline's warning
Judder on a joined video comes from resampled frame rates. Sume's Timeline warns output_fps_resamples_sources when a source rate differs. How to read it.

Video judder after you join clips usually means one clip's frame rate was forced to a different output rate. In Sume's Timeline 1.0, a rate that differs from a source's is met by repeating or dropping a frame every few frames, which the docs call judder on motion, and the job reports the warning output_fps_resamples_sources. The fix is to stop forcing a rate that no source has.
What causes the judder?
A clip records motion at a fixed number of frames per second. If the output runs at another rate, frames have to be repeated to fill it or dropped to fit it, and the spacing of repeats is uneven unless the rates divide evenly. The table is plain arithmetic, not from the docs: how many frames per second are repeated or dropped under nearest-frame resampling.
| Source | Output | Change per second |
|---|---|---|
| 24 fps | 30 fps | 6 frames repeated |
| 30 fps | 24 fps | 6 frames dropped |
| 25 fps | 30 fps | 5 frames repeated |
| 30 fps | 60 fps | 30 frames repeated |
How do I see the warning on a Sume render?
Read GET /v1/jobs/:id/result for the Timeline job. The result is kind: timeline_render and carries an optional warnings[] array. output_fps_resamples_sources appears there with the rate the sources wanted. It is a soft warning: the docs say soft warnings are not failures, so the job still finishes and you have to look for it yourself.
How do I avoid it?
Omit output.fps. The Timeline docs say an omitted rate renders at the rate the sources already run at, decided by the longest video sources. Set it only when a delivery spec requires one of 24, 25, 30 or 60, and accept that any source at another rate gets resampled.
Do not treat the warning as noise on a render you plan to publish. It is the job's signal that motion was resampled, and the rate it names is the one your sources wanted, which is usually the rate you should have asked for.
Keep clips that will be joined at one rate where you can. If one shot arrives at a different rate, you now know which slot to replace before rendering.
What about stills and compose?
Stills have no rate, and 30 applies only when nothing in the timeline has one. Timeline compose defaults to the video layer's own frame rate, which the docs call the only rate that repeats or drops no frame, and it raises the same output_fps_resamples_sources warning when an explicit output.fps differs from the clip.
For choosing a rate on purpose, see 24 fps vs 30 fps for AI video.
Sources
Related posts
More in Developers
- Gemini 3.8 Flash function calling: let it start a Sume video job
Declare a function for Gemini 3.8 Flash, run it against Sume's /v1/videos when the model returns a functionCall, and reply with a functionResponse with job id.
- Gemini CLI MCP OAuth metadata discovery blocked: Sume check
Gemini CLI v0.59.0 added SSRF prevention to MCP OAuth metadata discovery. Sume publishes metadata at two public HTTPS URLs; how to confirm both from a shell.
- Gemini CLI MCP servers not loading in an untrusted workspace
Gemini CLI v0.59.0 filters mcpServers in restricted mode. If Sume is missing in an untrusted folder, trust is the cause; then tell it from an OAuth issue.
- Golang HTTP client retry: what net/http retries on POST
Go's http.Transport retries only network errors on reused connections, and a POST only with an Idempotency-Key header. Write the 429 and 5xx loop yourself.
Written by Sume