Flutter Video SDK

The EnableX Flutter SDK (enx_flutter_plugin) brings real-time audio and video to Flutter applications targeting iOS and Android from a single Dart codebase. All SDK operations are performed through the EnxRtc class using static method calls and callback property assignments — there is no JSX component or event-listener pattern; callbacks are simply assigned as properties on the class before the session begins.

↗  View on pub.dev

Flutter SDK v3.1.5 — Released February 4, 2026

Prerequisites

Before writing any Flutter code, your backend server must have three things in place. These are server-side responsibilities — none of these credentials or operations should ever be performed inside the Flutter app itself.

1. App Credentials

Log in to the EnableX Portal and create a project to obtain your app_id and app_key. These credentials authenticate your server when calling the EnableX Video API. Never embed them in the Flutter app — treat them as server secrets.

2. A Room

A Room is a virtual session space. Create it via the Video REST API from your server and store the returned room_id. The room persists until you delete it, so you typically create it once per meeting and reuse it across participants.

3. A Token per Participant

Each participant who joins the session needs their own short-lived token. Your server generates the token by calling the Create Token API with the room_id and participant details, then passes it to the Flutter app. The app uses this token to authenticate when calling EnxRtc.joinRoom().

Token generation must always happen server-side. The app_key is required to generate tokens — if it is embedded in the app, it can be extracted and abused to create unauthorized sessions.
Installation

Add the dependency

The EnableX Flutter SDK is distributed as a pub package. Add it to your project's pubspec.yaml under the dependencies section:

dependencies:
  enx_flutter_plugin: ^3.0.3

Then fetch the package by running:

flutter pub get

iOS setup

Flutter apps on iOS require explicit permission declarations for camera and microphone access. Without these, iOS will crash the app at runtime the first time the SDK attempts to open either device. Open ios/Runner/Info.plist and add the following entries:

<key>NSCameraUsageDescription</key>
<string>Camera access is required for video calls.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required for audio calls.</string>

The EnableX Flutter SDK renders video using Flutter's PlatformView mechanism. To prevent a black video screen on iOS devices, you must also enable embedded views preview in Info.plist:

<key>io.flutter.embedded_views_preview</key>
<true/>

After adding the permission keys, build the iOS target to ensure everything compiles correctly:

flutter build ios --no-codesign
If your app requires background audio (call continues when the app is minimised), open the Runner target in Xcode → CapabilitiesBackground Modes and enable Audio, AirPlay, and Picture in Picture.

Android setup

No additional native configuration is required for Android beyond what Flutter handles automatically. Camera and microphone permissions are declared in the SDK's own AndroidManifest.xml and merged into your app's manifest at build time by the Android Gradle plugin.

Import

Import the SDK package at the top of any Dart file where you need video functionality. A single import gives you access to all SDK classes and widgets:

import 'package:enx_flutter_plugin/enx_flutter_plugin.dart';

This import provides three primary exports you will work with:

Callbacks — How the SDK Notifies Your App

The Flutter SDK uses a property assignment pattern for event notifications. Rather than registering listeners against event name strings (as you would with addEventListener in the Web SDK), or conforming to a delegate protocol (as with the iOS SDK), you assign handler functions directly to named static properties on the EnxRtc class.

When the SDK needs to notify your app of an event — a room connection established, a remote user joining, a stream becoming available — it calls whichever function you have assigned to the corresponding callback property. If no function has been assigned, the event is silently ignored.

Assign your callbacks in initState() or in a dedicated setup method, always before calling EnxRtc.joinRoom():

// Assign callbacks before joining the room
EnxRtc.onRoomConnected = (Map<dynamic, dynamic> map) {
  print('Connected to room: $map');
};

EnxRtc.onRoomError = (Map<dynamic, dynamic> map) {
  print('Error: ${map['msg']}');
};

EnxRtc.onUserConnected = (Map<dynamic, dynamic> map) {
  print('User joined: ${map['name']}');
};
Assign all callback handlers before calling EnxRtc.joinRoom(). Callbacks fire as soon as events occur — if you assign them after joining, you may miss early events like onRoomConnected or onStreamAdded.
Error Handling

When an SDK method fails, the SDK does not throw a Dart exception. Instead, it delivers an error payload to the callback associated with the failed operation. For example, if joinRoom() fails, the error arrives in EnxRtc.onRoomError. For recording failures, the error arrives in the relevant recording callback.

Every error payload follows this consistent structure:

{
  "errorCode": 1001,   // numeric error code
  "msg": "Error description",
  "desc": "Optional extended description"
}
Field Type Description
errorCode Number Numeric code identifying the error.
msg String Short human-readable error description.
desc String Optional extended explanation of the error.

A robust error handler reads both errorCode for programmatic branching and msg / desc for user-facing or log messages:

EnxRtc.onRoomError = (Map<dynamic, dynamic> map) {
  print('Error ${map['errorCode']}: ${map['msg']}');
  if (map['desc'] != null) print('Detail: ${map['desc']}');
};
Explore the Flutter SDK

The Flutter SDK documentation is organized into the following topics:

🔌
Connecting to a Session
Join and leave a room, manage audio device selection, handle reconnection and bandwidth alerts.
📹
Stream Management
Publish your camera, subscribe to remote streams, manage active talkers, mute audio and video, and switch devices.
💬
In-Session Communication
Chat messaging, file sharing, screen sharing, custom signalling, and annotation.
🎭
Session Management
Recording, live recording, room controls, moderation, user roles, and session lifecycle.
🎤
Floor Access Control
Request, grant, deny, and manage floor access in moderated sessions.
🔧
Developer Tools
Live stats, talker notifications, outbound calling, background handling, proximity sensor, screenshot, and logging.