VFR and CFR - Game Video Production
2,405 words.

This wasn’t what I planned for my next “game video production” post but Roger mentioned a topic on the Blaugust Discord that I hadn’t heard before, which led me down a deep rabbit hole on the subject of variable frame rate and constant frame rate in video files.
The Top of the Rabbit Hole
Roger was having an issue with audio drifting out of sync with the video over time, which is something I’ve never seen before in my OBS videos. At least not that I remember. Or at least not in a way that wasn’t attributable to an audio sample rate mismatch (44.1 versus 48).
He determined his issue is that OBS records “variable frame rate” or VFR videos, as opposed to “constant frame rate” or CFR, and his video editor (Corel something I think?) was having trouble working with them.
I’d never heard of this issue in OBS or a distinction between VFR and CFR videos, so I turned to my go-to search and research tool for technical information, which is ChatGPT and ChatGPT Search, because it’s about a thousand million times faster and better than Googling or DuckDuckGoing.
What I learned shocked me to my core.
Not really, but it was all new to me. Unfortunately none of my research is going to help Roger because his situation is vastly different from mine.
VFR Is A Thing. Who Knew?
It turns out that every video I’ve been recording in OBS and uploading to YouTube for the last nine years (or at least the most recent ones I checked from the last week) are, indeed, VFR videos. I had always assumed they were 60 fps because, you know, OBS says it records at 60 fps, but it turns out they average 60 fps, and there’s some variance in the frame rate.
Both the MKV and the remuxed MP4 videos that OBS generates are variable frame rate, despite MediaInfo telling me (incorrectly, it turns out) that the MKV files are CFR. (MediaInfo is a new tool to me, but it seems fine, if you discount the fact that it’s wrong sometimes.)
However, OBS recorded files (remuxed or not) have never been a problem for me. I only load maybe 1 out of 50 videos I record into a video editor, and I’ve never noticed any sync issues in those cases. This is despite the Internet wisdom, which I just learned in the past day, that you should always convert VFR videos into CFR before loading them into a professional video editor, because professionals only do CFR, thank you very much. Meanwhile, I’ve never done that and suffered no ill effects.
I’ve been using Davinci Resolve for the last couple of years, and before that I used Movie Studio Platinum which was ruined by MAGIX. I never once noticed game audio drifting out of sync because of a variable frame rate.
That’s not to say there weren’t issues… it’s just that I didn’t notice them, or I worked around them somehow without identifying a cause.
I have occasionally noticed the audio tracks from OBS videos will be a slightly different length than the video tracks, but it’s never been enough of a difference to move the audio far enough out of sync to matter. We’re talking less than a second of difference over hour-long videos. More like less than a tenth of a second.
If I ever needed to fix that, which would have been almost never, but I’m sure it’s happened once or twice, I would grab the end of the audio track clip and drag it to snap to the end of the video track clip. (Which would just remove the extra bit of audio off the end, or if I needed to I could hold down control or alt or whatever key it is and it would resample the audio to match the new length.)
All of the audio sync issues I’ve ever found troublesome are attributable to audio interface delays. (I’ve mostly solved that now by using an ASIO driver OBS plugin for my main microphone.)
Custom Muxer Setting: force-cfr=1
Roger mentioned Internet advice to set force-cfr=1
in the Custom Muxer Settings to force OBS to generate CFR videos. It’s still a top search result.
I can conclusively report that setting force-cfr=1
in the Custom Muxer Settings does absolutely nothing and the Internet is dead wrong. Definitely not the first time I’ve seen the Internet be wrong on a popular search result.
There may have been a time in the past when that worked, but it doesn’t work anymore. In any case, that would only affect the remuxed MP4 video files, and not the original MKV file that OBS records.
My understanding is that OBS uses ffmpeg to perform the remux operation, and there is no such setting documented for the ffmpeg mp4 muxer. You can type ffmpeg -h muxer=mp4
to verify. End of story.
In any case, you can’t “fix” VFR just by remuxing.
Converting VFR Videos to CFR Videos
So this is where things get complicated.
Based on my understanding of how video files are encoded, it’s not possible to “remux” a video from VFR to CFR. “Remuxing” is a term that essentially means changing the video container format without changing or re-encoding the actual contents of the video data.
CFR is not just a flag that’s set somewhere in the file. Whether a video is VFR or CFR is determined by examining the time stamp (officially called the PTS or “presentation time stamp”) of every frame in the video. If every single time stamp is snapped to a regular interval, the video is considered CFR. If even a single frame’s time stamp is off, it’s technically VFR.
Here’s the problem: In order to convert a video from VFR to CFR, the video needs to be re-encoded. Which takes time for one thing, but it also means there’s some risk of video quality loss, depending on the settings used.
If you have unlimited disk space, you’ll probably want to re-encode to a lossless format. Practically speaking, nobody has that much disk space.
Most Internet sources advise using something like Handbrake for video conversions, which I’ve used in the distant past and believe it generally works. But I like to automate things so here’s an ffmpeg command that I used to convert an OBS video to CFR:
ffmpeg -i "I:\Projects\DragonsDogma2-Panpan-Unedited (2024)\DD2-20250220194232 - Tolled To Rest, Worldsend Cavern.mp4" \
-filter_complex "[0:0] fps=60 [v]" \
-c:v h264_nvenc -profile:v high \
-rc:v vbr -multipass fullres -tune hq \
-b:v 16M -maxrate:v 18M -bufsize:v 20M \
-temporal-aq:v 1 -rc-lookahead:v 32 \
-c:a copy \
-map [v] -map 0:1 -map 0:2 -map 0:3 \
"I:\Projects\DragonsDogma2-Panpan-Unedited (2024)\cfr\cfrtest.mp4"
Your mileage may vary. The important part is the fps=60
filter and the video encoding settings.
-i "filename"
specifies the input filename.-filter_complex "[0:0] fps=60 [v]"
tells ffmpeg to run a filter to set the frame rate to exactly 60 fps, dropping or adding frames as needed, effectively converting the video to CFR. There are other filters that can blend frames instead of just dropping them, but I don’t think it’s necessary.-c:v h264_nvenc -profile:v high -rc:v vbr -multipass fullres -tune hq -b:v 16M -maxrate:v 18M -bufsize:v 20M -temporal-aq:v 1 -rc-lookahead:v 32
sets the video encoder and settings. I can’t explain my reasoning for these settings because I’ve reached them after years of tweaking and Googling and re-tweaking and re-Googling. You can probably copy it into ChatGPT to get a full explanation*. Basically this is using an Nvidia GPU-accelerated encoder and settings that should not result in too much loss of quality from the original file. (I record at 16Mbps.)-c:a copy
says to copy the audio tracks without re-encoding them.-map [v] -map 0:1 -map 0:2 -map 0:3
says to generate 1 video track from the filter results and 3 audio tracks from the original 3 audio tracks."I:\Projects\DragonsDogma2-Panpan-Unedited (2024)\cfr\cfrtest.mp4"
is the output filename.
* In fact, I did paste that into ChatGPT and asked it to explain the settings and suggest improvements, and, while I was complimented on my excellent settings, I got some new ideas to improve the quality even more. ChatGPT is very good for ffmpeg research, by the way.
What About Streaming in CFR?
So far I’ve only talked about recording videos to local files, because that’s what I do.
But if you’re here looking for info in how to get OBS to stream at a constant frame rate, I have no answers for you. I imagine it’s impossible directly in OBS, and I also imagine it’s unnecessary for most applications.
The only solution I can imagine is to proxy the video streamed from OBS through some kind of transcoding tool that forces the video to CFR. I imagine it can be done by setting up an RTMP server and streaming to that, which then transcodes the video and sends it on to Twitch or wherever. I’ve tinkered with an RTMP server setup in the past but I’ve long since forgotten how to do any of that. Good luck. It ain’t easy.
What About OBS Alternatives
I have no direct experience with anything other than OBS and GeForce Nvidia Shadowplay in terms of recording game videos. I’m skeptical that other recording software will do any better than OBS, but I asked ChatGPT if there are any OBS alternatives specifically for recording CFR videos and it assured me there are. I don’t necessarily believe it.
My experience with OBS alternatives is as follows:
- GeForce Nvidia Shadowplay works well for me, in fact there was one game I can’t remember that would only record with Shadowplay (I think it was The Division 2), but I record on a second PC so I usually don’t have any need to record on the gaming PC itself. I have no idea if ShadowPlay records CFR videos or not. ChatGPT said it did. Wait, I have some older files I can check. Uh oh. One of my GeForce video files from 2021 is definitely not CFR. Womp womp. Maybe it’s different now.
- I tried Xsplit a long time ago, but I didn’t like it for reasons I can’t remember.
- I can’t remember using any other video capture software in the last nine years. OBS has the distinct advantages of being free, popular, regularly updated, and it works most of the time. And I mostly get how to use it. (The disadvantages are that it’s hard to learn, the UI is weird, and I’ve noticed the developers can be obstinate sometimes.)
How OBS VFR Files Affect Me
For my situation, which is mostly script-based and automated, I don’t need to convert OBS video files to CFR before I start using them.
I’m a bit baffled why I’ve never once noticed any problems or issues from OBS recording VFR videos. I think it has to be because I record on a second PC, so there’s an entire computer dedicated to the capturing and encoding process, completely separate from my gaming PC, so the variability in frame rate is fairly low. Every video I checked had an average frame rate of 60 fps, even if there was a non-zero variability.
But going forward, I’ve added an fps=60
parameter to all of my scripts that render videos. From now on, all my uploaded videos, which are the highest quality renders of my OBS videos, will be CFR. Since I’m re-encoding the videos anyway to add the logo in the corner, it makes sense to add in the conversion to CFR at the end.
I don’t expect there to be any noticeable change in the way my videos appear on YouTube, but it makes me feel better.
As for editing OBS videos in Davinci Resolve, I may run a CFR conversation beforehand, but initial tests show it isn’t necessary. In fact, I ran some experiments with the above-mentioned cfrtest.mp4
file and I observed absolutely no difference in the way Davinci Resolve handles the video file between VFR and CFR.
Both with the original OBS file and after conversion to CFR, there were no sync issues whatsoever and the audio lined up perfectly with the video, right to the last frame after 37 minutes. (I’m using Davinci Resolve 19, and I have paid for the pro license because it renders amazingly fast.)
I’m just a simple country programmer, but it seems like a solvable problem for a professional timeline video editor to work with VFR videos, and it seems plausible to me that someone has figured out how to do that somewhere along the relentless march of humankind’s progress into the stars. The armies of Davinci Resolve forum dwellers out there yelling, “Bro, you have to convert to CFR or it won’t work! We’re industry professionals! We know this stuff!” seems outdated to me. Maybe I’m just lucky that it works for me.
Technical Notes
Just for fun, I ran an ffprobe
command to count the frames and length of an OBS video before and after converting from VFR to CFR.
Before:
> ffmpeg -i "DD2-20250220194232 - Tolled To Rest, Worldsend Cavern.mp4"
-vf vfrdet -f null -
[Parsed_vfrdet_0 @ 0000027907321f40] VFR:0.666664 (91027/45514)
min: 1440 max: 1530 avg: 1484
> ffprobe -v error -select_streams v:0 -count_frames
-show_entries stream=nb_read_frames,duration
-of default=nokey=1:noprint_wrappers=1
"DD2-20250220194232 - Tolled To Rest, Worldsend Cavern.mp4"
2275.699000 [video length in seconds]
136542 [video length in frames]
> python -c "print(136542/2275.699000)"
60.00002636552549 [average fps]
After:
> ffmpeg -i "cfr\cfrtest.mp4" -vf vfrdet -f null -
[Parsed_vfrdet_0 @ 000001ccdfbce0c0] VFR:0.000000 (0/136541)
> ffprobe -v error -select_streams v:0 -count_frames
-show_entries stream=nb_read_frames,duration
-of default=nokey=1:noprint_wrappers=1
"cfr\cfrtest.mp4"
2275.700000 [video length in seconds]
136542 [video length in frames]
> python -c "print(136542/2275.700000)"
60.00000000000001 [average fps]
What I’ve Learned From This Experience
- Mainly I learned the difference between variable and constant frame rates. (One might argue that all videos are always variable frame rate because of the way timing is encoded into every frame.)
- OBS definitely generates VFR videos. I don’t know if other recording software does too, but I would guess that most do, and it seems like it would be unusual if one didn’t.
- It doesn’t affect my workflow that OBS generates VFR videos because the variance in frame rate is not very high in my case, and Davinci Resolve 19 seems to handle my OBS VFR videos fine.
- If I ever do notice problems due to VFR, I now have some tools to re-encode a VFR video into CFR like a boss.
This is a homegrown DIY comment system I'm working on. It technically works but it hasn't been through extensive testing yet. Good luck. Go here to enter a comment on this post without Javascript.