I've left my year-long companion elementary os and changed to XeroLinux for my main machine. This was mostly due to being annoyed by the underlying Debian base and constant fighting to use not-so-outdated packages and having to use insecure sources a lot. It just didn't feel right anymore.
On elementary, I've used a lot of utility tools for various tasks, for example, for recording screencasts. Under the hood, these utils use shell commands such as FFmpeg. Unfortunately, these utils came with their own challenges and often didn't get updated enough. I ended up with a strong desire to go organic and run the FFmpeg commands directly. After all, I'm a developer and passionate Linux user, not a Window(s)-User ;) With the switch to XeroLinux it was time to also change this.
Here is how I use FFmpeg to record screens from bash for my daily work. My go-to solution is the built-in FFmpeg.
Record your Screen using FFmpeg on the CLI #
First, determine the screen size and position: To record the screen, you need to know the size and position of the screen. You can determine this by using the xdpyinfo
command in the terminal:
xdpyinfo | grep dimensions
For me, it prints:
dimensions: 2880x1800 pixels (762x476 millimeters)
Here 2880x1800
is my configured screen resolution.
Second, use the following command in the terminal to start recording the screen:
ffmpeg -f x11grab -s <screen-size> -i :0.0+<screen-position> -r 25 /tmp/output.mp4
Replace <screen-size>
with the size of your screen, here "2880x1800". The <screen-position>
with the position of your screen, for example, "0,0". The -r
option sets the frame rate to 25 frames per second, and /tmp/output.mp4
is the name of the output file written.
When you are finished with your recording press Ctrl+C in the terminal. FFmpeg will complete the file and write it to the disk.
How to record a specific window using FFmpeg? #
The above command will record the entire screen. If you want to record only a specific window, you can use the xwininfo
command to determine the position and size of the window, and use it in the -i
option instead of the screen position.
As a One-Liner #
These steps are a little unhandy in daily life. You can also merge the output xdpyinfo
into a single FFmpeg command using grep
and awk
:
ffmpeg -f x11grab -video_size $(xdpyinfo | grep 'dimensions:' | awk '{print $2;}') -i :0.0 -c:v libx264 -preset ultrafast output.mp4
This command records the entire screen, without audio. It uses xdpyinfo
to get the screen dimensions and sets them as the -video_size
option using a sub-shell ($(....)
).
The video codec used is libx264
with the ultrafast
preset. Again, the output file is named /tmp/output.mp4
.
As a One-Liner, with Audio #
ffmpeg -f x11grab -video_size $(xdpyinfo | grep 'dimensions:' | awk '{print $2;}') -i :0.0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac -b:a 128k /tmp/output.mp4
This command records the entire screen and audio from the default ALSA device. It uses xdpyinfo
to get the screen dimensions and sets them as the -video_size
option. The -f alsa -i default
options capture audio from the default ALSA device.
The video codec used is again libx264
and the audio codec used is aac
with a bitrate of 128k
. Of course, you can modify the options as needed.
Going Lossless #
If you aren't into losing any detail, you can go useless by setting the video codec to FFV1
. FFmpeg supports several lossless video codecs, such as FFV1, HuffYUV, and Ut Video. Using FFV1 you can run:
ffmpeg -f x11grab -video_size $(xdpyinfo | grep 'dimensions:' | awk '{print $2;}') -i :0.0 -c:v ffv1 -level 3 -g 1 -coder 1 -context 0 /tmp/output.mkv
In this command, the -c:v ffv1
option sets the video codec to FFV1
, which is one of FFmpeg's lossless video codecs. The -level 3
option specifies the compression level, with higher levels resulting in better compression but requiring more processing power. The -g 1
option sets the GOP (group of pictures) size to 1
, which means each frame is a keyframe and ensures that each frame is independently decodable. This is actually making it lossless. The flags -coder 1
and -context 0
appear to be also required for lossless encoding.
The output file is named /tmp/output.mkv
in this case. It's a container format that supports lossless video and other codecs.
Note: lossless video recording can result in very large file sizes and require high disk write speeds.
More? You can check the Arch documentation if you are keen to learn more about screencasts or find alternative tools.
🙏🙏🙏
Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.
Published