AI Video — Output Frame Rate Doesn't Match What You Requested

You asked for 24fps cinematic, got 30fps. Or 60fps slow-mo source plays back as judder. Why AI video FPS gets reinterpreted at every stage and how to lock it end-to-end.

You set the model to “24fps cinematic.” The export lands on your timeline and the file inspector says 30fps. Or worse: the video plays back fine in the model’s web preview but stutters everywhere else. Or you requested 60fps for a slow-motion shot and got a smooth-but-wrong 24fps clip that the model upscaled-in-time to fake the difference. AI video frame rate is one of those settings that looks like a clean parameter but gets reinterpreted at three or four stages: the model’s native generation rate, the temporal interpolation step, the export muxer, and finally whatever editor or player you load it into.

This article maps where the FPS gets rewritten, how to detect which stage flipped it, and how to lock the frame rate end-to-end so the output matches the request.

Common causes

Ordered by hit rate, highest first.

1. Model generates at a fixed native rate, then interpolates to your requested rate

Most current models (Sora, Runway Gen-3, Kling, Veo) generate at one or two native rates internally — typically 8, 12, 16, or 24fps — then temporally interpolate to the FPS you requested. The interpolation is not free: it introduces ghosting, double-edges, and motion that doesn’t match real footage at that rate.

How to spot it: Scrub frame-by-frame. If alternating frames look near-identical or you see interpolation halos around moving edges, the file is “30fps” in metadata but only ~15fps of unique frames.

2. Export muxer rounds to the nearest broadcast rate

You asked for 24fps. The muxer rounds to 23.976 (NTSC film) or 25 (PAL). Some platforms force 30 or 60 regardless of input. The metadata reads the rounded value, not your request.

How to spot it: Compare requested FPS to actual file FPS via ffprobe. A 0.024 fps drift (24 → 23.976) is the muxer; a full rate swap (24 → 30) is the platform forcing.

3. Container declares one FPS, stream is actually another (VFR vs CFR)

The file’s container says 30fps but the actual frame timestamps are variable frame rate (VFR). Players honor the container, editors honor the timestamps, and they disagree. Audio-video sync drifts after import.

How to spot it: ffprobe reports two different rates — r_frame_rate (container declared) vs avg_frame_rate (computed from timestamps).

4. You requested high FPS but the model’s max is lower

You asked for 60fps. The model’s supported set is [24, 30]. The platform silently clamps to 30 (or to 24 then interpolates to 60). Your slow-motion plan was based on a rate the model never actually delivers.

How to spot it: Check the model’s documented FPS support set. If 60 isn’t in it, you’re getting interpolation, not real high-FPS capture.

5. Editor’s project rate overrides clip rate on import

Your DaVinci/Premiere project is set to 30fps. You drop a 24fps clip onto the timeline. The editor either drops frames, duplicates frames, or applies time-conformance silently. The “wrong” rate you see is the project, not the clip.

How to spot it: Right-click the clip in the bin (not on the timeline). The bin shows source rate. The timeline shows project rate. Mismatch confirmed.

6. Slow-motion ramp baked into the file at generation time

You prompted “slow motion” or “120fps look.” The model interpolated frames into the clip and exported at 30fps. The “slow-motion” is fake-smooth, but the file FPS is still 30. There is no high-FPS source to ramp from in post.

How to spot it: The clip looks slow but the frame rate is normal. Re-timing it in post produces choppy results because there are no extra frames to draw from.

7. Re-encoding for upload changes the FPS

YouTube/TikTok/X re-encode on upload. They normalize to platform standards (30 or 60). The file you uploaded was 24fps; what plays back to viewers is 30fps with their server-side interpolation.

How to spot it: Download your own video back from the platform. Run ffprobe. Compare to your upload.

Shortest path to fix

Step 1: Identify your model’s native rate

Read the model docs (Runway, Pika, Kling, Sora, Veo) for “native frame rate” or “supported FPS.” If it’s not documented, generate a 1-second clip at your highest requested rate, run ffprobe, and count how many frames are actually unique:

