Building a Flutter Video Call App with in-Call Statistics
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.
Setting Up Your Project
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 Flutter
permission_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 device
With 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:
- RTC Engine: Includes most of the real time communication functions
- RTC Local View: Includes a view of the current users camera
- RTC Remote View: Includes a view of the other user that joins the camera
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
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
Building the App
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:
- Request permissions for the camera and the microphone, if not already requested.
- Create the communication client.
- Set up a listener to any event change from the client.
- Enable video for the current device.
- Join the channel.
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
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 channel
userJoined: Gets triggered when a remote user joins the same channel that the current user is on
userOffline: Gets triggered when a remote user leaves the same channel that the current user is on
rtcStats: Gets triggered every two seconds and returns the statistics of the call
For 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
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.
Improving Your App
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:
- Flip the local camera and the remote camera.
- Let the user type in which channel they want to join.
- Show a connection-lost screen whenever you lose connection.
- Leave the call.
- Mute your microphone.
- Show the bigger camera for the user who is speaking loudest.
- Add more statistics to the app.
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
Agora Flutter resource: AgoraIO-Community/Agora-Flutter-Quickstart: Quickstart for Agora Flutter SDK(Android/iOS)
Agora documentation: Agora Developer Center
I also invite you to join the Agora.io Developer Slack community.