Here is another method that uses Flatpak and
obs-vkcapture
, which don't meet my personal needs but are very likely to be useful for you. In the comments there there is also anobs-gstreamer
method.
Here is another method for recording that has its own GUI for Gaming Mode built with Decky Loader.
- Set a password (if you haven't already) and disable read-only rootfs (yes this means after updating SteamOS [not Steam Client] this will all be deleted and you will have to do all this again if you want to stream again)
passwd
sudo steamos-readonly disable
- (OPTIONAL) The on-Steam Deck OBS guide is written in a way that shouldn't require a separate device to actually execute any commands (the Sunshine guide requires a separate device for Moonlight), but for much less awkward and more efficient CLI activity, especially if you don't have a physical keyboard that's compatible with your Steam Deck, you can enable the SSH server to allow remotely connecting using your preferred keyboard-endowed device
sudo systemctl enable --now sshd
- Set up
pacman
WARNING: If you have a different version of SteamOS from me, this can mess up your rootfs, but luckily there is a backup rootfs in every OFW Steam Deck that you can access with the ・・・ + ⏻ button combination at boot, from which you can recover if that happens. Sometimes the contents of
pacman.conf
may be edited by SteamOS or become outdated. Thispacman.conf
is what's currently working correctly for me.SigLevel = Never
is set because sometimes, Valve doesn't have their packages signed correctly, making it sometimes impossible to get the correct signatures. What you hope to see aftersudo pacman -Syyu
is "there is nothing to do
", or at least very few upgrades available. That means you have found Valve repositories for yourpacman.conf
that contain packages very close to the rootfs image thatrauc
last installed, and the fewer packages that differ from your rootfs' preinstalled packages you have to install, the less likely it is you will encounter severe issues.
curl https://gist.githubusercontent.com/robertkirkman/753922262259486ec417e5ff8b5b924b/raw/2921bcd9d842a2ee8ad32d71e7c8367d7f941d5c/pacman.conf | sudo tee /etc/pacman.conf
sudo pacman-key --init
sudo pacman-key --populate
sudo pacman -Syyu
- Reinstall all corrupted packages that once contained header files before Valve deleted
/usr/include
You might see a huge number of errors generated by
dracut
during the post-transaction hooks phase. These are spurious and can be safely ignored.
sudo pacman -S $(pacman -Ql | grep include | cut -d' ' -f1 | awk '!a[$0]++')
- Install toolchain packages
sudo pacman --overwrite=/etc/ld.so.conf.d/fakeroot.conf -S base-devel meson cmake
- Install your preferred terminal emulator (unless you prefer
konsole
which is preinstalled), Launch KDE Plasma Xorg (Desktop Mode), open Steam LIBRARY tab, and add it as a non-Steam game; herekitty
is used as an example. At this time, I would also suggest you add a large number of dummy/duplicate non-Steam game entries for future use, because if you wish to remain in Gaming Mode, you will be able to change preexisting non-Steam game entries to add new shortcuts, which is otherwise impossible without switching to Desktop Mode.
paru -S kitty
- Suggested
kitty
Launch Options in non-Steam game properties:
LD_PRELOAD= %command% --start-as=fullscreen
- Fetch dependencies, build and install
sunshine
usingparu
paru -S sunshine
- Enable DRM capture mode in
sunshine
WARNING:
setcap
is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To removesetcap
permissions from any binaries granted this, usesudo setcap -r /path/to/file
.
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
- Create symlink to stub
xrandr
to work aroundError: [xrandr --output HDMI-1 --mode 1920x1080] failed with code [1]
, then runsunshine
:
ln -s /bin/true xrandr
export PATH=$(pwd):$PATH
sunshine &
- Make sure the Steam Deck is connected to Wi-Fi or Ethernet, and identify its local IP address for use in the following steps
ip a
- Now move to the LAN device you would like to connect to the Steam Deck's Sunshine from and install Moonlight and a browser capable of accessing Sunshine's PIN entry box, for example
epiphany
orungoogled-chromium
; example command for an Arch Linux device withyay
Unfortunately, OBS cannot record the
moonlight-qt
window in gamescope without adding the additional overhead of the OBS section below this section, andepiphany
is bugged and does not work ingamescope
, so both of these softwares can only be effectively used to connect to Steam Deck Gaming Mode Sunshine from a separate device.
yay -S moonlight-qt epiphany
- Launch your browser, connect to the Sunshine web server on the Steam Deck where you replace
192.168.12.146
with your Steam Deck's local IP address, accept all warnings (which occur on every default copy of Sunshine) and create a username and password for administration of Sunshine, re-enter the new credentials to log in, then navigate to the "PIN Pairing" entry box
epiphany https://192.168.12.146:47990
- Launch Moonlight and add the Steam Deck's IP address as a new device, then type the PIN provided by Moonlight into the PIN box in the browser window
Sometimes Moonlight will fail to authenticate the first time even if the PIN is correct, just keep trying until you can click on the Steam Deck's entry and see the "Desktop" button.
moonlight
- Click the Steam Deck's entry in Moonlight and the "Desktop" button, you can now see the entire Steam Deck screen and almost every menu and game, with a few exceptions - sometimes the onscreen keyboard and Quick Settings menu are invisible in Moonlight, but overall, Sunshine configured this way is capable of capturing much more, more reliably, than any other software. You can also capture the
moonlight-qt
window using OBS, which works better than the OBS guide below as long as you have this other system to run Moonlight on. Sometimes,sunshine
might crash or Moonlight might spontaneously disconnect; if that happens, just restart both and everything will start working again.
If you use Sunshine+Moonlight for streaming-based netplay (someone playing on Steam Deck while someone else plays on another device), you might want to configure advanced audio settings (such as making sure the person using Moonlight can hear the game audio, but not themselves through your VOIP software like Discord). Steam Deck contains two distinct digital sound controllers that behave almost the exact same way their desktop PC counterparts do, which makes such advanced audio settings both possible and nearly identical to how they would be on a desktop Arch Linux PC. Therefore, for now I consider such settings outside the scope of this guide, but if you struggle with audio settings, let me know and I will consider expanding this to cover that common audio use case.
- Install OBS
paru -S obs-studio
- If you do not have any unused dummy shortcuts to populate with OBS, launch KDE Plasma Xorg (Desktop Mode), open Steam and add OBS to Library as a non-Steam game, then right click on it, click Properties, and place the following text exactly as shown in the Launch Options box:
LD_PRELOAD= QT_QPA_PLATFORM=xcb %command%
- There are three possible capture sources for OBS that currently work in
gamescope
.obs-kmsgrab
used to work, and does still work in Xorg as a test, but I think it would need more updates to work with present-daygamescope
:
Unfortunately, this is a very messy method that encodes twice, stutters a lot, and sometimes looks green.
- Install FFmpeg
WARNING:
setcap
is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To removesetcap
permissions from any binaries granted this, usesudo setcap -r /path/to/file
.
yay -S ffmpeg
sudo setcap cap_sys_admin+ep $(readlink -f $(which ffmpeg))
- First create a new Scene in OBS, then add a new Media Source to the Scene and uncheck Local File. Then add the following and click OK
-
Input:
udp://localhost:4444
-
Input Format:
udp
- Switch to
gamescope
, navigate to Library and launch your terminal emulator, then execute this command;ffmpeg
will crash anytime you leave the Steam client window by selecting a game or non-Steam app, and this should automatically restart it
while true; do ffmpeg -thread_queue_size 512 -framerate 60 -device /dev/dri/card0 \
-f kmsgrab -i - -vaapi_device /dev/dri/renderD128 \
-vf 'hwmap=derive_device=vaapi,scale_vaapi=format=nv12' \
-c:v h264_vaapi -bf 1 -f mpegts udp://localhost:4444; done
- You will also need to bind Ctrl+C to actually be able stop this capture with the least difficulty; navigate to "Controller settings" for your terminal emulator's non-Steam game entry and bind buttons to these keys, as pictured below. It is very possible that there is a better way of controlling
ffmpeg
without an external keyboard than this, but unfortunately I haven't found that way yet.
- Navigate to Library, launch OBS and start your stream or recording now.
ffmpeg
will often crash when you switch windows, but wait for a few seconds each time you do. The loop will automatically resetffmpeg
, and anything you can look at should be captured. When you are done, navigate to OBS and stop your stream or recording, then navigate to your terminal emulator and hold down your Ctrl+C keybind for a few seconds to kill theffmpeg
loop
Sometimes,
ffmpeg
will only record a small rectangular portion of the screen and the rest will be black. I don't know exactly why this happens and I haven't found any way to consistently prevent it, but it doesn't happen every single time, so if the source looks incomplete in OBS, kill the loop and try running it again until it looks acceptable.
Special thanks to people who helped me with various parts of this guide: scaled#4479 logan2611#2351 kamae#7499 2zd9R#9421 and to the developers of all the software involved