惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
Scott Helme
Scott Helme
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
I
Intezer
Spread Privacy
Spread Privacy
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
Cloudbric
Cloudbric
V2EX - 技术
V2EX - 技术
Google Online Security Blog
Google Online Security Blog
L
Lohrmann on Cybersecurity
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LINUX DO - 热门话题
S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
Latest news
Latest news
B
Blog
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
L
LangChain Blog
GbyAI
GbyAI
Last Week in AI
Last Week in AI
S
Security Affairs
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
Security Latest
Security Latest
Vercel News
Vercel News
Y
Y Combinator Blog
G
GRAHAM CLULEY
S
Securelist
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
雷峰网
雷峰网

Morten Linderud

ACME device attestation, smallstep and pkcs11: attezt Personal infrastructure setup 2026 Self-hosting DNS for no fun, but a little profit! Easter hack: terraform-provider-openwrt SSH CA with device and identity attestation: ssh-tpm-ca-authority NixOS is not reproducible Stream to chromecast with resolved, vlc and bash Store ssh keys inside the TPM: ssh-tpm-agent Store age identities inside the TPM: age-plugin-tpm Golang crypto/ecdh and the TPM My FOSS work update coredumpctl, delve and debug packages for Go Monitoring the kernel.org Transparency Log for a year mkinitcpio v31 and UEFI stubs FOSS Activities in April 2021 FOSS Activities in March 2021 Simplifying and securing the boot process FOSS Activities in February 2021 FOSS Activities in January 2021 FOSS Activities in December 2020 Kubernetes in Arch Linux FOSS Activities in November 2020 PAM Bypass: when null(is not)ok FOSS Activities in October 2020 Improving the Secure Boot user experience Packaging LXD for Arch Linux Reproducible Arch Linux Packages Mailpile, sendmail and procmail The State of Hy Morten Linderud
Streaming the Steam Deck to OBS
Morten Linderud · 2022-03-26 · via Morten Linderud

Valve was kind enough to send Steam Deck devkits to Arch Linux maintainers and developers which gave us an opportunity to mess around with the device.

Personally I find it a bit fun to mess around with video streaming, thus one of the first things I wanted to try figure out was how I could stream the gamemode on the Steam Deck. Installing the OBS flatpak and adding it to the menu doesn’t actually work so we sadly have to be a bit more clever.

Essentially the goal is to run an RTMP server locally which OBS can read from using the “Media Source” layer, and figure out a way to have the Steam Deck to stream towards that.

Lets setup the RTMP stream first and check that it works.

Local Setup

We are going to use a quick docker container for this so we don’t have to deal with nginx directly.

λ ~ » podman run -d -p 1935:1935 --name rtmp-stream alfg/nginx-rtmp

This is going to give us a rtmp-stream container which will be serving us RTMP streams on port 1935. It accepts arbitrary path names with the prefix stream so for the purpose of this post we are going to use /stream/deck as our RTMP stream.

To test the stream we can simply use ffmpeg with a special testsrc input. Shamelessly stolen from Stack Overflow.

λ ~ » ffmpeg -r 30 -f lavfi -i testsrc  -vf scale=1280:960 -vcodec libx264 \
     -profile:v baseline -pix_fmt yuv420p  -f flv rtmp://localhost/stream/deck

To validate that this works we can just open the RTMP stream in vlc or mpv and get some test output back.

λ ~ » mpv rtmp://localhost/stream/deck

Now we can also make an OBS source for this. We are using the “Media Source” unhooking “Local File”. Add the RTMP source as “Input” and you should see the same test image in OBS.

For the next stems you need to figure out the local IP of your machine. This can be done by looking at ip -br addr, and for the purpose of this post the IP is 192.168.1.4 but this is going to be different on your system.

Steam Deck Setup

This setup assumes you have sshd running on your Steam Deck. The easiest way to get this done is to get into the Desktop Mode (Power Button -> Desktop Mode). Open konsole, set a password on the deck user with passwd and start ssh with systemctl start sshd.

Then you can run ip -br addr and find the IP of the wlan0 device and login with ssh deck@<localip>

Keep in mind that everything we do beyond this point is not going to be persistent and we need to rerun several of these steps after updating the Steam Deck.

Ffmpeg?

Ffmpeg is the bread and butter of modern video processing. It’s used everywhere and does any kind of media conversion and processing you can think of.

The first thing I tried was to get ffmpeg to stream from the Deck. There is a gist with instruction on how to use kmsgrab. But it overcomplicates a few things by trying to use obs-kmsgrab instead of having an outgoing RTMP stream.

For using the RTMP stream one could do the following

(deck@steamdeck ~)$ sudo ffmpeg -f kmsgrab -i - -vaapi_device /dev/dri/renderD128 \
-vf hwmap=derive_device=vaapi,scale_vaapi=format=nv12 -c:v h264_vaapi -bf 1 \
-f flv rtmp://192.168.1.4/stream/deck

The issue is that gamescope seems to change the byte layout of the buffer whenever you change from the gamemode UI to any games. ffmpeg seems expects this to never change. The “solution” to this is to wrap the ffmpeg command in a while loop so you restart the stream whenever it crashes, but you are still going to be left with green artifacts in the menu and some staggering.

The entire setup is less than stellar.

I made an issue on gamescope, but I don’t see how it’s going to be solved on their end. However, someone comments that gstreamer might work better. I gave that a shot instead.

Gstreamer

gstreamer is essentially a framework for video and audio where you can make pipelines. It’s super powerful and offers a bit more flexibility then the command line of ffmpeg.

First off we are going to install packages on the Deck. The first step to do this is to disable the readonly attribute of the system.

(deck@steamdeck ~)$ sudo steamos-readonly disable
(deck@steamdeck ~)$ sudo pacman -S gstreamer-vaapi gst-plugin-pipewire

We are using the vaapi plugins as we want hardware accelerated encoding, then the pipewire plugin for fetching the video itself.

Note that any changes to /etc is persistent, but since / is ephemeral it will actually loose track of any files pacman has written to this directory. If you install the above packages after an update you’ll find several file conflicts. You can ignore these by adding --overwrite='*' to pacman.

You might also need to initialize the pacman keyring if you see keyring error.

(deck@steamdeck ~)$ sudo pacman-key --init
(deck@steamdeck ~)$ sudo pacman-key --populate

The gstreamer pipeline itself took me a few days to figure out. We fetch the video from pipewiresrc and convert it to a h264 stream. We mux this with the pulseaudio sound source of the speakers. We encode this with aac and throw it towards the FLV muxer and onwards to the RTMP sink.

(deck@steamdeck ~)$ gst-launch-1.0 -e \
    pipewiresrc do-timestamp=True \
        ! queue \
        ! videoconvert \
        ! queue \
        ! vaapih264enc \
        ! h264parse \
        ! mux. \
    audiomixer name=mixer 
        ! fdkaacenc bitrate=32000 \
        ! queue 
        ! mux.
    pulsesrc device="alsa_output.pci-0000_04_00.5-platform-acp5x_mach.0.HiFi__hw_acp5x_1__sink.monitor" \
        ! queue \
        ! mixer.sink_0 \
    pulsesrc device="MIX THING HERE" \
        ! queue \
        ! mixer.sink_1 \
    flvmux name=mux streamable=True \
        ! rtmpsink location='rtmp://192.168.1.4/stream/deck live=1'

gst-launch-1.0 -e mp4mux name=mux ! filesink location=test.mp4

videotestsrc is-live=true ! nvvidconv ! nvv4l2h264enc ! h264parse ! queue ! mux.video_0

audiomixer name=mixer ! voaacenc ! queue ! mux.audio_0

audiotestsrc wave=sine ! queue ! mixer.sink_0

audiotestsrc wave=ticks ! queue ! mixer.sink_1

This seems works on my end. There seems to be some performance impact when doing this, even with vaapi. But it is probably negligible unless you are playing performance heavy games like Cyberpunk or Elden Ring.

And for the demonstration:

Improvements

There are probably several ways to make this easier to use. Asking people to deal with the terminal and ssh isn’t very approachable for non-Linux users. Someone on reddit added the script as a library application which can probably be a handy way of starting and stopping the stream.

It would also be neat to see if it would be possible to offload the encoding of the stream to the remote device and do less on the Deck itself.

This is a little bit of progress to enable streaming on the steam deck. Hopefully someone finds this useful! Thanks again to Valve for sending Devkits and thanks to folks on IRC for entertaining my cluelessness around gstreamer :)

Back to posts