C.W.K.
Stream
Lesson 05 of 10 · published

Frame Rate — Changing FPS Without Breaking Sync

~10 min · fps, frame-rate, vfr, cfr

Level 0Viewer
0 XP0/73 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Three ways to change frame rate

You can ask FFmpeg to change frame rate three different ways. They behave differently and the wrong one breaks A/V sync.

  • -r <fps> as an output flag — drops or duplicates frames so the video has that many fps. Container timestamps are preserved. Audio sync is preserved.
  • -vf fps=<fps> — same idea, expressed as a filter. Use this when chaining with other filters.
  • -vf setpts + -af atempo — actually slows down or speeds up the video (see Track 5 lesson 8).

Common conversions

60 fps → 30 fps for upload size: drop every other frame. 24 fps → 60 fps: duplicate frames. Neither interpolates motion (no synthesized in-between frames). For motion interpolation use the minterpolate filter or AI tools (Topaz, RIFE).

Variable frame rate (VFR)

Screen recordings, phone captures, and some streaming sources are VFR — frames arrive whenever the source feels like emitting one. This breaks editors that assume CFR. Convert to CFR with -vsync cfr -r 30 or use fps=30 filter.

Code

Frame rate recipes·bash
# 60fps → 30fps for smaller upload
ffmpeg -i in.mp4 -r 30 -c:v libx264 -crf 22 -c:a copy out_30.mp4

# Same with the filter form (clearer in chains)
ffmpeg -i in.mp4 -vf fps=30 -c:v libx264 -crf 22 -c:a copy out_30b.mp4

# VFR screen recording → CFR for editors that need it
ffmpeg -i screen.mov -vf fps=30 -vsync cfr -c:v libx264 -crf 20 -c:a copy out_cfr.mp4
Motion interpolation (synthesized in-between frames)·bash
# Genuine 30→60 with synthesized motion (slow, sometimes ghosty)
ffmpeg -i in.mp4 \
  -vf "minterpolate=fps=60:mi_mode=mci:mc_mode=aobmc:vsbmf=1:scd=fdiff" \
  -c:v libx264 -crf 20 -c:a copy out_smooth.mp4

# Use this only when you really want smooth slow-mo or a 24→60 conversion.
# For most 'reduce fps' work, plain -r is what you want.

External links

Exercise

Find or download a 60fps clip. Convert it to 30fps using -r 30 and verify with ffprobe that r_frame_rate=30/1 in the output. Then take a 24fps source and convert to 60fps with minterpolate=fps=60:mi_mode=mci. Watch both outputs side by side — the second has visible (sometimes ghostly) synthesized motion.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.