Overlays and Graphics
HTML5 graphics over program output, program overlay slots, per-input overlays, and stinger transitions.
LiveWing composites graphics over video using two separate systems: program overlay slots (up to 4 simultaneous overlays on top of the program output) and per-input overlays (other sources composited onto a specific input before it reaches the switcher). Both are rendered in the Metal pipeline alongside the video.
HTML5 graphics (CEF)
Each HTML5 graphic runs in an offscreen CEF (Chromium Embedded Framework) browser instance. CEF renders the page with a transparent background and delivers frames as IOSurface GPU handles (zero-copy, GPU path) or as CPU pixel buffers (fallback). Metal reads the IOSurface directly as a texture and composites it over video in the same render pass.
CEF is initialized lazily — it only starts when the first web page source or graphic layer is added. This means it has zero impact on app launch or CPU when you are not using it.
Hardware acceleration
By default, CEF uses GPU compositing (IOSurface). If you experience compatibility issues, hardware acceleration can be disabled in the app's settings, which switches CEF to software rendering with CPU pixel copies. The setting takes effect on the next launch because it is passed to CEF at initialization time.
Program overlay slots
The overlay engine manages up to 4 slots on the program output. Each slot holds a source angle ID and animates a fade-in/fade-out over 0.35 seconds when toggled. The Metal renderer reads the slot alpha values on every draw call — no polling required.
Assigning a source to a slot does not make it visible immediately. Toggle the slot on to fade it in, toggle it off to fade it out. Multiple slots can be active simultaneously, composited in slot order (slot 1 lowest, slot 4 highest).
Stinger transitions
LiveWing has 4 global stinger slots. Each slot holds:
- A URL to an HTML stinger file (
file://orhttps://) - A display name
When a stinger plays, LiveWing loads the stinger URL as a graphics layer at z-order 1000, which places it above all other layers. The stinger HTML page drives its own animation and posts a cutPoint message back to LiveWing when the animation fully covers the screen. LiveWing performs the source switch at that exact frame, then the stinger continues its reveal animation.
The source switch timing is controlled by the HTML page, not by a timer. Your stinger template determines exactly when the cut happens.
Configure a stinger slot in Settings by entering the URL to the stinger HTML file.
When the stinger plays (via the overlay.playStinger API or a source transition assignment), the HTML page animates over program output.
The stinger page posts cutPoint when fully opaque. LiveWing switches the source, then the page plays its reveal animation. The layer is removed when the page posts animationComplete.
Per-input overlays
In addition to program-wide overlays, each input slot can have multiple other sources composited on top of it before the frame enters the switcher. Each input overlay specifies:
- Source angle ID — which source to composite
- Transform — position, scale, crop, and optional border (same parameters as source transforms)
- Z-order — layer stacking within the input's overlays
- Enabled — toggle without removing
The default transform for a new input overlay is a 25% scale PiP in the bottom-right corner (position 0.8, 0.8).
LiveWing checks for circular dependencies before adding an overlay. Overlaying source A onto source B while B is already overlaid on A is rejected.
Preset persistence
Per-input overlays (transform, source ID, z-order, enabled state) are saved per-source in presets and restored on load. Stinger slot configurations (URL and name) are saved in the preset's global state.