Stoatworks Labs

WebLinked

A URL in, SDI, NDI and a screen out

Field provenv1.0.3ApplicationC++
WebLinked — A URL in, SDI, NDI and a screen out
The control page, rendering github.com to NDI at 1080p50.

What it does

Point WebLinked at a scoreboard, a lower third, a countdown clock, a dashboard or a whole HTML playback page and it becomes a source your vision mixer can cut to — or a feed for a projector or LED processor. It renders the page offscreen through Chromium at a broadcast raster and rate, then sends it to DeckLink and AJA over SDI, to the network as NDI and OMT, and fullscreen to an attached display — every output taking the same frame.

The engine clocks the browser one frame at a time rather than letting it paint on its own timer, so 50 ticks a second really is 50 paints. Small on purpose: one binary, no service to install, no framework in the page. It opens no window for an operator at all — the UI is the control page it already serves, which is why there is no GUI toolkit anywhere in the project. The one window it does open is an output: the fullscreen picture on a display, which takes no input and is simply another destination for the same frames.

  • SDI out to Blackmagic DeckLink and AJA, including separate key and fill
  • NDI and OMT out on the network, with alpha carried correctly — Chromium composites premultiplied and every destination expects straight, so it is un-premultiplied on the way out
  • Fullscreen out to a GPU-attached display for a projector, a wall or a confidence monitor — paced by that display, so a 50 Hz page on a 60 Hz head repeats frames rather than tearing, and fitted, filled or stretched to a head whose shape does not match the raster
  • Frame-accurate external pacing rather than free-running browser paint
  • Several sources in one process: each is a whole pipeline of its own and they share nothing, so one hung page or one missing card leaves the rest on air. HTTP and OSC address a feed by name; omit the name and you get the first, so anything that drove one source still works
  • An interactive preview: click, scroll and type into the live page to dismiss a cookie banner or sign in, on a machine whose browser you cannot otherwise reach
  • A settings page — outputs added, edited and started from the browser, saved to a file the next launch reads back
  • Diagnostics without a shell: the live log with the level changeable while the fault is happening, and a bundle that downloads as a file rather than naming a path
  • Driven from the command line, over HTTP, or over OSC from Companion or a show-control system
  • A menu-bar and system-tray icon on macOS, Windows and Linux, showing the running source count and opening the control page in a click
  • Syphon on macOS and Spout on Windows, so the page is a source inside Resolume, VDMX or TouchDesigner on the same machine, over shared memory, with its own alpha intact
  • RTMP and SRT to a streaming server, the page encoded to H.264 and AAC through an ffmpeg subprocess
  • The page's audio carried too — WebAudio, video elements, anything Chromium plays — as 48 kHz float, embedded in SDI or sent alongside the IP video

Where it stands

Field proven — run on a live event, and released as v1.0.3 (a maintenance release; the app is v1.0.2's) with installers for macOS, Windows and Linux. The engine now puts its own icon in the menu bar, so the separate tray launcher was retired and there is one download per platform. WebLinked has no window of its own: it is a render host and a control server, and the control page it serves is the whole UI - open it in any browser, or reach it from WebLinked's own menu-bar icon. NDI is verified end to end against a real receiver, alpha included. SDI is no longer an assumption either: measured against a real DeckLink Duo 2, with colour confirmed by a loopback capture against an independent BT.709 reference, a two-minute soak holding its buffer at 6 frames with zero dropped ticks, and key + fill measured to carry straight alpha rather than premultiplied - the bug that was real on NDI is absent on SDI. Not everything: the key channel itself, audio over SDI and genlock over hours are still unmeasured, and AJA and OMT compile against their SDKs and have never met hardware or a receiver. The fullscreen screen output is verified on this machine across two displays — picture, all three scaling modes, live add and remove, and pacing measured against the display's own refresh rather than the video rate: a 50 Hz source on a 60 Hz head presents at 60.1/s, a ratio of 1.199 against a theoretical 1.200. Its Linux backend is now verified as well — a 1920x1080 window under X11 and EGL on software GL, checked by screenshotting what landed on it against the source page rather than by reading its own counters. The Windows backend is written and still never run: the machine available for testing has no GPU at all, so the Direct3D path cannot be reached there. Several sources run as tabs, each a whole pipeline with its own browser, clock, raster and outputs, so one hung page cannot touch the others, and two instances can run side by side. Downloads bundle the NDI runtime, so NDI works on a machine that never installed the SDK; the hosted builders have no DeckLink or AJA SDK, so SDI out needs a local build. Windows and Linux are no longer signed off on a compile: in August 2026 both were run on real systems — a Windows 11 x86_64 machine and Ubuntu 24.04 — where the unit suite passes (115 tests, 26191 checks), the control API, OSC, mDNS and the tray all work, and NDI was received and decoded by an independent receiver on a different machine, in both directions. Two gaps remain on those machines and are worth stating plainly: neither has an SDI card, so DeckLink and AJA are untouched there, and the Windows one has two cores and no GPU driver, so it renders at a few frames a second and can demonstrate that the code works without proving anything at all about how fast it runs. That run also found that the v1.0.1 Linux tarball had been built without the application inside it — 355 MB of runtime and resources with nothing in it to run. **Linux users should take v1.0.2 or later**, which is the release that repairs it. docs/04-verification.md gives the numbers and the method rather than a promise.

Watch it running

WebLinked video thumbnail

Nothing loads from YouTube until you press play.Watch it there instead