Developer Tools & Diagnostics
This page covers the diagnostic, monitoring, and utility features available in the EnableX Web SDK. These tools help you test environments before a call starts, monitor media quality in real time during a session, instrument your application with structured logging, and integrate telephony features like PSTN dial-out.
Before a user joins a session, you can run a pre-call diagnostics test to verify that their microphone, camera, network connection, and media servers are all working as expected. The SDK provides two modes for running this check.
clientDiagnostics()
clientDiagnostics() runs a comprehensive self-test of the client environment. It checks device availability, media access permissions, STUN/TURN reachability, and server connectivity. The test proceeds through multiple stages, emitting events as each stage completes.
Event-Based Mode (Async)
In this mode, you listen for events as each diagnostic stage finishes. This is useful for building a real-time progress UI during the pre-call test.
var options = {
// Optional: specify which checks to run
};
room.clientDiagnostics(options);
// Listen for stage-by-stage results
room.on("client-diagnosis-status", function(event) {
console.log("Diagnosis stage:", event);
// Update progress in UI
});
room.on("client-diagnosis-finished", function(event) {
console.log("Diagnosis complete:", event);
// Show final summary
});
room.on("client-diagnosis-failed", function(event) {
console.error("Diagnosis failed:", event);
});
room.on("client-diagnosis-stopped", function(event) {
console.log("Diagnosis stopped before completion");
});
Callback Mode (Quick)
Pass a callback as the second argument to get a single result object when the entire test finishes. This is simpler to use when you only need a pass/fail summary.
room.clientDiagnostics(options, function(result) {
if (result.result === 0) {
console.log("Pre-call test passed:", result);
} else {
console.error("Pre-call test failed:", result.error);
}
});
| Event | When it Fires |
|---|---|
client-diagnosis-status | After each individual diagnostic stage completes |
client-diagnosis-finished | All stages have completed successfully |
client-diagnosis-failed | A critical stage failed and the test cannot continue |
client-diagnosis-stopped | The test was stopped before completing |
Client Bitrate Test
The bitrate test measures the upload and download bandwidth available to the client by connecting to an EnableX media server in a specified region. Use this before a session to verify whether the client has sufficient bandwidth for video calls.
var clientInfo = {
region: "sg" // Region code: "sg" (Singapore), "in" (India), etc.
};
room.clientBitrate(clientInfo);
room.on("client-bitrate-status", function(event) {
console.log("Bitrate measurement in progress:", event);
});
room.on("client-bitrate-finished", function(event) {
console.log("Bitrate test complete:", event);
// event contains upload/download bandwidth estimates
});
| Event | When it Fires |
|---|---|
client-bitrate-status | Progress updates during the bitrate measurement |
client-bitrate-finished | Test is complete — payload contains bandwidth estimates |
subscribeMediaStats()
During an active session, you can subscribe to real-time media statistics for all published streams — including audio/video bitrate, packet loss, jitter, and frame rate. This is useful for building in-session quality indicators or for diagnostics overlays.
subscribeMediaStats(reqType, callback) accepts a reqType string that controls the display and notification behavior:
| reqType Value | Behavior |
|---|---|
"display" | Stats are rendered in the SDK's built-in overlay (if available) |
"notify" | Stats are delivered via the media-stats event only (no display) |
"notify-display" | Stats are both displayed and delivered via the event |
"disable" | Stops stat collection and delivery |
// Start receiving stats via event
room.subscribeMediaStats("notify", function(response) {
if (response.result === 0) {
console.log("Media stats subscription started");
}
});
// Handle the stats payload
room.on("media-stats", function(stats) {
// stats.talkers — stats for received streams from other participants
// stats.publisher — stats for your own published stream
// stats.share — stats for screen share stream (if active)
// stats.canvas — stats for canvas stream (if active)
console.log("Publisher stats:", stats.publisher);
console.log("Talker stats:", stats.talkers);
});
The media-stats event payload structure:
{
"talkers": { /* stats per subscribed stream */ },
"publisher": { /* stats for the local published stream */ },
"share": { /* stats for screen share (stream ID 101) */ },
"canvas": { /* stats for canvas stream (stream ID 102) */ }
}
subscribeForTalkerNotification()
This method subscribes to real-time audio activity notifications. It detects who is speaking and who is making noise, updating your UI accordingly. This is different from the active talker list — it gives you finer-grained speech detection events.
// Enable talker notification
room.subscribeForTalkerNotification(true, function(response) {
if (response.result === 0) {
console.log("Talker notifications enabled");
}
});
// Receive notifications
room.on("talker-notification", function(event) {
var messages = event.message;
messages.forEach(function(item) {
if (item.speech) {
console.log("Speaking:", item.users.map(u => u.clientId));
}
if (item.noise) {
console.log("Noise detected from:", item.users.map(u => u.clientId));
}
});
});
// Disable talker notification
room.subscribeForTalkerNotification(false, function(response) {
console.log("Talker notifications disabled");
});
The talker-notification event payload structure:
{
"message": [
{
"speech": true,
"users": [
{ "clientId": "client-abc" }
]
},
{
"noise": true,
"users": [
{ "clientId": "client-xyz" }
]
}
]
}
The SDK includes a built-in logger with configurable verbosity. During development, you can set a verbose level to capture detailed WebRTC internals. In production, set a higher level to suppress noise.
setLogLevel()
Set the verbosity of SDK log output using EnxRtc.Logger.setLogLevel(Level). The Level parameter is a number from 0 to 5:
| Level | Label | Description |
|---|---|---|
| 0 | DEBUG | All logs including internal WebRTC details |
| 1 | TRACE | Detailed trace logs |
| 2 | INFO | General operational messages |
| 3 | WARNING | Warnings only |
| 4 | ERROR | Errors only |
| 5 | NONE | All logging suppressed |
// In development: capture all logs
EnxRtc.Logger.setLogLevel(0);
// In production: errors only
EnxRtc.Logger.setLogLevel(4);
setOutputFunction()
By default, SDK logs go to the browser console. You can redirect them to a custom function — for example to send logs to your own analytics backend or to filter by component.
EnxRtc.Logger.setOutputFunction(function(level, message) {
// level: number (0-5)
// message: string log line
myLogService.send({ level: level, log: message });
});
postClientLogs()
This method sends the last 500 log lines from the SDK's internal buffer directly to EnableX's log servers. Use this when a user reports an issue — it gives EnableX support teams the raw SDK logs for debugging without requiring users to copy from the browser console.
EnxRtc.postClientLogs(Token, function(response) {
if (response.result === 0) {
console.log("Logs submitted to EnableX");
} else {
console.error("Log submission failed:", response.error);
}
});
postClientLogs() in your application's error boundary or user feedback flow so that support logs are captured automatically when users report problems.
Video Frame Snapshot
getVideoFrameImage() captures a still image from a stream's video track and renders it to an HTML Canvas element. This is useful for building profile picture capture, visual debugging overlays, or attendance verification workflows.
// stream can be a local or remote EnxStream
stream.getVideoFrameImage();
// The frame is drawn to the canvas element associated with the stream's player.
// Access it via the DOM after calling this method.
Audio-Only Mode
setAudioOnlyMode(AudioOnly) switches the session between full audio+video mode and audio-only mode. When audio-only mode is enabled, all video tracks are suspended — which reduces bandwidth usage significantly. This is helpful when users are on poor network connections.
// Switch to audio-only (drops all video streams)
room.setAudioOnlyMode(true);
// Restore video
room.setAudioOnlyMode(false);
The EnableX Web SDK supports outbound telephony calls directly from within a video session. This allows you to invite PSTN (phone) or SIP participants who do not have an internet connection or the EnableX app. The call is established as part of the video room — the phone participant joins as an audio-only participant.
makeOutboundCall()
Initiate an outbound call to a phone number from within the session. The call state is tracked through a series of events.
var options = {
name: "John Doe", // Display name for the called participant
early_media: true, // Play ringback tone to the room while waiting
silent_join: false // If true, the dialed participant joins silently
};
room.makeOutboundCall(
dialout_number, // E.164 phone number, e.g. "+6512345678"
cli_number, // Caller Line ID (your outbound number)
options,
function(response) {
if (response.result === 0) {
console.log("Outbound call initiated");
} else {
console.error("Call failed:", response.error);
}
}
);
Track the call lifecycle by listening to the dial-state-events event:
room.on("dial-state-events", function(event) {
switch (event.state) {
case "initiated":
console.log("Call initiated to:", event.number);
break;
case "dialing":
console.log("Ringing...");
break;
case "connected":
console.log("Call connected — participant joined as audio-only");
break;
case "dtmf-collected":
console.log("DTMF digits collected:", event.digits);
break;
case "disconnected":
console.log("Call ended:", event.cause);
break;
}
});
| State Value | Meaning |
|---|---|
initiated | The dial-out request has been sent to the network |
dialing | The remote phone is ringing |
connected | The participant answered and is now in the session |
dtmf-collected | The remote participant entered DTMF digits (IVR response) |
disconnected | The call has ended (by either party) |
sendDTMF()
Send DTMF tones to a connected call participant. This is used when the called party is behind an IVR menu and needs to press keys to navigate (e.g. "Press 1 to confirm the meeting").
var options = {
number: "+6512345678", // The number to send DTMF to
digits: "1234" // The DTMF tone sequence to send
};
room.sendDTMF(options, function(response) {
if (response.result === 0) {
console.log("DTMF sent successfully");
} else {
console.error("DTMF failed:", response.error);
}
});
| Error Code | Meaning |
|---|---|
| 1155 | No active outbound call to send DTMF to |
| 1201 | Invalid phone number format |
| 1202 | Invalid DTMF digits — use only 0–9, *, # |