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.mp4

3. 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.mp4

Note: 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.mp4

Adjust -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.mp4

To list available audio sources to replace default:

pactl list short sources