External View Sharing
External View Sharing lets OdenVR share what the operator sees with the rest of your organisation. Any video source in the project - or the operator’s entire window, including the 3D scene and the GUI - can be sent out as a standard H.264 or H.265 video stream that any GStreamer-compatible receiver can play, record, or process.
Typical uses:
-
Show the operator’s view on a control-room monitor or video wall.
-
Let a supervisor follow a specific camera stream from another machine.
-
Feed live video into external recording, analysis, or AI systems.
Capture and encoding run entirely on the GPU, so an active stream has minimal impact on the operator’s frame rate and latency.
Requirements
-
A GStreamer output pipeline, see Output pipeline.
| GPU | Support |
|---|---|
NVIDIA |
Supported. Encoding uses the built-in NVENC hardware encoder. GeForce GTX 10-series or newer is recommended; H265 requires NVENC HEVC support. |
Apple |
Supported on macOS (Apple Silicon). Encoding uses the VideoToolbox hardware encoder. Requires a Homebrew GStreamer installation at runtime. |
AMD |
Not supported. |
Intel |
Not supported. |
Setting up a stream
-
In OdenVR, open .
-
Choose what to stream:
-
The Screen buffer entry streams the whole OdenVR window.
-
To stream a single video, pick it in the source selector at the bottom of the section and press Add.
-
-
Fill in the settings and the output pipeline (see below), then press Apply followed by Start.
A running stream shows (running) in its header, and the Application Settings header shows View Sharing while any stream runs. Each entry is its own independent stream - several can run at the same time.
- Width (0 = source)
-
Output width in pixels.
0uses the width the video stream has on the player when the stream is started. - Height (0 = source)
-
Output height in pixels.
0uses the height the video stream has on the player when the stream is started. - Frame rate
-
Limits how many frames per second are encoded, which directly limits bandwidth.
0encodes every rendered frame. - Bitrate (kbps)
-
Encoder target bitrate. Default 4000 kbps.
- Codec
-
H264 or H265. H265 gives better quality per bit but needs receiver support.
- Output pipeline
-
How the encoded video leaves OdenVR - see the next section.
Output pipeline
The output pipeline is a GStreamer fragment that receives the encoded video, so the transport is entirely under your control: send over SRT or RTP, record to a file, or anything else GStreamer can do.
It must start with a parser matching the codec (h264parse / h265parse) and end with a sink.
For H265, replace h264parse with h265parse in the examples below.
Examples
SRT
SRT is the recommended transport over anything but a dedicated LAN: it recovers lost packets and works well across the internet.
With mode=listener OdenVR waits for the receiver to connect:
h264parse ! mpegtsmux ! srtsink uri=srt://:9000?mode=listener
Play it on the receiving machine:
gst-launch-1.0 srtsrc uri=srt://<odenvr-host>:9000 ! tsdemux ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
The same address (srt://<odenvr-host>:9000) also opens directly in VLC or FFmpeg.
RTP
Lowest latency on a local network, but no recovery from packet loss:
h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=192.168.1.50 port=5000
Receive:
gst-launch-1.0 udpsrc port=5000 caps="application/x-rtp, media=video, encoding-name=H264, payload=96" ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
While streaming
-
Errors - an invalid pipeline, a receiver that cannot be reached, or a stream that dies while running - are shown inside the entry. Press Start to retry once the cause is fixed.
-
Pressing Apply on a running stream rebuilds and restarts it with the new settings.
-
Streams set up in the GUI are not saved and are gone after a restart. Use a plugin or web layout to start them automatically.
-
A share whose source video disappears, for example because its entity is deleted, is removed automatically after a moment. The screen buffer entry always remains.
|
Network and vehicle load
Using External View Sharing might have the following effects:
|
Automating streams
Streams do not have to be managed by hand - both plugins and web layouts can control them.
From a plugin
Plugins use three SceneApi functions, which keep the feature’s earlier name, Texture Streaming. An empty entity_id targets the screen buffer; otherwise the (entity_id, stream) pair selects a video stream of the entity with that id.
api.configure_texture_streaming(&TextureStreamingConfig {
width: 0,
height: 0,
frame_rate: 0,
bitrate_kbps: 0,
codec: TextureStreamingCodec::H264,
output_pipeline: "h264parse ! mpegtsmux ! srtsink uri=srt://:9000?mode=listener".to_string(),
entity_id: String::new(),
stream: 0,
})?;
api.start_texture_streaming("", 0)?;
api.stop_texture_streaming("", 0)?;
A source must be configured before it can be started.
Start and stop are asynchronous: Ok(()) means the request was accepted, not that the stream is running.
Failures that happen later, for example a pipeline that fails to connect, are shown under .
From a web layout
Web layouts send the configure_streaming named user message; see Webview and JavaScript SDK for the messaging mechanism.
{
"enable": true,
"video": "Vehicle 1:Front",
"pipeline": "h264parse ! mpegtsmux ! srtsink uri=srt://:9000?mode=listener",
"frame_rate": 30,
"bitrate_kbps": 4000,
"codec": "H264"
}
video is the stream name as reported by the layout client (<vehicle>:<stream>); an empty string targets the screen buffer.
enable, video, and pipeline are required; width, height, frame_rate, bitrate_kbps, and codec are optional.
|
For receiver developers
The encoded stream is standard 8-bit 4:2:0 H.264/H.265 with BT.709 limited-range color, so it plays in any normal video player or decoder once the transport is unwrapped. |