0

I wrote the following script to capture both the screen and the audio from the microphone, both lossless from my laptop:

#!/bin/bash d=$(date +"%Y%m%d_%-H%M") dimensions=$(xdpyinfo |grep dimensions| awk '{print $2}';) ffmpeg -f x11grab -r 25 -s "${dimensions}" -i "${DISPLAY}" -f alsa -ac 2 -i default -c:v libx264rgb -crf 0 -color_range 2 -preset ultrafast -c:a pcm_s16le -strict -2 "${d}.mkv" 

The sound becomes very intermittent when setting to a very low number of frames per second (the sound practically disappears when r is set to 7) and it improves substantially to an acceptable quality with -r set to 50 or higher. This behaviour is also present with lossy capturing of the screen and audio as with ffmpeg -f alsa -ac 2 -i default -f x11grab -s "${dimensions}" -r 7 -i "${DISPLAY}" "${d}.mkv"
Why does the -r parameter influence the quality of the sound? Is the syntax of my script incorrect? When I record the audio without screencasting, either ffmpeg -f alsa -ac 2 -i default "${d}.mp4" or ffmpeg -f alsa -ac 2 -i default "${d}.wav" works fine giving me satisfying quality of the audio. The output from recording with ffmpeg -f x11grab -r 25 -s "${dimensions}" -i "${DISPLAY}" -f alsa -ac 2 -i default -c:v libx264rgb -crf 0 -color_range 2 -preset ultrafast -c:a pcm_s16le -strict -2 "${d}.mkv" is:

