Developer Tools

The EnableX Flutter SDK includes utility features for monitoring session quality, notifying the app of speaker activity, managing application lifecycle, capturing video snapshots, and accessing logging and diagnostic tools. These capabilities help you build more polished and debuggable video applications.

Live Session Statistics

EnxRtc.enableStats(bool enableStats) activates real-time WebRTC statistics for all streams in the active session. Once enabled, the SDK periodically delivers quality metrics for both your published local stream and all streams you have subscribed to. This data is valuable for building live connection-quality indicators in your UI and for diagnosing bandwidth or packet-loss issues during development.

Pass true to begin receiving stats; pass false to stop. Stats collection is session-scoped — it covers all streams simultaneously rather than requiring per-stream configuration.

// Enable stats
EnxRtc.enableStats(true);

// Disable stats
EnxRtc.enableStats(false);

Callbacks

Callback Fires when
onAcknowledgeStats Stats monitoring was enabled or disabled.
onReceivedStats Periodic stats payload for all streams.
EnxRtc.onAcknowledgeStats = (Map<dynamic, dynamic> map) {
  print('Stats monitoring toggled: $map');
};

EnxRtc.onReceivedStats = (Map<dynamic, dynamic> map) {
  // Parse and display quality metrics
  print('Live stats: $map');
};

Stats provided per stream type

The metrics available depend on whether the stream is local (published) or remote (subscribed).

Local stream stats:

Subscribed (remote) stream stats:

Talker Notification

EnxRtc.subscribeForTalkerNotification(bool isTalkerNotification) subscribes to real-time notifications about who is currently speaking in the room. Unlike the Active Talkers list — which is limited to max_active_talkers — the talker notification list covers all participants who are producing audio, including noise sources. This makes it useful for implementing per-participant audio activity indicators in your participant tile UI.

Pass true to subscribe and begin receiving notifications. Pass false to unsubscribe and stop receiving them.

// Subscribe to talker notifications
EnxRtc.subscribeForTalkerNotification(true);

// Unsubscribe
EnxRtc.subscribeForTalkerNotification(false);

Callbacks

Callback Fires when
onAckSubscribeTalkerNotification Successfully subscribed to talker notifications.
onAckUnsubscribeTalkerNotification Successfully unsubscribed.
onTalkerNtification A participant started/stopped speaking or is producing noise.
EnxRtc.onAckSubscribeTalkerNotification = (Map<dynamic, dynamic> map) {
  print('Talker notification subscribed');
};

EnxRtc.onTalkerNtification = (Map<dynamic, dynamic> map) {
  // map contains 'speech' (array of talking participants)
  // and 'noise' (array of noise sources)
  List<dynamic> speakers = map['speech'] ?? [];
  List<dynamic> noiseSources = map['noise'] ?? [];
  print('Speaking: $speakers');
  print('Noise: $noiseSources');
  // Update audio activity indicators in participant tiles
};
Note the callback name is onTalkerNtification (without the 'i' in 'Notification') — this is the exact name in the SDK.
Audio-Only Mode

EnxRtc.setAudioOnlyMode(bool audioOnly) switches the local session between full audio+video and audio-only mode. In audio-only mode, neither the local video stream is published nor any remote video is received. This is a practical bandwidth-conservation measure for participants on constrained or unreliable connections.

Pass true to switch to audio-only mode. Pass false to restore full audio+video.

// Switch to audio-only
EnxRtc.setAudioOnlyMode(true);

// Restore audio + video
EnxRtc.setAudioOnlyMode(false);
Audio-only mode only affects the local user's own stream and received video. Other participants' audio+video streams remain active for them. Inform users visually before toggling so they are not surprised by the change in experience.
Background and Foreground Handling

When a Flutter app moves to the background, the OS may restrict access to camera and microphone resources. To handle this gracefully, the SDK provides two methods that let you pause and resume video tracks when the application lifecycle changes. Pausing tracks proactively prevents OS-level termination and reduces battery consumption when the app is not in the foreground.

Both methods accept two boolean parameters so you can control local and remote stream behaviour independently — for example, pausing outbound video while continuing to receive remote video, or vice versa.

Going to background — EnxRtc.stopVideoTracksOnApplicationBackground()

Parameter Type Description
localMuteState bool Whether to pause the local video stream when the app backgrounds.
remoteMuteState bool Whether to pause incoming remote video streams when the app backgrounds.

Returning to foreground — EnxRtc.startVideoTracksOnApplicationForeground()

Parameter Type Description
restoreVideoLocalStream bool Whether to restore the local video stream when the app returns to foreground.
restoreVideoRemoteStream bool Whether to restore incoming remote video streams when the app returns to foreground.

Implement WidgetsBindingObserver in your session widget to receive lifecycle change events and call the appropriate SDK methods:

import 'package:flutter/widgets.dart';

