I'm using FFmpeg to record a virtual X11 screen in automated tests. I've added a timestamp to the video to align it with log file times, but the clock in the video becomes out of sync with real time by several seconds. Initially, the video starts in sync, but over time, it drifts by as much as 30 seconds.
Here is the FFmpeg command I use:
ffmpeg -y -f x11grab -i "$DISPLAY" -framerate 8 -s 3840x2560 -vf "scale=1920:1280,drawtext=expansion=strftime:fontsize=20:fontcolor=red:text='%Y-%m-%d\ %T':x=10:y=10" -codec:v libx264 -pix_fmt yuv420p -preset ultrafast -crf 28 screenrecording.mp4
To understand this better, I launched xclock on the screen to compare the FFmpeg timestamp with real-time during recording.
At second 0 of recording, the clocks are in sync:
Several minutes into the video, the clock is out of sync by several seconds:
While using xclock as a workaround is possible, I want to understand and fix the issue.
The video length corresponds to the red ffmpeg clock. So one second of video footage does not equal one second of real time. I would like the recording to be time accurate.
Here is the FFmpeg log:
ffmpeg version N-115391-g63697d3350 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
configuration: --enable-libfontconfig --enable-libharfbuzz --enable-libfreetype --enable-gpl --enable-version3 --enable-nonfree --enable-small --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libvpx --enable-libfdk-aac --enable-libopus --enable-libxcb
libavutil 59. 20.100 / 59. 20.100
libavcodec 61. 5.104 / 61. 5.104
libavformat 61. 3.104 / 61. 3.104
libavdevice 61. 2.100 / 61. 2.100
libavfilter 10. 2.102 / 10. 2.102
libswscale 8. 2.100 / 8. 2.100
libswresample 5. 2.100 / 5. 2.100
libpostproc 58. 2.100 / 58. 2.100
(_NET_CLIENT_LIST or _WIN_CLIENT_LIST)
[x11grab @ 0x57eaa272f040] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, x11grab, from 'xserver:0.0':
Duration: N/A, start: 1716731100.208870, bitrate: 4713878 kb/s
Stream #0:0: Video: rawvideo (RGB[16] / 0x10424752), rgb565le, 3840x2560, 4713878 kb/s, 29.97 fps, 1000k tbr, 1000k tbn
[Parsed_drawtext_1 @ 0x57eaa2740400] expansion=strftime is deprecated.
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[Parsed_drawtext_1 @ 0x7e059000fe40] expansion=strftime is deprecated.
[libx264 @ 0x57eaa273acc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x57eaa273acc0] profile Constrained Baseline, level 6.0
[libx264 @ 0x57eaa273acc0] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=1 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=28.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to 'screenrecording.mp4':
Metadata:
encoder : Lavf61.3.104
Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 3840x2560, q=2-31, 29.97 fps, 30k tbn
Metadata:
encoder : Lavc61.5.104 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A dup=1 drop=0 speed=N/A
frame= 3 fps=2.0 q=18.0 size= 0KiB time=00:00:00.10 bitrate= 3.8kbits/s dup=2 drop=0 speed=0.0665x
frame= 10 fps=5.0 q=18.0 size= 0KiB time=00:00:00.33 bitrate= 1.2kbits/s dup=4 drop=0 speed=0.166x
frame= 15 fps=6.0 q=18.0 size= 0KiB time=00:00:00.50 bitrate= 0.8kbits/s dup=5 drop=0 speed= 0.2x
frame= 18 fps=6.0 q=18.0 size= 0KiB time=00:00:00.60 bitrate= 0.6kbits/s dup=5 drop=0 speed= 0.2x
frame= 20 fps=5.7 q=18.0 size= 0KiB time=00:00:00.66 bitrate= 0.6kbits/s dup=5 drop=0 speed=0.19x
frame= 23 fps=5.7 q=18.0 size= 0KiB time=00:00:00.76 bitrate= 0.5kbits/s dup=7 drop=0 speed=0.192x
frame= 29 fps=6.4 q=18.0 size= 0KiB time=00:00:00.96 bitrate= 0.4kbits/s dup=20 drop=0 speed=0.215x
frame= 37 fps=7.4 q=18.0 size= 0KiB time=00:00:01.23 bitrate= 0.3kbits/s dup=26 drop=0 speed=0.247x
[...]
frame=16715 fps= 29 q=18.0 size= 104448KiB time=00:09:17.72 bitrate=1534.2kbits/s dup=15558 drop=0 speed=0.969x
frame=16721 fps= 29 q=18.0 size= 104704KiB time=00:09:17.92 bitrate=1537.4kbits/s dup=15567 drop=0 speed=0.969x
frame=16726 fps= 29 q=18.0 size= 104704KiB time=00:09:18.09 bitrate=1536.9kbits/s dup=15567 drop=0 speed=0.968x
frame=16731 fps= 29 q=18.0 size= 104704KiB time=00:09:18.25 bitrate=1536.5kbits/s dup=15567 drop=0 speed=0.968x
frame=16733 fps= 29 q=18.0 size= 104704KiB time=00:09:18.32 bitrate=1536.3kbits/s dup=15582 drop=0 speed=0.967x
frame=16737 fps= 29 q=18.0 size= 104704KiB time=00:09:18.45 bitrate=1535.9kbits/s dup=15582 drop=0 speed=0.966x
frame=16744 fps= 29 q=18.0 size= 104704KiB time=00:09:18.69 bitrate=1535.3kbits/s dup=15582 drop=0 speed=0.966x
frame=16747 fps= 29 q=18.0 size= 104704KiB time=00:09:18.79 bitrate=1535.0kbits/s dup=15582 drop=0 speed=0.965x
frame=16749 fps= 29 q=15.0 size= 104704KiB time=00:09:18.85 bitrate=1534.8kbits/s dup=15601 drop=0 speed=0.964x
frame=16750 fps= 29 q=29.0 size= 104704KiB time=00:09:18.89 bitrate=1534.7kbits/s dup=15601 drop=0 speed=0.964x
frame=16750 fps= 29 q=29.0 size= 104704KiB time=00:09:18.89 bitrate=1534.7kbits/s dup=15601 drop=0 speed=0.963x
frame=16750 fps= 29 q=29.0 size= 104704KiB time=00:09:18.89 bitrate=1534.7kbits/s dup=15601 drop=0 speed=0.962x
frame=16750 fps= 29 q=29.0 size= 104704KiB time=00:09:18.89 bitrate=1534.7kbits/s dup=15601 drop=0 speed=0.961x
frame=16759 fps= 29 q=18.0 size= 106496KiB time=00:09:19.19 bitrate=1560.1kbits/s dup=15601 drop=0 speed=0.961x
frame=16768 fps= 29 q=18.0 size= 106496KiB time=00:09:19.49 bitrate=1559.3kbits/s dup=15633 drop=0 speed=0.96x
frame=16780 fps= 29 q=18.0 size= 106496KiB time=00:09:19.89 bitrate=1558.2kbits/s dup=15633 drop=0 speed=0.96x
[out#0/mp4 @ 0x57eaa2739a80] video:111962KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.064258%
frame=17543 fps= 29 q=-1.0 Lsize= 112034KiB time=00:09:45.35 bitrate=1567.9kbits/s dup=16344 drop=0 speed=0.977x
[libx264 @ 0x57eaa273acc0] frame I:71 Avg QP:15.30 size:970052
[libx264 @ 0x57eaa273acc0] frame P:17472 Avg QP:18.20 size: 2620
[libx264 @ 0x57eaa273acc0] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x57eaa273acc0] mb P I16..4: 0.1% 0.0% 0.0% P16..4: 0.9% 0.0% 0.0% 0.0% 0.0% skip:99.0%
[libx264 @ 0x57eaa273acc0] coded y,uvDC,uvAC intra: 20.3% 18.0% 16.8% inter: 0.2% 0.8% 0.1%
[libx264 @ 0x57eaa273acc0] i16 v,h,dc,p: 71% 27% 1% 1%
[libx264 @ 0x57eaa273acc0] i8c dc,h,v,p: 73% 23% 4% 1%
[libx264 @ 0x57eaa273acc0] kb/s:1566.90
Exiting normally, received signal 2.
-i "$DISPLAY"
to after-s 3840x2560
. Then add-fps_mode passthrough
after-codec:v libx264