FFmpeg Cookbook
JA

VFR to CFR Converter

Turn variable frame rate (VFR) screen recordings and phone videos into constant frame rate (CFR). The tool flags VFR from the header (average fps vs. base rate), confirms it by decoding the first 30 seconds, then re-encodes at the rate you pick.

Fully local processing — your file never leaves the browser
⏱️
Drag & drop a video, or tap to choose one
MP4 / MOV / WebM / MKV and more, up to 500 MB and 15 minutes
🎬
Reading the header…
Video goes through the fps filter, which snaps every frame to a fixed grid by duplicating or dropping frames, then re-encodes with H.264. Audio is re-encoded to AAC 160 kbps on its original timestamps. Playback speed does not change; the video is simply locked to the audio.
Working… 0%
This browser can't preview the result, but the downloaded file is fine.
Download CFR video

What to do next

Popular uses
Fix audio drift in screen recordings and phone videosMake footage CFR before Premiere / DaVinciEven out OBS / game-capture frame timing

What this tool does

  • Reads the average frame rate and base rate (tbr) and flags a mismatch as "likely VFR"
  • Decodes the first 30 s and counts irregular frame intervals to confirm VFR or effectively CFR
  • Output rate: auto (match the base rate) or 23.976 / 24 / 25 / 29.97 / 30 / 50 / 59.94 / 60 fps
  • 29.97 uses 30000/1001; this does not automatically repair existing audio drift
  • Re-reads the output header after converting to show average = base
  • Fully local: files never leave your device

How to use

  1. 1

    Drop a video

    MP4 / MOV / WebM / MKV and more, up to 500 MB and 15 minutes. The average fps, base rate, and VFR verdict appear as soon as the header is read.

  2. 2

    Confirm if you want to

    Press "Decode the first 30 s to confirm" to measure what share of frame intervals is irregular. Skip it if the header verdict is enough.

  3. 3

    Pick the output rate

    When in doubt, leave it on Auto. Screen and phone recordings are usually 30, game capture 60, broadcast material 29.97 / 59.94.

  4. 4

    Convert and download

    Video is re-encoded with H.264, audio to AAC 160 kbps. The result shows the output fps / tbr and the file name gets a suffix like `_cfr30`.

What each setting means

Average frame rate
Frames divided by duration across the whole file — the same value as ffprobe's `avg_frame_rate`.
Base frame rate (tbr)
FFmpeg's estimate of the lowest rate that can represent every timestamp (`r_frame_rate`). Usually close to the rate the recorder was aiming for.
Output frame rate
The value passed to the `fps` filter. Auto uses the base rate when it is a standard value (24 / 25 / 30 / 60 …) and otherwise the standard rate closest to the average.
Quality (CRF)
H.264 quality. 18 is visually near-lossless, 22 is the default, 26 is a lighter file for sharing. Higher numbers mean smaller and rougher.

Recommended settings

Give a screen recording regular frame intervals
Recording or project rate / CRF 22
Auto is a suggestion. Compare the original and output in the same player, including audio at the beginning, middle and end.
Prepare footage for an editor that requires CFR
Your project rate / CRF 18
Use when the destination requires it. VFR support and synchronization depend on the editor and source.
Game capture from a 144 Hz / 240 Hz monitor
60 / CRF 20
Anything above 60 is dropped and dips are filled by duplicates, giving a steady 60. YouTube streams at most 60 anyway.
Broadcast / DVD material that shows 29.97
29.97 / CRF 18
Check the source and destination. Frame-rate conversion differs from changing playback speed.

Common pitfalls

Symptom: Header says "Likely VFR" but the decode check says "Effectively CFR"

Cause: A header estimate and a frame-interval check limited to the first 30 seconds cover different things.

Fix: Do not infer the cause of audio drift or classify the whole file from that sample. The Audio Sync tool only addresses a constant offset.

Symptom: The converted video plays faster or is shorter (hand-written CLI)

Cause: Input-side -r ignores video timestamps and generates new ones at the requested rate.

Fix: To regularize intervals based on existing presentation times, use -vf fps=30 after the input, and check the resulting duration.

Symptom: The output is larger than the input

Cause: Frame count, codec, CRF and picture content all affect size. Duplicate frames do not have a fixed byte cost.

Fix: Adjust CRF while inspecting the result, or use a target size in the Video Compressor.

Symptom: The first 30 seconds are CFR but audio drifts later

Cause: Sampling the beginning cannot establish what happens to timestamps or sound later.

Fix: Compare the affected section and check whether the original already drifts. VFR is not the only possible cause.

Symptom: "Videos longer than 15 minutes cannot be processed"

Cause: This is the tool limit. Speed and memory depend on the source and device; shorter files can also fail.

Fix: Keep the original and run the commands below with desktop FFmpeg.

Equivalent FFmpeg commands

Reference commands you can run on the desktop FFmpeg CLI.

Historical log: 2026-09-11, 3 successful example executions and 2 excluded (desktop FFmpeg 8.1, fixtures). This log does not verify later edits, browser controls or visual quality.

Same as this tool (fps filter to 30 fps)
ffmpeg -i input.mp4 -vf fps=30 -c:v libx264 -preset veryfast -crf 22 -pix_fmt yuv420p -c:a aac -b:a 160k -movflags +faststart output.mp4
Article-style (-fps_mode cfr, audio copied losslessly)
ffmpeg -i input.mp4 -fps_mode cfr -r 30 -c:v libx264 -crf 20 -c:a copy output.mp4
FFmpeg 5.1 and later. Same meaning as the older `-vsync cfr`, which is deprecated.
Snap to 29.97 fps (NTSC)
ffmpeg -i input.mp4 -vf fps=30000/1001 -c:v libx264 -crf 20 -c:a copy output.mp4
Use 30000/1001 for the exact NTSC ratio. Its difference from decimal 29.97 is small; the earlier 3.6-seconds-per-hour claim was incorrect.
Suspect VFR (compare average and base rate)
ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate,avg_frame_rate -of default=nw=1 input.mp4
Different values suggest VFR. Equal values do not rule it out.
Confirm VFR (list frame times for the first 30 s)
ffprobe -v error -select_streams v:0 -read_intervals %+30 -show_entries frame=pts_time -of csv=p=0 input.mp4
Constant differences between neighbours mean CFR; varying ones mean VFR. The tool's decode check gathers the same data through the showinfo filter.

Browser support & limits

  • Up to 500 MB and 15 minutes (run the commands above on desktop beyond that)
  • The decode check covers only the first 30 s; a recording that turns VFR later can read as "Effectively CFR"
  • Output is always MP4 (H.264 + AAC). ProRes or lossless output needs desktop FFmpeg
  • Subtitles and extra audio tracks are dropped; only the first audio track is kept

Privacy

This tool runs ffmpeg.wasm directly in your browser. Files never leave your device — everything runs locally. Read the privacy policy →

Frequently asked questions

What is variable frame rate (VFR)?

Video with nonuniform presentation intervals. VFR is not itself corruption: correct timestamps and a compatible player can play it normally. Convert according to destination requirements or an observed problem.

Will this really fix my audio sync?

There is no guarantee. The fps filter duplicates or drops video frames using input timestamps; it does not match sounds to picture content. This tool re-encodes audio to AAC. A constant offset and drift that grows over time need different treatment.

Does it change the speed or duration?

Acceleration is not the intended operation. Rounding onto a frame grid and endpoint handling can change the video end time relative to audio. Compare the beginning, middle and end with the original.

Which rate does Auto choose?

It prefers a base rate (tbr) close to a standard rate, otherwise a standard rate near the average. tbr is an estimate, not proof of recording intent. Prefer known recording settings and project requirements.

Can this be done without re-encoding?

No. Making a file CFR changes which frames exist and when, and `-c:v copy` keeps the original timestamps. Audio can be copied losslessly with `-c:a copy` on desktop; this tool re-encodes it to AAC 160 kbps so WebM (Opus) and MKV (FLAC) sources still produce a valid MP4.

Should I pick 29.97 or 30?

Choose for the source and destination. The fps filter duplicates or drops frames according to timestamps; changing 29.97 to 30 does not necessarily cause 3.6 seconds of audio drift per hour. Using 30000/1001 also cannot guarantee correction of an existing sync problem.

Does it work with iPhone HEVC video?

It decodes HEVC to H.264, but profile support and device memory can cause failures. Try a short copy first and inspect HDR color and orientation. Processing time does not have a fixed multiplier.

How are irregular intervals counted?

The tool takes the presentation time (pts_time) of every frame in the first 30 s and buckets the gaps between neighbours at 0.1 ms resolution. The most common gap is treated as the intended interval; any gap more than 5% (at least 1.5 ms) away from it counts as irregular, and the file is called VFR when more than 2% of gaps are irregular. The 1.5 ms floor stops 60 fps WebM with a 1 ms timebase (16 / 17 ms alternating) from being misread as VFR.

Related tools

Related FFmpeg recipes

Convert variable presentation intervals into regularly spaced frames. Selected video is processed in the browser. The command execution record below does not prove that real recordings are repaired or that every browser interaction has been tested.

In depth: context unique to this tool

"Average ≠ base" is a suspicion, not proof

The tbr that FFmpeg prints (`r_frame_rate`) is its estimate of the lowest rate that can express every timestamp in the stream as an integer. It often matches what the recorder was aiming for, but rounding error or the container timebase (1 ms in WebM) can push it to values like 1000. The average (`avg_frame_rate`) is simply frames divided by duration. When the two differ, some frames probably have uneven spacing — but a CFR file missing its first frame also makes them differ.

After the header comparison, the tool can inspect presentation intervals in the first 30 seconds. This is a sample classified using a tolerance, not a guarantee that the whole file is CFR. Previously quoted fixture-specific measurements have been withdrawn because they could not be tied to a published reproduction record.

Distinguish the fps filter from input-side -r

The fps filter duplicates or drops frames based on input timestamps. Output-side -fps_mode cfr with -r also specifies constant-rate output, but rounding and endpoint handling need not produce identical results.

Input-side -r generates timestamps while ignoring video input timestamps. This can change duration when original intervals were irregular. Distinguish this from setting an image-sequence input rate. See the official -r and fps_mode documentation.

Choose using recording and project settings

An average of 12 fps does not prove that the recorder intended 30 fps. Inspect motion-heavy sections and avoid dropping useful frames with an unnecessarily low output rate. Duplicating frames to a higher rate does not create new motion either.

Auto uses the base rate as a clue, not proof of recording intent. Check editing requirements too. The fractional rates are 30000/1001 for 29.97 and 60000/1001 for 59.94. Regular frame intervals differ from compressed timestamps for accelerated playback.