{"id":1496,"date":"2021-03-02T05:02:11","date_gmt":"2021-03-01T23:32:11","guid":{"rendered":"https:\/\/www.enablex.io\/insights\/?p=1496"},"modified":"2025-06-06T06:31:58","modified_gmt":"2025-06-06T01:01:58","slug":"how-to-build-video-calling-app-using-flutter-and-enablex","status":"publish","type":"post","link":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/","title":{"rendered":"How To Build Video Calling App Using Flutter and EnableX"},"content":{"rendered":"<h1>How To Make A Video Calling App Using Flutter and EnableX<\/h1>\r\n<p>To make a <a href=\"https:\/\/www.enablex.io\/cpaas\/video-api\">video calling<\/a> app can be simple if you build it on a secure and robust communication platform such as EnableX . In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.<\/p>\r\n<h2>Prerequisites<\/h2>\r\n<p>Before we start on how to make a video calling flutter app, let\u2019s make sure we have the following in your development environment:<\/p>\r\n<h3><strong>For iOS<\/strong><\/h3>\r\n<ul style=\"margin-left: 40px;\">\r\n<li>Flutter 2.0.0 or later<\/li>\r\n<li>macOS<\/li>\r\n<li>Xcode (Latest version recommended)<\/li>\r\n<\/ul>\r\n<p><u>Note<\/u>: You need an iOS device<\/p>\r\n<h3><strong>For Android<\/strong><\/h3>\r\n<ul style=\"margin-left: 40px;\">\r\n<li>Flutter 2.0.0 or later<\/li>\r\n<li>macOS or Windows<\/li>\r\n<li>Android Studio (Latest version recommended)<\/li>\r\n<\/ul>\r\n<p><u>Note<\/u> : You can either use an Android simulator or an Android device<\/p>\r\n<p><strong>Cautions<\/strong> Please run flutter doctor to check if the development environment and the deployment environment are correct. \u00a0<\/p>\r\n<p><strong>Also read<\/strong>: <a href=\"https:\/\/www.enablex.io\/insights\/build-a-video-streaming-app-using-flutter\/\">How To Build A Video Streaming App Using Flutter<\/a><\/p>\r\n<h2>\u00a0<\/h2>\r\n\r\n<div class=\"wp-block-rank-math-faq-block\">\r\n<div class=\"rank-math-faq-item\">\r\n<h3 class=\"rank-math-question\"><strong>How can I make Video Calling App in Flutter? <\/strong>\u00a0<\/h3>\r\n<div class=\"rank-math-answer\">This can easily be done by creating a free developer account with EnableX. Follow the steps given below: \u00a0<br \/>1. Get an <a href=\"https:\/\/portal.enablex.io\/cpaas\/trial-sign-up\/\">EnableX account<\/a> to make your video calling app in Flutter.<br \/>2. Create a Flutter project.\u00a0<br \/>3. Add dependencies.\u00a0<br \/>4. Generate access token.\u00a0<br \/>5. Get device permission.\u00a0<br \/>6. Start video calling.\u00a0\u00a0<br \/>7. Run the project.\u00a0<br \/>8. It\u2019s done, you can go live now.\u00a0<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n<h2>Get an EnableX Account To Make A Video Calling App in Flutter<\/h2>\r\n<p>Please sign up for an account with us. It&#8217;s absolutely free! Once done, create a project and get the necessary credentials and you are ready to start!<\/p>\r\n<ul style=\"margin-left: 40px;\">\r\n<li>Sign up an Account <a title=\"Trial-sign-up\" href=\"https:\/\/portal.enablex.io\/cpaas\/trial-sign-up\/\">here<\/a><\/li>\r\n<li>Create a project<\/li>\r\n<li>Get App ID and App Key. Please refer here on how to get the ID and Key<\/li>\r\n<\/ul>\r\n<p>In order not to get you confused, you might be interested to know some of the common acronyms we used.<\/p>\r\n<p><strong>EnxRTC<\/strong>-This Class features a versatile method for developers to connect to a room and successfully publish a stream into it. To start using EnableX, an Object must be created using EnxRtc Constructor.<\/p>\r\n<p><strong>EnxRoom<\/strong>-The EnxRoom is a derived Class from EnxRtc. It handles all room related functions to communicate with EnableX, e.g. Connection of End-Points to EnableX Room, publishing &amp; subscribing of streams etc.<\/p>\r\n<p><strong>EnxStream<\/strong> -The EnxStream is a derived Class from EnxRtc. It handles all Media Stream related functions to initiate, configure and to transport streams to EnableX Media Servers. It is also used for receiving stream end-points to be played.<\/p>\r\n<p><strong>EnxPlayerView<\/strong>:\u202f\u202fIt use\u202fto display the video stream on a\u202fEnxPlayerview.<\/p>\r\n<h2>Let\u2019s Get Started<\/h2>\r\n<h3><strong>Create a Flutter Project<\/strong><\/h3>\r\n<p>Now that we have all things set up, you are ready to build a group video calling app. First, you need to start creating a new Flutter project You may use Visual Studio Code to create a Flutter project. Do install the Flutter plugin in Visual Studio Code. See <a title=\"Set up editor\" href=\"https:\/\/flutter.dev\/docs\/get-started\/editor?tab=vscode\" target=\"_blank\" rel=\"noopener\">Set up an editor<\/a>. Once done, please follow the steps below:<\/p>\r\n<ol style=\"margin-left: 40px;\">\r\n<li>Select the <strong>Flutter: New Project<\/strong> command in <strong>View &gt; Command<\/strong>. Enter the project name and press .<\/li>\r\n<li>Select the location of the project in the pop-up window. Visual Studio Code automatically generates a simple project.<\/li>\r\n<\/ol>\r\n<p>Alternatively, you may also use <strong>Android Studio<\/strong> to create a Flutter project. Do install the Flutter plugin in Android Studio. See <a title=\"Set up editor\" href=\"https:\/\/flutter.dev\/docs\/get-started\/editor?tab=vscode\" target=\"_blank\" rel=\"noopener\">Set up an editor<\/a>. Once done, please follow the step below<\/p>\r\n<ol style=\"margin-left: 40px;\">\r\n<li>Click on file Select the New -&gt; <strong>New Flutter Project<\/strong> -&gt;Flutter Application<\/li>\r\n<\/ol>\r\n<h3><strong>Add Dependencies <\/strong><\/h3>\r\n<p>Now, pls add the following dependencies in pubspec.yaml based on the following steps:<\/p>\r\n<ol>\r\n<li style=\"list-style-type: none;\">\r\n<ol style=\"margin-left: 40px;\">\r\n<li>Add the enx_flutter_plugin dependency to integrate EnableX <a href=\"https:\/\/www.enablex.io\/cpaas\/video-api\">Flutter SDK<\/a>. See\u00a0<a href=\"https:\/\/pub.dev\/packages\/enx_flutter_plugin\">https:\/\/pub.dev\/packages\/enx_flutter_plugin<\/a> for the latest version of enx_flutter_plugin.<\/li>\r\n<li>Add the permission_handler dependency to add the permission handling function.\r\n<pre><code>\r\n    environment:\r\n    sdk: &gt;=2.7.0&lt;3.0.0 dependencies:\r\n    flutter:\r\n    sdk: flutter# The following adds the Cupertino Icons font to your application.\r\n    # Use with the CupertinoIcons class for iOS style icons.\r\n    cupertino_icons: ^0.1.3\r\n    # Please use the latest version of enx_flutter_plugin\r\n    enx_flutter_plugin: ^1.8.0\r\n    permission_handler: ^3.0.0\r\n<\/code><\/pre>\r\n<\/li>\r\n<li>Install it &#8211; You can install packages from the command line:<\/li>\r\n<\/ol>\r\n<\/li>\r\n<\/ol>\r\n<p>with Flutter: $ flutter pub get Alternatively, your editor might support\u202fflutter pub get. Check the docs from your editor to learn more.<\/p>\r\n<h3><strong>Generate Access Token\u202f<\/strong><\/h3>\r\n<p>Every user is required to use an Access Token, uniquely to them, to connect to a room. This step is usually done\u202fby\u202f<a title=\"Rest API\u2019s Call\" href=\"https:\/\/openapi.enablex.io\/video\/v1\/api-docs\/#\/Rooms\">Rest API\u2019s Call<\/a>. Do use the following link to create token\u202fand\u202froomId <a href=\"https:\/\/openapi.enablex.io\/video\/v1\/api-docs\/#\/Rooms\">https:\/\/openapi.enablex.io\/video\/v1\/api-docs\/#\/Rooms\u202f<\/a><\/p>\r\n<h3><strong>Get Device Permission<\/strong><\/h3>\r\n<p>EnableX <a href=\"https:\/\/www.enablex.io\/cpaas\/video-api\">Video SDK<\/a> requires camera and microphone permission to start a video call. Simply follow the following steps to create device permission. <strong>Android\u202f<\/strong> Open the\u202fAndroidManifest.xml\u202ffile and add the required device permissions to the file.<\/p>\r\n<pre><code>\r\n<span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.READ_PHONE_STATE<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.INTERNET<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\u00a0\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.RECORD_AUDIO<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\u00a0\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.CAMERA<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\u00a0\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.MODIFY_AUDIO_SETTINGS<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\u00a0\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">&lt;uses-permission\u00a0<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android:<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">name<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">=<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"SpellingError SCXW166729875 BCX0\">android.permission.ACCESS_NETWORK_STATE<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\"<\/span><\/span><span class=\"TextRun SCXW166729875 BCX0\" lang=\"EN-SG\" xml:lang=\"EN-SG\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW166729875 BCX0\">\u00a0\/&gt;<\/span><\/span><span class=\"LineBreakBlob BlobObject DragDrop SCXW166729875 BCX0\"><span class=\"SCXW166729875 BCX0\">\u00a0<\/span><br class=\"SCXW166729875 BCX0\" \/><\/span>\u00a0<\/code><\/pre>\r\n<p><strong>iOS<\/strong> Open the\u202finfo.plist\u202fand add: Privacy &#8211; Microphone Usage Description, and a note in the Value column. Privacy &#8211; Camera Usage Description, and a note in the Value column. <strong>Note<\/strong> Your application will be able to have a voice call if the Background Mode is enabled. To enable Background Mode, simply following the following steps: Select the app target in Xcode, Click the\u202fCapabilities\u202ftab to enable\u202fBackground Modes, and check\u202fon Audio, AirPlay, and Picture in Picture.<\/p>\r\n<h3><strong>Handle Errors<\/strong><\/h3>\r\n<p><strong>iOS black screen<\/strong> Our SDK use\u202fPlatformView, you should set\u202fio.flutter.embedded_views_preview\u202fto\u202fYES\u202fin your\u202finfo.plist \u00a0<\/p>\r\n<h3><strong>Start Video Calling<\/strong><\/h3>\r\n<p>We are almost there! Now that we have all the setup and permission handling done, let\u2019s declare some variables needed to manage the state of the call <strong>Import packages<\/strong><\/p>\r\n<pre><code>\r\nimport 'package:enx_flutter_plugin\/enx_flutter_plugin.dart';\r\nimport 'package:flutter\/material.dart';\r\nimport 'package:permission_handler\/permission_handler.dart';\r\n<\/code><\/pre>\r\n<p><strong>Define VideoConferenceScreen Class<\/strong><\/p>\r\n<pre><code>\r\nclass VideoConferenceScreen extends StatefulWidget {\r\n@override\r\n_VideoConferenceScreenState createState() =&gt; _VideoConferenceScreenState();\r\n}\r\n<\/code><\/pre>\r\n<p><strong>Define App States<\/strong><\/p>\r\n<pre><code>class _VideoConferenceScreenState extends State { static String token = \"\"; @override void initState() { super.initState(); initPlatformState(); initEnxRtc(); } \/\/ Initialize the permission handler Future initPlatformState() async { \/\/ Get microphone permission await PermissionHandler().requestPermissions( [PermissionGroup.microphone, PermissionGroup.camera,],], ); }\r\n\r\n\/\/initialize ENXRTC\r\n\r\nFuture initEnxRtc() async {\r\nMap&lt;String, dynamic&gt; map1 = {\r\n'audio': true,\r\n'video': true,\r\n'data': true,\r\n'framerate': 30,\r\n'maxVideoBW': 1500,\r\n'minVideoBW': 150,\r\n'audioMuted': false,\r\n'videoMuted': false,\r\n'name': 'flutter',\r\n'videoSize': map2\r\n};\r\nawait EnxRtc.joinRoom(widget.token, map1, null, null);\r\n}\r\n<\/code><\/pre>\r\n<p><strong>\/\/Add ENXRC handler callbacks<\/strong><\/p>\r\n<pre><code>\r\n void _addEnxrtcEventHandlers() {\r\n EnxRtc.onRoomConnected = (Map&lt;dynamic, dynamic&gt; map) {\r\n setState(() {\r\n print('onRoomConnectedFlutter' + jsonEncode(map));\r\n });\r\n EnxRtc.publish();\r\n };\r\n\r\n EnxRtc.onPublishedStream = (Map&lt;dynamic, dynamic&gt; map) {\r\n setState(() {\r\n print('onPublishedStream' + jsonEncode(map));\r\n EnxRtc.setupVideo(0, 0, true, 300, 200);\r\n });\r\n };\r\n\r\nEnxRtc.onStreamAdded = (Map&lt;dynamic, dynamic&gt; map) {\r\nprint('onStreamAdded' + jsonEncode(map));\r\nprint('onStreamAdded Id' + map['streamId']);\r\n\r\nString streamId;\r\nsetState(() {\r\nstreamId = map['streamId'];\r\n});\r\nEnxRtc.subscribe(streamId);\r\n};\r\nEnxRtc.onActiveTalkerList = (Map&lt;dynamic, dynamic&gt; map) {\r\nprint('onActiveTalkerList ' + map.toString());\r\n\r\nfinal items = (map['activeList'] as List)\r\n.map((i) =&gt; new ActiveListModel.fromJson(i));\r\nif(_remoteUsers.length&gt;0){\r\nfor(int i=0;i&lt;_remoteUsers.length;i++){ setState(() { _remoteUsers.removeAt(i); }); } } if (items.length &gt; 0) {\r\nfor (final item in items) {\r\nif(!_remoteUsers.contains(item.streamId)){\r\nprint('_remoteUsers ' + map.toString());\r\nsetState(() {\r\n_remoteUsers.add(item.streamId);\r\n});\r\n}\r\n}\r\nprint('_remoteUsersascashjc');\r\nprint(_remoteUsers);\r\n\r\n}\r\n};\r\n\r\nEnxRtc.onUserConnected = (Map&lt;dynamic, dynamic&gt; map) {\r\nsetState(() {\r\nprint('onUserConnected' + jsonEncode(map));\r\n});\r\n};\r\n}\r\n<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<h3><strong>Run the project<\/strong><\/h3>\r\n<p>Finally, let\u2019s run the project J<\/p>\r\n<ol>\r\n<li>Run the following command in the root folder to install dependencies.\r\n<pre><code>flutter packages get<\/code><\/pre>\r\n<\/li>\r\n<li>Run the project\r\n<pre><code>flutter run<\/code><\/pre>\r\n<\/li>\r\n<\/ol>\r\n<p>Hurray! Now you have a one-to-one video calling. With this app, you users can connect to a\u202froom\u202fto publish their stream\u202fand subscribe to remote streams. In case, you want to find out more, visit <strong><a title=\"EnableX Developer\" href=\"https:\/\/www.enablex.io\/developer\/\" target=\"_blank\" rel=\"noopener\">EnableX Developer<\/a><\/strong> Hub or the <strong><a title=\"GitHub\" href=\"https:\/\/github.com\/EnableX?language=javascript\" target=\"_blank\" rel=\"noopener\">GitHub<\/a><\/strong> repository.<\/p>\r\n<p style=\"text-align: center;\">\u00a0<\/p>","protected":false},"excerpt":{"rendered":"<p>How To Make A Video Calling App Using Flutter and EnableX To make a video calling app can be simple if you build it on a secure and robust communication platform such as EnableX . In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app. Prerequisites Before we &#8230;<\/p>\n","protected":false},"author":26,"featured_media":1807,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[134,122,23,133,93],"tags":[189,195],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How To Build Video Calling App Using Flutter and EnableX - Insights about video API, SMS API; WhatsApp for Business API<\/title>\n<meta name=\"description\" content=\"In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How To Build Video Calling App Using Flutter and EnableX - Insights about video API, SMS API; WhatsApp for Business API\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/\" \/>\n<meta property=\"og:site_name\" content=\"Insights about video API, SMS API; WhatsApp for Business API\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-01T23:32:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-06T01:01:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2021\/03\/Building-App-option-1-1024x361-1.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"361\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Alison Chase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@enablexio\" \/>\n<meta name=\"twitter:site\" content=\"@enablexio\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alison Chase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How To Build Video Calling App Using Flutter and EnableX - Insights about video API, SMS API; WhatsApp for Business API","description":"In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/","og_locale":"en_US","og_type":"article","og_title":"How To Build Video Calling App Using Flutter and EnableX - Insights about video API, SMS API; WhatsApp for Business API","og_description":"In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.","og_url":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/","og_site_name":"Insights about video API, SMS API; WhatsApp for Business API","article_published_time":"2021-03-01T23:32:11+00:00","article_modified_time":"2025-06-06T01:01:58+00:00","og_image":[{"width":1024,"height":361,"url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2021\/03\/Building-App-option-1-1024x361-1.webp","type":"image\/webp"}],"author":"Alison Chase","twitter_card":"summary_large_image","twitter_creator":"@enablexio","twitter_site":"@enablexio","twitter_misc":{"Written by":"Alison Chase","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/#article","isPartOf":{"@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/"},"author":{"name":"Alison Chase","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/ad26077bd6abed9cb383c9fe9e4a7d62"},"headline":"How To Build Video Calling App Using Flutter and EnableX","datePublished":"2021-03-01T23:32:11+00:00","dateModified":"2025-06-06T01:01:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/"},"wordCount":956,"publisher":{"@id":"https:\/\/www.enablex.io\/insights\/#organization"},"keywords":["Video Calling","Video Calling App Using Flutter"],"articleSection":["Codes &amp; Tutorials","Communication APIs","TechTalks","Tips &amp; How-To","Video API"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/","url":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/","name":"How To Build Video Calling App Using Flutter and EnableX - Insights about video API, SMS API; WhatsApp for Business API","isPartOf":{"@id":"https:\/\/www.enablex.io\/insights\/#website"},"datePublished":"2021-03-01T23:32:11+00:00","dateModified":"2025-06-06T01:01:58+00:00","description":"In this tutorial, you\u2019ll learn how to add group calling function to your video calling Flutter app.","breadcrumb":{"@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.enablex.io\/insights\/how-to-build-video-calling-app-using-flutter-and-enablex\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.enablex.io\/insights\/"},{"@type":"ListItem","position":2,"name":"How To Build Video Calling App Using Flutter and EnableX"}]},{"@type":"WebSite","@id":"https:\/\/www.enablex.io\/insights\/#website","url":"https:\/\/www.enablex.io\/insights\/","name":"Enablex","description":"","publisher":{"@id":"https:\/\/www.enablex.io\/insights\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.enablex.io\/insights\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.enablex.io\/insights\/#organization","name":"Enablex","url":"https:\/\/www.enablex.io\/insights\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/logo\/image\/","url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/05\/EnableX-Logo-01.png","contentUrl":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/05\/EnableX-Logo-01.png","width":17382,"height":3567,"caption":"Enablex"},"image":{"@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/twitter.com\/enablexio","https:\/\/www.linkedin.com\/company\/vcloudx"]},{"@type":"Person","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/ad26077bd6abed9cb383c9fe9e4a7d62","name":"Alison Chase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/image\/","url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2025\/05\/envato-labs-ai-1b97716e-ce13-4ae0-b96b-06f8c577ca8b-96x96.jpg","contentUrl":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2025\/05\/envato-labs-ai-1b97716e-ce13-4ae0-b96b-06f8c577ca8b-96x96.jpg","caption":"Alison Chase"},"description":"Alison brings stories to life. With a background in content marketing and storytelling, and a strong sense of what resonates with audiences, she creates content that\u2019s clear, relevant and engaging \u2013 whether it\u2019s a blog post, a customer story or a campaign. Her role is all about making technology feel human and showing how real businesses are using EnableX to connect with customers in smarter ways.","sameAs":["https:\/\/www.enablex.io\/","https:\/\/www.linkedin.com\/company\/vcloudx\/"],"url":"https:\/\/www.enablex.io\/insights\/author\/alison-chase\/"}]}},"_links":{"self":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts\/1496"}],"collection":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/users\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/comments?post=1496"}],"version-history":[{"count":0,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts\/1496\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/media\/1807"}],"wp:attachment":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/media?parent=1496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/categories?post=1496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/tags?post=1496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}