utility-scripts/lanshare
Claude 4c223b47ed
Fix screenshare not visible until viewer reloads
When a screenshare was started while both peers were already connected,
the viewer never received the video stream. This worked after a reload
because the peer_joined handler proactively sends an offer to the new
peer.

The root cause: startSharing() relied on a request_stream round-trip
(viewer sends request_stream, sharer responds with offer). Since
handleSignal is async but never awaited by ws.onmessage, this
round-trip could silently fail when promises rejected or messages
interleaved during the exchange.

Fix by having the sharer proactively send offers to all connected peers
in startSharing(), matching the existing peer_joined behavior. Also add
a fallback in ontrack for when event.streams is empty.

https://claude.ai/code/session_01ALSwS4S8EHiP81i2KMsb9Y
2026-02-09 09:16:51 +00:00
..
src Fix ICE failures by replacing mDNS .local addresses with real peer IPs 2026-02-09 07:38:49 +00:00
static Fix screenshare not visible until viewer reloads 2026-02-09 09:16:51 +00:00
.gitignore Add local screenshare app 2026-02-04 12:18:48 +01:00
Cargo.lock Add local screenshare app 2026-02-04 12:18:48 +01:00
Cargo.toml Add local screenshare app 2026-02-04 12:18:48 +01:00
lanshare.crt Add local screenshare app 2026-02-04 12:18:48 +01:00
lanshare.key Add local screenshare app 2026-02-04 12:18:48 +01:00
README.md Update 2026-02-09 08:22:15 +01:00

LAN Share

A peer-to-peer screen sharing application for local networks. No accounts, no cloud services — just open a browser and share.

Features

  • WebRTC P2P: Direct peer-to-peer connections, video never touches the server
  • Audio support: Optionally share system audio with your screen
  • Multiple streams: View multiple shared screens, select which one to focus on
  • Zero config: Just run the server and open the URL in any browser
  • Keyboard shortcuts: F for fullscreen, M for mute, Escape to expand sidebar

Building

cargo build --release

The binary will be at target/release/lanshare.

Running

./target/release/lanshare

Or with cargo:

cargo run --release

The server starts on http://0.0.0.0:8080 by default.

CLI Options

Usage: lanshare [OPTIONS]

Options:
  -H, --host <IP>    IP address to bind to [default: 0.0.0.0]
  -p, --port <PORT>  Port to listen on [default: 8080]
  -v, --verbose      Enable verbose/debug logging
  -q, --quiet        Quiet mode - only show errors
  -h, --help         Print help
  -V, --version      Print version

Examples:

# Listen on a specific interface
lanshare --host 192.168.1.100 --port 3000

# Localhost only (for testing)
lanshare -H 127.0.0.1

# Quiet mode
lanshare -q

CLI Options

LAN Share - Peer-to-peer screen sharing for local networks

Usage: lanshare [OPTIONS]

Options:
  -H, --host <HOST>  Host address to bind to [default: 0.0.0.0]
  -p, --port <PORT>  Port to listen on [default: 8080]
  -v, --verbose      Enable verbose logging
  -h, --help         Print help
  -V, --version      Print version

Examples

# Run on default settings (0.0.0.0:8080)
lanshare

# Run on a specific port
lanshare -p 3000

# Bind to localhost only
lanshare -H 127.0.0.1 -p 8080

# Run with verbose logging
lanshare -v

Usage

  1. Start the server on any machine in your LAN
  2. Open http://<server-ip>:8080 in a browser on each device
  3. Enter your name when prompted
  4. Click "Start Sharing" to share your screen
  5. Select shared screens from the sidebar to view them

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Signaling Server                        │
│                    (Rust/Axum/WebSocket)                     │
│  - Peer discovery                                            │
│  - Relays SDP offers/answers (with bundled candidates)       │
└─────────────────────────────────────────────────────────────┘
           │                                    │
           │ WebSocket                          │ WebSocket
           │ (signaling only)                   │ (signaling only)
           ▼                                    ▼
    ┌─────────────┐                      ┌─────────────┐
    │   Peer A    │◄────────────────────►│   Peer B    │
    │  (Browser)  │     Direct WebRTC    │  (Browser)  │
    └─────────────┘   (video/audio)      └─────────────┘

100% Local Network — No external services, simple direct connections:

  • No STUN/TURN servers needed
  • No trickle ICE — candidates bundled directly in SDP
  • One offer + one answer = connected
  • Video/audio streams stay entirely on your LAN

Browser Support

Tested on:

  • Chrome/Chromium
  • Firefox
  • Edge
  • Safari (macOS)

Note: Screen sharing with audio requires Chrome/Edge on Windows/macOS. Firefox and Linux may have limited audio capture support depending on the system.

Configuration

Command-line options take precedence over defaults. See lanshare --help for all options.

Environment variables:

  • RUST_LOG: Override log level (e.g., RUST_LOG=lanshare=debug)

Security Notes

  • This is designed for trusted local networks only
  • No authentication — anyone with the URL can join
  • No encryption beyond what WebRTC provides by default (DTLS-SRTP)
  • Don't expose to the internet without additional security measures

License

MIT