Native Streamer
Settings, protocol, executable lookup, GStreamer dependencies, diagnostics, and fallback behavior
The native streamer is an optional Rust child process used when streamClientMode is set to native mode on a supported desktop platform. It is supervised by Electron and communicates over JSON-lines protocol version 3.
Native streaming is experimental
Native streaming is experimental and may have platform-specific bugs, missing media capabilities, or fallback behavior. OpenNOW defaults to the web streamer unless native mode is explicitly enabled. Report native-streamer issues on GitHub Issues or Discord.
Current platform support
The app accepts native mode on Windows, macOS, and Linux. Windows has the most complete path, including OS-level native input capture and the optional external renderer; macOS and Linux depend on their packaged or system GStreamer runtime and may fall back sooner when codec, decoder, input, or rendering capabilities are missing.
Settings
| Setting | Default/effective behavior | Purpose |
|---|---|---|
streamClientMode | "web" | Default renderer WebRTC path; experimental native mode opts into the child process on supported desktop platforms |
nativeStreamerBackend | "gstreamer"; compatibility forces this value | Backend requested through OPENNOW_NATIVE_STREAMER_BACKEND when needed |
nativeVideoBackend | "auto" | Normalized to auto, d3d11, d3d12, or vulkan |
nativeStreamerExecutablePath | "" | Optional user-selected executable path |
nativeCloudGsyncMode | "auto" | Forwarded to native child as Cloud G-Sync/VRR mode |
nativeD3dFullscreenMode | "auto" | Windows D3D fullscreen behavior |
nativeExternalRenderer | false; honored only on Windows | Use a separate native renderer window instead of the internal child-surface path |
showNativeStreamerStats | false | For native streaming, forwards the current render surface with showStats: true so the native renderer shows its own stats overlay |
enableCloudGsync | false | User-facing Cloud G-Sync/VRR preference |
If native startup fails, protocol versions mismatch, the backend reports stub, or required platform media support is missing, OpenNOW falls back to the renderer WebRTC client with a diagnostic reason.
Enabling native streaming from Settings opens an explicit experimental-feature confirmation before streamClientMode is changed to "native". The setting only applies to new sessions. The regular F3 stats HUD is an Electron overlay and is hidden while the external native renderer is active; showNativeStreamerStats controls the native renderer's own diagnostics overlay instead. In native mode on Windows, the native input bridge captures configured app shortcuts and reports them back to Electron so stop-stream, overlay, fullscreen, stats, microphone, screenshot, and recording actions still work while the native window has focus.
Backend selection
The Rust binary reads OPENNOW_NATIVE_STREAMER_BACKEND. Valid runtime backend names are:
| Backend | Behavior |
|---|---|
gstreamer | Uses GStreamer webrtcbin when the binary was built with the feature |
stub | Reports capabilities but cannot stream |
When no backend is requested, the compiled default is gstreamer if the binary has the feature, otherwise stub. Unknown or unavailable backends return stub capabilities with requestedBackend and fallbackReason.
Source modules
The Rust GStreamer path is split across focused source modules: gstreamer_backend.rs coordinates backend state, gstreamer_pipeline.rs builds and negotiates the webrtcbin pipeline, gstreamer_input.rs owns data channels/native input, gstreamer_liveness.rs emits stall diagnostics, gstreamer_platform.rs selects platform decode/render paths, gstreamer_transitions.rs tracks video path transitions, and gstreamer_config.rs normalizes backend configuration.
Protocol v3
Electron sends newline-delimited JSON commands on stdin and reads responses/events from stdout.
| Commands | Purpose |
|---|---|
hello | Version handshake; returns ready capabilities |
start | Provide session context before negotiation |
offer | Send server SDP offer and session context; returns answer |
remote-ice | Add server ICE candidate |
input | Send encoded input packet |
surface | Update native render surface/window info |
bitrate | Update max bitrate limit |
update-shortcuts | Refresh native-window shortcut bindings while streaming |
stop | Stop the native session |
| Responses | Purpose |
|---|---|
ready | Capabilities, protocol version, backend, fallback details |
ok | Command accepted |
answer | WebRTC/NVST answer payload for signaling |
error | Command failure |
| Events | Purpose |
|---|---|
log | Native log line |
status | starting, ready, streaming, or stopped |
local-ice | Candidate to send through main-process signaling |
input-ready | Native data channels are ready for input |
shortcut | Native renderer matched a configured app shortcut and asks Electron to run it |
video-stall | Liveness/stall diagnostics and recovery attempt data |
video-transition | Decoder/render path transition |
stats | Native stream telemetry |
error | Async backend error |
Executable lookup
Electron starts the selected native executable and sets protocol/video environment variables for the child on supported native-streaming platforms.
Lookup order:
OPENNOW_NATIVE_STREAMERenvironment override.nativeStreamerExecutablePathfrom settings.- Packaged app path:
resources/native/opennow-streamer/<platformKey>/opennow-streamer(.exe). - Development paths:
native/opennow-streamer/bin,native/opennow-streamer/dist, andnative/opennow-streamer/target/{release,debug}.
Packaged binaries are copied by npm run native:build into native/opennow-streamer/bin, including platform-specific directories such as win32-x64, darwin-arm64, linux-x64, or linux-arm64.
On unsupported platforms, the manager returns the unsupported status before probing executable lookup or GStreamer runtime state.
GStreamer dependencies and runtime layout
npm run native:build builds a release Rust binary. By default it enables the gstreamer feature and verifies GStreamer capabilities. OPENNOW_NATIVE_STREAMER_FEATURES=none disables optional features.
Release packaging behavior:
| Platform | Runtime strategy |
|---|---|
| Windows x64 | Bundle private GStreamer runtime next to resources/native/opennow-streamer/win32-x64/opennow-streamer.exe |
| Windows ARM64 | Package app without native streamer build in the current release matrix |
| macOS x64 / arm64 | Bundle private GStreamer runtime next to the platform streamer binary |
| Linux x64 / arm64 | Use host distro GStreamer packages; .deb declares common dependencies |
Linux package builds use distro GStreamer dependencies, and native mode requires those packages to match the host GPU/driver stack. Install GStreamer base/good/bad/ugly/libav plugins plus hardware packages such as VAAPI, V4L2, GL, Vulkan, and distro driver packages where available.
Platform video paths
| Platform | Native backend paths |
|---|---|
| Windows | D3D12, D3D11, Vulkan diagnostic path, software fallback |
| macOS | VideoToolbox, software fallback |
| Linux x64 | VAAPI, V4L2, Vulkan, software fallback |
| Linux ARM/Raspberry Pi | V4L2 stateless, VAAPI, Vulkan, software fallback |
The backend logs selected decoder, renderer, memory mode, and fallback path at startup. D3D presentation limiting can be used to avoid stale-frame buildup when D3D11 is forced for high-FPS sessions.
Environment variables
| Variable | Set by | Purpose |
|---|---|---|
OPENNOW_NATIVE_STREAMER | User/dev | Override executable lookup |
OPENNOW_NATIVE_STREAMER_PROTOCOL | Electron | Expected protocol version |
OPENNOW_NATIVE_STREAMER_BACKEND | Electron/user | Backend request |
OPENNOW_NATIVE_CODEC | User/dev | Override native offer codec during diagnostics |
OPENNOW_NATIVE_VIDEO_BACKEND | Electron | User video backend preference |
OPENNOW_NATIVE_EXTERNAL_RENDERER | Electron on Windows | External native renderer flag |
OPENNOW_NATIVE_CLOUD_GSYNC | Electron | Cloud G-Sync/VRR mode |
OPENNOW_NATIVE_D3D_FULLSCREEN | Electron | Windows D3D fullscreen mode |
OPENNOW_NATIVE_VIDEO_API | User/dev | Force diagnostic video API |
OPENNOW_NATIVE_PRESENT_MAX_FPS | User/dev | Override presentation limiter |
OPENNOW_NATIVE_ZERO_COPY | User/dev | Diagnostic zero-copy setting |
Build variables: OPENNOW_NATIVE_STREAMER_FEATURES, OPENNOW_NATIVE_STREAMER_TARGET, OPENNOW_NATIVE_STREAMER_PLATFORM_KEY, and OPENNOW_BUNDLE_GSTREAMER_RUNTIME.
Diagnostics and fallback
The native manager validates the protocol handshake and backend capabilities before streaming. Runtime events surface status, input readiness, local ICE, video stalls, video transitions, stats, logs, and errors.
Fallback is expected and intentional when:
- The executable cannot be found or started.
- Protocol version is not
3. - The binary reports
stubbecause GStreamer was not compiled in. - A requested backend is unknown or unavailable.
- Required GStreamer plugins or platform decoders are missing.
- The app is running on an unsupported desktop platform, or the platform's required GStreamer/runtime pieces are unavailable.
- Native streaming errors before a usable session is established.
In those cases, OpenNOW returns to the web streamer path rather than leaving the user in a partial stream state.