ffprobe -v error -count_frames -select_streams v:0 \
  -show_entries stream=r_frame_rate,nb_read_frames \
  -of csv input.mp4

If nb_read_frames divided by the duration matches the declared rate, you have real frames. If it’s half, the model interpolated.

Step 2: Pick a target rate that matches the model’s native rate

Don’t fight the model. If the native rate is 16fps, ask for 24 (close enough that interpolation is light) instead of 60. The output looks much better at a rate the model can honestly produce.

Step 3: Lock the export muxer to the requested rate

When re-encoding from the model output, force a constant frame rate:

ffmpeg -i input.mp4 -vsync cfr -r 24 \
  -c:v libx264 -crf 18 -preset slow output.mp4

The -vsync cfr flag converts variable frame rate to constant. The -r 24 sets the exact target. No platform muxer guesswork.

Step 4: Set the editor’s project rate before import

In DaVinci: Project Settings → Master Settings → Timeline Frame Rate. In Premiere: New Sequence → match the source clip rate. Set this before you import the AI clip. If you have multiple AI clips at different rates, set the project to the most common rate and convert outliers explicitly with optical flow.

Step 5: For true slow-motion, generate high-rate then ramp in post

If you want slow-motion, you need real high-FPS source. Generate at 48 or 60fps if the model supports it natively (verify per Step 1). Then drop the clip on a 24fps timeline and reinterpret. Don’t ask the model for “slow motion” — that produces a fake slowdown baked into a normal-rate file.

Step 6: Verify after every encode stage

Build a habit:

# After model export
ffprobe model_output.mp4 | grep fps

# After your re-encode
ffprobe your_export.mp4 | grep fps

# After upload, download back and check
ffprobe downloaded_from_youtube.mp4 | grep fps

If any stage flipped the rate, you’ll catch it before delivery.

Step 7: Upload at the platform’s native rate, not “highest possible”

If the platform re-encodes to 30, upload at 30. You skip one round of interpolation. For TikTok/YouTube Shorts, 30 is the safest target. For cinematic uploads to YouTube long-form, 24 is preserved if the file is honest CFR 24.

When this is not on you

Many models do not expose true frame rate control — they generate at their internal rate and the “FPS” parameter only affects the export step’s interpolation. You can pick the export rate but not the underlying capture rate. This is a model limitation, not a config bug.

Easy to misdiagnose as

  • “Stuttering playback.” The file may be the correct frame rate; the issue is the player or display refresh rate mismatch (e.g., 24fps file on a 60Hz monitor with no 3:2 pulldown). Test on a different player before blaming the file.
  • “Slow-motion looks bad.” If the model returned a 30fps file with baked-in fake slowness, no amount of post-production can recover the missing frames. Regenerate at higher native rate instead.
  • “Audio drift.” Audio-video drift after import is usually a VFR-vs-CFR issue, not a frame rate value issue. Re-encode to CFR first, then troubleshoot drift.

Prevention

  • Document each model’s native generation rate; share with your team.
  • Always re-encode model output to CFR before edit; never bring VFR onto a timeline.
  • Set editor project rate to match the dominant source rate before importing clips.
  • Run ffprobe on every model output as a first step before editing.
  • For slow-motion shots, generate at the highest native rate the model supports and ramp in post.
  • Don’t request frame rates the model doesn’t natively support; you only get interpolation.

FAQ

  • Why does the model give me 30fps when I asked for 24? Most models default-clamp to platform-friendly rates. Even when you select 24, the export muxer may round to 23.976 or override to 30. Re-encode locally to lock the exact rate.
  • Is interpolated 60fps the same as real 60fps? No — interpolated frames are guessed midpoints, not captured motion. They look smooth but reveal artifacts on fast motion (ghosting, soft edges) and don’t enable real-time slow-motion playback.

Tags: #ai-video #Troubleshooting #Video generation #frame-rate #fps #export