{"id":50745702,"url":"https://github.com/zalo/webrtc-vnc","last_synced_at":"2026-06-10T20:32:13.677Z","repository":{"id":355968044,"uuid":"1187630182","full_name":"zalo/webrtc-vnc","owner":"zalo","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-06T02:43:33.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-06T04:37:35.582Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zalo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-21T00:28:55.000Z","updated_at":"2026-05-06T02:43:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zalo/webrtc-vnc","commit_stats":null,"previous_names":["zalo/webrtc-vnc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zalo/webrtc-vnc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zalo%2Fwebrtc-vnc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zalo%2Fwebrtc-vnc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zalo%2Fwebrtc-vnc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zalo%2Fwebrtc-vnc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zalo","download_url":"https://codeload.github.com/zalo/webrtc-vnc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zalo%2Fwebrtc-vnc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34170162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-10T20:32:12.951Z","updated_at":"2026-06-10T20:32:13.672Z","avatar_url":"https://github.com/zalo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# webrtc-vnc\n\nStream your desktop to any browser over WebRTC — keyboard, mouse, and gamepad input included. Cross-platform: Linux, macOS, Windows.\n\n## Features\n\n- H.264 video via WebRTC media tracks (Safari, iOS, Firefox) and WebCodecs data channel (Chrome, Edge)\n- Opus audio (Linux only for now)\n- Keyboard, mouse, and gamepad input\n- Multi-peer: host + up to 3 guest players, spectators\n- Per-OS hardware-accelerated capture+encode pipelines:\n  - **Linux**: `nvfbc_nvenc` (NVIDIA, GPU-only) → `kmsgrab` → PipeWire → `x11grab`. Encoders: NVENC / VAAPI / V4L2 M2M (Raspberry Pi) / libx264.\n  - **macOS**: `screenkit_vt` (ScreenCaptureKit + VideoToolbox, ANE on Apple Silicon) → ffmpeg avfoundation + h264_videotoolbox.\n  - **Windows**: `dxgi_mf.exe` (Desktop Duplication + MediaFoundation auto-routing to NVENC/QSV/AMF) → ffmpeg ddagrab + h264_nvenc/qsv/amf/mf.\n- Optional cloudflared quick tunnel: server exposes itself to the public internet on startup (default on, `-tunnel=false` to disable).\n\n## Requirements\n\n- Go 1.25+ (1.26 used via the `GOTOOLCHAIN=auto` mechanism — `go build` will fetch it automatically)\n- ffmpeg in PATH (Linux primary path skips ffmpeg on the hot path; ffmpeg is needed for fallbacks and audio)\n\n## Linux\n\n```bash\ngo build -o webrtc-vnc .\nsudo ./setup.sh          # one-time: groups, udev, ffmpeg capabilities\n./webrtc-vnc\n```\n\nOpen `http://localhost:8080` in a browser.\n\nThe startup probe picks the best capture method automatically. To confirm:\n\n```bash\ncurl http://localhost:8080/api/encoder\n# {\"status\":true,\"encoder\":\"h264_nvenc (nvfbc)\"}\n```\n\n### Raspberry Pi 4b\n\nThe VideoCore VI GPU supports hardware H.264 via `h264_v4l2m2m`. The server detects and uses it automatically.\n\n```bash\nsudo apt install ffmpeg\ngo build -o webrtc-vnc .\nsudo ./setup.sh\n./webrtc-vnc -width 1280 -height 720 -fps 30 -bitrate 2000\n```\n\n## macOS\n\nBuild the Go server (cgo on, for Quartz CoreGraphics input):\n\n```bash\nCGO_ENABLED=1 go build -o webrtc-vnc .\n```\n\nBuild the native capture helper (universal arm64 + x86_64):\n\n```bash\ncd cmd/screenkit_vt\nmake install        # produces ./screenkit_vt and copies it next to webrtc-vnc\ncd ../..\n./webrtc-vnc\n```\n\nThe first run will prompt for **Screen Recording** and **Accessibility** permissions in *System Settings → Privacy \u0026 Security*. Grant both.\n\nIf the helper isn't present, the server falls back to ffmpeg's `-f avfoundation -c:v h264_videotoolbox` path automatically.\n\n## Windows\n\nInstall `ffmpeg.exe` somewhere on `PATH` (or copy alongside `webrtc-vnc.exe`).\n\nBuild the Go server:\n\n```powershell\ngo build -o webrtc-vnc.exe .\n```\n\nBuild the native capture helper (from a Visual Studio \"x64 Native Tools Command Prompt\"):\n\n```cmd\ncd cmd\\dxgi_mf\nbuild.bat install   :: produces dxgi_mf.exe and copies it next to webrtc-vnc.exe\ncd ..\\..\nwebrtc-vnc.exe\n```\n\nIf the helper isn't present, the server falls back to ffmpeg's `-f ddagrab` + best detected encoder (`h264_nvenc` / `h264_qsv` / `h264_amf` / `h264_mf`).\n\n## Options\n\n```\n  -port int        HTTP server port (default 8080)\n  -display string  X11 display id (Linux only; default $DISPLAY or :0)\n  -width int       Capture width (default 854)\n  -height int      Capture height (default 480)\n  -fps int         Capture framerate (default 144)\n  -bitrate int     Video bitrate in kbps (default 1000)\n  -encoder string  Video encoder: auto, nvenc, vaapi, qsv, amf, software (default auto)\n  -no-audio        Disable audio capture\n  -tunnel          Expose this server via a cloudflared quick tunnel (default true)\n```\n\n## Tunnel (public internet exposure)\n\nThe server can launch a [cloudflared](https://github.com/cloudflare/cloudflared) quick tunnel on startup so you can hand the URL to a friend without configuring port-forwarding:\n\n```bash\ngit submodule update --init third_party/cloudflared\n(cd third_party/cloudflared \u0026\u0026 GOTOOLCHAIN=auto go build -o ../../cloudflared-bin ./cmd/cloudflared)\n./webrtc-vnc                 # tunnel URL is printed to the log\n./webrtc-vnc -tunnel=false   # local-only\n```\n\n⚠️ **Anyone with the trycloudflare URL can view and control this computer.** Treat it like a password.\n\n## Setup details (Linux)\n\n`setup.sh` makes the following system changes (revert with `unsetup.sh`):\n\n- Creates `/etc/udev/rules.d/99-webrtc-vnc-uinput.rules` for `/dev/uinput` access\n- Adds your user to the `input`, `render`, and `video` groups\n- Copies `ffmpeg` to `./ffmpeg-cap` and grants it `cap_sys_admin` (required for kmsgrab)\n- On NVIDIA systems: adds `nvidia-drm.modeset=1` to GRUB for kmsgrab support\n\nInput injection requires `/dev/uinput` access. Without it the server runs view-only.\n\n## Architecture\n\n| File | Purpose | OS |\n|------|---------|----|\n| `main.go` | HTTP server, flags, graceful shutdown, embed `web/` | all |\n| `tunnel.go` | Supervised cloudflared quick tunnel launcher | all |\n| `stream.go` | WebRTC room, signaling, peer + quality management | all |\n| `capture.go` | Capture struct + generic process orchestration + Annex-B reader | all |\n| `capture_linux.go` | Linux probe (NvFBC/kmsgrab/pipewire/x11grab) + ffmpeg pipeline | linux |\n| `capture_darwin.go` | macOS probe (screenkit_vt → avfoundation+videotoolbox) | darwin |\n| `capture_windows.go` | Windows probe (dxgi_mf → ddagrab+nvenc/qsv/amf) | windows |\n| `input_linux.go` | `/dev/uinput` keyboard / mouse / scroll / gamepad | linux |\n| `input_darwin.go` | Quartz CGEvent input (cgo) | darwin |\n| `input_windows.go` | `user32.SendInput` mouse + keyboard (no cgo) | windows |\n| `cmd/nvfbc/` | NVIDIA NvFBC + NVENC GPU-only helper (C) | linux |\n| `cmd/screenkit_vt/` | macOS ScreenCaptureKit + VideoToolbox helper (Swift) | darwin |\n| `cmd/dxgi_mf/` | Windows DXGI Duplication + MediaFoundation helper (C++) | windows |\n| `web/` | Browser frontend (single-page) | all |\n\nThe native helpers all speak the same protocol the Go server already consumes: H.264 Annex B with SPS/PPS prepended to every IDR, written to stdout.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzalo%2Fwebrtc-vnc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzalo%2Fwebrtc-vnc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzalo%2Fwebrtc-vnc/lists"}