Skip to main content

Gamepad streaming for Linux

Project description

stick-stream

stick-stream is an ultra low-latency, virtual USB streaming system for Linux-based OSes. It is designed as an Linux-native, open-source alternative to VirtualHere for gaming purposes.

stick-stream can be used to forward controller input from one machine (for example, a Raspberry Pi with USB gamepads attached) to another machine over the network and exposes those controllers as virtual Linux input devices via uinput.

stick-stream is designed to work seamlessly with Sunshine and Steam for gaming. The original use case was to forward controller inputs from a Raspberry Pi in my living room to my gaming PC which resides in a different room.

Features

  • 🎮 Stream one or more gamepads over a local network.
  • ⚡ Low-latency UDP-based transport. I play FPS games with stick-stream and do not notice any input lag.
  • 🧠 Correctly handles analog sticks, triggers, D-pads, and all controller buttons.

How It Works

stick-stream consists of two components:

  1. Broadcaster – Runs on the machine with the physical controllers attached

    • Reads input events from /dev/input/event*
    • Serializes button and axis events
    • Sends them over the network
  2. Receiver – Runs on the host machine (e.g. Sunshine server)

    • Receives events over UDP
    • Recreates controllers using uinput

From the perspective of games and applications, the streamed controller is indistinguishable from a locally connected USB gamepad.

Usage

I'm still developing and testing this package, so there is no pip distribution of this software (yet). If you want to use it, the following is a hacky way to get it to work. The instructions are split into what you need to do on both the broadcast and receiving computers.

  • Broadcast computer: has gamepads plugged into it
  • Receiving computer: receives the gamepad events

⚠️ Ensure Python 3.12.7 is installed on both the broadcast and receiving computer.

On both the broadcast and receiving computers

  1. Clone this repo: git clone git@github.com:danielschwabacher/stick-stream.git

  2. Setup a Python venv in the repo you just cloned: python -m venv .

  3. Start the venv: source bin/activate

  4. Install the dependencies: pip install -r ./requirements.txt

  5. Install the stick-stream binary: pip install -e .

On the broadcast computer

  • stick-stream broadcast --to={IP of the receiving computer} --port={an empty port the service can used for communication}

On the receiving computer

  • stick-stream receive --port={the same port used by the first command}

If the software is working properly, you can now do gamepad inputs from the broadcast computer and see them reflected in the receiver computer!

FAQs

Does this replace VirtualHere?

Short answer: no.

VirtualHere supports anything that can be plugged into a USB port (like flash drives and Bluetooth dongles). stick-stream is really only designed to forward gamepad inputs.

My guess is that VirtualHere captures everything sent into the USB port and somehow replays them remotely to the connected VirtualHere clients. This is much different than stick-stream which only forwards controller input at the Linux input (evdev) level.

However, if you were only using VirtualHere to forward your gamepad inputs over the network, then stick-stream will accomplish these same goals.

Does this work on non-Linux OSes?

No, not in it's current state. stick-stream relies heavily on some Linux-specific Kernel features and I have no plans to port it to other operating systems.

Technical info (ignore this section)

Sender

  • Any Linux distro (tested on Debian)
  • Python 3.12.7
  • python-evdev

Receiver

  • Any Linux distro (tested on Fedora 43)
  • Python 3.12.7
  • python-evdev
  • python-uinput

Installation

1. Install system dependencies

sudo apt install python3-evdev
sudo modprobe uinput

Ensure uinput loads at boot:

echo uinput | sudo tee /etc/modules-load.d/uinput.conf

2. Install Python dependencies

pip install evdev uinput

⚠️ Note: python-uinput has multiple incompatible APIs across distros. stick-stream targets the tuple-based API commonly found on Debian/Ubuntu systems.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stick_stream-0.1.0.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stick_stream-0.1.0-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file stick_stream-0.1.0.tar.gz.

File metadata

  • Download URL: stick_stream-0.1.0.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for stick_stream-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6670114a5a9bc34e4e2a2e9928cf1941608462834b58baa27e1dfedae323fe6d
MD5 a800a20fa2fda8617e6e741e775f6b7b
BLAKE2b-256 84e94a96d22d89c37d30fc63ab5314e5fd6635fe564f7594349e3edfe27b2a1f

See more details on using hashes here.

File details

Details for the file stick_stream-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: stick_stream-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for stick_stream-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 801a061a75f8d26aad2794d4f7daf96a53f1bf71a78617a5f4c21a2b42b4a4a3
MD5 2759278efcf1f87adc57416b5cdaa6ef
BLAKE2b-256 5d2b3739c4ffed86c2b84f6b34fbb07f2dadb28d6d8fca93be250d3d3eb78ea1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page