ffmpeg version 5.1.4-0+deb12u1 Copyright (c) 2000-2023 the FFmpeg developers built with gcc 12 (Debian 12.2.0-14) configuration: --prefix=/usr --extra-version=0+deb12u1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-libjxl --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared libavutil 57. 28.100 / 57. 28.100 libavcodec 59. 37.100 / 59. 37.100 libavformat 59. 27.100 / 59. 27.100 libavdevice 59. 7.100 / 59. 7.100 libavfilter 8. 44.100 / 8. 44.100 libswscale 6. 7.100 / 6. 7.100 libswresample 4. 7.100 / 4. 7.100 libpostproc 56. 6.100 / 56. 6.100 [x11grab @ 0x55d20fe24040] Stream #0: not enough frames to estimate rate; consider increasing probesize Input #0, x11grab, from ':0': Duration: N/A, start: 1707046868.487852, bitrate: 1658880 kb/s Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 1658880 kb/s, 25 fps, 1000k tbr, 1000k tbn Guessed Channel Layout for Input Stream #1.0 : stereo Input #1, alsa, from 'default': Duration: N/A, start: 1707046868.768038, bitrate: 1536 kb/s Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s Stream mapping: Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264rgb)) Stream #1:0 -> #0:1 (pcm_s16le (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help [libx264rgb @ 0x55d20fe7e9c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 [libx264rgb @ 0x55d20fe7e9c0] profile High 4:4:4 Predictive, level 4.0, 4:4:4, 8-bit [libx264rgb @ 0x55d20fe7e9c0] 264 - core 164 r3095 baee400 - H.264/MPEG-4 AVC codec - Copyleft 2003-2022 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=24 lookahead_threads=4 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=cqp mbtree=0 qp=0 Output #0, matroska, to '20240204_1241-loseless.mkv': Metadata: encoder : Lavf59.27.100 Stream #0:0: Video: h264 (H264 / 0x34363248), bgr0(pc, progressive), 1920x1080, q=2-31, 25 fps, 1k tbn Metadata: encoder : Lavc59.37.100 libx264rgb Side data: cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s16, 1536 kb/s Metadata: encoder : Lavc59.37.100 pcm_s16le frame= 1 fps=0.0 q=0.0 size= 1kB time=00:00:00.02 bitrate= 286.5kbits/sframe= 21 fps=0.0 q=0.0 size= 1kB time=00:00:00.02 bitrate= 286.5kbits/s[alsa @ 0x55d20fe30440] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8) [alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 33 fps= 32 q=0.0 size= 1kB time=00:00:00.81 bitrate= 7.3kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 46 fps= 30 q=0.0 size= 1kB time=00:00:00.82 bitrate= 7.3kbits/sframe= 58 fps= 28 q=0.0 size= 1kB time=00:00:01.58 bitrate= 3.8kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 71 fps= 28 q=0.0 size= 1kB time=00:00:02.34 bitrate= 2.6kbits/sframe= 84 fps= 28 q=0.0 size= 5376kB time=00:00:02.34 bitrate=18780.5kbits/[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 96 fps= 27 q=0.0 size= 5376kB time=00:00:03.14 bitrate=14003.2kbits/[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 109 fps= 27 q=0.0 size= 5376kB time=00:00:03.93 bitrate=11186.2kbits/frame= 122 fps= 27 q=0.0 size= 5376kB time=00:00:03.93 bitrate=11186.2kbits/[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 134 fps= 26 q=0.0 size= 5376kB time=00:00:04.70 bitrate=9358.3kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 147 fps= 26 q=0.0 size= 5376kB time=00:00:04.88 bitrate=9020.9kbits/sframe= 160 fps= 26 q=0.0 size= 5376kB time=00:00:05.49 bitrate=8010.2kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 173 fps= 26 q=0.0 size= 5376kB time=00:00:06.25 bitrate=7039.7kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 185 fps= 26 q=0.0 size= 5376kB time=00:00:06.39 bitrate=6889.9kbits/sframe= 198 fps= 26 q=0.0 size= 5376kB time=00:00:07.02 bitrate=6268.2kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. [matroska @ 0x55d20fe7d800] Non-monotonous DTS in output stream 0:1; previous: 7108, current: 7104; changing to 7108. This may result in incorrect timestamps in the output file. [matroska @ 0x55d20fe7d800] Non-monotonous DTS in output stream 0:1; previous: 7173, current: 7170; changing to 7173. This may result in incorrect timestamps in the output file. frame= 211 fps= 26 q=0.0 size= 7424kB time=00:00:07.82 bitrate=7776.2kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 223 fps= 26 q=0.0 size= 7424kB time=00:00:07.97 bitrate=7626.0kbits/sframe= 236 fps= 26 q=0.0 size= 7424kB time=00:00:08.58 bitrate=7088.3kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 248 fps= 26 q=0.0 size= 7424kB time=00:00:09.34 bitrate=6510.1kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 261 fps= 26 q=0.0 size= 7424kB time=00:00:09.40 bitrate=6469.2kbits/sframe= 273 fps= 26 q=0.0 size= 7424kB time=00:00:10.14 bitrate=5996.0kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 286 fps= 26 q=0.0 size= 8960kB time=00:00:10.93 bitrate=6711.2kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 299 fps= 26 q=0.0 size= 8960kB time=00:00:10.94 bitrate=6703.8kbits/sframe= 312 fps= 26 q=0.0 size= 8960kB time=00:00:11.69 bitrate=6276.2kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 324 fps= 26 q=0.0 size= 8960kB time=00:00:12.46 bitrate=5888.5kbits/sframe= 337 fps= 26 q=0.0 size= 8960kB time=00:00:12.46 bitrate=5888.5kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 349 fps= 26 q=0.0 size= 8960kB time=00:00:13.26 bitrate=5533.0kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 362 fps= 26 q=0.0 size= 8960kB time=00:00:13.47 bitrate=5445.9kbits/s[matroska @ 0x55d20fe7d800] Non-monotonous DTS in output stream 0:1; previous: 13457, current: 13451; changing to 13457. This may result in incorrect timestamps in the output file. [matroska @ 0x55d20fe7d800] Non-monotonous DTS in output stream 0:1; previous: 13457, current: 13453; changing to 13457. This may result in incorrect timestamps in the output file. frame= 374 fps= 25 q=0.0 size= 8960kB time=00:00:14.05 bitrate=5220.9kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 387 fps= 25 q=0.0 size= 8960kB time=00:00:14.82 bitrate=4952.8kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 400 fps= 25 q=0.0 size= 8960kB time=00:00:15.04 bitrate=4878.7kbits/sframe= 413 fps= 25 q=0.0 size= 11776kB time=00:00:15.57 bitrate=6193.0kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 425 fps= 25 q=0.0 size= 11776kB time=00:00:16.33 bitrate=5905.7kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. frame= 438 fps= 25 q=0.0 size= 11776kB time=00:00:16.48 bitrate=5853.3kbits/sframe= 451 fps= 25 q=0.0 size= 17408kB time=00:00:17.09 bitrate=8340.0kbits/s[alsa @ 0x55d20fe30440] ALSA buffer xrun. [q] command received. Exiting. frame= 455 fps= 25 q=-1.0 Lsize= 21617kB time=00:00:18.16 bitrate=9750.7kbits/s speed=1.01x video:20715kB audio:896kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.025721% [libx264rgb @ 0x55d20fe7e9c0] frame I:2 Avg QP: 0.00 size:950424 [libx264rgb @ 0x55d20fe7e9c0] frame P:453 Avg QP: 0.00 size: 42629 [libx264rgb @ 0x55d20fe7e9c0] mb I I16..4: 100.0% 0.0% 0.0% [libx264rgb @ 0x55d20fe7e9c0] mb P I16..4: 56.4% 0.0% 0.0% P16..4: 0.1% 0.0% 0.0% 0.0% 0.0% skip:43.5% [libx264rgb @ 0x55d20fe7e9c0] coded y,u,v intra: 1.8% 1.8% 2.0% inter: 0.1% 0.1% 0.1% [libx264rgb @ 0x55d20fe7e9c0] i16 v,h,dc,p: 98% 2% 0% 0% [libx264rgb @ 0x55d20fe7e9c0] kb/s:9323.81 

The laptop (Debian based system, utilizing X11 for the window manager, 16GB of RAM, Intel i7-10870H CPU 2.20GHz - 16 cores, NVIDIA Corporation GA106M [GeForce RTX 3060 Mobile / Max-Q]) does not lack compute, the loading averages when not recording are: 0.16, 0.14, 0.38.

1 Answer 1

1

For x11grab you should be using -framerate and not -r.

Here is what you should use:

ffmpeg -f x11grab -framerate 25 -s ${dimensions} -i ${DISPLAY} -f alsa -ac 2 -i default -c:v libx264rgb -crf 0 -color_range 2 -vf mpdecimate=0:1:1:1 -preset superfast -c:a flac ${d}.mkv 

I also changed the preset to superfast to enable CABAC coding which improves compression ratio significantly and in my experience will never be a bottleneck for screen recording.

I also added a video filter which will deduplicate frames that are 100% identical and create a VFR video (very very useful when screen recording and lets you increase the framerate a lot without increasing system load or video bitrate much). It's still lossless and has identical output to a CFR video with duplicated frames.

Finally I changed the audio codec to flac. It is lossless and it's much better to use flac than raw pcm.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.