Mesibo Voice and Video Call APIs - Secure and end-to-end encrypted calling
Mesibo provides a set of powerful voice and video call APIs to add secure & end-to-end encrypted voice and video calling into your apps. The mesibo call APIs are easy to use, and in just a few lines of code, your app will be able to make and receive secure voice and video calls. Mesibo calls are secure and end-to-end encrypted. Mesibo also provides ready to use and open-source user-interface (UI) with all the features you can find in any commercial app so that you can add voice and video calling in your app without any coding.
Quick Start with Mesibo Video and Voice Call APIs
If you do not plan to modify the default user interface, you can copy the following two lines of the code and stop reading further. It's that easy! You only need to initialize once which will automatically handle incoming calls. For outgoing calls, invoke call API as required. Note that, mesibo maintains the same API signatures across all the supported platforms as far as possible which makes it easy for you to write code on one platform and then port it on another.
One time initialization
MesiboCall.init(context);
To make a video call
MesiboCall.getInstance().callUi(this, profile, true);
To make a voice call
MesiboCall.getInstance().callUi(this, profile, false);
One time initialization
MesiboCall.getInstance().init(applicationContext)
To make a video call
MesiboCall.getInstance().callUi(this, profile, true)
To make a voice call
MesiboCall.getInstance().callUi(this, profile, false)
One time initialization
MesiboCall.start(with: nil, name: "mesibo first app", icon: nil, callKit: true)
To make a video call
MesiboCall.getInstance().callUi(self, profile: mProfile, video: true)
To make a voice call
MesiboCall.getInstance().callUi(self, profile: mProfile, video: false)
One time initialization
[MesiboCall startWith:nil name:@"mesibo first App" icon:nil callKit:YES];
To make a video call
[MesiboCallInstance callUi:self profile:mProfile video:YES];
To make a voice call
[MesiboCallInstance callUi:self profile:mProfile video:NO];
One time initialization
MesiboUI _mesiboUi = MesiboUI();
To make a video call
_mesiboUi.call(profile, true);
To make a voice call
_mesiboUi.call(profile, false);
IMPORTANT - Secure https website is required
- You MUST use a secure website (https) to use mesibo javascript. It may NOT work from
http://
orfile://
sites due to browser security restrictions.- You MUST also use a valid certificate with recognized authority, the self-signed certificate will NOT work.
The browser will not grant the camera and microphone permissions unless your app meets the above requirements. If permissions are not granted, calls and conferencing will not work.
These restrictions are by the browsers and NOT by the mesibo. Refer Security section in the Mozilla documentationopen_in_new for more information.
Setup video views
<div class="row" style="background-color: #f1f1f1;">
<div class="col-6" style="padding: 10px;">
<video id="localVideo" playsinline autoplay muted></video>
</div>
<div class="col-6" style="padding: 10px;">
<video id="remoteVideo" playsinline autoplay></video>
</div>
</div>
<audio id="audioPlayer" autoplay="autoplay" controls="controls" style="visibility:hidden;">
</audio>
To make a video call
api.setupVideoCall("localVideo", "remoteVideo", true);
api.call(demo_destination);
To make a voice call
api.setupVoiceCall("audioPlayer");
api.call(demo_destination);
In iOS, ensure that the background modes “Audio, AirPlay and Picture in Picture” and "Voice Over IP" are enabled.
Source code and the Sample code
We recommend looking at Android, iOS, and Javascript sample codeopen_in_new to quickly get started with Mesibo Calls and other APIs. Refer to the Download page for download instructions for your platform.
However, if you plan to customize the user interface, the entire source code is available on GitHub that you can modify to suit your needs. You should continue reading this document before you modify the source code.
Understanding Mesibo Call Architecture in Detail
There are two key components to the Mesibo Call architecture:
Mesibo Call Processing API: The Call processing API handles the entire call processing, including incoming and outgoing call establishment, reconnection, quality, bitrate control, and other control functionalities like muting audio/video, selecting cameras, filtering/blocking calls, etc. The call processing API runs in the background and does not provide any UI. You can even create a headless application(without any UI) using the Call API. You can control the call behavior (for example, video size, bitrate, etc.) using the call properties.
Mesibo Call User Interface (UI): The Call user interface (UI) component uses Mesibo call processing API to control the call and show the call information, for example, local and remote video screens, call ringing, call timer, buttons, etc. The entire Call UI source code is available on GitHub, which you can modify to suit your needs or use it as it is.
Mesibo Call component follows Model-View-Controller (MVC) architecture where call API represents model/controller, and the UI represents the View.
Key components in the Call API
Following are the key components in the Call API:
- MesiboCall, The Entrance class to the Call API. It provides various functions to initialize call APIs, setting up listeners, creating call objects, etc.
- IncomingListener, to Handle incoming calls, errors, show call UI, etc. You only need to implement this listener if you plan to customize the default call behavior.
- CallProperties, to define various call properties and behavior, for example, video size, bitrate, hide on proximity, etc.
- Call, the core call API.
- InProgressListener, Handle various call events for an ongoing call, for example, call ringing, answered, declined, hang up, audio device changed, etc. It is optional to implement this listener.
These components are described in detail in the following subsections.
Initializing the Call API
You can use mesibo call modules with default call handling logic and UI as it is. All you need to do is to intitalize mesibo calls, with a single line of code.
For example, In Android, you can initialize mesibo calls like, similarly for other platforms.
MesiboCall.init(context);
After initializing mesibo calls, you will be able to make outgoing calls and receive incoming calls using various methods in the Call API. In the upcoming sections, you will learn more about using the Call API.
Listening to incoming calls and customizing - IncomingListener
By default, mesibo handles incoming calls for you without any effort from your end. However, if your app requires to alter the call properties (say, video resolution, bandwidth, etc.), OR to launch a custom user interface, your app will need to implement an IncomingListener. We recommend that you implement this listener interface in MainApplication in Android or AppDelegate in iOS. However, you can implement it wherever it suits your application architecture.
Every time there is a new incoming call, mesibo will call
MesiboCall_OnIncoming. Depending on your app logic, you can decide to allow the incoming call or filter it. For example, perform call filtering at the application level to reject callers who are blocked/identified as spam, etc. If you decide to allow the call, you need to create a
CallProperties object and return it. In the CallProperties
object, you can set the video resolution, video/audio bitrate, etc. Mesibo sets the default values for the call properties, but you can override it as required by your app. To reject an incoming call, return null.
For example, in Android,
@Override
public MesiboCall.CallProperties MesiboCall_OnIncoming(MesiboProfile profile, boolean video){
// In this example, we use video as a filter to accept video calls only
if(!video)
return null; //Accept video calls only
if(profile.address == null || profile.address.isEmpty())
return null;
// your app specific function to check if the caller is allowed
if(isInBlockedList(profile.address)){
// Check if the caller is part of the blocked list.
// You can block spam callers this way.
return null; // reject the call by returning null
}
// Define call properties
MesiboCall.CallProperties cp = MesiboCall.getInstance().createCallProperties(true);
// Define optional parameters
cp.video.bitrate = 2000; //bitrate in kbps
return cp;
}
Similarly for other platforms. Refer to MesiboCall_OnIncoming in the API Reference.
If the call is accepted, mesibo prepares the call API object and invokes MesiboCall_OnShowUserInterface listener to show the user-interface. Your application should return true to show your custom user-interface or return false to show the mesibo default call user-interface.
For example, in Android,
boolean MesiboCall_OnShowUserInterface(Call call, CallProperties properties)
{
// Show call screen
return false;
}
Refer MesiboCall_OnShowUserInterface.
You also need to implement MesiboCall_OnError which will be called if any error occurs during a call and #mesibocall_onnotify which you can use to display call notifications for missed calls, etc.
Refer to IncomingListener in the API reference.
Call Properties - CallProperties
CallProperties
defines various aspects of a call such as,
- Voice or Video Call
- The initial video source, for example, front camera, back camera, screen capture
- The initial audio device, for example, speaker
- Video resolution
- Audio / Video bitrates
- Call behaviors, for example, automatically mute camera when app goes to background, handling proximity sensor, etc.
- and more...
There are default values for various call properties. However, you can modify them to suit your needs.
You need to create a CallProperties object for outgoing calls and pass it to the method MesiboCall.call(). If the outgoing call is successful, it will return a Call object( which you can use in your Activity/Fragment or View Controller).
For example, in Android,
MesiboCall.Call mCall = MesiboCall.getInstance().getActiveCall();
if(mCall == null){
...
// Create Call Properties
MesiboCall.CallProperties cp = MesiboCall.getInstance().createCallProperties(true);
cp.video.enabled = true; //create a Video call
cp.user = new MesiboProfile();
mCall = MesiboCall.getInstance().call(cc);
if(mCall == null){
//Call failed
}
}
In case of an incoming call, MesiboCall_OnIncoming will be called. Here, you should create and return a CallProperties object. If your app does not implement IncomingListener, mesibo will create CallProperties object with the default values.
For example, in Android,
@Override
public MesiboCall.CallProperties MesiboCall_OnIncoming(MesiboCall.Call call, MesiboProfile profile, boolean video) {
// call object will created by mesibo for you
// Initialize call properties
cp = MesiboCall.getInstance().createCallProperties(true);
// use default values
return cp;
}
Refer to CallProperties in the API reference.
Creating the core Call API object - Call
The Call
class is the most important class that handles the entire call processing for your app. To manage any call (incoming or outgoing), you need a Call
object.
There is no Call
constructor available. Instead, you need to call a factory method MesiboCall.call()
to create an instance of the Call
object. Using this factory method ensures that no call object is created if another call is in progress.
In case of an outgoing call, you need to create a
CallProperties object, and pass it to
MesiboCall.call(). If the outgoing call is placed successfully, MesiboCall.call()
will return a Call
object.
In case of an incoming call, mesibo will create a Call object and pass it to you in the MesiboCall_OnShowUserInterface callback.
You can access the Call
object anytime, by calling
getActiveCall(). Before you make an outgoing call, it is recommended that you use isCallInProgress()
or getActiveCall()
to check if there is an ongoing call. If there is no ongoing call, getActiveCall()
will return null
.
MesiboCall.Call mCall = MesiboCall.getInstance().getActiveCall();
if(mCall == null){
//There is no active call
//We can make an outgoing call
//Create a CallProperties object
MesiboCall.CallProperties cp = MesiboCall.getInstance().createCallProperties(true);
// Call Factory method to create a call object
mCall = MesiboCall.getInstance().call(cp);
if(mCall == null){
//Error
}
}
Refer to Call in the API reference.
Monitoring a Call - InProgressListener
The InProgressListener is invoked by mesibo call API for various events such as - change in call status (ringing, answered, etc.), when remote peer mutes, when the active audio device changes from an earpiece to a speaker, etc. You can implement InProgressListener in your user interface to get continuous feedback on what is happening on the call to update your user interface or take any actions based on this information, for example,
- If the call is ringing, MesiboCall_OnStatus will be called. You can update your user interface or play a ringing sound or a custom caller tune.
- When the call is answered, you can start a call timer and update the user interface.
- When active audio device changes, MesiboCall_OnAudioDeviceChanged will be called. If it is a speaker you may choose to highlight the speaker button.
- Etc.
Refer to InProgressListener in the API reference for more details.
In the next section, we will discuss some of the fundamental concepts of designing a good calling app.
Essentials of a Calling App
This section will describe the essentials of a call app and how to use mesibo voice and video call APIs to create one such app.
Designing your Call Screens
In a typical call application, the call screen is one of the most important steps in the design flow. Although mesibo allows you to design your user interface as you like, it is essential to remember that users are accustomed to a particular way of handling calls. Hence, it is recommended to follow standard practice when designing call screens.
There are typically two types of call screens.
Incoming Screen, which allows the user to know the caller, type of the call (voice or video), and controls to accept or decline the call.
InProgress Screen, the screen is shown after the incoming call is accepted or for an outgoing call. The Inprogress screen typically has buttons to hangup, change audio devices, muting, hang up, timer, etc. If the call is of type video, it may have additional controls for remote and local video views, camera controls (only for video calls), etc.
Following are some examples of typical Incoming and Inprogress screens:
Incoming Screen
Inprogress Screen
Mesibo makes it easy for you to design a calling screen by invoking necessary callbacks as the call progresses. For example, MesiboCall_OnUpdateUserInterface
will be called depending on the call status, which you can use to change UI on the fly as the call progresses, MesiboCall_OnMute
is called when the remote user mutes the video or voice, etc.
Request Microphone and Camera Permissions
Mesibo Call API requires a microphone and camera (only for video calls) access to make and receive calls. Hence, your app should have permission to access the microphone and the camera. Both Android and iOS requires you to prompt the user for necessary permissions at run-time, microphone for voice calls, and microphone+camera for video calls.
You can use Android or iOS API calls to request necessary permissions, OR you can use the mesibo helper function checkPermissions
, which simplifies the handling of required permissions.
checkPermissions
Mesibo provides checkPermissions
, a function that you can use to request and check for permissions. It takes the following parameter:
- video, Set to true if requesting permissions for a video call, false otherwise
Returns:
0
if the user granted all permissions1
if the app is prompting the user for permissions- A negative value if the user declines the permissions.
For example, in Android,
//Request permissions necessary for a video call
int res = checkPermissions(true);
if(res < 0) {
/* permissions were declined */
}
if(0 == res) {
/* all permissions granted */
}
In the upcoming sections, we will describe how to make outgoing calls and receive calls. We will explain how mesibo handles outgoing and incoming calls. We will then explain how your app should handle outgoing and incoming calls with the Call API's help.
How Mesibo handles an Outgoing Call
Mesibo handles an outgoing call as follows:
- The App invokes MesiboCall.call() to place an outgoing call.
- Mesibo checks if there is any call in progress (an active call on the application or the phone).
- If there is any call in progress, the outgoing call fails. If there are no other active calls, mesibo returns a call object.
- The app initiates an outgoing call by calling MesiboCall.start().
- If the destination answers the call, the call continues.
- If either of the parties on the call hangs up, the call is completed and MesiboCall_OnHangup will be called.
How the app should initiate an Outgoing Call
In a typical application flow, the user presses a button to place an outgoing call. The app then displays a screen showing an outgoing call and other information like the destination’s profile, the phone number or address, etc.
However, before the app launches a call screen, it should check if there is no call is in progress.
Check for any active calls
Before making an outgoing call, we need to be sure that there are no other ongoing calls. If getActiveCall() returns null then we are free to make a new call by creating a Call object.
MesiboCall.Call mCall = MesiboCall.getInstance().getActiveCall();
if(mCall == null){
//There is no active call
//We can make an outgoing call
}
Once the app launches the call screen, the app can create a call object and initiate the outgoing call.
Initialize CallProperties
To make an outgoing call, the app needs to create a CallProperties object. See CallProperties for a complete list of properties that you can set for a call.
Then pass the CallProperties
to
MesiboCall.call() method, which will then return a Call
object. Invoke start()
on the call object to initiate the call.
For example, in Android,
MesiboCall.Call mCall = MesiboCall.getInstance().getActiveCall();
if(mCall == null){
//There is no active call
//We can make an outgoing call
MesiboCall.CallProperties cp = MesiboCall.getInstance().createCallProperties(false);
// When using an Activity
cp.parent = this;
cp.activity = this;
cp.video.enabled = true; //make a video call
cp.user = profile;
mCall = MesiboCall.getInstance().call(cp);
if(mCall == null){
//Alert user about the error.
}
}
else {
// Alert user that another call is ongoing or show UI for that call
}
After initiating an outgoing call, we display the Inprogress screen. The call screen can then update the UI based on various callbacks in the InProgressListener
.
How Mesibo handles an incoming call
- The mesibo user logged in on the application receives an incoming call from another mesibo user.
- Mesibo checks if there is any call in progress (a call active on the application or the phone).
- If there is any call in progress, a busy status is sent to the caller. If there are no other active calls, MesiboCall_OnIncoming will be called with the profile of the caller(contains the caller's address, photo, etc).
- The application should create, initialize, and return a
CallProperties object from
MesiboCall_OnIncoming. To reject the call,
MesiboCall_OnIncoming should return
null
. - If CallProperties is initialized, Mesibo creates a Call object.
- MesiboCall_OnShowUserInterface is called with the Call object and the CallProperties object, initialized in the previous step as parameters.
- The application should now show the incoming call UI. Display the Call screen with the Answer and Hangup button. See How app should handle an incoming call.
- If the user accepts the call, mesibo will continue the call. If the user declines the call, the call ends, and mesibo informs the caller that the user is busy.
- As the call progresses, listeners in InProgressListener will be invoked for various events.
- If either of the parties on the call hangs up, the call is completed, and mesibo calls MesiboCall_OnHangup.
How the app should handle an incoming call
Follow the steps below to handle an incoming call:
- Implement MesiboCall_OnIncoming. It will be called whenever there is an incoming call.
- Initialize and return
CallProperties
inMesiboCall_OnIncoming
. - Implement MesiboCall_OnShowUserInterface. When this listener is called, launch the incoming call screen.
- The user can then accept or decline the incoming call. If the user accepts the call, the call continues. Display the call in progress screen.
- Implement listeners in InProgressListener and update the Call UI for events.
Initialize CallProperties in MesiboCall_OnIncoming
Mesibo provides
MesiboCall_OnIncoming as part of the listener interface, MesiboCall.IncomingListener
. If you implement MesiboCall_OnIncoming
, it will be called whenever there is an incoming call.
To handle the incoming call, you need to return a
CallProperties object from MesiboCall_OnIncoming
. The CallProperties
can define various aspects of the call, such as the call title, video width, bitrate, etc., that you can modify as per your needs. Refer to
CallProperties for a complete list of the various properties that you can set.
For example, in Android,
@Override
CallProperties MesiboCall_OnIncoming(MesiboProfile profile, boolean video){
MesiboCall.CallProperties cc;
cp = MesiboCall.getInstance().createCallProperties(video);
cp.video.enable = true; // Video call
cp.video.bitrate = 1800; // Set Maximum video bitrate
cp.video.codec = MesiboCall.MESIBOCALL_CODEC_H265;
return cc;
}
After you return a valid CallProperties object, Mesibo will invoke MesiboCall_OnShowUserInterface with the Call object and CallProperties object as parameters.
For example, in Android,
@Override
boolean MesiboCall_OnShowUserInterface(MesiboCall.Call call, MesiboCall.CallProperties properties){
//launch Call Screen
}