streamverse
Version:
Zero-config real-time video calls and streaming. WebRTC made simple for developers.
514 lines (375 loc) ⢠13.2 kB
Markdown
š **Zero-Config Real-Time Video Calls and Streaming**
StreamVerse is a TypeScript SDK that makes real-time communication effortless. Build video calls, voice calls, live shows, and screen sharing with **zero server setup** for single-user testing, or use our hosted signaling service for multi-user functionality!
[](https://www.npmjs.com/package/streamverse)
[](https://streamverse-delta.vercel.app)
[](https://opensource.org/licenses/MIT)
[](https://www.typescriptlang.org/)
- šÆ **Zero Configuration** ā No server setup required, works out of the box
- š” **Simple API** ā Subscribe by userId, publish streams, handle remote streams
- š„ **Multi-Stream Support** ā Camera, microphone, screen sharing, custom media streams
- ā” **Auto-Scaling Architecture** ā P2P for small groups, SFU for large audiences
- š **Bi-Directional Streaming** ā Any user can send and receive multiple streams
- š **Developer-Friendly** ā Focus on your UI, not WebRTC complexity
- š± **Cross-Platform** ā Works in browsers, React Native, and Electron
- š **Type-Safe** ā Full TypeScript support with comprehensive type definitions
```bash
npm install streamverse
```
**Experience StreamVerse in action:** [**Live Demo**](https://streamverse-delta.vercel.app)
- ā
**Multi-user video calls** - Test with multiple browser tabs
- ā
**Screen sharing** - Real-time screen presentation
- ā
**Audio streaming** - Voice-only communication
- ā
**Zero setup** - Just open and start testing!
> **š” Pro Tip:** Open the demo in multiple browser tabs with different names to test multi-user functionality!
```typescript
import { createStreamShareClient } from "streamverse";
// Create client - uses hosted signaling service automatically!
const client = createStreamShareClient({ userId: "alice" });
// Subscribe and join session
await client.subscribe("alice");
await client.startSession("my-room");
// Get user media and publish
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
await client.publishStream(stream, "camera");
// Handle remote streams
client.onRemoteStream(({ userId, stream }) => {
const video = document.createElement("video");
video.srcObject = stream;
video.autoplay = true;
video.muted = false; // Don't mute remote streams
document.body.appendChild(video);
});
// Clean up when done
await client.close();
```
> **Note:** For multi-user functionality, StreamVerse requires a signaling server to coordinate WebRTC connections. By default, it uses our hosted service. For local development, see the [Local Development](
```typescript
// Get screen sharing stream
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true,
});
// Publish screen stream
await client.publishStream(screenStream, "screen");
// Remote users will receive it via onRemoteStream callback
```
```typescript
// Audio-only stream
const audioStream = await navigator.mediaDevices.getUserMedia({
video: false,
audio: true,
});
await client.publishStream(audioStream, "microphone");
```
```typescript
// Host: Publish stream for many viewers
const client = createStreamShareClient({ userId: "host" });
await client.subscribe("host");
await client.startSession("live-show");
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
await client.publishStream(stream, "camera");
// Viewers: Join and receive host's stream
const viewer = createStreamShareClient({ userId: "viewer1" });
await viewer.subscribe("viewer1");
await viewer.startSession("live-show"); // Same session ID
viewer.onRemoteStream(({ userId, stream }) => {
if (userId === "host") {
// Display host's stream
displayStream(stream);
}
});
```
Creates a new StreamVerse client instance.
**Options:**
- `userId` (string, required): Unique identifier for this user
- `signalingUrl` (string, optional): Custom signaling server URL
**Returns:** `StreamShareClient`
Subscribe the client with the given user ID to start receiving session invitations and remote streams.
Start a new session or join an existing session with the given ID.
Publish a media stream to all other participants in the session.
**Stream Kinds:**
- `'camera'` ā Video from camera
- `'microphone'` ā Audio from microphone
- `'screen'` ā Screen sharing
- `'custom'` ā Custom media stream
Listen for remote streams from other participants. Returns an unsubscribe function.
**RemoteStreamEvent:**
```typescript
{
userId: string; // ID of the user who sent the stream
stream: MediaStream; // The media stream
}
```
Clean up the client, close all connections, and stop all streams.
StreamVerse automatically chooses the best architecture for your use case:
- **š Direct P2P** (2-4 users): Ultra-low latency for small groups
- **š SFU (Selective Forwarding Unit)** (5+ users): Scalable for larger audiences
- **āļø Hosted Infrastructure**: Zero-config experience with managed signaling service
Build Zoom-like video calls with minimal code:
```typescript
const client = createStreamShareClient({ userId: "user123" });
await client.subscribe("user123");
await client.startSession("meeting-room");
// Publish camera + audio
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
await client.publishStream(stream, "camera");
```
Create Twitch-like streaming experiences:
```typescript
// Streamer
await client.publishStream(gameStream, "screen");
await client.publishStream(cameraStream, "camera");
// Viewers join the same session and receive streams automatically
```
Add screen sharing to any application:
```typescript
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
});
await client.publishStream(screenStream, "screen");
```
Perfect for:
- Virtual events and webinars
- Online gaming with voice chat
- Collaborative tools and whiteboards
- Customer support with video
- Educational platforms
- Social audio apps
**Without StreamVerse:**
```typescript
// 200+ lines of WebRTC boilerplate
const pc = new RTCPeerConnection(iceServers);
pc.onicecandidate = (event) => {
/* signaling logic */
};
pc.ontrack = (event) => {
/* handle remote streams */
};
// ... complex signaling server setup
// ... SDP offer/answer handling
// ... ICE candidate exchange
// ... connection state management
```
**With StreamVerse:**
```typescript
// 5 lines of code
const client = createStreamShareClient({ userId: "alice" });
await client.subscribe("alice");
await client.startSession("room");
await client.publishStream(stream, "camera");
client.onRemoteStream(({ stream }) => displayStream(stream));
```
```typescript
const client = createStreamShareClient({
userId: "alice",
signalingUrl: "wss://your-signaling-server.com",
});
```
For local development with multi-user testing:
```bash
git clone https://github.com/shivamgupta1319/streamverse.git
cd examples/signal-server
npm install
npm start
```
Then configure your client:
```typescript
const client = createStreamShareClient({
userId: "alice",
signalingUrl: "ws://localhost:8787",
});
```
```typescript
try {
await client.startSession("room");
} catch (error) {
console.error("Failed to join session:", error);
}
```
```typescript
// Monitor connection state
client.onConnectionStateChange((state) => {
console.log("Connection state:", state);
});
```
```jsx
import { useEffect, useState } from "react";
import { createStreamShareClient } from "streamverse";
function VideoCall({ userId, roomId }) {
const [client, setClient] = useState(null);
const [remoteStreams, setRemoteStreams] = useState([]);
useEffect(() => {
const setupClient = async () => {
const newClient = createStreamShareClient({ userId });
newClient.onRemoteStream(({ userId, stream }) => {
setRemoteStreams((prev) => [...prev, { userId, stream }]);
});
await newClient.subscribe(userId);
await newClient.startSession(roomId);
setClient(newClient);
};
setupClient();
return () => {
if (client) client.close();
};
}, [userId, roomId]);
return (
<div>
{remoteStreams.map(({ userId, stream }) => (
<VideoElement key={userId} stream={stream} />
))}
</div>
);
}
```
```vue
<template>
<div>
<video
v-for="stream in remoteStreams"
:key="stream.userId"
:srcObject="stream.stream"
autoplay
/>
</div>
</template>
<script>
import { createStreamShareClient } from "streamverse";
export default {
data() {
return {
client: null,
remoteStreams: [],
};
},
async mounted() {
this.client = createStreamShareClient({ userId: this.userId });
this.client.onRemoteStream(({ userId, stream }) => {
this.remoteStreams.push({ userId, stream });
});
await this.client.subscribe(this.userId);
await this.client.startSession(this.roomId);
},
beforeUnmount() {
if (this.client) this.client.close();
},
};
</script>
```
1. **HTTPS Required**: WebRTC requires HTTPS in production
2. **STUN/TURN Servers**: Configure for NAT traversal
3. **Signaling Server**: Use our hosted service or deploy your own
4. **Error Handling**: Implement proper error handling and reconnection logic
StreamVerse includes a hosted signaling service for zero-config deployment. For production applications with high traffic, consider:
- Custom signaling server deployment
- CDN integration for global reach
- Load balancing for scalability
- Analytics and monitoring
StreamVerse works in all modern browsers that support WebRTC:
- ā
Chrome 60+
- ā
Firefox 60+
- ā
Safari 12+
- ā
Edge 79+
- ā
Mobile browsers (iOS Safari, Chrome Mobile)
## š Troubleshooting
### Common Issues
**"Permission denied" for camera/microphone:**
```typescript
// Request permissions explicitly
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
} catch (error) {
if (error.name === "NotAllowedError") {
console.log("Camera/microphone permission denied");
}
}
```
**Connection failures:**
- Ensure HTTPS in production
- Check firewall settings
- Verify STUN/TURN server configuration
**No remote streams received:**
- Verify both clients joined the same session
- Check that streams are being published
- Ensure `onRemoteStream` callback is registered before joining
- **Latency**: <100ms for P2P connections
- **Bandwidth**: Adaptive bitrate based on network conditions
- **CPU Usage**: Optimized WebRTC implementation
- **Memory**: Minimal memory footprint (~2MB)
- **Concurrent Users**: Scales with SFU architecture
## š Security
- End-to-end encryption via WebRTC DTLS
- Secure WebSocket connections (WSS)
- No media data stored on servers
- GDPR and privacy compliant
## š Monitoring
```typescript
// Monitor connection quality
client.onStats((stats) => {
console.log("Bitrate:", stats.bitrate);
console.log("Packet loss:", stats.packetLoss);
console.log("RTT:", stats.roundTripTime);
});
```
- š [Documentation](https://streamverse.dev)
- š¬ [Discord Community](https://discord.gg/streamverse)
- š [Issue Tracker](https://github.com/shivamgupta1319/streamverse/issues)
- š§ [Email Support](mailto:support@streamverse.dev)
MIT License - see [LICENSE](LICENSE) for details.
We welcome contributions! Please see our [Contributing Guide](https://github.com/shivamgupta1319/streamverse/blob/main/CONTRIBUTING.md) for details.
---
**StreamVerse** ā Zero-config real-time communication for developers š
_Made with ā¤ļø for the developer community_