When the pandemic hit in 2020, remote communication became an even more vital part of the way we communicate. Clearly, remote communication will continue to be a big part of our future. Adding video call capabilities to your current app will allow users to stay on your app longer, help connect the users to connect to one another, and increase the value that your app provides. This is where Agora comes in. Using the Agora Flutter SDK, which can be installed with a plugin from pub.dev, you can connect people via voice, video, and other mediums.
In this article, we will cover how to create a simple video call application with in-call statistics. Agora can do much more, but many of us learn best by something very basic and building up from that.
The very first thing you will need is:
For this project, we will be working with only the main file. The next step for any Flutter project is running
flutter create agora_project
Once you have the project ready, you will need to add the necessary packages into the pubspec.yaml file.
agora_rtc_engine
: A wrapper for the Agora SDK that is made for Flutterpermission_handler
: Assists with checking whether permissions are granted for using the camera and the microphone for this app but can be used for any other permissions on the deviceWith these packages added, your dependencies should look like this:
After you have Agora imported into your project, you can include all the imports that you will need to use inside the actual project. From Flutter, we will use the material library that is provided by Flutter for our UI. Then from Dart, we will need to use the async library since a lot of the methods we will be using rely on Futures (we will call the Agora SDK and will need to wait for a response). The other imports are from Agora and the permissions handler.
Agora will be using three imports:
The top of the file should look like this:
The last preparation step will be to get the appId and the token so we can use Agora securely. For this project, we will use a temporary token. The first step is to create an Agora project. Once it is created, go to edit. There you will find your appId, and you can generate a temporary token. In your app, create global variables named appId
and token
and set them to the values retrieved from Agora.
Note: This project is meant for reference purposes and development environments. It is not intended for production environments. Token authentication is recommended for all RTE apps running in production environments. For more information about token-based authentication in the Agora platform, see this guide: https://bit.ly/3sNiFRs
Now all the preconditions are set up, and we are ready to jump to the actual code. Once again, we will be using one file to keep things as simple as possible. We will start with a simple stateful widget layout with a Scaffold
inside a Material App
like this:
The initState is a key part of this app because that is where we will need to check the permissions and initialize all the things necessary for Agora video calls to work. The following things will happen in our app initialization, but they can occur happen at any point when you need to use the Agora SDK:
Before we start anything else, let’s deal with the permissions. Without permissions to the microphone and the camera, we can’t make any video calls.
The main thing we will be using to do all of the logic within our application is the Agora communication engine. In order to use it, we will need to create an instance of the engine and initialize it with the App ID that we created inthe Agora Console. We set that App ID to a variable called appId
.
Next comes the main logic within the app: the event handler for any events that occur on the engine. To do this, we call the setEventHandler
method on the engine and we can define what we want to happen on specific events. Agora supports a huge list of events, but we are going to use only four of them for our simple app:
joinChannelSuccess
: Gets triggered when the current user of the app successfully joins a channeluserJoined
: Gets triggered when a remote user joins the same channel that the current user is onuserOffline
: Gets triggered when a remote user leaves the same channel that the current user is onrtcStats
: Gets triggered every two seconds and returns the statistics of the callFor these four methods, we are going to set some local variables: first, a boolean to tell us whether the current user has successfully joined (_localUserJoined
); then an integer for the user ID of the remote user who joins the channel (when the user leaves the channel we will set this id back to null
); and finally, we will update our local stats variable every two seconds with fresh information.
The last thing we will do during the initialization is enable video on the engine and have the current user join the channel which we will call firstchannel
. In order to successfully join the channel we will need to pass the token we created earlier and stored into a variable called token
.
We can’t do all these functions within the actual initState
, however. The initState
will have to call another function because initState
cannot be asynchronous. So we need to create another function. Let’s call it initForAgora. Inside the initForAgora
, we can add all the code we had above. The portion outside of our build method should look like this:
All the logic for the app is completed. Now, the fun part is displaying the video and stats for the user and seeing it all work together. We will keep the UI as minimalist as possible. Inside the Scaffold
widget, we will display a simple Stack
. On the bottom layer of the Stack
will be a big view of the other user’s live camera. In the top-left corner we will have the current user’s camera, which is similar to all the video call app layouts. To display the current user’s video we will use RtcLocalView.SurfaceView()
, which is retrieved from the import we got in the setup, and and the remote user’s video from RtcRemoteView.SurfaceView(uid: _remoteUid)
, where we pass in the uid for the specific user’s camera.
Then for showing the statistics of the call we will use the floatingActionButton
parameter of the Scaffold
to display either a button with the text “Show Stats” or the actual statistics of the call, depending on whether the button has been clicked or not. The statistics view is pretty simple. If the data is null we will show a loading indicator. If we have data, the view shows a column of just a couple of the stats that we have available and then a button to close out of this view and return to the “Show Stats” button.
So our complete build function looks like this:
There we go. That is a complete working video call app in ~100 lines of Flutter code.
We made the app very simple so that it is easy to understand. However, with Agora, you can improve it very easily. Here are a couple of quick suggestions you can try to implement:
The Agora Flutter plug-in makes it so simple to implement video calls with in-call statistics in your Flutter app. Using the base we have created in this article, you can build up a fully functioning video call app. Or you can just add it to your existing app to help users connect to one another. Agora features some really great documentation as well as articles that will help guide you through learning how to use the SDK. Go give it a shot!
Link to code: https://github.com/tadaspetra/agora-video-call