Simple and powerfull remote controlled html pages useful for overlays in OBS Studio, CasperCG, XSplit or simply fullscreen browser.
- server holds overlay state
- on refresh or reconnect, state is updated from server for overlay and controller so you don't loose texts etc.
- multiple overlay-controller groups on 1 server instance (via different websocket paths)
- server is needed only for first connect, both controller and overlay holds state info
Open in browser scoreboard/controller.html.
Open in browser scoreboard/overlay.html on other PC or display.
Setting you might need to change is websocket URI in overlay.html and controller.html in directory your-overlay/.
Set it to the same IP address and port as your server is running on, (i.e. http://127.0.0.1:3000/gun).
- Click the plus button under Sources
- Select BrowserSource
- Name the source and click "OK"
- Check the "Local file" box
- Click the "Browse" button on the right and select the client.html you want to use
- Set the Resolution to 1920x1080 (Width: 1920; Height: 1080) or the overlay resolution
- Set FPS to you stream FPS (examples: 25, 30, 50, 60)
https://github.com/CasparCG/help/wiki/Media:-HTML-Templates
ProPresenter browser capabilities in versions 6 and 7 are very limited, and this overlays are not usable. https://learn.renewedvision.com/propresenter6/the-features-of-propresenter/web-view
https://www.xsplit.com/broadcaster/manual/sources/webpage
You can create your own overlay and associated controller without implementing server.
HOST=0.0.0.0 PORT=8089 node server/ws.cjs
or
HOST=0.0.0.0 PORT=3000 node server/gun.cjs
or
HOST=0.0.0.0 PORT=8081 node server/mqtt.cjs
Once you've created a project and installed dependencies with npm install (or pnpm install or yarn), start a development server:
python3 -m http.server 8080 -d staticThis project was inspired by
- https://github.com/lebaston100/htmlOverlayFramework
- https://github.com/hberntsen/websocket-png-overlayer
- https://github.com/Scrxtchy/ts3-overlay-ws
- https://github.com/slugalisk/win-loss-overlay
- https://github.com/filiphanes/websocket-overlays
- more overlays
Today multiBrokerState (in static/js/broker.js and src/lib/broker.svelte.js)
builds one getter/setter per key with Object.defineProperty. That works but is
fixed to the keys passed at construction — keys can't be added later, and every
key costs a property descriptor.
An alternative is to back the returned object with a single Proxy over a
Map of van.states. Same s.show ergonomics, plus dynamic keys for free
(useful for a generic key/value editor or transports that surface arbitrary
keys):
function reactiveStore(seed, onSet) {
const $ = new Map();
const get$ = k => ($.has(k) ? $ : $.set(k, van.state(undefined))).get(k);
for (const [k, v] of Object.entries(seed)) get$(k).val = v;
return new Proxy({}, {
get: (_, k) => get$(k).val, // tracks VanJS deps
set: (_, k, v) => { get$(k).val = v; onSet(k, v); return true; },
ownKeys: () => [...$.keys()],
getOwnPropertyDescriptor: (_, k) =>
({ enumerable: true, configurable: true, value: get$(k).val }),
});
}
// self[k] = reactiveStore(init, (k, v) => send(k, v));Caveat: a Proxy is less greppable than named properties (s.show no longer has
a literal definition) and needs the ownKeys / descriptor traps for
Object.keys() and spread to work. Worth doing only if runtime-added keys
become a real need; otherwise the current defineProperty loop is simpler.