DEV Community

ajitha-zoom
ajitha-zoom

Posted on • Updated on

Getting Started with Zoom's Android Video SDK

Introduction

The Zoom Video SDK for Android allows you to build custom video meeting applications with access to raw video and audio data, enabling highly-interactive, custom user experiences. When we say "custom", it lets you customise almost everything to cater your needs. It helps you build the product with your brand.

The goal of this article is to get you started with Video SDK in Android platform. We'll cover:

  • SDK contents
  • Pre-requisites
  • JWT Authentication
  • Project structure
  • Init SDK & Join/Leave Session
  • Video, Audio, & Screen-Share Functionality

SDK contents

There are three .aar files packaged in the Android SDK downloaded from Zoom marketplace.

  • mobilertc.aar : Consists of Zoom UI components
  • video-effects.aar: Used when you implement Virtual Background feature
  • zm-annoter.aar: Used when you use annotation service

In our project, I will be using "java" as the primary language of coding. We shall be demonstrating the basic abilities like audio, video and screenshare and hence I will be importing only the mobilertc.aar package as a module in main project.

Pre-requisites

To build the app, you must have:

  • Zoom Video SDK package for Android downloaded from marketplace
  • Android Studio
  • SDK Key and secret values
  • A physical Android device with Android API Level 21+
  • Experience building Android Apps

Note: This tutorial is built on top of v1.8.5 in Java.

JWT Authentication

JWT authorisation is used in the SDK. The payload information is provided here.

To begin with, let's construct the JWT token using a webapp and invoke the HTTP POST request in our Android application. It is advisable to host the JWT token server in your own web server due to security reasons. The webapp code looks like below.

app.post('/', (req, res) => {

  const iat = Math.round(new Date().getTime() / 1000) - 30;
  const exp = iat + 60 * 60 * 2

  const oHeader = { alg: 'HS256', typ: 'JWT' }

  const oPayload = {
    app_key: process.env.ZOOM_VIDEO_SDK_KEY,
    tpc: req.body.sessionName,
    role_type: req.body.role,
    user_identity: req.body.userIdentity,
    session_key: req.body.sessionKey,
    geo_regions: req.body.geoRegions,
    cloud_recording_option: req.body.cloudRecordingOption,
    cloud_recording_election: req.body.cloudRecordingElection,
    version: 1,
    iat: iat,
    exp: exp
  }

  const sHeader = JSON.stringify(oHeader)
  const sPayload = JSON.stringify(oPayload)
  const signature = KJUR.jws.JWS.sign('HS256', sHeader, sPayload, process.env.ZOOM_VIDEO_SDK_SECRET)

  res.json({
    signature: signature
  })
})
Enter fullscreen mode Exit fullscreen mode

The complete web app code is located here: https://github.com/ajitha-zoom/videosdk-demo-endpoint

Let us now invoke the HTTP POST api from our Android application using following payload. The response shall have the JWT signature.

    private String JSON_PAYLOAD = "{\"sessionName\":\"" + SAMPLE_SESSION_NAME +
            "\",\"role\":" + SAMPLE_ROLE +
            ",\"userIdentity\":\"" + SAMPLE_USER_IDENTITY +
            "\",\"sessionKey\":\"" + SAMPLE_SESSION_PWD +
            "\",\"geoRegions\":\"US,AU,CA,IN,CN,BR,MX,HK,SG,JP,DE,NL\"," +
            "\"cloudRecordingOption\":1,\"cloudRecordingElection\":0}";
Enter fullscreen mode Exit fullscreen mode

The response shall be parsed as shown below to retrieve the JWT signature

JSONObject jsonObject = null;
try {
    jsonObject = new JSONObject(result);
} catch (JSONException e) {
    throw new RuntimeException(e);
}]

// Retrieve the "signature" parameter
String signature = jsonObject.optString("signature");
jsa.onPostExecution(signature);
Enter fullscreen mode Exit fullscreen mode

Project structure

To create a new project,

  • Open Android studio
  • File -> New -> New Project -> Choose "No Activity"
  • Choose Language as "java" and Build configuration as "Groovy DSL" and press "finish"
  • Create a new folder "mobilertc" and place the mobilertc.aar package inside the folder. Also copy the following contents inside mobilertc/build.gradle
configurations.create("default")
artifacts.add("default", file('mobilertc.aar'))

