I want to generate a "timecode" video and need the output to be constant frame rate (CFR). I've tried multiple approaches with the fps filter, vsync etc, but MediaInfo always reports that the output file is VFR.
How do I force constant frame rate output?
Command:
ffmpeg -loglevel info -y \
-loop 1 \
-i backgroundImage.png \
-r 25 \
-vsync cfr \
-t 15 \
-c:v libx264 -b:v 0.45M -threads 2 \
-x264opts fps=25:keyint=25:min-keyint=25 -tune stillimage \
-filter_complex \
fps=fps=25,format=yuv420p,drawtext=fontfile='/fonts/NotoSans-Bold.ttf':x=30:y=400:fontcolor=white::fontsize=100:text='%{pts\\:localtime\\:1689994200}' \
-sws_flags bilinear \
-f mpegts -metadata service_name='Service01' -metadata service_name='MyService' \
-muxrate 0.5M \
outputTimecodeFile.ts
MediaInfo says:
Width : 1280
Height : 720
Pixel aspect ratio : 1.000
Display aspect ratio : 16:9
Frame rate mode : VFR
Frame rate mode : Variable
Color space : YUV
EDIT I
Based on the comment by 1NN and the related link I tried putting -framerate before the -i input (see below).
However, the result is the same: MediaInfo reports "Variable Frame Rate"...
ffmpeg -loglevel info -y \
-loop 1 \
-framerate 25 \
-i backgroundImage.png \
-r 25 \
-t 15 \
-c:v libx264 -b:v 0.45M -threads 2 -x264opts keyint=25:min-keyint=25 -tune stillimage \
-filter_complex \
format=yuv420p,drawtext=fontfile='fonts/NotoSans-Bold.ttf':x=30:y=400:fontcolor=white::fontsize=100:text='%{pts\\:localtime\\:1689994200}' \
-sws_flags bilinear \
-f mpegts -metadata service_name='Service01' -metadata service_name='myService' \
-muxrate 0.5M \
timecodeFile.ts
EDIT II
According to this MediaInfo bug report, MediaInfo uses the fixed_frame_rate_flag within the H264 stream to decide if a stream is variable or fixed.
However, ffmpeg is creating the stream with fixed_frame_rate_flag set to zero (confirmed using ffmpeg -i inputFile.ts -c:v copy -bsf:v trace_headers -f null - 2>&1 | grep fixed_frame_rate
Supposedly I can set that flag using the bitstream filters. I tried adding -bsf:v h264_metadata=fixed_frame_rate_flag=1 to the command but I get a lot of errors:
Error applying bitstream filters to an output packet for stream #0:0.
[h264_metadata @ 0x1887380] PPS id 0 not available.
[h264_metadata @ 0x1887380] Failed to write unit 0 (type 1).
[h264_metadata @ 0x1887380] Failed to write access unit into packet.
References: