Overlay is a browser-based lower-third control system for live production with synchronized Control / PVW / PGM / Output pipelines, multi-session operation, and ATEM-ready PNG export.
Live demo: https://overlay.simplifyed.in
“Freely you have received; freely give.”
- Matthew 10:8
Requires Node.js 20 or newer. Use the lockfile for a reproducible install:
npm ci
npm startRun the built-in checks with npm run check && npm test.
Open:
- Control UI:
http://localhost:3333/ - Output window:
http://localhost:3333/output.html?session=<session-id>
Use the same session ID in both windows.
- Select mode:
Bible Reference,Speaker,Custom, orTicker. - Build and validate content in
PVW. - Choose
Cut,Swipe, orFade, then take PVW toPGMand Output. - Click
CLEARto remove active lower-third/ticker output.
Keyboard shortcuts:
Enter: Take to AirEsc: ClearB: Bible modeS: Speaker modeC: Custom modeT: Ticker modeO: Open Output WindowH: Open User Guide
- Every session is isolated via URL:
?session=<id>. - Control and Output must share session ID.
- You can run multiple sessions from one server at the same time.
- You can set a custom session at load time (URL/session switcher).
- Appearance and output settings are stored atomically on the server per session and restored when that session is opened again.
- Persistent snapshots are written to
data/sessions/<session-id>.jsonby default. Override the directory withSESSION_DATA_DIR. - Connected control panels receive saved-setting changes immediately over the existing WebSocket room. The latest committed change wins.
- Existing browser-only settings initialize a session automatically the first time it is opened on a server with no saved snapshot.
- Live
PGMvisibility is intentionally transient. Saved settings and presets survive a restart; an on-air graphic is not automatically replayed after one.
- Set
Book,Chapter,Verse(s),Translation, andReference Language. - Optional toggles:
Hide translation line (Line 2)Append translation abbreviation on line 1
Look Up Textfetches verse text (using configured source/fallback chain).Use verse text as line 2 in outputis intentionally independent from translation visibility.
Recommended runbook:
- Build reference.
- Optionally fetch verse text.
- Confirm line 1/line 2 behavior.
- Check PVW.
- Cut to air.
- Enter speaker name (required for meaningful on-air output).
- Role/title is optional.
- Preview first, then cut.
- Enter any text to show as a lower-third.
- Choose how many lines the custom text can use.
- Preview first, then take to air.
- Set message, badge, speed, style, position, colors, and size.
- Ticker can be operated independently from lower-third overlays.
The operator interface includes both the Nocturne and Modernist directions from Design/Overlay Design System Template. Nocturne provides the dark compact palette, Inter typography, soft radii, and layered surfaces suited to dim production environments. Modernist provides Archivo typography, high-contrast editorial rules, square geometry, pale surfaces, and a vivid red accent. The header theme switch saves the operator's preference locally and synchronizes it across open control tabs.
Lower-third styles use the template's visual gallery pattern: numbered preview cards, a clear selected state, responsive columns, and arrow-key navigation. Each card is a miniature render using the same lower-third markup and style rules as PVW, PGM, and Output, including the current accent, background, opacity, and direction. The gallery retains the original style identifiers internally, keeping saved presets and output rendering backward compatible.
The control design system is intentionally separate from the rendered output. Lower thirds, ticker themes, saved settings, and logos retain their own broadcast colors and typography, so control-panel design changes do not alter an on-air composition.
- Includes classic, gradient, scripture/high-capacity, and modern inline variants.
- Supports line-1-only and line-1+line-2 workflows.
- Line 2 multiline can be enabled for longer scripture text.
Each line (Line 1 / Line 2) supports:
- Font family
- Supported font weight (filtered by selected font)
- Italic
- Font size scale
- Custom color
- Stroke (toggle + color + width)
- Drop shadow (toggle + direction/depth/blur/opacity/color)
Logosupports PNG logos with transparency for lower thirds and the standalone output logo.
- Reference presets
- Speaker presets
- Ticker presets
Presets are stored in the server-side session snapshot and synchronize to every connected control using that session ID. Save Preset reports success only after the server acknowledges its disk write or the client reads the exact preset collection back from /api/state. Existing browser-only presets are used to initialize a session when the server has no saved snapshot yet.
Browser storage is a session-scoped cache and migration fallback, not the authoritative store. Back up data/sessions (or the configured SESSION_DATA_DIR) if session setups must survive machine or container replacement.
The current session ID is its saved server-side profile; no separate Save or Load action is required. To reuse a complete setup under another session ID:
- Open the source session and choose Download Session Setup.
- Open a different target session ID.
- Choose Import Setup Here and select the exported JSON file.
An export cannot be imported back into the same session ID because that session already owns the configuration.
Settings -> Output Setup
Use this when integrating with OBS/vMix/Wirecast:
- Copy Output URL.
- Add as Browser Source.
- Match source resolution with selected output resolution.
- Choose keying method:
Transparentmode for alpha-capable browser pipelines.- Blue/Green/Magenta/Custom for chroma-key pipelines.
Use this when feeding ATEM media workflow.
- Include/pin current session for export.
- Session-specific URLs are provided.
- Ticker is not included in ATEM PNG export; ATEM PNG output is lower-third graphics only.
- Export endpoints support both alpha models:
- Premultiplied (ATEM production use)
- Straight (browser QA/comparison)
Typical endpoints:
/atem-live.png(default export)/atem-live/<session>.png/atem-live/<session>.png?alpha=premultiplied/atem-live/<session>.png?alpha=straight
Recommended ATEM runbook:
- Pin the active session.
- Cut lower-third to air.
- Regenerate if you need immediate refresh.
- Use premultiplied URL for ATEM key workflow.
- If mismatch is suspected, compare straight variant first in browser.
Note: premultiplied images can look visually different in standard browser preview; validate in the target switcher/key pipeline.
- Default reference:
John 3:16-18 - Default translation selector:
None (hide translation) Hide translation line (Line 2): enabled by defaultUse verse text as line 2: disabled by default- Default ticker style:
Dark - Default ticker text:
The Live Stream has been restored. Thank you for your patience, and our sincere apologies for the interruption. - Settings panel default: collapsed/hidden for faster operation
curl -fsSL https://raw.githubusercontent.com/jabez4jc/Overlay/main/scripts/bootstrap_ubuntu_server.sh | sudo bashThis bootstrap updates the server, installs required tools, clones/updates repo, and runs the full installer (Node, service, Nginx, HTTPS).
Manual path:
sudo apt-get update -y && sudo apt-get upgrade -y
sudo apt-get install -y git curl ca-certificates
sudo git clone https://github.com/jabez4jc/Overlay /opt/overlay
cd /opt/overlay
sudo bash scripts/install_ubuntu_server.shRecommended for reliable ATEM PNG export: Dockerfile deployment (not Nixpacks).
- Repo:
https://github.com/jabez4jc/Overlay - Branch:
main - Build Pack: Dockerfile
- Dockerfile Path:
./Dockerfile - Port:
3333
Why Dockerfile mode:
- Uses Playwright official runtime image with Chromium + required OS libraries preinstalled.
- Avoids runtime dependency gaps that cause ATEM PNG to stay in placeholder mode.
Coolify settings:
- Expose port
3333. - Add domain (for example
overlay.simplifyed.in). - Mount persistent storage at
/app/data/sessionsif session settings and presets must survive container replacement or redeployment. - Optional env vars:
ATEM_PNG_MODE=premultipliedATEM_PNG_SESSIONS=<comma-separated-session-ids>if you want pre-pinned sessions.SESSION_DATA_DIR=/app/data/sessionsto set the server snapshot directory explicitly.
If you still prefer Nixpacks:
- Keep install command as
npm ci(do not use--ignore-scripts). - Ensure postinstall logs show Chromium installed.
- If browser download is blocked, ATEM export will remain placeholder-only.
- Preset shows
WebSocket is not connected:- Open the control through the Node server rather than as a local
file://page. - Confirm the header connection indicator is online.
- Open the control through the Node server rather than as a local
- Preset save is not acknowledged or persisted:
- Restart the Node process after updating
server.js; refreshing the browser does not reload backend code. - Hard-refresh the control page after updating
js/control.js. - Confirm the service user can write to
SESSION_DATA_DIR. - Check the saved snapshot with
GET /api/state?session=<session-id>and inspect the server log for disk-write errors.
- Restart the Node process after updating
- Deployed UI does not reflect new CSS or JavaScript:
- Confirm the deployment is built from the latest
maincommit; a successful backend health check does not prove a later CSS-only commit was included. - Restart/redeploy the Node container so it generates new content-hashed asset URLs.
- The served HTML should reference assets such as
css/control.css?v=<12-character-hash>with no__CONTROL_ASSET_VERSION__placeholder remaining.
- Confirm the deployment is built from the latest
- Output not syncing:
- Confirm same session ID in Control and Output URLs.
- Confirm active WebSocket connection.
- PVW/PGM vs Output mismatch:
- Verify mode and active cut state.
- Confirm the same overlay style and appearance settings are selected.
- ATEM PNG mismatch:
- Regenerate export.
- Compare
?alpha=straightvs?alpha=premultiplied. - Validate with actual ATEM key settings.
- Mobile UX issues:
- Keep settings collapsed unless editing.
- Use User Guide (
H) for fast-operate workflow.
- Session IDs isolate production lanes; they are not passwords or authentication tokens.
- Run Overlay on a trusted production network or place it behind an authenticated reverse proxy before exposing it to the public internet.
- The server validates session IDs, limits WebSocket payloads and per-session clients, separates control/output roles, and serves only application assets.
index.html- Control UIoutput.html- Output rendererjs/control.js- control logic, synchronization, presets, and session transferjs/output.js- output rendering logicjs/data.js- Bible data, translation/font metadatacss/control.css- control stylescss/output.css- output stylesserver.js- HTTP/WebSocket + ATEM PNG export pipelinetest/- protocol, persistence/restart, security, and UI-contract regression testsDesign/Overlay Design System Template/- retained Modernist and Nocturne design-system sourcescripts/bootstrap_ubuntu_server.sh- Ubuntu bootstrapscripts/install_ubuntu_server.sh- Ubuntu installer
Generated runtime content is intentionally not tracked:
node_modules/- installed dependenciesexports/- generated ATEM PNGsdata/sessions/- server-owned session snapshots; back this directory up separately when needed
- Copyright © 2026 Jabez Vettriselvan
- License: AGPL-3.0-only
- This project remains free software under AGPL-3.0-only.