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.
This latest version of the Browser SDK is ideal for Chat applications and streaming or conferencing with audio and video. If you need to add browser support for voice calls or dial the PSTN or SIP endpoints, please use our previous version of the Browser SDK.
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
});