Repository navigation
Releases: i-is-evil-duck/OpenDisplayWebBridge
Release list
v0.4.0 — the first public build: runs on macOS 13
OpenDisplay Web Bridge — v0.4.0
Turns a spare iPad into a second display for a Mac, over the network. A sender
connects as it would to any receiver; this forwards the picture to the browser
over a WebSocket binding of the OpenDisplay protocol (pv 3).
What it does
- Passthrough — the sender's H.264 reaches the browser untouched, for
anything with WebCodecs. Zero work, zero added latency. - WebRTC/VP8 fallback — for devices that cannot decode H.264 at all. The
bridge decodes and re-encodes in software, then hands pixels to libwebrtc as
VP8. Chosen over H.264 inside WebRTC because libwebrtc statically links
libvpx at no extra size, VP8 is mandatory-to-implement in every browser, and
H.264 inside WebRTC would need a hardware encoder an unsigned app cannot
reach. - Input — touch (
began/moved/ended/cancelled, normalised) and
scroll, injected into the Mac as real events. - Remote cursor — drawn at the sender's position, in the sender's sprite,
and kept visible in fullscreen by preferring page fullscreen over the native
iOS player, which cannot draw an overlay. - Live diagnostics — the receiver reports what it can see, so a black
screen is attributable to the sender, the bridge or the receiver rather than
guesswork.
Requirements
- macOS 13 or later
- An OpenDisplay sender (the real
OpenDisplay.app; it discovers this over
Bonjour and dials in on port 9000) - Any modern browser as the receiver
Try it
OpenDisplayBridge-v0.4.0.zip is self-contained: OpenH264 and libwebrtc are
bundled and every load path is rewritten, so it needs no Homebrew, no
DYLD_LIBRARY_PATH, and nothing from the machine that built it.
unzip OpenDisplayBridge-v0.4.0.zip
open OpenDisplayBridge.app
The window shows a 6-digit code and a URL. Open the URL on the receiver and
enter the code; the session cookie survives reloads.
Gatekeeper will object once. The app is ad-hoc signed, so right-click ->
Open, or xattr -dr com.apple.quarantine OpenDisplayBridge.app. A Developer ID
signature and notarisation remove that step, and both require a paid Apple
Developer account — a free one cannot notarise at all, and its certificates
expire after 7 days.
Building from source
./tools/build-openh264.sh # software H.264 decoder, ~1 min
swift run # or ./tools/make-app.sh for a bundle
The OpenH264 step is not optional for a portable build. Homebrew's bottle is
built against a recent macOS (minos 26.0), so linking it makes the app
macOS-26-only; building the same source with a 13.0 deployment target does not.
brew install openh264 also works, if you do not need the older target.
The icon is generated rather than committed, by tools/make-icon.swift — an
.icns is a container of pre-rendered PNGs, so there is nothing reviewable in
a diff, and the drawing is.
Verification
- 141 unit tests pass, and a smoke test drives a running bridge over HTTP and
WebSocket: static assets, the pairing gate, cookie issuance, WebSocket gating,
and the hello -> welcome -> streamConfig exchange. - Every new regression test was checked to fail with its fix reverted and pass
with it restored, rather than assumed to be one. - The bundle reports
LSMinimumSystemVersion 13.0and the bundled dylib reports
minos 13.0. - No absolute build-machine path survives in
otool -Lor the rpath list. An
unzipped copy, launched from/tmp, loads zero libraries from outside the
bundle or the OS. - Corrupting one byte of the OpenH264 tarball makes the build script refuse
rather than build something of unknown provenance.
Not covered by anything here: a live sender changing resolution while a receiver
disconnects, with the software decoder active. That sequence needs real hardware.
Licensing
MIT — see LICENSE. NOTICE.md records the third-party attributions
(OpenH264 BSD-2-Clause, WebRTC BSD-3-Clause) and sets out the OpenDisplay
position: this is an independent implementation of a documented wire protocol,
not a fork, and no upstream source is included.