<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Richard Dewan</title>
    <description>The latest articles on DEV Community by Richard Dewan (@rdewan).</description>
    <link>https://dev.to/rdewan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1065796%2Fe2ae4e78-1608-46f3-82dc-8cf7ec9763d4.jpeg</url>
      <title>DEV Community: Richard Dewan</title>
      <link>https://dev.to/rdewan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rdewan"/>
    <language>en</language>
    <item>
      <title>Flutter Video Calling App</title>
      <dc:creator>Richard Dewan</dc:creator>
      <pubDate>Sun, 16 Apr 2023 11:34:58 +0000</pubDate>
      <link>https://dev.to/rdewan/flutter-video-calling-app-5cgd</link>
      <guid>https://dev.to/rdewan/flutter-video-calling-app-5cgd</guid>
      <description>&lt;p&gt;In this article, You will be learning how to build a Video calling using the &lt;a href="https://www.zegocloud.com/product/video-call" rel="noopener noreferrer"&gt;Video Call&lt;/a&gt; SDK and API provided by the &lt;a href="http://bit.ly/3LVErPZ" rel="noopener noreferrer"&gt;ZEGOCLOUD&lt;/a&gt;. Let me introduce ZEGOCLOUD it is a global communication service provider which provides developer-friendly and powerful SDK &amp;amp; APIs to build many communication feature on mobile app and web app, such as video call, chat, video conference, live streaming,etc.&lt;/p&gt;

&lt;p&gt;When you register an account with ZEGOCLOUD you will receive a FREE 10,000 minutes to build and test your app and the cool part is it does not require any credit card to register a new account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create an Account
&lt;/h3&gt;

&lt;p&gt;Use the link to register a new account &lt;a href="http://bit.ly/3FFkj0q" rel="noopener noreferrer"&gt;http://bit.ly/3FFkj0q&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Project
&lt;/h3&gt;

&lt;p&gt;Once you have successfully registered an account, next step will be to create a project. Click on the Overview menu and click on &lt;strong&gt;create your first project&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47u6b17y4d6kiiselsgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47u6b17y4d6kiiselsgi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Select a use case for your app
&lt;/h4&gt;

&lt;p&gt;Next step you will need to select a use case for your app, since we are &lt;a href="https://www.zegocloud.com/blog/flutter-callkit" rel="noopener noreferrer"&gt;building a Video Call app&lt;/a&gt; select &lt;strong&gt;Voice &amp;amp; Video Call&lt;/strong&gt; for the list of options and click on &lt;strong&gt;Next&lt;/strong&gt; button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6qpcoz2us2b6ou5flge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6qpcoz2us2b6ou5flge.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Select the most appropriate way to get started
&lt;/h4&gt;

&lt;p&gt;Next step you will need to provide a &lt;strong&gt;Project Name&lt;/strong&gt;. I will provide a project name as &lt;strong&gt;ChattyApp&lt;/strong&gt;. Here you will have an option to choose UIKit or SDK, we will be using a UIKit to build an app as it provides a pre-build UI to speed up our development. Click on the &lt;strong&gt;Start with UIKits button&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec216ypqx64p2d0jmre1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec216ypqx64p2d0jmre1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiira6g00ajiknqo9s6nq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiira6g00ajiknqo9s6nq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Framework Selection
&lt;/h3&gt;

&lt;p&gt;Next step you will need to select a &lt;strong&gt;Framework&lt;/strong&gt;. We will be creating a Flutter app , so let's select Flutter as our framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi96txre2fn83igzfueg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi96txre2fn83igzfueg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  UI Configuration
&lt;/h3&gt;

&lt;p&gt;Next step you will need to select a &lt;strong&gt;1-on 1 Call&lt;/strong&gt; option since we will be build a 1-1 Video Calling App and click on &lt;strong&gt;Save &amp;amp; Start to integrate button&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqrb74be2nzcl5rp9pyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqrb74be2nzcl5rp9pyy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtain Configuration
&lt;/h3&gt;

