Low-latency screen streaming over your local network Windows → Linux — GPU-accelerated capture, hardware H.264/HEVC encoding, OpenGL rendering
LANStream streams your Windows desktop to a Linux machine on the same network with 10–20 ms glass-to-glass latency. It uses:
- dxcam for near-zero-CPU DirectX GPU capture on Windows
- ffmpeg NVENC for hardware H.264/HEVC encoding (falls back to
libx264if no NVIDIA GPU) - RTP/UDP for efficient, low-overhead video transport
- PyAV for hardware-capable decode on the Linux client
- QOpenGLWidget + GLSL for GPU-accelerated display with a sub-millisecond texture upload
Windows (server.py) Linux (client.py)
──────────────────────────────────────── ──────────────────────────────────────
dxcam (DirectX 11 GPU capture, ~0 CPU)
│ raw BGRA frames via pipe
ffmpeg NVENC (H.264 / HEVC hardware encode)
│ RTP/UDP stream over LAN
──► PyAV (RTP demux + H.264/HEVC decode)
│ decoded RGB frames
QOpenGLWidget (GLSL texture → screen)
│
KDE Plasma / Wayland / X11
A separate TCP control channel carries authentication, client registration, and keepalive messages using newline-delimited JSON — fully compatible with v1 clients.
| Component | v1 | v2 |
|---|---|---|
| Capture | dxcam / mss | dxcam / mss (same) |
| Encode | cv2 JPEG + custom UDP | ffmpeg NVENC H.264/HEVC |
| Transport | Raw UDP chunked frames | Standard RTP |
| Decode | cv2.imdecode JPEG | PyAV H.264/HEVC |
| Display | QPainter QPixmap | QOpenGLWidget + GLSL shader |
| Server CPU | Medium (JPEG encode) | Near zero (NVENC on GPU) |
| Client CPU | Medium (cv2 decode) | Low (libavcodec + GL upload) |
| Latency | ~30–60 ms | ~10–20 ms |
| Requirement | Details |
|---|---|
| Python | 3.10 or newer |
| ffmpeg | In PATH, with NVENC support — download here (recommend BtbN/FFmpeg-Builds) |
| NVIDIA GPU | Required for NVENC; auto-falls back to libx264 otherwise |
pip install -r requirements_server.txtNo NVIDIA GPU? No problem — the server detects codec availability at startup and automatically falls back to
libx264software encoding. Same RTP output, just slightly higher CPU usage.
Arch Linux:
sudo pacman -S ffmpeg qt6-base python-pyqt6 python-numpy
pip install av PyOpenGLUbuntu / Debian:
sudo apt install ffmpeg python3-pyqt6 python3-numpy python3-opengl
pip install avOr use the requirements file:
pip install -r requirements_client.txtpython server.py- Select your monitor, codec, bitrate, and FPS in the GUI
- Click ▶ Start Streaming
- The server announces itself via UDP multicast — Linux clients discover it automatically
python client.py- Click ⚡ Connect
- If auto-discovery found the server, it appears in the dropdown
- Otherwise, enter the server IP manually
- The server assigns an RTP port automatically per client
| Key | Action |
|---|---|
F11 |
Toggle fullscreen |
Escape |
Exit fullscreen |
Ctrl+H |
Toggle HUD overlay |
Ctrl+N |
Open connect dialog |
Ctrl+D |
Disconnect |
Ctrl+Q |
Quit |
| Scenario | Codec | Bitrate | Notes |
|---|---|---|---|
| Gaming / fast motion | h264_nvenc |
8000k–16000k | p4 preset |
| Desktop / productivity | h264_nvenc |
4000k–6000k | p4 preset |
| Slow LAN / WiFi | h264_nvenc |
2000k–4000k | p3 preset |
| No NVIDIA GPU | libx264 |
4000k–8000k | ultrafast auto-selected |
| Better quality (HEVC) | hevc_nvenc |
4000k–8000k | Requires PyAV with HEVC |
NVENC presets: p1 = fastest (lowest quality) → p7 = slowest (best quality).
p4 is the recommended balance for 60 FPS gaming.
| Port | Protocol | Direction | Purpose |
|---|---|---|---|
9876 |
TCP | client → server | Control channel (auth, registration, keepalive) |
9877 |
UDP | multicast | Server auto-discovery |
5004+ |
UDP | server → client | RTP video stream (one port per client) |
RTP ports are assigned from 5004 upward — each connected client gets its own port.
ffmpeg: command not found
Add ffmpeg to your Windows PATH. Verify it works by running ffmpeg -version in Command Prompt.
NVENC not available
Run ffmpeg -encoders | findstr nvenc — if the output is empty, your ffmpeg build lacks NVENC support or you have no NVIDIA GPU. The server will automatically fall back to libx264.
PyAV not found
pip install avPyAV bundles its own ffmpeg libraries on Linux, so you don't need a separate ffmpeg install just for the client.
PyOpenGL not found
pip install PyOpenGLIf PyOpenGL is missing, the client automatically falls back to a QPainter/QPixmap renderer — slightly higher CPU usage but identical output.
Black screen / no video
- Verify your firewall allows UDP on the RTP port shown in the client's status bar
- Confirm the RTP listen port in the connect dialog matches what the server assigned
- Temporarily disable the Windows Firewall to rule it out during testing
High latency
- Use a wired LAN connection — WiFi adds 5–20 ms jitter
- Increase the bitrate so the encoder doesn't drop frames
- Use NVENC preset
p1orp2for minimum encode latency
LANStream/
├── server.py # Windows capture & streaming server (GUI)
├── client.py # Linux RTP receiver & OpenGL viewer (GUI)
├── requirements_server.txt # Python dependencies for the server
├── requirements_client.txt # Python dependencies for the client
└── README.md
Pull requests are welcome! For major changes, please open an issue first to discuss what you'd like to change.
- Fork the repository
- Create your feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'Add some feature' - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
This project is licensed under the MIT License — see the LICENSE file for details.
Made with ❤️ for low-latency LAN streaming