Skip to content

VeScreen App ​

English · 简体中文 · Getting started

VeScreen App provides local rooms and native screen capture through the VeScreen web interface in your system Browser.

Run A Package ​

Extract the matching platform bundle in full and keep runtime beside the App executable. Run piik-app.exe on Windows, ./piik-app on Linux, or VeScreen.app on macOS. The launcher opens in the system Browser. Linux native capture uses the system dependencies described in the Linux capture guide.

If the page does not open automatically, open the address shown in the terminal or press O there to retry. Keep the App running while using that page.

Windows App and browser sharing are the primary tested paths. Physical-device coverage for the macOS and Linux apps is still limited; test results and feedback are welcome. macOS native capture requires macOS 13 or newer on Apple silicon or Intel. Package construction and public Release publication are separate steps in deployment.

Modes ​

  • With no mode argument, the App opens a small launcher in the system Browser. It selects Local, a temporary public HTTPS invitation, or a saved Site, then enters the normal Host page.
  • The launcher remembers the last mode confirmed with Open VeScreen and the saved Site address. Without a saved mode, it selects Site when an address is saved, otherwise Public invite; it waits for confirmation before starting. The mode preference is stored beside the settings in client.json.mode; App configuration covers saved preferences and custom paths.
  • The --site, --local, and --link flags select a mode for CI and development.
  • The default launcher checks official releases after it opens, using GitHub first and Gitee if GitHub is unavailable. Click the update button to download the matching platform ZIP, or open the release page when no package matches. Release notes opens separately; a new major version includes an upgrade warning. The App does not install or replace itself.

Local rooms last for this App run and work on a reachable LAN. Public invite uses the packaged Cloudflare Tunnel helper to expose that same room service at a temporary HTTPS address. Picture and sound travel between participants (P2P), outside the tunnel. Both modes need a usable UDP media path and provide no media-server forwarding (SFU) or TURN relay fallback. The routing reference explains connection setup.

For Local invitations, the App automatically selects a sole active address or sole private IPv4. If several addresses remain possible, choose an interface and IP in the launcher. Public invite and Site mode need no LAN selection. When bypassing the launcher with --local, use --lan-address <address> to resolve an ambiguous choice. The selected address is checked again at startup; it affects Local invitation links, while ICE selects media paths independently.

Site mode uses the configured Site's rooms and any enabled SFU fallback. An App-opened Site remembers native activation, so later pages there may reuse the running App. Browser capture remains available without the App; see the entry workflow.

The Host page offers Browser capture and available native windows or screens; select the source explicitly. Windows native capture offers VP8/Auto/H264; Auto chooses one codec for the share. macOS and Linux native capture require hardware H264. Source and audio support vary by platform; their setup is covered in the Windows, macOS and Linux capture guides. Native capture uses the Host's current quality settings. The media-quality reference owns codec selection, live changes and encoding reuse; verification status keeps the measured limits.

On supported Windows versions, the Apps / Windows and Screens tabs offer Show capture border, off by default. Change it when selecting or switching a source; the Host page remembers your choice. Windows 10, system policy or another active capture can keep the yellow border visible; sharing remains available. See capture-border troubleshooting for an optional Windows 10 workaround.

The App configuration keeps an optional Local site passphrase. Leave it blank for an open Local site, or enter a password in the launcher before starting. Viewer invitations grant access to their room independently; see rooms and access.

The terminal shows the current mode, entry links and startup state; its language follows the launcher and App-enabled pages. Press o to reopen the Browser, or q / Ctrl+C to end Local rooms and stop the local server and temporary public link. Plain-text output uses Ctrl+C. The App keeps running after a Site tab closes. When launched in its own Windows console, a startup or runtime error leaves the error visible until Enter is pressed. Normal shutdown, existing terminals and redirected or automated runs exit directly.

For one-link Internet sharing, open the App launcher, choose Public invite, create a room in the opened Browser, and send its normal invitation link. The random trycloudflare.com origin lasts only for that App run; a later launch creates a new temporary link. Cloudflare Quick Tunnels provide no uptime guarantee; use a configured Site when persistent control availability or SFU fallback matters.

Troubleshooting ​

Chromium WebRTC Connections ​

Why can the page open, or screen capture succeed, while sharing or viewing fails?

Browser settings, extensions or managed policies can block WebRTC UDP, including the local Browser-to-App media connection. Follow the documentation center's browser WebRTC checks. For codec-specific failures, see Windows H264 troubleshooting.

Diagnostics ​

Enable Debug launch in the mode selector before opening VeScreen, reproduce the problem, then press D in the interactive terminal to export a local ZIP. Use --debug for failures before the selector opens. Exporting does not stop the share or upload the archive. For Browser diagnostics, click the Debug chip icon after the theme control, confirm the reload, then use Web report to download. For cooperation failures, include both reports from the same reproduction. The diagnostic reference owns log locations, export commands, retention and privacy boundaries.

Development ​

Use the Node/npm/Go versions in Run from source. The binary embeds the Browser assets, so build them from the repository root first:

sh
npm ci
npm run build:web

On Linux or macOS:

sh
go run ./cmd/piik-app

On Windows, build and run from a stable executable path for the system firewall:

powershell
go build -o build/dev/piik-app.exe ./cmd/piik-app
./build/dev/piik-app.exe

These commands build the App only. Choose Local room or a configured Site for Browser capture. Native capture and Public invite need their helpers; use --capture-process / --tunnel-process to select built helpers, or follow packaging for a complete bundle.

The repository-level entry used locally and by CI is:

sh
npm run check:go

On Windows, its generated App, capture, and media-test executables are written to the ignored repository build/go-check directory and reused on the next run. This keeps the executable identity stable for the system firewall; the files are local build output and are never packaged or committed.

