In-Session Communication
Beyond audio and video, the EnableX Web SDK lets participants communicate in a variety of ways within a live session — chat messages, structured custom signals, file transfers, screen and canvas sharing, live streaming to CDNs, whiteboard annotation, and real-time speech transcription.
Chat — Text Messaging
EnxRoom.sendMessage() sends a text message to one participant, a group, or everyone in the room. It works even if the sender has not published a stream — useful for observer-mode participants.
- Method:
EnxRoom.sendMessage(Message, IsBroadcast, RecipientIDs, Callback) - Event:
message-received— fired at each recipient's endpoint
| Parameter | Type | Description |
|---|---|---|
Message | String | The text message to send |
IsBroadcast | Boolean | true = send to everyone; false = send to specified recipients only |
RecipientIDs | Array | Array of Client IDs. Used when IsBroadcast is false. Pass [] for broadcast. |
// Public message — everyone in the room receives it
room.sendMessage("Hello everyone!", true, [], function(data) {
console.log("Message sent");
});
// Private message — only Alice (clientId) receives it
room.sendMessage("Hey Alice, are you ready?", false, ["alice-client-id"], function(data) {
console.log("Private message sent");
});
// Receive messages
room.addEventListener("message-received", function(event) {
var msg = event.message;
// msg.broadcast — true if public, false if private/group
// msg.sender — sender's name
// msg.senderId — sender's client ID
// msg.message — the text content
// msg.timestamp — Unix timestamp
// msg.receipients — array of recipient client IDs (private only)
if (msg.broadcast) {
showPublicChatMessage(msg.sender, msg.message);
} else {
showPrivateChatMessage(msg.sender, msg.message);
}
});
Custom Signalling
EnxRoom.sendUserData() is for application-level signalling — sending structured JSON data between participants rather than plain chat text. Use it to synchronize UI state, send poll responses, trigger remote actions, or pass any business-specific payload.
- Method:
EnxRoom.sendUserData(MessageOpt, IsBroadcast, RecipientIDs, Callback) - Event:
user-data-received— theMessageOptJSON is delivered asevent.message.msg
// Example: send a poll response as structured data
var signalData = {
type: "poll-response",
question: "Q1",
answer: "option_b",
userId: "alice"
};
// Broadcast to all
room.sendUserData(signalData, true, [], function(data) {
console.log("Signal sent");
});
// Or send to specific participants
room.sendUserData(signalData, false, ["moderator-client-id"], function(data) {});
// Receive custom signals
room.addEventListener("user-data-received", function(event) {
var payload = event.message.msg;
// payload is exactly what the sender put in MessageOpt
if (payload.type === "poll-response") {
recordPollAnswer(payload.userId, payload.answer);
}
});
File sharing lets participants upload files to the EnableX server and share them with others in the session. Files are uploaded once and each recipient downloads independently. Available from Web SDK v1.5.3 onwards.
Upload a File
EnxRoom.sendFiles() uploads one or more files to the EnableX server and notifies intended recipients that a file is available for download.
- Method:
EnxRoom.sendFiles(files, options, callback) - Event:
fs-upload-result— tracksupload-started,upload-completed,upload-failedstates
// fileInput is an <input type="file"> element
var fileList = document.getElementById("fileInput").files;
var shareOptions = {
isMobile: false, // true for WebView-based mobile apps
broadcast: true, // true = share with all; false = share with clientList only
clientList: [] // Client IDs when broadcast is false
};
room.sendFiles(fileList, shareOptions, function(resp) {
if (resp.result === 0) {
console.log("Upload job started, ID:", resp.response.upJobId);
} else {
console.error("Upload error:", resp.error);
}
});
// Track upload progress
room.addEventListener("fs-upload-result", function(event) {
var msg = event.message;
switch (msg.messageType) {
case "upload-started":
showUploadProgress(msg.response.upJobId, msg.response.uploadInfo.name);
break;
case "upload-completed":
hideUploadProgress(msg.response.upJobId);
showUploadSuccess(msg.response.uploadInfo.name);
break;
case "upload-failed":
showUploadError(msg.response.upJobId);
break;
}
});
Download a Shared File
When a file is shared, recipients are notified via the fs-download-result event with messageType: "download-available". They can then inspect room.availableFiles and initiate a download.
// Listen for new files available for download
room.addEventListener("fs-download-result", function(event) {
var msg = event.message;
if (msg.messageType === "download-available") {
var files = room.availableFiles;
// files: [{ name: "report.pdf", size: 191002, index: 0 }]
showDownloadPrompt(files);
}
if (msg.messageType === "download-started") {
showDownloadProgress(msg.response.jobId, msg.response.downloadInfo.name);
}
if (msg.messageType === "download-completed") {
hideDownloadProgress(msg.response.jobId);
}
if (msg.messageType === "download-failed") {
showDownloadError(msg.response.jobId);
}
});
// Initiate download by file index
function downloadFile(index) {
room.recvFiles(index, { isMobile: false }, function(resp) {
if (resp.result !== 0) {
console.error("Download error:", resp.error);
}
});
}
Cancel File Transfers
// Cancel a specific upload (by upJobId)
room.cancelUploads(upJobId, false, function(resp) {
console.log("Upload cancelled");
});
// Cancel ALL in-progress uploads
room.cancelUploads(null, true, function(resp) {});
// Cancel a specific download (by jobId)
room.cancelDownloads(jobId, false, function(resp) {
console.log("Download cancelled");
});
// Cancel ALL in-progress downloads
room.cancelDownloads(null, true, function(resp) {});
Screen Sharing
Screen sharing captures the user's screen (or a specific window or tab) and publishes it as a separate stream (Stream ID 101) into the room. To use this feature, the room must be created with "screen_share": true in the room settings.
Screen sharing must be enabled at room creation time: "settings": { "screen_share": true }. Subscribers receive screen share as Stream ID 101.
Start Screen Sharing
- Method:
EnxRoom.startScreenShare(options, Callback)(SDK v2.1.2+) - Event:
share-started— broadcast to everyone when sharing begins
var shareOption = {
audio: true, // Capture system audio (if browser supports)
layout: "presenter" // Custom hint to receivers for UI layout switching
};
var screenStream = room.startScreenShare(shareOption, function(result) {
if (result.result !== 0) {
console.error("Screen share failed:", result.error);
}
});
// Everyone is notified
room.addEventListener("share-started", function(event) {
// event.layout — the layout hint sent by the sharer
if (event.layout === "presenter") switchToPresenterLayout();
// Subscribe to stream ID 101 to receive the shared screen
var screenStream = room.remoteStreams.get(101);
if (screenStream) {
screenStream.play("screen-share-player", { player: { width: "100%", height: "auto" } });
}
});
Stop Screen Sharing
- Method:
EnxRoom.stopScreenShare(sharedStream, Callback) - Event:
share-stopped— broadcast to everyone when sharing stops
room.stopScreenShare(screenStream, function(result) {
console.log("Screen share stopped");
});
room.addEventListener("share-stopped", function(event) {
switchToNormalLayout();
});
Force Stop Sharing (Moderator)
A moderator can force-stop any participant's screen share or canvas stream using stopAllSharing(). Available from SDK v2.1.2 onwards.
room.stopAllSharing(function(result) {
console.log("All sharing stopped by moderator");
});
| Error Code | Description |
|---|---|
| 1143 | Device not found — screen sharing disabled at OS level |
| 1151 | Another screen sharing stream is already active in the room |
Canvas Streaming
Canvas Streaming publishes an HTML5 <canvas> element as a live video stream (Stream ID 102). Use it to build shared whiteboards, slide presentations, or any dynamic visual — subscribers see your canvas updates in real time. The room must be created with "canvas": true in settings.
Start Canvas Streaming
- Method:
EnxRoom.startCanvas(CanvasOpt, Callback) - Event:
canvas-started— broadcast to everyone; subscribe to Stream ID 102 to receive it
var canvasOpt = {
canvasSelector: "myCanvasId", // The id attribute of the <canvas> element
fps: 15 // Frame rate, range: 1–23
};
room.startCanvas(canvasOpt, function(arg) {
if (arg.result !== 0) {
console.error("Canvas start failed, code:", arg.result);
}
});
room.addEventListener("canvas-started", function(event) {
// Subscribe to stream ID 102 to display the canvas
var canvasStream = room.remoteStreams.get(102);
if (canvasStream && canvasStream.stream !== undefined) {
canvasStream.play("canvas-player");
}
});
| Error Code | Description |
|---|---|
| 1154 | Frame rate out of valid range (1–23) |
| 1157 | Canvas element ID not found in DOM |
| 1158 | Browser does not support the HTML5 Canvas element |
| 1159 | Failed to create canvas stream — source canvas ID not in DOM |
Stop Canvas Streaming
- Method:
EnxRoom.stopCanvas(Callback) - Event:
canvas-stopped
room.stopCanvas(function(arg) {
if (arg.result === 0) console.log("Canvas streaming stopped");
});
room.addEventListener("canvas-stopped", function(event) {
// Remove canvas player from UI
});
RTMP Live Streaming
Moderators can forward the live session to any RTMP-compatible CDN (YouTube Live, Twitch, Facebook Live, etc.). The session continues normally for participants while simultaneously being broadcast to a wider audience.
Only users with the moderator role can start and stop RTMP streaming.
Start RTMP Forwarding
- Method:
EnxRoom.startStreaming(streamingConfig, Callback) - Events:
streaming-started,streaming-updated(intermediate),streaming-failed
var streamingConfig = {
rtmpDetails: {
rtmpUrl: "rtmp://live.youtube.com/live2/YOUR-STREAM-KEY"
},
urlDetails: {
url: "https://your-custom-streaming-view.example.com/" // Optional custom view URL
}
};
room.startStreaming(streamingConfig, function(resp) {
if (resp.result === 0) {
console.log("You are now live!");
} else {
console.error("Streaming failed:", resp.error);
}
});
room.addEventListener("streaming-started", function(event) {
showLiveBadge();
// event.message.startedBy — who started the stream
});
room.addEventListener("streaming-failed", function(event) {
hideLiveBadge();
});
Stop RTMP Forwarding
- Method:
EnxRoom.stopForwarding(Callback) - Event:
streaming-stopped— broadcast to everyone
room.stopForwarding(function(resp) {
console.log("Streaming stopped");
});
room.addEventListener("streaming-stopped", function(event) {
hideLiveBadge();
// event.message.stoppedBy — who stopped it
});
HLS Streaming
HLS streaming scales a live video session to very large audiences using adaptive bitrate delivery. Unlike RTMP which targets CDN re-streaming, HLS is EnableX-managed and designed for in-app audience playback.
HLS streaming is a subscription-based service. Contact your EnableX account manager to enable it. If not subscribed, room definitions with HLS settings are rejected.
Room Configuration for HLS
HLS must be enabled in the room definition. The audiences count must be a positive number:
{
"name": "Webinar Room",
"settings": {
"mode": "group",
"moderators": "1",
"participants": "4",
"audiences": 500,
"hls_view_url": "https://your-domain.com/hls-view/?token=",
"send_audiences_stats": true,
"quality": "HD"
}
}
Audience Token
Audiences join with a special "role": "audience" token. HLS streaming starts automatically when the first audience connects and stops when the last audience leaves.
{
"name": "Viewer Name",
"user_ref": "viewer-001",
"role": "audience"
}
Playing the HLS Stream
When HLS starts, the hls-started event delivers the stream URL. Use the EnableX HLS Player or your own HLS-compatible player.
- Download HLS Player: EnxHls.v1.zip
- Method:
hlsPlayer.playStreamerURI(element, hls_url)
room.addEventListener("hls-started", function(event) {
var response = event.message;
if (!response.error) {
var hlsUrl = response.hls_url;
var hlsPlayer = new EnxHls();
if (hlsPlayer) {
hlsPlayer.playStreamerURI("hls-player-div", hlsUrl);
}
}
});
room.addEventListener("hls-stopped", function(event) { hideHlsPlayer(); });
room.addEventListener("hls-failed", function(event) { showHlsError(); });
room.addEventListener("hls-waiting", function(event) { showHlsWaiting(); });
Annotation
Annotation lets participants draw and mark up over a remote stream in real time — useful for tutoring, design reviews, or technical walkthroughs. Annotation uses the canvas streaming infrastructure (Stream ID 102) and therefore requires the room to have "canvas": true in its settings.
Configure the Annotation Toolbar
Before starting annotation, configure the drawing tools available to users.
- Method:
EnxRoom.annotateToolAction(action, value)
// Set pen color
room.annotateToolAction("Color", "#ff0000");
// Set line width
room.annotateToolAction("LineWidth", 3);
// Set draw type
room.annotateToolAction("drawType", "Pencil");
// Enable/disable drawing mode
room.annotateToolAction("draw", true);
Start Annotation
- Method:
EnxRoom.startAnnotation(EnxStream, Callback) - Event:
canvas-startedwithevt.canvasType === "Annotation"
// Annotate over a specific remote stream
var targetStream = room.remoteStreams.get(streamId);
room.startAnnotation(targetStream, function(arg) {
console.log("Annotation started:", arg);
});
room.addEventListener("canvas-started", function(event) {
if (event.canvasType === "Annotation") {
// Show annotation overlay UI
showAnnotationControls();
}
});
Stop Annotation
- Method:
EnxRoom.stopAnnotation(Callback) - Event:
canvas-stoppedwithevt.canvasType === "Annotation"
room.stopAnnotation(function(arg) {
console.log("Annotation stopped");
});
room.addEventListener("canvas-stopped", function(event) {
if (event.canvasType === "Annotation") {
hideAnnotationControls();
}
});
Live Transcription
Live transcription converts speech from active talkers into text in real time and delivers it to subscribed endpoints. It is useful for accessibility, multilingual sessions, and meeting notes. Transcription is session-scoped: anyone can start it; it continues until the last subscriber stops.
Live transcription is a subscription-based service. Contact EnableX to enable it for your account. If not subscribed, the method returns error code 3002.
Room Configuration for Transcription
{
"settings": {
"live_transcription": {
"language": "english_us",
"auto_transcribe": false,
"enable": true
}
}
}
| Setting | Description |
|---|---|
language | Primary language for the speech engine (e.g., english_us, hindi) |
auto_transcribe | If true, transcription starts automatically and does not stop when the last subscriber leaves |
enable | Set false to disable transcription for this specific room even if your account is subscribed |
Start Live Transcription
Use startLiveTranscription() to subscribe yourself to the transcription feed. If you are the first to call it, this also starts the transcription process in the room. Use startLiveTranscriptionForRoom() to start room-level transcription that is shared with all participants.
- Method (self):
room.startLiveTranscription(language, Callback) - Method (room-wide):
room.startLiveTranscriptionForRoom(language, Callback) - Events:
self-transcription-on,room-transcription-on,transcription-events
room.startLiveTranscription("english_us", function(result, error) {
if (error) console.error("Transcription start failed:", error);
});
// Confirmation events
room.addEventListener("self-transcription-on", function(event) {
showTranscriptionActiveIndicator();
});
room.addEventListener("room-transcription-on", function(event) {
showRoomTranscriptionBadge();
});
// Receive transcription text in real time
room.addEventListener("transcription-events", function(event) {
// event.type: "speech_recognising" (interim) or "speech_recognised" (final)
// event.text: the transcribed text
// event.clientID: who is speaking
// event.duration: speech duration in seconds
if (event.type === "speech_recognised") {
appendTranscriptLine(event.clientID, event.text);
} else {
// "speech_recognising" — show interim/partial text
showInterimText(event.text);
}
});
Stop Live Transcription
- Method:
room.stopLiveTranscription(Callback) - Events:
self-transcription-off,room-transcription-off
room.stopLiveTranscription(function(result, error) {
console.log("Stopped receiving transcription");
});
room.addEventListener("self-transcription-off", function(event) {
hideTranscriptionActiveIndicator();
});
room.addEventListener("room-transcription-off", function(event) {
hideRoomTranscriptionBadge();
});
| Error Code | Description |
|---|---|
| 3002 | Live transcription subscription not enabled on your account |