A Dirty Hack to Enable Acceptable Sway WM Screen Recording
I’ve been running the Wayland display server on my XPS 9550 for a while now, using sway, the drop-in replacement for the i3 window manager. One of the significant changes you’ll notice moving to Wayland from X is that “regular” screen capture tools1 don’t work. This is due to Wayland’s security architecture; applications are no longer allowed access to the full frame buffer. In other words, apps can’t see what other apps are displaying unless they get special permission from the window manager. Because there is apparently no standardized screenshot/screen recording API to be used across different window managers, each window manager is effectively responsible for developing and including their own screenshot/screen-recording tool. Sway’s screenshot & screen recording tool is called swaygrab.
Recording with swaygrab
It’s really easy. I typically just use the following command to get a high-quality recording:
-c means “capture” a display continuously; without it,
swaygrab will just take a screenshot.
If you’re wondering what to use for
[display], you can list the displays that Sway sees by running
swaymsg -t get_outputs.2
I’ll leave it up to you to decide what to call your
You might also be interested in capturing audio while you’re doing this.
swaygrab does not capture audio, so my recommendation would be to use
arecord from the
alsamixer audio driver package.
-f cd argument is a present for 16-bit, 44100khz, stereo quality.
-D [device] specifies the recording device – you can list available devices by running
arecord -l, which will spit out something like the following:
To use that device, then your argument would be
-D hw:0,0. The first
0 specifies the card, and the second
0 specifies the subdevice.
The Dirty Hack
If you’ve recorded your screen and audio, you’ll notice that the resulting output files are of differing lengths – this is what I was talking about in the Background. The
.wav audio file you recorded will be the right length… but your
.mkv video file will come up short, often around 50% of the length of the
.wav file. This is no good. And even if they were the same length, it’d still be nice to have the audio and video embedded into one media file so you can easily share/upload the video.
First thing to do is calculate the length of the
.mkv in seconds. Then, divide the longer length (should be the
.wav's length) by the shorter length (the
.mkv's length); you should end up with a floating-point number between ~1.5 and ~2.5, although this may vary greatly. We’ll call this number the
[multiplier]. We’ll use the
[multiplier] to “stretch” the length of the
.mkv file to match that of the
[input_mkv] is actually the original, too-short
.mkv you already created.
[output].mkv is the new, proper-length
.mkv the preceding command will create.
Now, we just need to squash our new
.mkv and our original
.wav into one media file, which can be done with the following command:
In this case,
[input_mkv] is the newer, proper-length
[input_wav] is the audio you recorded. The
-c:v copy tells
ffmpeg to just keep the current video format/bitrate/etc., and the
-c:a aac tells
ffmpeg to convert the
.wav audio to the compressed AAC format for the final
Conclusion & Automation!
So was that confusing and poorly explained, or what? Probably… Fortunately, I love writing crappy Bash scripts, and so I’ve turned all of the information here into a script you can download and run yourself. It has the added bonus of automatically starting & stopping the screen and audio recording simultaneously!