8.1 KiB
OBS overlays
Admins manage overlays at Admin → OBS overlays. Management pages use the normal Lumi session, role checks, layout, forms, lists, modals, and confirmation flow. Browser Source pages use a separate transparent document with no Lumi navigation or authenticated website data.
Editing an overlay
The editor uses the same basic model as OBS: scenes contain ordered sources, and the selected source has a red box with resize handles. On a wide screen the preview stays beside the settings; on smaller screens it moves above them.
- Drag a source to move it.
- Drag any corner or edge handle to resize it.
- Use arrow keys for small moves, or Shift plus an arrow for larger moves.
- Snapping uses canvas edges, center lines, and other source edges/midpoints.
- Hold Ctrl on Windows/Linux or Cmd on macOS to temporarily reverse the Snap setting.
- Center, Fit to canvas, and Reset box provide familiar transform shortcuts.
Every source can use any corner, edge midpoint, or center as its anchor. Text sources have separate horizontal and vertical alignment plus wrapping, shrinking, clipping, single-line, and scrolling ticker behavior. The editor only shows fields that apply to the selected source type.
Private OBS links
Each overlay has one server-controlled URL. It follows the active overlay scene. Each scene also has a fixed URL that always renders that scene. Both URL forms contain 256-bit random bearer tokens instead of database IDs. Tokens are stored encrypted for admin copy actions and as SHA-256 hashes for public lookup. Regenerating a URL immediately revokes the old token.
Treat every Browser Source URL as a password. Only admins can view, copy, preview, or regenerate it. Public state responses contain render data only; they do not contain other URLs, tokens, OBS credentials, or website session data.
Browser Sources receive scoped live-change events through Lumi's existing event service. The render page fetches a fresh authorized snapshot after each event and after every reconnect, so temporary network loss does not require an OBS refresh.
Scenes and sources
An overlay always keeps at least one scene. Admins can create, edit, duplicate, order, enable, activate, and delete scenes. Current built-in source types are:
- Text
- Image URL
- Video / media URL
- Audio URL
- Website or alert overlay
Module instances can be created, edited, duplicated, ordered, enabled, and
deleted. New module types can call registerOverlayModuleType(...) in
src/services/overlay-modules.js; providers normalize their configuration and
select the safe built-in text, image, video, audio, or web render type while the overlay
service retains the same instance model.
Video and audio
Video sources support browser-playable media such as WebM and MP4; audio sources support browser-playable formats such as Ogg, MP3, and WAV. Actual codec support follows the Chromium/CEF build used by the browser or OBS.
Playback can start once when the overlay scene loads, loop continuously, or wait for manual playback. Sources also provide volume, start offset, playback speed, optional player controls, and a live Restart playback action. Video adds mute and contain/cover/stretch sizing. Activating another Lumi scene removes the old scene's media elements, which stops their playback; returning to the scene applies its configured start behavior again.
Website overlays can play their own alert audio because their iframe receives autoplay permission. To route video, audio, and website-alert sound through an independent OBS mixer channel, enable Control audio via OBS in the Lumi Browser Source properties, then configure monitoring/output in OBS as desired.
External website and alert overlays
Website sources support third-party browser overlays such as alert and chat overlays. They run in a sandbox and do not receive the Lumi admin page or its login data. The Refresh now action sends a live refresh command to every open OBS copy of that source.
Automatic recovery is optional. When enabled it watches for a page that never finishes loading, can check public website replies for HTTP errors, empty content, unexpected content types, and obviously malformed pages, retries at 5, 15, and 45 second-style bounded intervals, and periodically reloads the source to avoid stale content. Retry count and refresh interval are configurable. Local/private website addresses are periodically refreshed but are not fetched by the Lumi server for security; browser load-timeout recovery still applies.
Website sources also support per-edge percentage cropping, zoom, and isolated
custom frame CSS. Custom CSS is scoped to the source frame so it cannot restyle
the Lumi render page or other sources. Standard browser cross-origin security
does not allow parent-page CSS to select elements inside a third-party iframe;
use crop and zoom to hide unwanted portions of an external site. Frame-level CSS
can target iframe, for example iframe { filter: saturate(1.2); }.
OBS WebSocket
The connector is disabled by default. Enable OBS WebSocket in OBS, keep its
password enabled, and use the default local endpoint
ws://127.0.0.1:4455 when Lumi runs on the streaming computer. If Lumi runs on
another trusted machine, use a private LAN/VPN address and firewall rules. Do not
port-forward or publicly expose OBS WebSocket.
The admin page can test the connection, read OBS scenes, change the current OBS scene, and map OBS scene names to overlay scenes. Sync can run in either direction or bidirectionally. Source tagging and a short outbound suppression window prevent sync loops. Connector errors never stop overlay rendering, and optional reconnect uses bounded exponential backoff.
OBS passwords use authenticated AES-256-GCM encryption derived from Lumi's stored session secret. They are never returned by public APIs or rendered for non-admins.
OBS Browser Bridge
The optional OBS Browser Bridge uses the window.obsstudio bindings that OBS
injects into Browser Sources. It does not need an OBS WebSocket address or
password. Select the provider, save it, then load the private Lumi overlay URL in
OBS. The render page reports a heartbeat every five seconds and immediately after
relevant OBS events.
Use the minimum Page permission needed:
- Read access to user information reads the current scene, scene list, transitions, canvas dimensions, output status, and Browser Source activity.
- Advanced access to OBS is needed only when Lumi should change OBS scenes.
- Full access is not requested or used by the current bridge.
Lumi elects one recently active Browser Source instance per overlay as the bridge, targets commands to that instance, and deduplicates command IDs. Existing scene-direction checks and outbound suppression prevent synchronization loops. If the source stops reporting, Lumi marks the bridge as waiting instead of breaking overlay rendering. Leave OBS's Shutdown source when not visible option off if the bridge must remain available outside the source's active scene.
The Apply detected OBS setup action adds missing OBS scenes, maps same-name Lumi scenes, adopts the detected OBS canvas size, and selects the current OBS scene. It does not delete existing Lumi scenes. OBS Browser bindings do not expose profile or scene-collection names, so those fields are explicitly reported as unavailable; the OBS WebSocket provider can read them when that metadata is required.
Connector extension point
src/services/overlay-connectors.js owns the provider registry. A provider
creates a connector with these operations:
connect()anddisconnect()status()listScenes()andgetActiveScene()setActiveScene(sceneName)onSceneChanged(listener)andonClosed(listener)
The reserved trusted_lumi_client provider is intentionally unavailable. A
future trusted desktop client can implement this interface to transport OBS state
and commands without changing overlay routes, mappings, or synchronization rules.
Plugins can register providers, module types, or future scoped access providers
through global.lumiFrameworks.overlays.
Run focused verification with npm run verify:overlays.