A P2P watch party system
- Go 100%
|
|
||
|---|---|---|
| .github/workflows | ||
| cmd | ||
| docs | ||
| internal | ||
| .gitignore | ||
| go.mod | ||
| LICENSE | ||
| main.go | ||
| readme.md | ||
PeerWatch
Serverless peer-to-peer video watch party. One person hosts a video file, others join with a token. No central server — peers transfer chunks directly to each other, BitTorrent-style, and play back in sync via mpv.
flowchart LR
Host["Host<br/><code>./peerwatch start movie.mp4</code><br/>✓ Has all chunks<br/>✓ Serves video & sync"]
PeerB["Peer B<br/><code>./peerwatch join <token></code><br/>• Downloads & uploads<br/>• Plays back in sync"]
PeerC["Peer C<br/><code>./peerwatch join <token></code><br/>• Downloads & uploads<br/>• Plays back in sync"]
Host <-->|"TCP Full Mesh"| PeerB
Host <-->|"TCP Full Mesh"| PeerC
PeerB <-->|"TCP Full Mesh"| PeerC
classDef hostClass fill:#1e3a8a,stroke:#3b82f6,stroke-width:2px,color:#fff;
classDef peerClass fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#fff;
class Host hostClass;
class PeerB,PeerC peerClass;
Features
- Zero dependencies — single Go binary, stdlib only
- No server — direct peer-to-peer over TCP
- Full mesh — every peer connects to every other peer (optimized for 5-10 people)
- Chunk-based transfer — 512KB chunks with SHA-256 integrity verification
- Batch requests — request multiple chunks in a single message
- Periodic bitfield — peers broadcast availability every ~1s (self-correcting)
- Format agnostic — supports
.mp4,.mkv,.avi,.webm(mpv handles decoding)
Usage
Host a room
./peerwatch start movie.mp4
This prints a connection token (base64-encoded host address + metadata).
Join a room
./peerwatch join <token>
Options
# Host on a specific port (default: 9876)
./peerwatch start -port 8080 movie.mp4
# Save downloaded video to a specific directory
./peerwatch join -out ~/Videos <token>
Build
go build -o peerwatch .
Test
go test ./... -v
Project Structure
peerwatch/
├── main.go # CLI entry point
├── cmd/
│ ├── start.go # "peerwatch start" command
│ └── join.go # "peerwatch join" command
├── internal/
│ ├── chunk/
│ │ ├── chunker.go # Fixed-size file chunking
│ │ ├── manifest.go # SHA-256 manifest builder
│ │ ├── store.go # Chunk storage + bitfield tracking
│ │ └── store_test.go
│ ├── peer/
│ │ ├── peer.go # Peer connection (read/write loops)
│ │ ├── swarm.go # Full-mesh manager
│ │ ├── tracker.go # Chunk availability tracker
│ │ └── peer_test.go
│ ├── player/
│ │ ├── mpv.go # mpv process JSON-RPC socket control
│ │ └── server.go # HTTP Range-request server for mpv
│ ├── protocol/
│ │ ├── message.go # 10 wire protocol message types
│ │ ├── codec.go # Binary encode/decode
│ │ ├── handler.go # Handler dispatch interface
│ │ └── codec_test.go
│ ├── scheduler/
│ │ ├── scheduler.go # Download orchestration loop
│ │ ├── strategy.go # Chunk priority + peer scoring
│ │ ├── scheduler_test.go
│ │ └── strategy_test.go
│ ├── sync/
│ │ ├── sync.go # P2P playback synchronization
│ │ └── sync_test.go
│ └── token/
│ ├── token.go # Connection token (base64url)
│ └── token_test.go
└── docs/
├── architecture.md # High-level design & topology
├── types.md # Struct reference & ownership graph
├── protocol_sequence.md # Message ordering & sequences
└── security.md # Threat model & security assumptions
Documentation
- Architecture Overview — how PeerWatch works, network topology, chunk strategy
- Type Reference — every struct, its fields, ownership graph, invariants
- Protocol Sequence — exact message ordering for connections, transfers, sync
- Security & Threat Model — IP address visibility, trusted media parsing, and unencrypted traffic considerations
Requirements
- Go 1.26+
- Linux (other platforms untested)
- mpv (for synchronized video playback)
License
See LICENSE.