Blog Infos
Author
Published
Topics
,
Published

In this digital world, we want to stay connected with our friends and family.

The demand for video calling apps is increasing day by day.

we can build apps to stay connected using WebRTC.

The flow of the Article:

  1. What are WebRTC and PeerJS?
  2. Basics about WebRTC.
  3. Developing Video Calling App using Peer.js and WebViews in android.
What are WebRTC and PeerJS?

WebRTC stands for Web Real-Time Communication. WebRTC technology helps you to exchange video, audio, and arbitrary data with peers. WebRTC is supported in Web Browsers and native devices for native devices, you need to add webrtc libraries.

PeerJS is simply a wrapper around the browser’s webrtc implementation and using this we can add video and audio streaming support very easily. It abstracts all the hard tasks which we have to handle. We will be using WebViews for our purpose to call javascript code and rendering HTML.

Basics about WebRTC.

WebRTC works by establishing connections between peer to peer by using a set of protocols.

  1. Signaling: Signaling process helps set up and control the communication session. Signaling uses SDP(Session Description Protocol) protocol which is in plain text format that contains data about. a) Locations of peers(IP address of the peers). b) media type
  2. Connecting: In WebRTC, connections happen in a Peer-to-Peer manner not a client-server. It could be tough to connect two peers may be because of incompatibilities. This connection problem can be solved by using ICE, TURN, and STUN servers.
    a). ICE stands for Interactive Connectivity Establishment. It helps to find the optimal path to connect two peers so that data transfer can happen optimally.
    b). STUN stands for Session Traversal Utilities for NAT. It is a standard method used by NAT traversal. WebRTC client requests the STUN server to get the Public IP address.
    c). TURN stands for Traversal Using Relays around NAT. When it is not possible to use STUN. then services have to relay media streams through this server.
  3. Securing Data Exchange: Webrtc ensures security. It encrypts the data which is exchanged between peers. It uses two protocols SRTP and DTLS.
    a)SRTP stands for Secure Real-Time Transport Protocol. It is a secure version of RTP. The protocol provides encryption, confidentiality, message authentication, and replay protection to your transmitted audio and video traffic.
    b). DTLS stands for Datagram Transport Layer Security. DTLS is a protocol used to secure datagram-based communications. Ordered Delivery is not guaranteed and it has less latency.
  4. Exchanging Data: Using WebRTC we can transfer data, audio, and video streams. We use RTP and RTCP protocols for data transfer.
    a). RTP stands for the real-time transport protocol. It helps for real-time transmission of media streams.
    b). RTCP stands for real-time control protocol. The messages that can control the transmission and quality of data as well as also allow the recipients so they can send feedback to the source. A protocol designed for this purpose is RTCP.
Developing Video Calling App using Peer.js and WebViews in android.

Let’s start working on it.

Here is the GitHub link.

Step 1: Create a new Android Project.

Step 2: You need to add 4 files to your android project

Here is the link.

This is the place where you have to add files.

VideoCallDemo/app/src/main/assets/

Step 3: You need to add these permissions in Manifest.xml.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

I am using this dependency for handling permissions in jetpack compose.