&lt;p&gt;Next step you will need to obtain the &lt;strong&gt;AppID&lt;/strong&gt; and &lt;strong&gt;AppSign&lt;/strong&gt; configuration key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0smdnowiqvo2v7xczvns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0smdnowiqvo2v7xczvns.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Flutter application
&lt;/h2&gt;

&lt;p&gt;Now you will need to create the Flutter application, run the below command in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter create chatty --org io.mobileacademy.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add Dependencies
&lt;/h2&gt;

&lt;p&gt;Next let us add our dependencies. Open your &lt;em&gt;pubspec.yaml&lt;/em&gt; file and add &lt;strong&gt;zego_uikit_prebuilt_call: ^3.2.0&lt;/strong&gt;&lt;br&gt;
 in the dependencies section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  flutter:
    sdk: flutter


  cupertino_icons: ^1.0.2
  # https://pub.dev/packages/zego_uikit_prebuilt_call/install
  zego_uikit_prebuilt_call: ^3.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create UI
&lt;/h2&gt;

&lt;p&gt;Next inside the &lt;em&gt;lib&lt;/em&gt; folder create a new folder &lt;em&gt;screen&lt;/em&gt; and inside the &lt;em&gt;screen&lt;/em&gt; folder create a new file &lt;strong&gt;video_call_screen.dart&lt;/strong&gt; and paste the below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:chatty/const.dart';
import 'package:flutter/material.dart';
import 'package:zego_uikit_prebuilt_call/zego_uikit_prebuilt_call.dart';


class VideoCallScreen extends StatefulWidget {
  final String userId;
  final String userName;
  final String callId;
  const VideoCallScreen({
    Key? key,
    required this.userId,
    required this.userName,
    required this.callId,
  }) : super(key: key);

  @override
  State&amp;lt;VideoCallScreen&amp;gt; createState() =&amp;gt; _VideoCallScreenState();
}