class _VideoSessionState extends State<VideoSessionPage>
    with WidgetsBindingObserver {

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) {
      EnxRtc.stopVideoTracksOnApplicationBackground(true, true);
    } else if (state == AppLifecycleState.resumed) {
      EnxRtc.startVideoTracksOnApplicationForeground(true, true);
    }
  }
}
Always implement WidgetsBindingObserver to handle lifecycle changes. On iOS, failing to pause media when backgrounded can result in the system terminating the app for holding camera or microphone resources.
Video Scaling Type

EnxRtc.setScalingType() controls how a video feed is scaled inside an EnxPlayerWidget. Choosing the right scaling mode ensures video fits your UI layout without unexpected cropping or letterboxing. You can set different scaling modes for the local preview and for remote participant widgets independently.

Method Signature

static Future<void> setPlayerScalingType(
  ScalingType scalingType,
  int viewId,
  int uid,
  bool isLocal
)
Parameter Type Description
scalingType ScalingType One of: SCALE_ASPECT_BALANCED, SCALE_ASPECT_FIT, SCALE_ASPECT_FILL.
viewId int ID of the EnxPlayerWidget.
uid int EnxPlayerWidget UID.
isLocal bool true if the widget renders the local stream.
EnxRtc.setScalingType(ScalingType.SCALE_ASPECT_FIT, viewId, uid, true);

Scaling Modes

Scaling Mode Behaviour
SCALE_ASPECT_BALANCED Balanced between fit and fill — default.
SCALE_ASPECT_FIT Entire video is visible; letterboxed if aspect ratios differ.
SCALE_ASPECT_FILL Video fills the container; cropped if aspect ratios differ.
Proximity Sensor

EnxRtc.enableProximitySensor(bool isEnabled) controls the device proximity sensor during a call. When enabled and the device is held close to the user's face — as in an earpiece call — the screen automatically dims and touch input is disabled, preventing accidental taps on call controls. When the device is moved away, the screen and touch input are restored.

The sensor works by comparing the ambient LUX reading against a threshold and returning a state of either NEAR or FAR.

// Enable proximity sensor (for earpiece mode)
EnxRtc.enableProximitySensor(true);

// Disable proximity sensor (for speaker mode)
EnxRtc.enableProximitySensor(false);
Enable the proximity sensor when the user switches to earpiece audio. Disable it when they switch to speaker mode since the device will be held away from the face and the proximity sensor would otherwise keep the screen dimmed.
Outbound Calling

EnxRtc.makeOutboundCall(String number) initiates an outbound PSTN call from within the active video session. The recipient's phone audio is bridged into the video room so they can participate in the session audio without needing the app. This is useful for bringing in participants who cannot or do not want to use the mobile or web client.

The Flutter SDK takes a single parameter — just the destination number. There is no separate caller ID parameter.

EnxRtc.makeOutboundCall('9896xxxxxx');

EnxRtc.onOutBoundCallInitiated = (Map<dynamic, dynamic> map) {
  print('Outbound call initiated: $map');
};

EnxRtc.onDialStateEvents = (String state) {
  // state can be: initiated, calling, connecting, connected,
  // terminated, failed, disconnected
  print('Call state: $state');
};

Callbacks

Callback Fires when
onOutBoundCallInitiated Call request sent to the PSTN network.
onDialStateEvents Status update for the outbound call. Possible states: initiated, calling, connecting, connected, terminated, failed, disconnected.
Outbound calling requires PSTN dialling to be enabled on your EnableX project. Contact EnableX support to activate this feature before attempting to use makeOutboundCall().
Screenshot Capture

EnxRtc.captureScreenShot(streamId) captures a still frame from a specific stream currently being rendered in the session. The captured image is returned as a Base64-encoded bitmap string via the OnCapturedView callback, which your app can then decode to display, save, or share as needed.

Pass the streamId of the stream you want to capture. This can be a local stream ID or the ID of any subscribed remote stream.

EnxRtc.captureScreenShot(streamId);

EnxRtc.OnCapturedView = (Map<dynamic, dynamic> map) {
  // map contains the base64-encoded bitmap
  String base64Image = map['bitmap'];
  // Convert to image for display or save to device
};
Logging

The SDK provides two logging utilities to support development and production troubleshooting. The first enables verbose console output so you can trace SDK behaviour locally. The second uploads recent SDK logs directly to EnableX for remote analysis — useful when a user reports an issue you cannot reproduce locally.

Enable / Disable Logging — EnxRtc.enableLogs()

Call EnxRtc.enableLogs(true) during development to activate verbose output to the console. This logs SDK internals including stream events, signalling messages, and media state transitions. Disable it before shipping to production.

// Enable verbose logging during development
EnxRtc.enableLogs(true);

// Disable in production
EnxRtc.enableLogs(false);

Upload Logs to EnableX — EnxRtc.postClientLogs()

EnxRtc.postClientLogs() sends the last 500 lines of the SDK log to EnableX for remote analysis. Call this method when debugging a user-reported issue that you cannot replicate in your own environment — it gives the EnableX support team direct visibility into what the SDK was doing during the problematic session.

EnxRtc.postClientLogs();
Always call EnxRtc.enableLogs(false) in production builds. Verbose logging can expose session metadata and increases I/O overhead. Enable it only during development and testing, or temporarily when capturing logs for a support request.