Real-time peer-to-peer video streaming using WebRTC and WebSockets
Features β’ Installation β’ Usage β’ Architecture β’ Troubleshooting
|
|
Make sure you have the following installed:
- Node.js (v16 or higher)
- npm or yarn
git clone <your-repository-url>
cd webrtc-video-streamingnpm install
# or
yarn installcd server
npm install ws
# or
yarn add wscd server
npx tsx server.ts
# or if you have ts-node installed
ts-node server.tsYou should see:
WebSocket server running on ws://localhost:8080
In a new terminal:
npm run dev
# or
yarn dev- Sender: Navigate to
http://localhost:5173/sender - Receiver: Navigate to
http://localhost:5173/receiver
- On the Sender page, click "Send Video"
- Grant camera permissions when prompted
- The Receiver page will automatically start displaying the video stream
graph LR
A[Sender] -->|WebSocket| B[Signaling Server]
B -->|WebSocket| C[Receiver]
A -.->|WebRTC P2P| C
style A fill:#4CAF50
style C fill:#2196F3
style B fill:#FF9800
-
Connection Setup
- Sender and Receiver connect to WebSocket server
- Both identify themselves (
identify-as-sender/identify-as-receiver)
-
Signaling Process
Sender β Create Offer β Server β Receiver Receiver β Create Answer β Server β Sender -
ICE Candidate Exchange
- Both peers exchange ICE candidates through the server
- Establishes optimal connection path
-
Media Streaming
- Direct peer-to-peer video transmission via WebRTC
- No server involved in media transfer
webrtc-video-streaming/
βββ src/
β βββ components/
β β βββ Sender.tsx # Video sender component
β β βββ Receiver.tsx # Video receiver component
β βββ App.tsx # Main application
β βββ main.tsx # Entry point
βββ server/
β βββ server.ts # WebSocket signaling server
βββ package.json
βββ README.md
Port: 8080 (default)
To change the port, edit server.ts:
const wss = new WebSocketServer({ port: 8080 });Located in both Sender.tsx and Receiver.tsx:
const pc = new RTCPeerConnection({
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{ urls: "stun:stun1.l.google.com:19302" },
],
});Symptoms: Video shows "Connecting..." but never plays
Solutions:
- β Ensure WebSocket server is running
- β Check browser console for errors
- β Grant camera permissions to the Sender page
- β Make sure both Sender and Receiver are connected
- β Try refreshing both pages
Solutions:
- Restart the WebSocket server
- Wait 2-3 seconds after page load before clicking "Send Video"
- Check if port 8080 is available
Solutions:
- Check your firewall settings
- Ensure STUN servers are accessible
- Try adding TURN servers for better connectivity
| Error | Cause | Solution |
|---|---|---|
TypeError: Failed to construct 'RTCIceCandidate' |
Invalid ICE candidate | Update to latest server code |
Camera access denied |
Browser permissions | Allow camera access in browser settings |
WebSocket closed |
Server not running | Start the WebSocket server |
To see detailed logs, open browser DevTools Console:
Sender logs to look for:
β Sender: WebSocket connected
β Sender: Creating offer...
β Sender: Offer sent to receiver
β Sender: Received answer from receiver
β Sender: Connection state: connected
Receiver logs to look for:
β Receiver: WebSocket connected
β Receiver: Processing offer
β Receiver: Answer sent to sender
β Receiver: Track received! video
β Receiver: Video playing!
Enables peer-to-peer audio, video, and data sharing directly between browsers without intermediary servers.
The process of coordinating communication and sending control messages between peers. Uses WebSocket in this project.
Framework for connecting peers across NATs and firewalls using STUN/TURN servers.
Format for describing multimedia communication sessions (codecs, formats, etc.).
// Identify as sender
{ type: "identify-as-sender" }
// Send offer
{ type: "create-offer", sdp: RTCSessionDescription }
// Send ICE candidate
{ type: "ice-candidate", candidate: RTCIceCandidate }// Identify as receiver
{ type: "identify-as-receiver" }
// Send answer
{ type: "create-answer", sdp: RTCSessionDescription }
// Send ICE candidate
{ type: "ice-candidate", candidate: RTCIceCandidate }- π¬ Video Quality: Modify constraints in
getUserMedia() - π Network: Use TURN servers for better NAT traversal
- πΎ Bandwidth: Adjust video bitrate in RTCPeerConnection
- π₯οΈ CPU: Lower video resolution for better performance
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- WebRTC API Documentation
- MDN Web Docs
- React Documentation
- ws WebSocket library
Made with β€οΈ and TypeScript
β Star this repo if you find it helpful!