implementation "com.google.accompanist:accompanist-permissions:0.27.1"
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalPermissionsApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainActivity = this
setContent {
val permissionState =
rememberMultiplePermissionsState(
listOf(
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
)
)
LaunchedEffect(key1 = true) {
permissionState.launchMultiplePermissionRequest()
}
if (permissionState.allPermissionsGranted) {
VideoCallCompose()
}
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

Step 4: We will create an XML file to use webView.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webView"
android:layout_width="374dp"
android:layout_height="612dp"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.491"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.078" />
</androidx.constraintlayout.widget.ConstraintLayout>

Now, we will add our XML file to our composable.

AndroidView(factory = {
val layoutInflater: LayoutInflater = LayoutInflater.from(it)
val view: View = layoutInflater.inflate(R.layout.activity_call, null, false)
view
}, update = { view ->
val webView: WebView = view.findViewById(R.id.webView)
webViewCompose = webView
webView.loadUrl(mUrl)
WebRTCUtil.setupWebView(webView)
})

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

Step 5: Now, create UI for the mic, video, and end call.

Column(verticalArrangement = Arrangement.Bottom, modifier = Modifier.fillMaxHeight()) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Image(
modifier = Modifier.clickable {
isAudio = !isAudio
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:toggleAudio(\"$isAudio\")"
);
},
painter = painterResource(id = if (isAudio) R.drawable.btn_mute_normal else R.drawable.btn_unmute_normal),
contentDescription = "audio"
)
Image(
modifier = Modifier.clickable {
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:disconnectCall()"
);
mainActivity.finish()
},
painter = painterResource(id = R.drawable.btn_endcall_normal),
contentDescription = "end"
)
Image(
modifier = Modifier.clickable {
isVideo = !isVideo
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:toggleVideo(\"$isVideo\")"
);
},
painter = painterResource(id = if (isVideo) R.drawable.btn_video_muted else R.drawable.btn_video_normal),
contentDescription = "video"
)
}
}

Step 6: Now, the VideoCallCompose

@Composable
fun VideoCallCompose() {
Scaffold(
content = { MyContent() }
)
}
@Composable
fun MyContent() {
val mUrl = "file:android_asset/call.html"
var isAudio by remember {
mutableStateOf(true)
}
var isVideo by remember {
mutableStateOf(true)
}
var webViewCompose: WebView? by remember {
mutableStateOf(null)
}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
) {
AndroidView(factory = {
val layoutInflater: LayoutInflater = LayoutInflater.from(it)
val view: View = layoutInflater.inflate(R.layout.activity_call, null, false)
view
}, update = { view ->
val webView: WebView = view.findViewById(R.id.webView)
webViewCompose = webView
webView.loadUrl(mUrl)
WebRTCUtil.setupWebView(webView)
})
Column(verticalArrangement = Arrangement.Bottom, modifier = Modifier.fillMaxHeight()) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Image(
modifier = Modifier.clickable {
isAudio = !isAudio
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:toggleAudio(\"$isAudio\")"
);
},
painter = painterResource(id = if (isAudio) R.drawable.btn_mute_normal else R.drawable.btn_unmute_normal),
contentDescription = "audio"
)
Image(
modifier = Modifier.clickable {
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:disconnectCall()"
);
mainActivity.finish()
},
painter = painterResource(id = R.drawable.btn_endcall_normal),
contentDescription = "end"
)
Image(
modifier = Modifier.clickable {
isVideo = !isVideo
WebRTCUtil.callJavaScriptFunction(
webViewCompose!!,
"javascript:toggleVideo(\"$isVideo\")"
);
},
painter = painterResource(id = if (isVideo) R.drawable.btn_video_muted else R.drawable.btn_video_normal),
contentDescription = "video"
)
}
}
}
}

Now, as you can see there is a method we are calling callJavaScriptFunction() using this we will call js methods like toggleAudiotoggleVideostartCall, and disconnect.

We are loading the call.html file in webView.

You need to pass uniqueId to init() javascript method. you need to call startCall() javascript method and pass the uniqueId of the remote peer for that you need to store the uniqueId in a backend and fetch that id from there.

For simplicity purposes. I will not store it in the backend as the main purpose is to show how to use webView and peer.js in android.

Using the UI.

First, click on Create Room. It will generate a unique Id.

Now, on the second phone in the text field put that peer id and click Join Room.

I have not added any validation in the UI. So try adding the correct id.

Now, Join/Create a Room.

As You can see I have connected with two devices and video calling is working.

Thank You For Reading.

This article was originally published on proandroiddev.com on December 08, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
WebView is an essential component in Android for displaying web content in mobile apps.…
READ MORE
blog
When I first released my open-source certificate transparency library for Android and the JVM,…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu