LinuxPlay captures your desktop with FFmpeg (kmsgrab or x11grab on Linux),
encodes it with GPU or CPU (NVENC QSV VAAPI or software), and streams
unicast UDP directly to the client’s IP on per-monitor ports (video from 5000+, audio 6001).
A tiny TCP handshake (7001) negotiates the host encoder and shares monitor geometry; inputs go back over
UDP control (7000), controller/gamepad over UDP (7005), clipboard sync uses UDP (7002),
file drag-and-drop uploads via TCP (7003), and a PING/PONG heartbeat runs on UDP (7004).
The client decodes with PyAV + optional hardware accel and renders via a low-latency PyQt5 + OpenGL path.
Scope & Security: Hosting is Linux-only; the client runs on Linux and Windows. For WAN, put the host behind a WireGuard tunnel and connect to the tunnel IP. No built-in password prompts are used—assume your LAN is trusted or use WireGuard.
On Linux, the host auto-selects kmsgrab when possible (great for Wayland/KMS; cursor isn’t drawn)
or falls back to x11grab.
The handshake shares all monitors as WxH+X+Y so the client can open one window per monitor or a
specific index.
# Example (x11grab fallback)
ffmpeg -f x11grab -draw_mouse 0 -framerate 60 -video_size 1920x1080 -i :0.0+0,0 …
Pick h.264 (lowest latency) or h.265 (higher efficiency). Backends include
nvenc, qsv, vaapi, or CPU.
Preset, GOP, QP, tune, and pixel format are configurable. A comment marker is embedded so player logs can
attribute streams to LinuxPlay.
Client connects and sends HELLO. Host replies OK:<codec>:<monitor-list>
and remembers the client IP for unicast.
# Client → Host
HELLO
# Host → Client
OK:h.264:1920x1080+0+0;1920x1080+1920+0
client_ip:5000+i (MPEG-TS, pkt_size≈1316, low-delay flags)client_ip:6001 (Opus)7000 from client → hosthost:7005 client → host (gamepad events; uinput injection on host)7002 bidirectional7004 PING/PONG7003 client → host (drag-and-drop)# Host (conceptual): send video for monitor 0 to the client
ffmpeg … -f mpegts udp://<client_ip>:5000
# Client listens locally and decodes
av.open("udp://@0.0.0.0:5000", format="mpegts", options={"fflags":"nobuffer","flags":"low_delay"})
The client uses PyAV (FFmpeg) and auto-chooses
vaapi/cuda/qsv/d3d11va when available. Frames are uploaded
to an OpenGL widget for tear-free, vsync-off presentation. An optional Ultra mode further cuts
buffering for LAN.
MOUSE_* / KEY_* UDP messages; host injects
via pynput (preferred) or xdotool fallback.7005 (auto-detects common pads like Xbox, DualSense, 8BitDo).
Host receives and injects through a uinput virtual device; no system-wide remapper required.pyperclip; client uses Qt clipboard. Both sides exchange
CLIPBOARD_UPDATE messages.~/LinuxPlayDrop via TCP.kmsgrab or x11grab, encodes via NVENC/QSV/VAAPI/CPU.Tip: You can run LinuxPlay directly from the terminal. The previews below reflect the current CLI flags and env hints.