dependencies.add("default","androidx.security:security-crypto:1.1.0-alpha03")
dependencies.add("default","com.google.crypto.tink:tink-android:1.5.0")
dependencies.add("default","androidx.appcompat:appcompat:1.3.0")
Enter fullscreen mode Exit fullscreen mode
  • Once done, the project structure shall look like below:

Project structure

  • Include the mobilertc package in settings.gradle and build.gradle inside your application folder.

settings.gradle

include ':mobilertc'
Enter fullscreen mode Exit fullscreen mode

build.gradle

implementation project(':mobilertc')
Enter fullscreen mode Exit fullscreen mode

Since we created project with "No Activity", the source folder shall be empty. Right on the package folder inside "java" and create a empty activity "MainActivity", select "java" as language and set it as a launcher activity for the project.

For building our project, I have used four activity screens.

  • MainActivity : Launcher activity showing a "join" button.
  • JoinSessionActivity: To enter "session" details and join
  • IntegrationActivity: To help in navigation in and out of application during the screen-share
  • MeetingActivity: The in-meeting screen

I have also created a service called "NotificationService" which is our foreground service created during call.

We need to add the necessary permissions required for the project in the AndroidManifest.xml file. The manifest file shall look like here: https://github.com/ajitha-zoom/video-sdk-android/blob/main/app/src/main/AndroidManifest.xml

Init SDK & Join/Leave Session

In order to initialise SDK, we need to use the intialize method with the InitParams.

ZoomVideoSDKInitParams params = new ZoomVideoSDKInitParams();
params.domain = "zoom.us";
params.enableLog = true;
params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryMode.ZoomVideoSDKRawDataMemoryModeHeap;
params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryMode.ZoomVideoSDKRawDataMemoryModeHeap;
params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryMode.ZoomVideoSDKRawDataMemoryModeHeap;

int ret = ZoomVideoSDK.getInstance().initialize(this.getApplicationContext(), params);
Enter fullscreen mode Exit fullscreen mode

The initialisation can be verified using the return code.

if (ret != ZoomVideoSDKErrors.Errors_Success) {
    //Failure
} else {
    //Success
}
Enter fullscreen mode Exit fullscreen mode

Once you initialise the SDK correctly, you will be able to call the SDK functions. Android application requires end user to accept all the necessary permission. So, we need to allow the end user to accept all permissions before attempting to join a session. The same shall be done using the ActivityCompat.requestPermissions() method. To join a session, we need to supply the session context with audio option, video option and JWT token. I have initialised the sessionContext as shown below.

ZoomVideoSDKSessionContext sessionContext=new ZoomVideoSDKSessionContext();

/* ------------ SET AUDIO OPTIONS ------------ */
ZoomVideoSDKAudioOption audioOption=new ZoomVideoSDKAudioOption();
audioOption.connect=true;
audioOption.mute=false;
audioOption.isMyVoiceInMix=true;
sessionContext.audioOption=audioOption;

/* ------------ SET VIDEO OPTIONS ------------ */
ZoomVideoSDKVideoOption videoOption=new ZoomVideoSDKVideoOption();
videoOption.localVideoOn=true;
sessionContext.videoOption=videoOption;

/* ------------ VALIDATE INPUTS ------------ */
userName = nameEdit.getText().toString();
if (TextUtils.isEmpty(userName)) {
    userName = Build.MODEL;
}

sessionName = sessionEditText.getText().toString().toLowerCase().trim();

if (TextUtils.isEmpty(sessionName)) {
    Toast.makeText(this, "Session name is empty", Toast.LENGTH_LONG).show();
    return;
}
//Required
sessionContext.sessionName = sessionName;
sessionContext.userName = userName;

password = passwordEdit.getText().toString();
//Optional
sessionContext.sessionPassword = password;

/* ------------ GENERATE JWT ------------ */
JWTGenerator jwtGenerator = new JWTGenerator(this);
jwtGenerator.execute();

.
.
//after retrieving the token
sessionContext.token = token;

/* ------------ JOIN SESSION ------------ */
ZoomVideoSDKSession session=ZoomVideoSDK.getInstance().joinSession(sessionContext);
Enter fullscreen mode Exit fullscreen mode

If the "session" is not null, you have successfully created a new videosdk session.

To leave a created session,

ZoomVideoSDK.getInstance().leaveSession(true);
Enter fullscreen mode Exit fullscreen mode

Video, Audio, & Screen-Share Functionality