class _VideoCallScreenState extends State&amp;lt;VideoCallScreen&amp;gt; {
  @override
  Widget build(BuildContext context) {
    return ZegoUIKitPrebuiltCall(
      appID: appId, // Fill in the appID that you get from ZEGOCLOUD Admin Console.
      appSign: appSign, // Fill in the appSign that you get from ZEGOCLOUD Admin Console.
      userID: widget.userId,
      userName: widget.userName,
      callID: widget.callId,
      // You can also use groupVideo/groupVoice/oneOnOneVoice to make more types of calls.
      config: ZegoUIKitPrebuiltCallConfig.oneOnOneVideoCall() 
    );
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see from the above code that &lt;em&gt;ZegoUIKitPrebuiltCall&lt;/em&gt; constructor requires few argument's.&lt;br&gt;
&lt;strong&gt;appID&lt;/strong&gt;: You can get the appID from ZEGOCLOUD Admin Console&lt;br&gt;
&lt;strong&gt;appSign&lt;/strong&gt;: You can get the appSign from ZEGOCLOUD Admin Console&lt;br&gt;
&lt;strong&gt;userID&lt;/strong&gt;: You can provide a unique user ID for each user&lt;br&gt;
&lt;strong&gt;userName&lt;/strong&gt;: You can provide a user name, which will be displayed in the call screen.&lt;br&gt;
&lt;strong&gt;callID&lt;/strong&gt;: This is a unique ID that is required to make and connect a call, both party should have a same call ID.&lt;/p&gt;

&lt;p&gt;Next let us replace our &lt;strong&gt;main.dart&lt;/strong&gt; file code with the below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:math';

import 'package:chatty/screen/video_call_screen.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(      
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State&amp;lt;MyHomePage&amp;gt; createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  final GlobalKey&amp;lt;FormState&amp;gt;  _formKey = GlobalKey();
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _callIdController = TextEditingController();

  @override
  void dispose() {
    _nameController.dispose();
    _callIdController.dispose();
    super.dispose();
  }

  void _generateCallId(){
    final value = Random().nextInt(1000) + 1;
    setState(() {
      _callIdController.text = value.toString();
    });
  }

  @override
  Widget build(BuildContext context) {    
    return Scaffold(
      appBar: AppBar(        
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Center(        
          child: SingleChildScrollView(
            child: Column(          
              mainAxisAlignment: MainAxisAlignment.center,
              children: &amp;lt;Widget&amp;gt;[
                Form(
                  key: _formKey,
                  child: Column(
                    children: [
                      TextFormField(
                        controller: _nameController,
                        decoration: InputDecoration(
                          labelText: 'Name',
                          hintText: 'enter your name',
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(8.0)
                          )
                        ),
                        validator: (value) {
                          if (value == null || value == '') {
                            return 'Please enter your name';
                          }
                          return null;
                        },
                      ),

                      const SizedBox(height: 16.0,),

                      TextFormField(
                        controller: _callIdController,
                        decoration: InputDecoration(
                          labelText: 'Call Id',
                          hintText: 'enter your call Id',
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(8.0)
                          )
                        ),
                        validator: (value) {
                          if (value == null || value == '') {
                            return 'Please enter call id';
                          }
                          return null;
                        },
                      )
                    ],
                  ),
                ),

                FilledButton.tonal(
                  onPressed: () {
                    _generateCallId();
                  }, 
                  child: const Text('Generate CallId'),
                ),

                FilledButton.tonal(
                  onPressed: () {
                    _startVideoCall();
                  }, 
                  child: const Text('Video Call'),
                )
              ],
            ),
          ),
        ),
      ),

    );
  }

  void _startVideoCall() {
    final isValid = _formKey.currentState?.validate();
    if (isValid != null &amp;amp;&amp;amp; isValid) {
      Navigator.of(context).push(
        MaterialPageRoute(builder: (_) =&amp;gt; VideoCallScreen(
          userId: (Random().nextInt(100) + 1).toString(), 
          userName: _nameController.text, 
          callId: _callIdController.text),
        )
      );
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code we have a two main function &lt;strong&gt;_generateCallId&lt;/strong&gt; this function is used to generate a random number for call ID and the next one is &lt;strong&gt;_startVideoCall&lt;/strong&gt; this function is used to validate a form and if the form is valid will open our VideoCallScreen&lt;/p&gt;

&lt;h2&gt;
  
  
  iOS Setup
&lt;/h2&gt;

&lt;p&gt;Next you will need to setup the camera and microphone permission for iOS. Open your &lt;strong&gt;Info.plist&lt;/strong&gt; from &lt;em&gt;your_project/ios/Runner/&lt;/em&gt; add the following code inside the "dict" tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;key&amp;gt;NSCameraUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;We require camera access to connect to a call&amp;lt;/string&amp;gt;
    &amp;lt;key&amp;gt;NSMicrophoneUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;We require microphone access to connect to a call&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next to use the notifications and build your app correctly, open ios folder in Xcode and navigate to the Build Settings tab, and set the following build options for your target app.&lt;/p&gt;

&lt;p&gt;Refer to and set the following build options:&lt;/p&gt;

&lt;p&gt;In the Runner Target:   &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a. Build Libraries for Distribution -&amp;gt; NO

b. Only safe API extensions -&amp;gt; NO

c. iOS Deployment Target -&amp;gt; 11 or greater
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In other Targets:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a. Build Libraries for Distribution -&amp;gt; NO

b. Only safe API extensions -&amp;gt; YES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Android Setup
&lt;/h2&gt;

&lt;p&gt;Next you will need to open the your_project/android/app/build.gradle file, and modify the compileSdkVersion to 33 and minSdkVersion to 21 or higher&lt;/p&gt;
&lt;h4&gt;
  
  
  Android Permission
&lt;/h4&gt;

&lt;p&gt;Open the file your_project/app/src/main/AndroidManifest.xml, and add the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.INTERNET"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.CAMERA"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.RECORD_AUDIO" /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build and Run App
&lt;/h2&gt;

&lt;p&gt;Finally it's time to run your app. To test the video call, you will need to run in the real device.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
As you can see, adding the video call option to your flutter app is very easy and simple using the &lt;a href="https://www.zegocloud.com/uikits" rel="noopener noreferrer"&gt;pre-built UIKits&lt;/a&gt; from ZEGOCLOUD, please visit their website to get more information about their products and services.&lt;/p&gt;

&lt;p&gt;I hope this tutorial has been useful to you, see you in the next article.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
