lokust-stream — streaming server¶
Rust binary that runs on a GPU droplet. Captures the server's X11 display, encodes via NVENC (or x264 fallback), and serves WebRTC peer connections with H.264 video.
Binary¶
Built from session-vm/crates/stream-server/ as target/release/lokust-stream.
Configuration (environment variables)¶
| Var | Default | Purpose |
|---|---|---|
LOKUST_STREAM_PORT |
7800 |
Signaling + HTTP port |
DISPLAY |
:1 |
X display to capture |
LOKUST_ENCODER |
nvenc |
One of nvenc, vaapi, x264 |
LOKUST_STREAM_WIDTH |
1920 |
Capture width |
LOKUST_STREAM_HEIGHT |
1080 |
Capture height |
LOKUST_STREAM_FPS |
60 |
Target framerate |
LOKUST_STREAM_BITRATE_KBPS |
8000 |
Initial bitrate target |
LOKUST_STUN |
stun:stun.l.google.com:19302 |
STUN server for ICE |
HTTP endpoints¶
GET /¶
Serves a minimal LOKUST-branded test client HTML page. Useful for verifying a streaming setup without building the iPad app first.
GET /health¶
Liveness check.
Response 200 OK
GET /signal — WebSocket¶
WebRTC signaling endpoint. See protocol/webrtc-signaling.md for the full message format.
Pipeline¶
┌─────────────┐ ┌─────────────┐ ┌──────────┐ ┌──────────────────────────────┐
│ ximagesrc │ → │ videoconv + │ → │ H.264 │ → │ appsink → broadcast channel │
│ display=:1 │ │ videoscale │ │ encoder │ │ │
└─────────────┘ └─────────────┘ └──────────┘ └──────────────────────────────┘
│
▼
┌────────────────┐
│ Each WS peer: │
│ subscribe → │
│ TrackLocal │
│ StaticSample │
│ → write_sample │
└────────────────┘
One encode, N peers. The broadcast channel is bounded at 32 buffers; slow consumers are dropped with a warning (sample broadcast lagged).
Encoder selection¶
| Encoder | When to use |
|---|---|
nvenc |
Production on NVIDIA GPUs. Requires GStreamer built with NVENC SDK (not the default Ubuntu package). |
vaapi |
Intel/AMD hardware encode. |
x264 |
CPU fallback. Works everywhere GStreamer is installed. Zero-latency preset used. |
The NVENC path expects nvcudah264enc or nvh264enc to be registered in GStreamer; the server falls back automatically if only the modern element is available, otherwise errors explicitly.
Running¶
# On the droplet (Ubuntu 22.04 + GStreamer + NVIDIA drivers)
DISPLAY=:1 LOKUST_ENCODER=x264 \
./target/release/lokust-stream
Logs use tracing (env-filter). Default is info,stream_server=debug.
2026-04-12T23:52:49 INFO lokust_stream: gstreamer initialized
2026-04-12T23:52:49 INFO lokust_stream: config loaded port=7800 display=:1 encoder=X264
2026-04-12T23:52:49 INFO lokust_stream::pipeline::bridge: video pipeline started encoder=X264 width=1920 height=1080 fps=60
2026-04-12T23:52:49 INFO lokust_stream::signaling: signaling server listening addr="0.0.0.0:7800"
Firewall requirements¶
On the GPU droplet:
- TCP
7800— signaling + HTTP (or proxy via Cloudflare Tunnel) - UDP
49152-65535— WebRTC media (STUN/DTLS-SRTP)
Latency targets¶
On an H200 droplet in NYC2 with a consumer broadband client on the same continent:
| Stage | Budget |
|---|---|
| Capture (ximagesrc) | <16 ms (60 fps frame interval) |
| Encode (NVENC) | <8 ms |
| Packetize + network | ~30 ms RTT |
| Decode (client Metal/GPU) | <5 ms |
| Display | <16 ms (one frame) |
| Total glass-to-glass | ~75 ms |
x264 fallback adds 5–15 ms depending on CPU.