It runs Go formatting, unit tests, vet, and Windows/Linux cgo-free cross-builds. The Darwin App and peer gate build only on macOS with cgo enabled and an installed SDK; other hosts report that skipped platform explicitly. The pinned media dependency's Darwin CPU statistics use Mach APIs through cgo, so a Windows or Linux core check does not establish Darwin build acceptance. The check compiles the current platform's isolated capture process and validates its bounded capability response. macOS additionally encodes one in-memory hardware H.264 IDR; Linux probes the Portal/PipeWire/GStreamer adapter. Real capture, GPU attribution, Browser decode, and public-network paths remain explicit physical gates rather than environment-dependent unit tests.

App and Hosted share the Go room service. The Browser UI coordinates native capture and Viewer receive/relay through the App's local control service; Viewer receive/relay remains available without a supported native capture encoder. Use the module map and contract map to find the source owners. The candidate packager checks that capture helpers match the App's contract.

Packaged builds report the product version and source SHA in the terminal and diagnostics. Versioning explains build identity and update notices; GitHub operations describes automatic publication.

Packaging ​

From a clean revision, build the application release and run the platform's candidate wrapper on its native operating system. The wrapper builds capture, verifies the pinned public-link helper, and assembles and checks the App:

sh
node scripts/package-server-release.mjs /outside/repository/app-release
node scripts/package-app-candidate.mjs /outside/repository/app-release windows-amd64 /outside/repository/app-candidate

Supported targets are windows-amd64, linux-amd64, linux-arm64, darwin-arm64 and darwin-amd64. Use the matching target name in the command above. Darwin assembly requires a native macOS runner with its SDK and enables cgo; Windows and Linux assembly keep cgo disabled. The result is a ZIP bundle and SHA-256 file. Manual sidecar assembly, explicit CI packaging, Release publication and updates are documented in deployment; creating a candidate does not publish it.

The extracted bundle contains:

text
piik-app[.exe]
REVISION
LICENSE
THIRD-PARTY-NOTICES.txt
runtime/native/piik-capture[.exe] # supported native-media packages
runtime/tunnel/cloudflared[.exe] # packages that support --link

The executable embeds the Browser assets of the consumed application release and carries that same full Git revision as the package REVISION. App/Site interoperability follows the public compatibility contract.

The Windows App embeds the shared VeScreen mark through the cmd/piik-app/piik_windows_amd64.syso resource; the platform suffix keeps that Windows resource out of Linux and macOS builds. Linux packages include the standard share/applications desktop entry and hicolor icon. macOS packages include a thin VeScreen.app launcher with an ICNS resource; the raw Go executable remains available beside it.

For a native Host smoke run, launch the App and select a window in the Host page, then open its invitation on another device. Choose the mode for that network as described above.

Gates ​

The Local gate starts the packaged process, loads a real built page in Chromium, proves bootstrap access and LAN invitation construction, and verifies complete process/profile cleanup. The loopback gate separately proves Site access with and without Chromium Local Network Access permission. Environment syntax below is POSIX; use equivalent variables on Windows.

sh
PIIK_CLIENT_LOCAL_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_CLIENT_EXE=/path/to/piik-app \
PIIK_CLIENT_GATE_LAN_ADDRESS=192.168.1.10 \
npm run gate:app-local

PIIK_CLIENT_LOOPBACK_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_CLIENT_EXE=/path/to/piik-app \
npm run probe:app-loopback

PIIK_CLIENT_MEDIA_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_CLIENT_GATE_STUN_URLS=stun:<stun-host>:3478 \
npm run gate:app-media

PIIK_CLIENT_NATIVE_HOST_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_GO=/path/to/go \
npm run gate:app-native-host

PIIK_CLIENT_NATIVE_HOST_GATE=true \
PIIK_CLIENT_CROSS_NAT_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_GO=/path/to/go \
PIIK_REMOTE_HOST=<public-test-host> \
PIIK_REMOTE_USER=<ssh-user> \
PIIK_REMOTE_SSH_KEY=/path/to/key \
PIIK_CLIENT_GATE_STUN_URLS=stun:<stun-host>:3478 \
npm run gate:app-native-host

PIIK_CLIENT_NATIVE_HOST_GATE=true \
PIIK_CLIENT_LINK_MEDIA_GATE=true \
CHROME_PATH=/path/to/chrome \
PIIK_GO=/path/to/go \
PIIK_CLOUDFLARED=/path/to/cloudflared \
PIIK_REMOTE_HOST=<public-test-host> \
PIIK_REMOTE_USER=<ssh-user> \
PIIK_REMOTE_SSH_KEY=/path/to/key \
npm run gate:app-native-host

PIIK_CLIENT_LINK_GATE=true \
PIIK_GO=/path/to/go \
PIIK_CLOUDFLARED=/path/to/cloudflared \
PIIK_REMOTE_HOST=<public-test-host> \
PIIK_REMOTE_USER=<ssh-user> \
PIIK_REMOTE_SSH_KEY=/path/to/key \
npm run gate:app-link

The Windows media gate proves one hardware-H.264 capture generation, shared Pion source, Browser decode, PLI recovery, and STUN candidate gathering. The native Host gate proves room creation and native video delivery through the current route; native audio is included when the capability probe and target OS support it. The cross-NAT variant uses a temporary reverse SSH path for signaling only and requires a selected srflx or prflx media pair; media never travels through SSH. The one-link media variant instead carries the same signaling through the App's temporary public origin and requires direct media delivery to an independent Linux peer. Native P2P quality evidence and embedded SFU delivery have explicit gates. macOS and Linux capture still require physical desktop/media gates; CI compilation and package smoke do not substitute for them.

Third-party licenses