AAA 12d4b4e4aa chore: merge main into feat/sfu-udp-exact-room
# Conflicts:
#	docs/project-memory.md
#	docs/status.md
#	docs/方案设计.md
#	docs/需求理解.md
#	src/shared/protocol.ts
#	tests/server-signal.test.ts
2026-08-19 20:46:57 +08:00

Screener

Screener is a private, low-latency screen-sharing project for one game player and a small group of friends. Its accepted media target is WebRTC P2P-first, with an SFU virtual parent feeding only the necessary roots and optional authenticated TURN for explicitly supported restrictive networks. Roots continue distributing to bounded peer descendants; this is not an always-SFU conferencing design. Viewers should be able to join from a desktop or mobile browser without installing the sender application.

The first measurable Web proof of concept is implemented. A host captures a screen, window, or browser tab and shares a numeric room code; friends can open /r/{code} directly or enter the code at /join, with no separate viewer token. During a share, the host can change between three ceiling profiles without reopening the source picker: 1080p60 at 8 Mbps, 1080p30 at 5 Mbps, and 720p30 at 3 Mbps. The host can also temporarily pause the picture or switch sources. Rooms are random and temporary by default. A password-protected deployment can optionally use SQLite-backed room numbers starting at 1, reusable links, and a waiting state after sharing stops. Default routing gives each viewer an independent direct WebRTC connection; the exact-room controller can instead use bounded peer descendants and LiveKit SFU roots. The default room capacity is eight viewers and deployments may configure 1 through 16, but that admission limit is not a performance promise.

This is not yet a production release. The currently deployed old release verified public TURN/UDP and TURN/TCP relay paths, but the repository candidate now uses self-hosted STUN-only ordinary ICE plus a separate LiveKit SFU/UDP domain. Real cross-network Screener media, game audio, a sustained 1:8 room, mobile browser lifecycle behavior, and latency targets still require the documented manual test matrix.

Run locally

Node.js 24 and npm 11 are required.

npm ci
npm run dev

ACCESS_PASSWORD is optional. Leaving it empty makes the site public; setting it gates both hosting and viewing behind one site-wide password. Internet deployments intended to stay private should set it, because in public mode the numeric room code is the only viewing capability and does not provide strong privacy by itself.

Open http://localhost:8787. The server listens on 0.0.0.0 by default so a phone on the same LAN can load http://<computer-lan-ip>:8787. To generate an invite that the phone can open while the host keeps using secure-context localhost capture, set PUBLIC_BASE_URL to that LAN URL and include both origins in ALLOWED_ORIGINS. LAN viewers can join over HTTP; the sharing page must remain on localhost or HTTPS because screen capture requires a secure context. The local default has no STUN, so cross-network use still requires HTTPS and the production ICE configuration documented separately.

The current production release still requires STUN plus separate TURN/UDP and TURN/TCP URLs; keep that old release and configuration intact for rollback. The repository candidate deliberately replaces that contract: ordinary authenticated ICE contains only self-hosted STUN, LiveKit separately serves normally one or two SFU/UDP roots, and exhausted paths fail clearly after bounded recovery. Run it on an isolated instance for exact-room acceptance rather than retaining a same-process legacy transport branch. Optional generation-bound TURN for a selected exceptional edge is not implemented and requires a separate evidence-backed change. HTTPS/WSS continues to use TLS/TCP independently.

Run the complete automated validation with:

npm run check

Start here:

S
Description
Free, open-source screen sharing for friends. P2P-first, with browser viewing, a desktop app and optional self-hosting.
https://piik.tv
Readme MIT
9.7 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 46.2%
Go 36.5%
C++ 5.9%
JavaScript 5%
CSS 2.5%
Other 3.9%