Doraemon’s Gadget

Step by Step Guide to Build WebRTC Native Android App

Shivam Maindola
5 min readMay 16, 2020

--

I’m writing this during the lockdown. Earlier I was thinking about what should I do productive in this lockdown then I came up with an idea of video calling an android app. I think Video calling will be the next revolution in every industry. Every other app will integrate this feature and use it according to their requirements, in view of this, I’ve tried to implement a video calling android app using WebRTC technology.

Every time I search for “WebRTC tutorial for Android”, I could not find anything that is almost useful and complete for the Android native app(Or maybe, I should work on my Googling skills).

So here I am, set out to do a tutorial series on my own (with little to all help from Google, of course). This tutorial is hugely based on the codelabs for WebRTC. This codelab is for browsers only. Google should provide codelab tutorial for android too or google should make my tutorial their codelab(just kidding). Codelabs is a great place to get started with WebRTC for browsers. This article will be porting the same experience for native Android.

What you’ll learn

You’ll get to know about the following things(if you know, you know).

  1. WebRTC
  2. Socket.io
  3. NodeJs
  4. Heroku

Let’s start-

Basically, there are not that many steps involved. You need to display local video on your phone, send it to another device, receive remote video/audio, and play them.

Display local video

For displaying video I have SurfaceViewRenderer which extends SurfaceView and implements VideoRenderer.Callbacks. And PeerConnectionFactory from WebRTC library handles creating audio/video streams. If you want

The steps to display a video stream from the camera to view are,

  1. Create and initialize PeerConnectionFactory
  2. Create a VideoCapturer instance that uses the camera of the device
  3. Create a VideoSource from the Capturer
  4. Create a VideoTrack from the source
  5. Create a video renderer using a SurfaceViewRenderer view and add it to the VideoTrack instance.

Connect two peers

WebRTC uses RTCPeerConnection to communicate streaming data between browsers (aka peers) but also needs a mechanism to coordinate communication and to send control messages, a process known as signaling. Signaling methods and protocols are not specified by WebRTC: signaling is not part of the RTCPeerConnection API.

In short- Two peers are connected through the signaling server. The signaling server helps to exchange information on both the clients. In this tutorial, we’ll make a signaling server using socket.io and NodeJs and deploy it in Heroku.

Don’t worry, everything is easy.

Let us first understand the signaling process.

Signaling

We’ll take the example of Nobita and Shizuka(Those who know them- your childhood was amazing).

Suppose Nobita and Shizuka want to communicate with each other. Nobita asked Doraemon to give him a gadget for communication. So, he introduced the WebRTC video calling app. Before giving it to Nobita, Doraemon explains the whole process.

Suppose Nobita and Shizuka exchange network information. (The expression ‘finding candidates’ refers to the process of finding network interfaces and ports using the ICE framework).Following steps to be followed.

  1. Nobita creates an RTCPeerConnection object with an onicecandidate handler.
  2. The handler is run when network candidates become available.
  3. Nobita sends serialized candidate data to Shizuka, via whatever signaling channel they are using: WebSocket or some other mechanism.
  4. When Shizuka gets a candidate message from Nobita, he calls addIceCandidate, to add the candidate to the remote peer description.

WebRTC clients (known as peers, aka Nobita and Shizuka) also need to ascertain and exchange local and remote audio and video media information, such as resolution and codec capabilities. Signaling to exchange media configuration information proceeds by exchanging an offer and an answer using the Session Description Protocol (SDP):

  1. Nobita runs the RTCPeerConnection createOffer() method. The return from this is passed an RTCSessionDescription: Nobita’s local session description.
  2. In the callback, Nobita sets the local description using setLocalDescription() and then sends this session description to Shizuka via their signaling channel. Note that RTCPeerConnection won't start gathering candidates until setLocalDescription() it is called: this is codified in JSEP IETF draft.
  3. Shizuka sets the description Nobita sent him as the remote description using setRemoteDescription().
  4. Shizuka runs the RTCPeerConnection createAnswer() method, passing it the remote description he got from Nobita, so a local session can be generated that is compatible with hers. The createAnswer() callback is passed an RTCSessionDescription: Shizuka sets that as the local description and sends it to Nobita.
  5. When Nobita gets Shizuka’s session description, she sets that as the remote description with setRemoteDescription.
  6. Ping!

Nobita didn’t understand anything.

JSEP Architecture

Once the signaling process has been completed successfully, data can be streamed directly from peer to peer, between the caller and callee — or if that fails, via an intermediary relay server. Streaming is the job of RTCPeerConnection.

docall() function is to initiate a call. Nobita’s side.

private void doCall() {
MediaConstraints sdpMediaConstraints = new MediaConstraints();

sdpMediaConstraints.mandatory.add(
new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
sdpMediaConstraints.mandatory.add(
new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
peerConnection.createOffer(new SimpleSdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d(TAG, "onCreateSuccess: ");
peerConnection.setLocalDescription(new SimpleSdpObserver(), sessionDescription);
JSONObject message = new JSONObject();
try {
message.put("type", "offer");
message.put("sdp", sessionDescription.description);
sendMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, sdpMediaConstraints);
}

doAnswer() function is for answering. Shizuka’s side.

private void doAnswer() {
peerConnection.createAnswer(new SimpleSdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
peerConnection.setLocalDescription(new SimpleSdpObserver(), sessionDescription);
JSONObject message = new JSONObject();
try {
message.put("type", "answer");
message.put("sdp", sessionDescription.description);
sendMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new MediaConstraints());
}

setMessage function sends the information to the server.

private void sendMessage(Object message) {
socket.emit("message", message);
}

There are many things to explain, you can read all about them from here and here.

Now, Let’s start the tutorial.

Android Studio Side

  1. Download the android project from here.
  2. Open VideoWebRTC app in android studio.

Server Side

We’ll make a server using socket.io and NodeJs and deploy the same in Heroku.

Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.

You can download the code from here. This code is taken from codelab.

Now do the following steps to set up your server.

  1. First, download NodeJs from here.
  2. Open CMD and change the directory to your SignallingServer folder.
  3. Type this command.
install npm

4. Run index.js.

node index.js

5. Open browser and type localhost:8080 in URL. You will see that your server is running. Congrats, you’ve set up your server locally. Now to use it in your android app you have to make it live using Heroku.

Deploy on Heroku

  1. Make an account on Heroku.
  2. Download Heroku CLI for git from here.
  3. Now enter the following commands one by one to deploy.
git add .
git commit -m "initial commit"
heroku login
heroku create
git push heroku master

4. You will get a URL of a server.

5. Add that URL inside the socket function in your CompleteActivity.

private void connectToSignallingServer() {
try {
socket = IO.socket("https://calm-badlands-59575.herokuapp.com/");

6. Now run your app in android studio and test it. You can test it using a web browser(open server URL as a client) or another android phone (as 2nd client).

Voila, You finally made a one-to-one video calling app.

Claps for yourself and me too.

GitHub repo is here- https://github.com/shivammaindola/AndroidWebRTC

--

--