Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wire — peer-to-peer voice/video calls + screen share + chat

A two-person call app. PHP handles the page and a tiny signaling relay; audio, video, screen share, and chat all travel directly between the two browsers via WebRTC — none of it passes through your server.

Features

  • Voice call, on by default the moment both people join.
  • Camera, off by default — click the camera button to turn yours on. The other person sees it as soon as you do; turning it off removes your video instantly on their end too.
  • Screen share — uses your browser's native screen/window/tab picker. While sharing, your screen shows large on the other person's screen, with your camera (if also on) as a small thumbnail. Clicking the browser's own "Stop sharing" bar works exactly like clicking the button in Wire.
  • Chat — a slide-out panel sent over a WebRTC data channel, which is the same direct peer-to-peer pipe as the audio/video. Messages never touch your server, and there's no history — closing the tab clears it, by design.

How it works

  1. You open the page → it generates a random room code (or use one already in the URL) and shows you an invite link.
  2. You send that link to the other person. When they open it, both browsers start polling signal.php once a second.
  3. Once both are present, they automatically exchange a WebRTC offer/answer and ICE candidates through signal.php (this is just a few KB of text — "here's how to reach me"). This is called signaling, and it's the only thing that touches your server.
  4. As soon as that handshake finishes, the browsers open a direct peer-to-peer connection and audio (and a data channel for chat) flow straight between them. signal.php goes idle for the rest of the call — except briefly again any time someone turns their camera or screen share on/off, which needs a quick renegotiation round through the same relay before the new video starts flowing, peer-to-peer, same as everything else.

A pair of free public STUN servers (Google's) are used so each browser can discover its own public address — this is also just address discovery, not media relay.

Limitations, honestly

  • True peer-to-peer media is achieved for most networks, but a small fraction of users sit behind "symmetric NAT" routers (some corporate and mobile networks) where two browsers genuinely cannot find a direct path. In that case WebRTC needs a TURN relay server — a third party that forwards the encrypted media because no direct route exists. I did not include one because that means media does pass through a server (just not necessarily yours). If you hit calls that get stuck at "Connecting…", that's almost always this — see below.
  • Signaling uses 1-second polling, so call setup (and turning on camera/ screen share for the first time) takes ~1-2 seconds longer than a websocket-based app would. Once connected, this has zero effect on call quality — media is real-time WebRTC, not polled.
  • This is a two-person, one-room-at-a-time design: a third visitor to the same room link is told the room is full rather than joining.
  • No persistence anywhere: room state lives in flat files in storage/rooms/ and is pruned automatically; chat has no history; nothing is logged or kept after the call.
  • Screen share captures video only (no system audio) — this matches most browsers' default screen-share audio support, which is patchy across OSes. Let me know if you'd like system-audio capture added for browsers that support it.

Setup

Needs PHP 7.4+ with write access to storage/rooms/.

# Quick local test:
cd wire/
php -S localhost:8000

# then open http://localhost:8000 in two different browsers/devices

For real use between two people on different networks, this needs to be on a publicly reachable server (any shared host with PHP works) served over HTTPS — browsers refuse microphone/camera/screen-share access on plain HTTP for any host other than localhost.

your-domain.com/
├── index.php       # generates/joins room, renders the UI
├── signal.php      # the only server-side logic: message relay
├── style.css
├── app.js          # WebRTC + polling logic (call, video, screen, chat)
└── storage/
    └── rooms/      # must be writable by the web server user

If calls won't connect

If both people consistently get stuck at "Connecting…", it's almost always restrictive NAT/firewalls on one or both sides, not a bug. The fix is adding a TURN server to the iceServers list in app.js — free options like Twilio's or Cloudflare's TURN have a generous free tier for this. If you want, I can wire one in — it's a few lines — just know that with a TURN relay involved, media for those specific stuck calls would route through that third-party relay instead of staying fully peer-to-peer.

About

Wire — peer-to-peer voice/video calls + screen share + chat

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages