Skip to content

Windows Native Unreal Pixel Streaming

Bohan Zhang edited this page Aug 27, 2026 · 1 revision

Windows Native Unreal Pixel Streaming

Architecture

On Windows, Unreal runs as a native packaged executable. Docker Desktop runs the React frontend, Flask backend, fake storage service, Pixel Streaming signalling server, and TURN relay.

The runtime path is:

Browser /simulator
  -> iframe http://localhost:8888
  -> signalling container
  -> host-only streamer socket 127.0.0.1:8889
  -> native DRV.exe with -RenderOffscreen

The user-visible player stays on port 8888. Port 8889 exists because the container uses its internal port 8888 for streamer connections while host port 8888 is already assigned to its browser player.

Release acquisition

windows_simulator.ps1 queries the latest GitHub release from UAVLab-SLU/DRV-Unreal. It selects Windows.zip and every matching numbered part such as Windows.z01, validates the published file sizes and SHA-256 digests, then extracts the split archive with 7-Zip.

The default ignored cache is sim/windows-release. A matching installed release is reused. Override the location with DRV_WINDOWS_RELEASE_DIR when a different drive has more space.

Authentication is resolved in this order:

  1. GITHUB_TOKEN in the process environment
  2. GITHUB_TOKEN in the ignored repository .env
  3. The token from an authenticated GitHub CLI session

Tokens are used only by the host downloader and are not added to Docker build contexts or image layers.

Native launch

The packaged launcher is discovered as DRV.exe, Blocks.exe, or SADE_drone_rep.exe. It starts hidden with:

-AudioMixer
-RenderOffscreen
-PixelStreamingURL=ws://127.0.0.1:8889
-ResX=1920 -ResY=1080 -ForceRes
-Unattended -NoSplash -StdOut -FullStdOutLogOutput

Do not add -nullrhi. Pixel Streaming needs the active rendering path to produce frames.

The helper records the launcher PID and writes Unreal output under <release-root>\logs. Stop operations inspect executable paths and terminate only matching Unreal processes inside the configured release root.

Browser process controls

dev.ps1 starts windows_simulator_control.ps1, a small TCP HTTP service bound only to 127.0.0.1:8890. The Simulator page uses it for Start Unreal, Shut down, and Refresh.

Supported endpoints are:

  • GET /status
  • POST /start
  • POST /stop
  • POST /shutdown

Mutating browser requests are accepted only from http://localhost:3000 or http://127.0.0.1:3000. Requests from other browser origins receive HTTP 403. The service is not exposed through Docker or a LAN interface.

DroneLume configuration path

During dev.ps1 full, the release is prepared before the backend starts. The helper discovers the packaged DRV\Config directory and sets it as the host source for /app/dronelume-config in the backend container.

The backend validates DroneLume InitDSL, derives the system under test from the first Mission drone, atomically replaces InitDSL.json, archives a copy to the configured storage service, and reports the active task through /state. Therefore the backend and native Unreal application operate on the same configuration file.

Local credentials

Credentials remain outside Git history:

  • CESIUM_CREDENTIALS_DIR selects the host folder containing frontend-cesium-token.json.
  • BACKEND_ENV_FILE selects an ignored backend .env file.
  • DRONELUME_CONFIG_DIR selects the native package Config directory and is set automatically by dev.ps1 full.

These path overrides are useful from a Git worktree where the original local credentials are stored elsewhere.

Ports

Port Scope Purpose
3000 Host DRV frontend
5000 Host Flask backend
8888 Host Pixel Streaming browser player
8889 Host loopback Native Unreal streamer WebSocket
8890 Host loopback Simulator control API
3478 TCP/UDP Host TURN listener
49160-49200 UDP Host TURN relay range

Verification

A healthy Windows run has these properties:

  1. The signalling container is healthy.
  2. The native launcher and its Win64 child remain running.
  3. Signalling commits the streamer ID as DefaultStreamer.
  4. http://localhost:8888 returns the player and establishes WebRTC.
  5. http://localhost:3000/simulator embeds the stream and accepts input.
  6. GET http://127.0.0.1:8890/status reports Unreal running.
  7. The DroneLume schema endpoint returns HTTP 200 and the backend sees the packaged DRV\Config mount.

Troubleshooting

  • GitHub returns 404: verify private release access and organization SSO for the token.
  • Archive extraction fails: install 7-Zip and confirm every Windows.zNN part and Windows.zip are present.
  • Player loads without a streamer: check that host port 8889 is free and look for committedId: DefaultStreamer in signalling logs.
  • Unreal starts without frames: confirm -RenderOffscreen is present and -nullrhi is absent.
  • Cesium tiles fail: confirm the local token can access Cesium ion asset 2275207, then recreate the frontend container.
  • DroneLume is missing: confirm the frontend and backend are from the same revision and /api/dronelume/schema returns HTTP 200.
  • Simulator buttons are unavailable: start through dev.ps1 full, dev.ps1 dev, or dev.ps1 simulator so the loopback control service runs.
  • Windows firewall prompts: allow the packaged Unreal executable on the network profile used by Docker Desktop.