Let's begin to add the basic functionality. The UI screens shall be created as per your convenience. For receiving the session related events and user related events, we need to implement "ZoomVideoSDKDelegate" in our MeetingActivity.

I have designed three buttons in my meeting screen "Video", "Audio" & "Screen share" button.

Video

To turn on/off the video of self during a session,

public void onClickVideo(View view) {
    ZoomVideoSDKUser zoomSDKUserInfo = session.getMySelf();
    if (null == zoomSDKUserInfo) return;
    if (zoomSDKUserInfo.getVideoStatus().isOn()) {  
     ZoomVideoSDK.getInstance().getVideoHelper().stopVideo();
    } else {
     ZoomVideoSDK.getInstance().getVideoHelper().startVideo();
    }
}
Enter fullscreen mode Exit fullscreen mode

In order to access the remote participant's video, we need to retrieve the user's canvas and then render the video in the ZoomVideoSDKVideoView.

zoomCanvas = new ZoomVideoSDKVideoView(this, false);
..
..
int ret = user.getVideoCanvas().subscribe(zoomCanvas, aspect);
Enter fullscreen mode Exit fullscreen mode

To remove the remote participants video, we need to unsubscribe.

user.getVideoCanvas().unSubscribe(zoomCanvas);
Enter fullscreen mode Exit fullscreen mode

When the users video state is changed, the corresponding delegate method shall be called and we shall update the UI accordingly.

public void onUserVideoStatusChanged(ZoomVideoSDKVideoHelper videoHelper, List<ZoomVideoSDKUser> userList)
Enter fullscreen mode Exit fullscreen mode

Audio

Before trying to turn on/off the audio, we need to start the audio. Only after starting, we would be allowed to mute/unmute the audio of self.

public void onClickAudio(View view) {
    ZoomVideoSDKUser zoomSDKUserInfo = session.getMySelf();
    if (zoomSDKUserInfo.getAudioStatus().getAudioType() == ZoomVideoSDKAudioStatus.ZoomVideoSDKAudioType.ZoomVideoSDKAudioType_None) {
        ZoomVideoSDK.getInstance().getAudioHelper().startAudio();
    } else {
        if (zoomSDKUserInfo.getAudioStatus().isMuted()) {
            ZoomVideoSDK.getInstance().getAudioHelper().unMuteAudio(zoomSDKUserInfo);
        } else {
            ZoomVideoSDK.getInstance().getAudioHelper().muteAudio(zoomSDKUserInfo);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

When the remote users audio states are changed, the corresponding delegate methods shall be invoked.

public void onUserAudioStatusChanged(ZoomVideoSDKAudioHelper audioHelper, List<ZoomVideoSDKUser> userList)
Enter fullscreen mode Exit fullscreen mode

Screen-Share

In order to use screen-share there are pre-requisites:

  • Permissions to be accepted for using MediaProjectionManager
  • Screen overlay permission for creating a "Stop share" button
  • A running foreground service (in latest versions of Android)

Once the above are achieved, then we can simply invoke the startScreenShare in the ShareHelper.

int ret = ZoomVideoSDK.getInstance().getShareHelper().startShareScreen(data);
if (ret == ZoomVideoSDKErrors.Errors_Success) {
    //do something
}
Enter fullscreen mode Exit fullscreen mode

Screen sharing can be stopped using,

ZoomVideoSDK.getInstance().getShareHelper().stopShare();
Enter fullscreen mode Exit fullscreen mode

Remote participants screen sharing can be subscribed and unsubscribed similar to their video using share canvas.

user.getShareCanvas().subscribe(zoomCanvas, ZoomVideoSDKVideoAspect.ZoomVideoSDKVideoAspect_Original);
Enter fullscreen mode Exit fullscreen mode

and

currentShareUser.getShareCanvas().unSubscribe(zoomCanvas);
Enter fullscreen mode Exit fullscreen mode

When the remote users share status is changed, the corresponding delegate method shall be triggered:

public void onUserShareStatusChanged(ZoomVideoSDKShareHelper shareHelper, ZoomVideoSDKUser userInfo, ZoomVideoSDKShareStatus status)
Enter fullscreen mode Exit fullscreen mode

Summary

Developing basic functionalities using video sdk is very simple and can be achieved with few lines of code. There are many more features in video-sdk like accessing raw data, cloud recording, live streaming, chat, transcriptions etc., The possibilities are exponential.

Complete source code for above tutorial can be found here: https://github.com/ajitha-zoom/video-sdk-android

Top comments (0)