How to minimize usage of CPU/memory by ffmpeg when recording video

1. Make a lossless RGB output first

ffmpeg -y -framerate 25 -video_size 1280x1024 -f x11grab -i :0.0 -c:v libx264rgb \
-crf 0 -preset ultrafast temp.mp4
  • The input is RGB, so using the encoder libx264rgb will avoid the potentially slow RGB to YUV conversion that would occur if you use plain libx264.

  • This uses the quickest x264 encoding preset: ultrafast.

  • The output will be lossless because -crf 0 is used.

2. Then re-encode it

The output from the first command will be huge, and most dumb players can't handle RGB H.264 so you can re-encode it:

ffmpeg -i temp.mp4 -c:v libx264 -crf 23 -preset medium -vf format=yuv420p out.mp4
  • You can experiment with the -crf value to control output quality. A subjectively sane range is 18-28, where 18 is visually lossless or nearly so. Default is 23.

  • Use the slowest preset you have patience for: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Default is medium.

  • I added -vf format=yuv420p to ensure the output works with dumb players like QuickTime and Windows Media Player. You can omit this if you're uploading it to YouTube or only playing it on VLC, mpv, MPlayer, or any other FFmpeg based player.

Also see

  • FFmpeg Wiki: H.264 Encoding Guide

It is better to concentrate on using different ffmpeg options that will achieve the same result in a way that uses less resources. That said, there are ways to use less resources if you really need to accomplish a specific thing with ffmpeg and it is using too many resources.

You can decrease the priority of ffmpeg's CPU process:

  • Terminal method: Use the nice command to change the process's priority: nice -n 8 ffmpeg -y -r 15 -g 600 -s 1280x1024x24 -f x11grab -i :100 -vcodec libx264 /tmp/video.mov. In Linux, the priority number (the nice command format is nice -n <priority> <command>) ranges from -20 to 20. The greater the integer, the lower the priority is; neutral is 0. If you use the command I gave you and set it to 8, the CPU will give the process less time, which seems like less "power". If this number is too high or two low, of course, you can change it.
  • GUI method: This isn't recommended because it gives you less control over the exact number and it doesn't take effect as soon as the process begins. However, it is more comprehensible. With ffmpeg running, open the System Monitor. Scroll down to the process named ffmpeg, left click it to select, right click it, and set the priority to "Low" or "Very Low".

If you're worried about memory usage, too, know that it is not possible to tell a process to only take so much memory and still run. The kernel automatically controls memory allocation for processes. There is a way to cage processes, with the timeout script, so that when a process and any child processes take up too much memory (a limit set by you) they are terminated safely and a notification is displayed. However, if a process is only given so much memory (say by the kernel) and it requests more memory that it cannot have, it will crash.

Some helpful things to know about:

  • Cgroups - https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
  • The kernel's memory controller - https://www.kernel.org/doc/Documentation/cgroups/memory.txt

Using knowledge of Cgroups, you can do lots of fun things like controlling the swappiness of a process.