Timeline output.fps: why a 24 fps clip judders when you force 30

Leave output.fps unset and Timeline renders at the source rate. Force 30 on a 24 fps clip and frames repeat; the job reports output_fps_resamples_sources.

5 min readSume
All posts

Leave output.fps out of your Timeline request and the render uses the frame rate of your sources. Set it to a value that differs from a source, for example 30 on a 24 fps clip, and the job repeats or drops a frame every few frames, which shows as judder on motion. The job reports that with the warning output_fps_resamples_sources, together with the rate the sources wanted. Allowed values are 24, 25, 30 and 60.

The rule for sources is spelled out in the docs: the longest video sources decide the rate, stills have no rate, and 30 applies only when no source carries a rate.

What the resampling does

Going from 24 to 30 fps means 6 extra frames per second must be invented by repeating. The ratio is 30 / 24 = 1.25, so on average every fourth frame is shown twice, which is uneven timing and what the eye reads as stutter. Going from 60 to 30 drops every second frame, which is regular and less visible, but still not a free change.

Mixed sources make the decision harder. If one clip is 24 fps and another 30 fps, the longest source sets the rate when you omit output.fps, and the other is resampled. The warning in the job result tells you which rate was wanted, so read warnings[] after the first render.

Frame-rate behaviour in a Timeline render (read 2026-10-07 from the Sume docs)
SituationResult
output.fps omitted, all sources 24Renders at 24
output.fps omitted, no source has a rate (all stills)Renders at 30
output.fps 30, source 24Frames repeat; warning output_fps_resamples_sources
output.fps 24, source 60Frames dropped; same warning
output.fps 25 or 60Allowed values; same rule applies

A render with the rate left alone

The sample below renders one clip over a 20-second voiceover with no output.fps. After the job completes, the result's warnings[] is empty if nothing needed resampling. Run the plan call first if you only want to see the cost; its billable_minutes for 20 seconds of audio is 1, so $0.10.

curl -X POST https://api.sume.com/v1/timeline-1.0/render \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fps-keep-001" \
  -d '{
    "audio": {
      "url": "https://media.sume.com/artifacts/artf_demo/voice.wav",
      "duration_seconds": 20
    },
    "video": [
      {
        "source_url": "https://media.sume.com/artifacts/artf_demo/clip24.mp4",
        "start": 0,
        "duration": 20
      }
    ]
  }'

When you do need a fixed rate

Some destinations ask for one frame rate. YouTube's upload page, for example, lists different recommended bitrates for standard and high frame rates. If you must conform, do it once and do it deliberately: video trim can conform a clip with output: { fps: 30 } ahead of the Timeline job, and a conform there is the same re-encode you would otherwise get inside the render.

Note that the plan call does not predict these warnings; the docs say a plan cannot predict padded or looped sources and similar soft warnings. You find out from the result.

A short checklist

Probe the sources first with video inspect and read the frame rate in the probe block. If all sources agree, omit output.fps. If they differ, decide which rate wins and conform the others with video trim before rendering. Re-render only after changing the program, since each render is a new job.

Reading the warning

The warning is soft, which means the job still succeeds and you are billed as usual: it does not fail the render. That is why it is easy to miss. Make your pipeline read warnings[] from GET /v1/jobs/:id/result and log any entry whose code is output_fps_resamples_sources, along with the rate the sources wanted.

If you see it on a render where you did not set output.fps, one of your clips has a different rate than the longest source. Fix it by conforming that clip in advance, not by forcing the render to a third value.

Stills in the mix

A still has no frame rate, so a program made only of stills renders at 30 when you omit output.fps. If you mix stills with 24 fps clips, the clips decide the rate and the stills simply hold. That is the common case for ads that open on a product shot, and it means you rarely need to set the rate at all.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume