How to Capture Wayland Screen with FFmpeg
This article provides a guide to recording your desktop screen on
Linux under a Wayland session using FFmpeg. Because Wayland's security
architecture restricts applications from reading the screen directly,
traditional tools like x11grab do not work. Below, you will
learn the most direct methods to capture your Wayland display using
FFmpeg: via Kernel Mode Setting (kmsgrab) for
hardware-level capture, and by piping PipeWire streams into FFmpeg for
desktop-integrated recording.
Method 1: Direct
Hardware Capture with kmsgrab
The kmsgrab input device allows FFmpeg to capture raw
frames directly from the Linux Direct Rendering Manager (DRM) / Kernel
Mode Setting (KMS) interface. This bypasses Wayland compositor
restrictions entirely.
1. Grant Permissions
kmsgrab requires administrative privileges to read the
framebuffer. You can grant FFmpeg the necessary capabilities without
running the entire command as root:
sudo setcap cap_sys_admin+ep $(which ffmpeg)2. Record the Screen (Software Encoding)
Run the following command to record the entire display to an MP4 container using the CPU:
ffmpeg -device /dev/dri/card0 -f kmsgrab -i - \
-vf 'hwdownload,format=bgr0' \
-c:v libx264 -preset ultrafast -crf 23 \
output.mp43. Record the Screen (Hardware Accelerated via VA-API)
If you use an Intel or AMD GPU, you can keep the frames in GPU memory using VA-API to drastically reduce CPU usage:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-device /dev/dri/card0 -f kmsgrab -i - \
-vf 'hwmap=derive_device=vaapi,scale_vaapi=format=nv12' \
-c:v h264_vaapi -b:v 5M \
output.mp4Note: Replace /dev/dri/card0 and
/dev/dri/renderD128 with your system's corresponding
graphics card and render nodes if different.
Method 2: Capture via PipeWire and GStreamer Pipe
Modern Wayland compositors (such as GNOME, KDE Plasma, and Sway) use
PipeWire and the Desktop Portal framework
(xdg-desktop-portal) to handle screen sharing. You can use
GStreamer to request the Wayland video stream through PipeWire and pipe
the raw output into FFmpeg.
1. Install Dependencies
Ensure you have pipewire,
gstreamer1.0-pipewire, and
gstreamer1.0-plugins-base installed on your
distribution.
2. Pipe the Stream into FFmpeg
Execute the following pipeline:
gst-launch-1.0 -q pipewiresrc capture-screen=true ! \
videoconvert ! \
video/x-raw,format=BGRx ! \
fdsink fd=1 | \
ffmpeg -f rawvideo -pixel_format bgr0 -video_size 1920x1080 -framerate 30 -i pipe:0 \
-c:v libx264 -preset veryfast -crf 20 \
output.mp4Adjust -video_size and -framerate to
match your display resolution and desired capture rate.
Adding Audio to the Capture
To include desktop audio or microphone input alongside your screen
recording, add the PulseAudio/PipeWire audio source using the
pulse input format.
Record Screen and Desktop Audio:
ffmpeg -device /dev/dri/card0 -f kmsgrab -i - \
-f pulse -i default \
-vf 'hwdownload,format=bgr0' \
-c:v libx264 -preset ultrafast \
-c:a aac -b:a 192k \
output.mp4To list available audio sources to replace default:
pactl list short sources