Omniverse Realtime Viewer
OpenAIOfficialCreated by NVIDIA OmniverseDistributed by OpenAI
- Skill
- Meta (authoring, orchestration, planning, memory)
- Software development
- Apache-2.0
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Omniverse Realtime Viewer skill acts as a central orchestrator for developing USD-based viewer applications. It provides a structured approach to selecting implementation recipes, enforcing architectural conventions, and managing dependencies. By utilizing a set of focused reference documents, it guides developers through the lifecycle of building, configuring, and validating viewer applications, ensuring consistent behavior across different delivery paths such as local workstations or streaming environments.
What it does
- Routes development requests to specific implementation recipes based on the target delivery path.
- Enforces architectural rules for USD rendering, stage management, and UI integration.
- Provides guidance on camera selection, input handling, and viewport interaction.
- Standardizes the integration of AOV switching and render product configuration.
- Facilitates the capture of validation evidence for viewer readiness.
- Maintains separation between user-provided USD files and application-specific session state.
When to use it
- When initiating the development of a new USD viewer application within the Omniverse ecosystem.
- When determining the appropriate delivery path for a viewer, such as local native or streaming.
- When needing to implement consistent camera, selection, or UI behavior across viewer projects.
- When integrating advanced rendering features like AOV switching into an existing viewer.
Advantages
- Ensures architectural consistency across diverse viewer implementations.
- Provides a clear, modular path for adding specific capabilities like input routing or data display.
- Promotes clean separation of concerns between stage data and viewer-owned state.
- Standardizes the validation process for consistent delivery.
Usage examples
- “I need to build a browser-based viewer for USD files.”
- The agent will route you to the streaming viewer recipe, providing guidance on WebRTC stream setup, UI integration, and viewport interaction.
- “How do I implement AOV switching in my local USD viewer?”
- The agent will provide the AOV switching reference, detailing how to map render vars and update the display state on the server.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/openai/omniverse-realtime-viewer/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip omniverse-realtime-viewer.zip -d .agents/skills
Documentation by NVIDIA Omniverse
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
Omniverse Realtime Viewer
This is the top-level entry point for the Omniverse Realtime Viewer skill package. It is self-contained: all required routing, conventions, and validation guidance live in the selected references.
Use the focused reference documents as implementation recipes. This file chooses the right recipes and preserves the architectural rules that must hold across all generated viewer apps.
Instructions
Start by classifying the requested viewer, then read only the references needed
for that delivery path and feature set. Implement the render path first, layer
interaction and UI behavior on top of it, and finish by capturing validation
evidence from references/validation.md.
Read Order
Read
references/routing.mdto choose the delivery path and focused references.Read
references/conventions.mdbefore implementing camera, input, selection, viewport, streaming protocol, scene loading, or environment behavior.For broad viewer requests, read
references/usd-viewer-app/README.md.If the delivery path is unclear, read
references/streaming-vs-local/README.md.If the prompt includes layout, panels, controls, inspectors, status, or UX, read
references/viewer-ux-workflow/README.mdand then the focused viewer UI references. This applies to React/WebRTC, Tauri, Electron,ovui,ovwidgets, and Dear ImGui apps; "frontend" means user-facing UI, not only browser UI.For viewport interaction, read
references/viewer-input-routing/README.mdbeforereferences/camera-controls/README.md,references/native-picking-selection/README.md, orreferences/object-selection/README.md.Read only the focused capability references needed for the requested app.
Use
references/validation.mdto capture review evidence before handoff.
Non-Negotiables
Use
ovrtxfor all USD and 3D rendering.Browser apps display an
ovstreamWebRTC video stream plus UI. The browser does not render USD geometry.Do not substitute WebGL, Three.js, Babylon.js, PlayCanvas, A-Frame, model-viewer, react-three-fiber, glTF browser viewers, or other client-side 3D renderers.
If local validation cannot run because the GPU/runtime environment is absent, scaffold the
ovrtxpath and document the runtime requirement. Do not add a browser-renderer fallback.Keep user USD files unmodified. Viewer cameras, render products, render vars, settings, selection metadata, and runtime state belong in session/composite layers or app state.
Keep one owner for
renderer.step(), stage mutation, native picking, selection writes, and live attribute writes.Keep dependency acquisition in
references/dependencies/README.mdand deployment choices inreferences/cloud-deployment/README.md; do not duplicate package locations or deployment setup.
Focused Reference Families
Entry points and recipes:
references/usd-viewer-app/README.md,references/streaming-viewer-recipe/README.md,references/ovui-local-viewer-recipe/README.md,references/streaming-vs-local/README.md,references/electron-shm-viewer/README.md,references/ovwidgets-editor-shell/README.md.Rendering and stage:
references/ovrtx-rendering/README.md,references/stage-loading/README.md,references/stage-management/README.md,references/render-settings/README.md,references/aov-switching/README.md,references/stage-hierarchy/README.md,references/stage-queries/README.md,references/stage-attribute-reads/README.md,references/prim-transform-safety/README.md,references/usd-sample-data/README.md.Delivery and runtime:
references/streaming-server/README.md,references/streaming-client/README.md,references/streaming-messages/README.md,references/streaming-lifecycle/README.md,references/local-viewer/README.md,references/tauri-local-viewer/README.md,references/cpp-native-viewer/README.md,references/headless-shm-cli/README.md,references/viewer-backend-interface/README.md,references/webgl-shm-transport/README.md.Viewer UI/UX:
references/viewer-ux-workflow/README.md,references/viewer-layout-patterns/README.md,references/viewer-control-patterns/README.md,references/viewer-data-view-patterns/README.md,references/viewer-feedback-status/README.md.Interaction:
references/viewer-input-routing/README.md,references/camera-controls/README.md,references/object-selection/README.md,references/native-picking-selection/README.md,references/selection-feedback/README.md,references/selection-animation/README.md,references/transform-manipulator/README.md,references/gl-viewport-overlay/README.md,references/ovui-library/README.md,references/prim-pick-effects/README.md,references/prim-info-display/README.md,references/viewport-overlays/README.md.Infrastructure:
references/dependencies/README.md,references/windows-native-setup/README.md,references/cloud-assets/README.md,references/cloud-deployment/README.md,references/troubleshooting/README.md.
Build Workflow
Classify the prompt by delivery path, target user, required capabilities, runtime environment, validation needs, and explicit constraints.
Select a small reference set. Start with the recipe or routing reference, then add focused capabilities such as camera, picking, hierarchy, properties, render settings, transform tools, cloud assets, or deployment.
Read selected references before writing app code. Follow their build order, import order, data-channel contracts, and renderer ownership rules.
Implement the core render path first, then input routing and camera, then selection and data panels, then scene/settings features, then packaging or deployment.
Treat the selected references as the behavior contract for API shape, compatibility, and generated project structure.
Capture validation evidence before calling the viewer ready.
Examples
For a browser viewer request, use the streaming recipe references plus camera, picking, hierarchy, properties, render settings, and stream-status references.
For a local workstation viewer request, use the local or native delivery references plus renderer setup, stage loading, viewport input, and validation.
Completion Checklist
Selected references match the user's intent and delivery path.
No code path uses a browser-side 3D renderer for USD.
The generated app has one clear owner for render stepping and stage mutation.
User USD files remain untouched by viewer-owned session data.
Camera, input, selection, scene loading, and stream behavior follow
references/conventions.md.Setup/build/run results and visual interaction evidence are captured with
references/validation.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- BENCHMARK.md5.5 KiB
- LICENSEAdded by AutoGineer10.0 KiB
- SKILL.md7.4 KiB
- agents/openai.yaml315 B
- evals/evals.json8.1 KiB
- references/aov-switching/README.md15.2 KiB
- references/camera-auto-select/README.md7.4 KiB
- references/camera-controls/README.md17.1 KiB
- references/camera-picker/README.md9.7 KiB
- references/cloud-assets/README.md10.4 KiB
- references/cloud-deployment/README.md18.0 KiB
- references/conventions.md5.3 KiB
- references/cpp-native-viewer/README.md2.4 KiB
- references/cpp-native-viewer/interaction-features.md19.2 KiB
- references/cpp-native-viewer/presentation-loop.md9.0 KiB
- references/cpp-native-viewer/project-build.md6.4 KiB
- references/cpp-native-viewer/renderer-session.md4.5 KiB
- references/cpp-native-viewer/validation.md3.3 KiB
- references/dependencies/README.md3.4 KiB
- references/dependencies/electron-shm.md1.5 KiB
- references/dependencies/environment-validation.md4.4 KiB
- references/dependencies/frontend.md2.3 KiB
- references/dependencies/local-openusd-gpu.md4.4 KiB
- references/dependencies/nvidia-runtime.md9.0 KiB
- references/dependencies/ovrtx.md2.4 KiB
- references/dependencies/ovstream.md2.5 KiB
- references/dependencies/quick-setup.md5.3 KiB
- references/electron-shm-viewer/README.md2.2 KiB
- references/electron-shm-viewer/architecture-project.md6.3 KiB
- references/electron-shm-viewer/electron-client.md5.6 KiB
- references/electron-shm-viewer/protocol-interaction-lifecycle.md6.9 KiB
- references/electron-shm-viewer/python-shm-server.md4.9 KiB
- references/electron-shm-viewer/validation.md2.8 KiB
- references/gl-viewport-overlay/README.md7.9 KiB
- references/gl-viewport-overlay/architecture.md4.1 KiB
- references/gl-viewport-overlay/example-gizmo.md5.5 KiB
- references/gl-viewport-overlay/interaction-pattern.md4.0 KiB
- references/gl-viewport-overlay/projection-alignment.md4.3 KiB
- references/headless-shm-cli/README.md12.2 KiB
- references/huggingface-usd/README.md7.7 KiB
- references/local-viewer/README.md15.0 KiB
- references/native-picking-selection/README.md10.4 KiB
- references/object-selection/README.md9.4 KiB
- references/ovrtx-rendering/README.md18.2 KiB
- references/ovui-library/README.md3.3 KiB
- references/ovui-library/api-reference.md4.3 KiB
- references/ovui-library/extending.md4.8 KiB
- references/ovui-local-viewer-recipe/README.md3.7 KiB
- references/ovui-local-viewer-recipe/interaction-features.md16.1 KiB
- references/ovui-local-viewer-recipe/project-structure.md6.2 KiB
- references/ovui-local-viewer-recipe/setup-shell-renderer.md14.3 KiB
- references/ovui-local-viewer-recipe/validation-build-order.md5.5 KiB
- references/ovwidgets-editor-shell/README.md8.6 KiB
- references/prim-info-display/README.md9.3 KiB
- references/prim-pick-effects/README.md5.9 KiB
- references/prim-transform-safety/README.md8.2 KiB
- references/render-settings/README.md9.9 KiB
- references/routing.md16.5 KiB
- references/seg-outline-highlight/README.md1.4 KiB
- references/selection-animation/README.md9.7 KiB
- references/selection-feedback/README.md6.6 KiB
- references/stage-attribute-reads/README.md5.5 KiB
- references/stage-hierarchy/README.md17.1 KiB
- references/stage-hierarchy/fallback-worker-protocol.md3.5 KiB
- references/stage-loading/README.md19.3 KiB
- references/stage-management/README.md10.1 KiB
- references/stage-queries/README.md5.3 KiB
- references/streaming-client/README.md17.4 KiB
- references/streaming-lifecycle/README.md8.8 KiB
- references/streaming-messages/README.md16.5 KiB
- references/streaming-messages/server-handler-map.md3.1 KiB
- references/streaming-server/README.md18.6 KiB
- references/streaming-server/frame-loop-and-continuity.md3.3 KiB
- references/streaming-viewer-recipe/README.md4.8 KiB
- references/streaming-viewer-recipe/client-protocol.md11.0 KiB
- references/streaming-viewer-recipe/interaction-features.md13.0 KiB
- references/streaming-viewer-recipe/project-structure.md7.0 KiB
- references/streaming-viewer-recipe/server-runtime.md16.8 KiB
- references/streaming-viewer-recipe/validation-build-order.md5.8 KiB
- references/streaming-vs-local/README.md8.1 KiB
- references/tauri-local-viewer/README.md18.2 KiB
- references/tauri-shm-transform-gizmo/README.md11.8 KiB
- references/transform-manipulator/README.md15.0 KiB
- references/troubleshooting/README.md7.2 KiB
- references/troubleshooting/scenario-playbooks.md18.8 KiB
- references/usd-sample-data/README.md11.7 KiB
- references/usd-viewer-app/README.md7.5 KiB
- references/validation.md3.0 KiB
- references/viewer-backend-interface/README.md17.7 KiB
- references/viewer-control-patterns/README.md4.8 KiB
- references/viewer-data-view-patterns/README.md4.8 KiB
- references/viewer-feedback-status/README.md4.9 KiB
- references/viewer-input-routing/README.md7.8 KiB
- references/viewer-layout-patterns/README.md4.7 KiB
- references/viewer-ux-workflow/README.md4.6 KiB
- references/viewport-overlays/README.md4.8 KiB
- references/viewport-resize/README.md8.5 KiB
- references/webgl-shm-transport/README.md14.5 KiB
- references/windows-native-setup/README.md5.7 KiB
- skill-card.md2.9 KiB
- skill.oms.sig28.6 KiB
references/streaming-viewer-recipe/server-runtime.md
Streaming Server Runtime
2. Install Dependencies And Configure The Environment
Read references/dependencies FIRST. Its references/nvidia-runtime.md file is
the source of truth for NVIDIA runtime locations. Do not guess install paths and
do not repeat ovstream, ovui, ovrtx, or ov-web-rtc client acquisition
details in this recipe.
Do this on the server side:
Install
ovrtxusing the package guidance inreferences/dependencies.Install
ovstreamusing the current package guidance inreferences/dependencies. Ifovstream.initialize()reports missing native StreamSDK libraries, follow the current dependency guidance.Install
warp-langfor CUDA-side channel conversion (pip install warp-lang).Install
numpyfor matrices and camera math (pip install numpy).Install
usd-core==24.11only when the server process needs directpxrqueries. Pin to 24.11 — newer versions cause TfType schema conflicts with ovrtx. Prefer subprocess query mode on Windows or when USD registry conflicts appear.
For generated browser viewers, create app-local setup and run wrappers rather
than pointing users at repo-level scripts. The setup wrapper should install the
server dependencies above, run the verification checks from
references/dependencies/environment-validation.md, and fail with the exact
command that did not pass. The run wrapper should set OVRTX_SKIP_USD_CHECK,
derive OVRTX_BIN_PATH from the installed ovrtx package when needed, preserve
the selected ovstream package layout, start the server, and write logs to a
known project-local path.
Do this on the frontend side:
Create a Vite React app (
npm create vite@latest frontend -- --template react-ts).Configure and install
@nvidia/ov-web-rtcusingreferences/dependencies. Use only the standaloneovstreamDirect connection pattern fromstreaming-client; do not use Kit, OVC, NVCF, or GFN client connection profiles in the browser WebRTC config. If OKAS or another orchestrator launches the container, convert its exposed endpoint into DirectserverandsignalingPortvalues.Add normal UI dependencies only when they are part of the requested UI. Keep the core connection path dependency-light.
Set these environment contracts before starting the server:
OVRTX_SKIP_USD_CHECK=1must be set before ovrtx is imported or the renderer is constructed.OVRTX_BIN_PATHmust point at the ovrtxbindirectory when materials or renderer plugins fail to resolve.The ovrtx plugin library path must be first in the dynamic library path if another USD build is present.
OVSTREAM_LIB_PATHmust point at the ovstream native library directory when the Python binding cannot find native libraries.If
ovstreamnative libraries are not found, use the current runtime guidance fromreferences/dependenciesinstead of copying stale fallback library paths from older recipes.
Decision points:
If the target is local development, use WebRTC signaling port
49100, stream port defaulting through ovstream, and public IP127.0.0.1.If the target is LAN access, expose signaling host and port through frontend URL parameters and environment variables.
If the target is cloud deployment, do not invent a new deployment model in this recipe; read
references/cloud-deploymentand keep to supported paths.If running on Windows with
pxrimports for advanced USD inspection, prefer a separate USD query subprocess rather than importingpxrin the ovrtx render process.
Common failure modes:
usd-core detected, duplicate USD debug symbols,_tfimport failures, or MDL resolver crashes usually mean import order or library path is wrong.Magenta materials usually mean
OVRTX_BIN_PATHor plugin library path is missing.ovstream import or initialize failure usually means native StreamSDK libraries are missing,
OVSTREAM_LIB_PATHpoints at the wrong layout, the platform build does not match, or GPU/driver support is missing.No matching distribution found for ovrtx: wrong package guidance, unsupported platform, or unsupported Python version; re-checkreferences/dependencies.ovstream package not found: wrong package source, stale package metadata, wrong platform tag, or network/proxy issue; re-check
references/dependencies.
Read for depth: see references/dependencies for install commands, references/ovrtx-rendering and references/streaming-server for the full environment and native library contracts.
3. Build The Server Runtime Shell
Do this:
In
server/ov_web_viewer_server.py, parse width, height, target FPS, signaling port, public IP, initial scene URL/path, asset root, and settings path.Construct a single application runtime object that owns the renderer runtime, scene manager, stream server, message router, input router, settings store, and command queue.
Follow the canonical startup order: set env, construct an ovrtx renderer with native selection outline support when needed, load the initial stage through
open_usd()oropen_usd_from_string(), warm up the renderer, initialize ovstream, register callbacks, start readiness health, then start the render loop.Initialize ovstream once, create a WebRTC server, register
on_connection,on_message, andon_input, then start the server.Enter one render loop that drains queued commands, updates camera/selection/settings state, steps ovrtx when a scene is loaded, converts the frame to BGRA, and submits video to ovstream.
On shutdown, stop streaming, close the ovstream server, close renderer resources if exposed by the API, and call ovstream shutdown exactly once for each initialize call.
Canonical startup sequence:
set OVRTX_SKIP_USD_CHECK=1
import ovrtx and construct Renderer(RendererConfig(sync_mode=True, selection_outline_enabled=True))
load initial stage:
build an inline root USDA that sublayers the user stage and authors viewer render config
renderer.open_usd_from_string(inline_root_usda)
bind /OVCamera omni:xform
initialize native selection outline styles and clear outline groups
warm up renderer:
write camera transform
step /Render/OVServer/ViewportTexture0 several frames
probe render vars and allocate persistent BGRA stream buffer
initialize ovstream and register callbacks:
on_connection -> push_initial_state
on_message -> JSON app protocol
on_input -> raw mouse/keyboard input routed through viewer-input-routing
start /healthz:
503 until first valid frame
200 after first successful converted frame
start render loop threadCritical contracts:
Register callbacks before
server.start().Keep callbacks fast. They may be called from StreamSDK internal threads.
Do not call renderer load/reset/step/write APIs directly from ovstream callbacks. Enqueue work for the render loop.
Guard
send_messagewith the connected-client state.Maintain explicit runtime states: starting, idle/no scene, loading, streaming, error, shutting down.
Keep the most recent loaded stage URL, root hierarchy summary, selection, render settings, and loading state in server memory so a newly connected browser can receive initial state.
Readiness is not liveness:
/healthzmust return503 not readyuntil the render loop has produced and copied the first valid frame, then200 ok.Readiness must not depend on an active browser client or on
stream_video()succeeding. Before any client connects, frame submission can no-op or raise transient no-client/disconnect errors depending on the selected ovstream build.
Decision points:
If no initial scene is configured, start the server in idle state and let the frontend send
openStageRequest.If an initial scene is configured, load it before or during the first render loop iteration, then push state when the client connects.
If one client is already connected and a second browser connects, follow ovstream's one-client WebRTC constraint. Either reject the new client clearly or replace the old session intentionally.
If the render loop falls behind target FPS, prefer dropping frames or reducing render quality over running concurrent renderer steps.
Common failure modes:
Registering callbacks after
start()causes missed connection and data-channel events.Calling
renderer.step()duringreset_stage(),open_usd*(), or reference mutation causes races, stale buffers, or crashes.Sending messages while no client is connected silently loses important state unless the runtime pushes initial state after connection.
Read for depth: see references/streaming-server and references/streaming-lifecycle for the full lifecycle contract.
4. Construct The ovrtx Renderer
Do this:
Create the renderer in
server/renderer_runtime.pyafter environment variables are set.Use synchronous rendering first. Add asynchronous rendering only after buffer lifetime, readiness, and stream pacing are explicitly handled.
Store the active render product path, stream width, stream height, current frame index, and whether a valid stage is loaded.
Expose render-loop-only operations for loading a scene, resetting the stage, stepping a frame, mapping render vars, enqueueing and decoding pick queries, setting selection outline groups, and writing live attributes.
Critical contracts:
The application calls
renderer.step()explicitly. ovrtx does not run a hidden app loop for the viewer.Pass the exact viewer RenderProduct path to every step call.
Extract
LdrColorfrom the returned frame. This is RGBA8 from ovrtx.For AOVs, handle both single-tensor and multi-tensor render var outputs. Single-tensor outputs are consumed directly through DLPack; multi-tensor outputs must select a named image tensor and read params separately. Image tensors are channel-last (
H x W x C), not channel-first.Map CUDA buffers for streaming. Avoid CPU round trips in the normal streaming path.
Keep mapped or converted frame buffers alive until
stream_video()returns.Use
write_attributefor live camera transforms and other live state. Writeomni:xform, not authoredxformOp:*, for interactive updates.Use the correct transform semantic and create-new prim mode for attributes that may not already exist in Fabric.
Decision points:
If the app only needs basic video streaming, start with
LdrColoronly.Object selection uses native pick queries. Do not add segmentation render vars just to make picking work.
If render settings include debug segmentation view, keep both render vars available and switch the streamed image source intentionally.
If the renderer reports stale GPU hangs after a crash, inspect running Python GPU processes before changing code.
Common failure modes:
Unable to find RenderProduct primmeans scene setup did not create the path used byrenderer.step().Black frame usually means camera relation, render product resolution, render var source, or camera transform is invalid.
Red/blue color swap means ovrtx RGBA was submitted to ovstream without BGRA conversion.
Live camera changes doing nothing usually means the app wrote
xformOp:transforminstead ofomni:xform, or used existing-only prim mode.
Read for depth: see references/ovrtx-rendering for the full renderer construction, frame extraction, and live attribute contract.
5. Implement Scene Loading
Do this in server/scene_loader.py and call it only from the render loop:
Resolve the requested URL/path against the configured asset root, allowed schemes, and security policy.
Create viewer-owned camera, RenderProduct, RenderVar, and RenderSettings data in one inline root USDA string when the user stage lacks viewer render config.
Load the user stage without modifying it.
Store the viewer camera path and render product path in runtime state.
Reset selection, native selection outline groups, hierarchy cache, pending pick queries, and loading progress for the new stage.
Fit the camera to the stage bounds unless the user requested preserving the current camera or using an authored stage camera.
Critical contracts:
Every loaded stage needs Camera -> RenderProduct -> RenderVar -> RenderSettings wiring that ovrtx can find.
The viewer camera path must be the same path used by camera controls when writing
omni:xform.Do not inject lights unless the user explicitly asks for viewer-controlled lighting. User stages usually own their lighting.
Include segmentation render vars only for explicit debug/AOV display modes, not for picking.
Prefer
renderer.open_usd_from_string()for inline roots that sublayer the user USD and author viewer render config. This avoids temporary file lifetime issues while preserving relative asset resolution through the sublayer path.Do not call reference or layer-add APIs after a stage is already loaded unless the renderer has been reset to an empty stage and the operation is part of the serialized load path.
Decision points:
Use a single inline root USDA string with
subLayers = [@user_scene@]when the user file needs viewer camera/render-product/render-var data.If the user stage has an authored camera and the requested policy is
stage-camera, copy its focal length, apertures, clipping range, and transform into the viewer camera.If the user requests persistent camera across scene switches, keep camera state but sanitize and refit only when the old state is invalid for the new bounds.
If the user requests viewer lighting controls, add explicit viewer-owned light prims only with a verified live apply path or an explicit reload/profile workflow; otherwise leave lighting untouched and omit live lighting controls.
Common failure modes:
Inline roots that omit or misquote the user sublayer path fail composition or break relative asset resolution.
Camera path mismatch makes input appear connected but the view never moves.
A stage-load operation that reports an error must not be treated as a successful load just because the enqueue call returned.
Read for depth: see references/stage-loading, references/render-settings, references/selection-feedback, and references/stage-hierarchy for the full contracts.
6. Build Frame Streaming
Do this in server/stream_server.py and server/frame_converter.py:
Start ovstream in WebRTC mode.
Configure width, height, target FPS, signaling port, optional public IP, and video codec policy.
For each rendered frame, map
LdrColoron CUDA, convert RGBA8 to BGRA8 on CUDA, wrap the CUDA buffer as an ovstream video frame, and submit it.Pace the render loop to target FPS while allowing command queue work to run between frames.
Send loading and error state messages even when video frames are temporarily unavailable.
Log the first valid converted BGRA frame and set readiness before depending on browser connection state. This lets validation distinguish renderer/frame-conversion failures from WebRTC negotiation failures.
Critical contracts:
ovstream expects BGRA8 for raw CUDA frames; ovrtx
LdrColoris RGBA8.Avoid CPU readback in the normal path. CPU readback is acceptable only for debugging screenshots or tests.
stream_video()does not own a deep copy of the source buffer. Keep the buffer alive until the call returns.stream_video()can fail during disconnect races. Catch and debug-log transient failures; do not crash the render loop.First-frame readiness should be set after render-var mapping and RGBA-to-BGRA conversion into the persistent app-owned stream buffer. Do not wait for an attached browser client.
Stream width, height, frame pitch, RenderProduct resolution, and camera aspect must agree for the fixed stream size.
The WebRTC signaling port is not the media port. The browser discovers media endpoints through SDP.
For local WebRTC development, set the server public IP to
127.0.0.1when ICE discovery otherwise hangs.
Decision points:
Use raw frames first. Add H264, H265, AV1, or custom encoded frames only when latency, bandwidth, or deployment constraints require it.
If using encoded frames, make the encoder own color format conversion and frame lifetime explicitly.
If no client is connected, still run scene loading and state updates, but consider pausing expensive frame submission work.
If the user asks for RTSP, treat it as a separate delivery mode; the browser-streamed Omniverse Realtime Viewer path should remain WebRTC.
Common failure modes:
Connected browser with no video often means frontend configured a media port manually, server ICE/public IP is wrong, or frame submission never happens.
One frame then black usually means the frontend connected, received state, rerendered, and accidentally terminated/restarted the AppStreamer connection. Inspect server logs for
connected=Truefollowed byconnected=Falsewithin about a second.Wrong colors mean missing RGBA-to-BGRA conversion.
GPU memory growth can mean mapped frame resources or conversion buffers are retained beyond the intended frame lifetime.
Read for depth: see references/streaming-server and references/streaming-lifecycle for the full frame streaming contract.
Requirements and compatibility
Written for: OpenAI Codex
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
The author says: Orchestrator skill. Downstream focused references may require NVIDIA GPUs, ovrtx, ovstream, ovui, OpenUSD, Python, Node/React, Tauri, Electron, C++, or cloud GPU deployment access depending on the selected viewer path.
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- NVIDIA Omniverse
- Publisher
- OpenAI (Official)
- Distributed by
- OpenAI
- Source
- openai/plugins · plugins/nvidia/skills/omniverse-realtime-viewer · commit d420d13
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (written by AutoGineer)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA Omniverse or OpenAI.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download omniverse-realtime-viewer.zip