No one expected that working from home would be the new normal. This pandemic has been tough for everyone but it has proved that even when the complete country is in lockdown, people can work with ease in their homes. Where people are connected online with their colleagues, friends, and family .
Connecting via video call is the need of the hour, and people are using various applications to do that. But such applications aren’t usually customizable to your needs, because they are built with a common UI that solves general use cases. Also, these applications might compromise on the privacy of your data.
https://giphy.com/gifs/election2020-dnc-2020-democratic-national-convention-KenZCPB6lReAsffAIE
The solution is pretty simple: a webRTC service that helps you customize your application according to your use case. In this post, we will look at a sample of how we can implement our own video calling application using the Agora Flutter SDK.
If you’re new to Flutter, then install the Flutter SDK from here.
flutter create agora_group_calling
2. Navigate to your pubspec.yaml
file. In that file, add the following dependencies:
pubspec.yaml
Be careful with the indentation when adding the packages because you might get an error if the indentation is off.
3. In your project folder, run the following command to install all the dependencies:
flutter pub get
4. Once we have all the dependencies, we can create the file structure. Navigate to the lib folder and create a file structure like this:
To begin with, we navigate to main.dart
. Replace the template code with the following code:
This code just initializes your Flutter application and calls MyHomePage()
, which we defined in HomePage.dart
.
Continuing with our home page, we will be asking our users to enter a channel name. A channel name is a unique string that will put people with the same channel name in a single group call:
HomePage.dart
This will create a UI similar to the image on the left, which has an input field for the channel name and a join button. The join button calls a function onJoin
, which first gets the user’s permission to access their camera and microphone during the call. Once the user grants these permissions, we move to the next page, CallPage.dart
To ask the user for access to the camera and microphone, we use a package named permission_handler. Here I declare a function named _handleCameraAndMic(),
which I will be referring to in the onJoin()
function:
HomePage.dart — _handleCameraAndMic()
Now, in our onJoin()
function we create reference for the above function and then pass the channel name that the user submitted to the next page, CallPage.dart
Before we begin with our CallPage.dart, let’s use the App ID that we got from the Agora developer account. (Follow the instructions here to learn how to generate an App ID.) Navigate to AppID.dart in your utils folder and create a variable named appID.
var appID = '<--- Enter your app id here --->'
After this we move to our CallPage.dart and we begin by importing all the files.
importing the Agora SDK
Here I create a stateful widget called CallPage such that it’s constructor can read the channel name that the user submitted.
Then we declare some variables in our CallPageState, which we will use while making this page:
_users
is a list that contains the uid
of all the users that are in the channel._infoStrings
contains all the logs for all the events that occur during the call.muted
is a Boolean state variable to mute and unmute a user._engine
is an object for our RtcEngine classAgora CallPageState
We will create the initialize() function, such that it is a common call for all major functions. The main use of initialize() function is to initialize the Agora SDK. In the initialize function, I am creating the reference of the _initAgoraRtcEngine()
and _addAgoraEventHandlers()
functions:
_initAgoraRtcEngine()
is used as an instance of the Agora SDK. Initialize it using the App ID that you got from the Agora dashboard. We also use the enableVideo()
function to enable the video module. This function can be called before joining the channel or during a call. If you call it before joining the channel, then the call is by default launched in video mode. Otherwise, it launches the app in the audio mode, which can be switched to the video later if required._initAgoraRtcEngine()
_addAgoraEventHandlers()
is a function that takes care of all the major callback functions. So we begin with setEventHandler()
, which listens for engine events and receives the statistics of the corresponding RtcEngine.Some important callbacks include:
joinChannelSuccess()
is triggered whenever a local user joins the specified channel. It returns the channel name, the uid of the user, and the time elapsed (in ms) for the local user to join the channel.leaveChannel()
is the opposite of that because it is triggered when the user leaves the channel. It returns the stats of the call whenever the user leaves the channel. These stats include latency, CPU usage, duration, etc.userJoined()
is a method that is triggered when a remote user joins a particular channel. A successful callback returns the uid and the time elapsed of the remote user.userOffline()
is the opposite of that because it occurs when a user leaves the channel. A successful callback returns the uid and the reason for going offline, which includes dropping, quitting, etc.firstRemoteVideoFrame()
is a method that is called when the first video frame of a remote video is rendered. This helps you in returning the uid, the width, the height, and the time elapsed._addAgoraEventHandlers()
To end our initialize() function, we will be adding the joinChannel()
function. A channel acts as a common room for people to be in the same video call. This joinChannel() method can be called with something like:
joinChannel()
It takes four parameters to run successfully:
This sums up all the functions and methods required to make this video calling application. Now we can make our widgets, which will take care of the complete UI for our application.
Here I am declaring two widgets (_viewRows()
and _toolbar()
), which take care of displaying up to four users and adding buttons at the bottom for disconnecting, muting, and switching the camera.
build
Let’s start with _viewRows()
. For this we need to know the user and their uid for displaying their video. We need a common list of local and remote users with their uid. To implement this, we create a widget named _getRendererViews()
, in which we use RtcLocalView and RtcRemoteView.
Then we simply use expanded views using our widget called _videoView()
and put them in a row using the _expandedVideoRow()
widget.
Once we have our views structured properly, we will hard code the design using a switch case, which creates columns where views are stacked.
With this, you will have a complete video calling app implemented. Now, to add features like disconnecting the call, muting yourself, and switching the camera, we will create a basic widget called _toolbar() with three buttons:
Here we have declared three functions:
_onToggleMute()
lets you mute and unmute your stream. Here, we use the muteLocalAudioStream()
method, which takes a Boolean input to mute or unmute the stream._onCallEnd()
disconnects the call and takes the user back to the home page._onSwitchCamera()
lets you toggle between the front and the rear cameras. Here, we use the switchCamera() method, which helps you achieve the desired functionality.Once we are done building the group video calling application, we can test it on our device. To do that, navigate to your project directory in your terminal and run this command:
flutter run
Congratulations! You have implemented your own group calling application, which you built using the Agora Flutter SDK, with some basic functionality like muting the local stream, switching the camera, and disconnecting the call.
You can get the complete code for this application here.
To learn more about the Agora Flutter SDK and other use cases, you can refer to the developer guide here.
You can also have a look at the complete documentation for the functions discussed above and many more here.
I also invite you to join Agora Developer Slack Community.