Overview
The SignalWire Browser SDK is a JavaScript library that enables WebRTC-based voice, video, and chat applications directly in web browsers. Built on WebSocket architecture, it provides real-time communication capabilities without plugins or downloads.
How It Works
The SDK operates through WebSocket connections that handle both method calls and real-time events.
When you call methods like join()
or publish()
, the SDK sends requests and returns promises.
Simultaneously, you can listen for real-time events like new members joining or messages arriving using the .on()
method.
Getting Started
Install the SDK
Choose your preferred installation method:
npm install @signalwire/js
Or include it via CDN:
<script src="https://cdn.signalwire.com/@signalwire/js"></script>
Obtain tokens from your server
Browser applications require tokens from SignalWire's REST APIs for security. Create these server-side:
// Server-side: Get a Video Room token
// Replace <YOUR_SPACE>, <username>, and <password> with your actual values
const response = await fetch('https://<YOUR_SPACE>.signalwire.com/api/video/room_tokens', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Basic ' + btoa('<PROJECT_ID>:<API_TOKEN>') // Your SignalWire credentials
},
body: JSON.stringify({
room_name: "my_room",
user_name: "John Smith",
permissions: [
"room.self.audio_mute",
"room.self.audio_unmute",
"room.self.video_mute",
"room.self.video_unmute",
"room.self.deaf",
"room.self.undeaf",
"room.self.set_input_volume",
"room.self.set_output_volume",
"room.self.set_input_sensitivity"
],
room_display_name: "My Room",
join_as: "member"
})
});
const { token } = await response.json();
Test your setup
Create a simple video room to test your setup:
- NPM Package
- CDN
import { Video } from "@signalwire/js";
// Join a video room
const roomSession = new Video.RoomSession({
token: "your-room-token", // From your server
rootElement: document.getElementById("video-container")
});
// Listen for events
roomSession.on("member.joined", (e) => {
console.log(`${e.member.name} joined the room`);
});
roomSession.on("room.joined", () => {
console.log("Successfully joined the room!");
});
// Join the room
await roomSession.join();
<script src="https://cdn.signalwire.com/@signalwire/js"></script>
<script>
// Access SignalWire from the global window object
const { Video } = window.SignalWire;
// Join a video room
const roomSession = new Video.RoomSession({
token: "your-room-token", // From your server
rootElement: document.getElementById("video-container")
});
// Listen for events
roomSession.on("member.joined", (e) => {
console.log(`${e.member.name} joined the room`);
});
roomSession.on("room.joined", () => {
console.log("Successfully joined the room!");
});
// Join the room
roomSession.join().then(() => {
console.log("Join initiated");
});
</script>
Add this HTML element to your page:
<div id="video-container"></div>
Usage Examples
- Video Conferencing
- Real-time Chat
- PubSub Messaging
- WebRTC Utilities
import { Video } from "@signalwire/js";
const roomSession = new Video.RoomSession({
token: "your-room-token",
rootElement: document.getElementById("video-container"),
video: true,
audio: true
});
// Handle room events
roomSession.on("room.joined", () => {
console.log("Joined the video room");
// Set up UI controls after joining
setupControls();
});
roomSession.on("member.joined", (e) => {
console.log(`${e.member.name} joined`);
});
roomSession.on("member.left", (e) => {
console.log(`${e.member.name} left`);
});
// Detect when members are talking
roomSession.on("member.talking", (e) => {
if (e.member.id === roomSession.memberId) {
console.log("You are talking");
} else {
console.log(`${e.member.name} is talking`);
}
});
// Join the room
await roomSession.join();
// Example: Set up media controls for your UI
function setupControls() {
// Toggle camera on button click
document.getElementById("cameraBtn").onclick = async () => {
if (roomSession.localVideo.active) {
await roomSession.videoMute();
console.log("Camera muted");
} else {
await roomSession.videoUnmute();
console.log("Camera unmuted");
}
};
// Toggle microphone on button click
document.getElementById("micBtn").onclick = async () => {
if (roomSession.localAudio.active) {
await roomSession.audioMute();
console.log("Microphone muted");
} else {
await roomSession.audioUnmute();
console.log("Microphone unmuted");
}
};
}
import { Chat } from "@signalwire/js";
const chatClient = new Chat.Client({
token: "your-chat-token"
});
// Subscribe to channels
await chatClient.subscribe(["general", "support"]);
// Listen for messages
chatClient.on("message", (message) => {
console.log(`${message.member.name}: ${message.content}`);
// Add your custom logic to display messages in your UI
});
// Listen for member events
chatClient.on("member.joined", (member) => {
console.log(`${member.name} joined the channel`);
});
chatClient.on("member.left", (member) => {
console.log(`${member.name} left the channel`);
});
// Send messages
await chatClient.publish({
channel: "general",
content: "Hello everyone!"
});
// Send with metadata
await chatClient.publish({
channel: "general",
content: "Check out this image!",
meta: {
image_url: "https://example.com/image.jpg",
message_type: "image"
}
});
import { PubSub } from "@signalwire/js";
const pubSubClient = new PubSub.Client({
token: "your-pubsub-token"
});
// Subscribe to channels
await pubSubClient.subscribe(["notifications", "alerts"]);
// Listen for messages
pubSubClient.on("message", (message) => {
console.log(`Channel: ${message.channel}`);
console.log(`Content:`, message.content);
// Handle different message types
if (message.channel === "alerts") {
console.log("Alert received:", message.content);
// Add your custom logic to show alerts in your UI
}
});
// Publish messages
await pubSubClient.publish({
channel: "notifications",
content: {
type: "user_action",
user_id: "123",
action: "button_click",
timestamp: Date.now()
}
});
// Publish with metadata
await pubSubClient.publish({
channel: "alerts",
content: "System maintenance in 30 minutes",
meta: {
priority: "high",
category: "maintenance"
}
});
import { WebRTC, Video } from "@signalwire/js";
// Check browser support
if (WebRTC.supportsGetUserMedia()) {
console.log("Browser supports getUserMedia");
}
if (WebRTC.supportsGetDisplayMedia()) {
console.log("Browser supports screen sharing");
}
// Get available devices
const cameras = await WebRTC.getCameraDevices();
const microphones = await WebRTC.getMicrophoneDevices();
const speakers = await WebRTC.getSpeakerDevices();
console.log("Cameras:", cameras);
console.log("Microphones:", microphones);
console.log("Speakers:", speakers);
// Get user media with SignalWire WebRTC helper
const stream = await WebRTC.getUserMedia({
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30 }
},
audio: {
echoCancellation: true,
noiseSuppression: true
}
});
// Use custom stream in video room
const roomSession = new Video.RoomSession({
token: "your-room-token",
rootElement: document.getElementById("video"),
localStream: stream
});
// Device monitoring
const deviceWatcher = await WebRTC.createDeviceWatcher();
deviceWatcher.on("changed", (event) => {
console.log("Devices changed:", event.changes);
// Add your custom logic to handle device changes
});