Twilio migration guide (Android)

This guide walks you through how to migrate your existing Twilio Video implementation to the Vonage Video SDK. Vonage offers two ways to get started: Vonage’s Video API.

Overview

Twilio and Vonage Video APIs have very similar concepts. This starter guide aims to assist you in migrating your video application.

The main difference is that in Twilio you need to create a room SID whereas in Vonage you create a SessionID. You then create authentication tokens which are used on the client side to connect to rooms in Twilio or sessions in Vonage.

The following diagrams detail the main differences:

Vonage Twilio migraiton illustration 1 Vonage Twilio migraiton illustration 1

Get Video SDK credentials

Create a developer Account to access the developer portal. To get started with video you need to create an application. You can follow the create an application guide to obtain your application ID and private key.

Install the SDK

Replace the Twilio video SDK reference in your Gradle file (build.gradle) with the Vonage video SDK.

Thus from implementation 'com.twilio:video-android:7.5.1' to implementation ‘com.opentok.android:opentok-android-sdk:2.27.0’.


Enable required permissions

If not already done, please enable the following permission in the AndroidManifest.xml file:

Authentication

The Vonage Video SDK uses tokens to authenticate users. When generating a token you can set the user’s role (subscriber, publisher, or moderator). Optionally, you can also assign a string of metadata to the token (i.e. to identify the connected client).Please refer to our Token Creation Overview article for options you can use when generating tokens. Tokens are generated on the server-side and sent to the client-side. Visit the Server-side SDKs guides to learn more.

Create a video session

A session is like a room, clients with the same session ID will be able to communicate with each other. Like tokens, sessions are created on the server side.

Please refer to our Creating a session guide to learn more as well as the various configuration options available.

To create a session and generate a token, use one of our server SDKs.

Connect to a video session

To connect a client endpoint to a Vonage Video session you need an application ID, session ID, and token.

These credentials can be retrieved from the Dashboard and hardcoded in the application for development, however for a production environment use the server SDKs to provide the session ID and token (check Basic-Video-Chat project).

Twilio Vonage terminology mapping

Twilio Vonage
Room Session
Participants Subscriber(s) + Publisher(s)
Tracks Stream
RemoteTracks Subscribers(s).stream
LocalTracks Publisher(s).stream

Connecting to a video session

Connecting and managing video streams are done using event handler.

There are three key event listeners you need to implement:

  • Session.SessionListener (private Session mSession;)
  • PublisherKit.PublisherListener (private Publisher mPublisher;)
  • SubscriberKit.SubscriberListener (private Subscriber mSubscriber;)

SessionListener

The Session.SessionListener methods are used to handle events involving the addition and removal of participants (subscribers and publishers).

This is equivalent to Twilio's Room.Listener event handler.

Below is the structure of the exposed SessionListener interface:

private Session.SessionListener sessionListener = new Session.SessionListener() {
   @Override
   public void onConnected(Session session) {
       Log.d(TAG, "onConnected: Connected to session: " + session.getSessionId());


       mPublisher = new Publisher.Builder(MainActivity.this).build();
       mPublisher.setPublisherListener(publisherListener);
       mSession.publish(mPublisher);
   }


   @Override
   public void onDisconnected(Session session) {
       Log.d(TAG, "onDisconnected: Disconnected from session: " + session.getSessionId());
   }


   @Override
   public void onStreamReceived(Session session, Stream stream) {
       Log.d(TAG, "onStreamReceived: New Stream Received " + stream.getStreamId() + " in session: " + session.getSessionId());


       mSubscriber = new Subscriber.Builder(MainActivity.this, stream).build();
       mSubscriber.setSubscriberListener(subscriberListener);
       mSession.subscribe(mSubscriber);
   }


   @Override
   public void onStreamDropped(Session session, Stream stream) {
       Log.d(TAG, "onStreamDropped: Stream Dropped: " + stream.getStreamId() + " in session: " + session.getSessionId());   
   }


   @Override
   public void onError(Session session, OpentokError opentokError) {
       Log.e("Session error: " + opentokError.getMessage());
   }
};

PublisherListener

The PublisherKit.PublisherListener is used to implement logic to execute based on the creation and end streams.

Below is the structure of the exposed PublisherListener interface:

private PublisherKit.PublisherListener publisherListener = new PublisherKit.PublisherListener() {
   @Override
   public void onStreamCreated(PublisherKit publisherKit, Stream stream) {
       Log.d(TAG, "onStreamCreated: Publisher Stream Created. Own stream " + stream.getStreamId());
   }


   @Override
   public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) {
       Log.d(TAG, "onStreamDestroyed: Publisher Stream Destroyed. Own stream " + stream.getStreamId());
   }


   @Override
   public void onError(PublisherKit publisherKit, OpentokError opentokError) {
       Log.e("PublisherKit onError: " + opentokError.getMessage());
   }
};

SubscriberListener

The SubscriberKit.SubscriberListener is used to implement logic to execute when a subscriber joins a stream.

Below is the structure of the exposed SubscriberListener interface:

SubscriberKit.SubscriberListener subscriberListener = new SubscriberKit.SubscriberListener() {
   @Override
   public void onConnected(SubscriberKit subscriberKit) {
       Log.d(TAG, "onConnected: Subscriber connected. Stream: " + subscriberKit.getStream().getStreamId());
   }


   @Override
   public void onDisconnected(SubscriberKit subscriberKit) {
       Log.d(TAG, "onDisconnected: Subscriber disconnected. Stream: " + subscriberKit.getStream().getStreamId());
   }


   @Override
   public void onError(SubscriberKit subscriberKit, OpentokError opentokError) {
       Log.e("SubscriberKit onError: " + opentokError.getMessage());
   }
};

Connecting to a session

You will need your APP_ID , SESSION_ID to connect to a video stream.

A TOKEN corresponding to the stream you will like to join is also required.

Twilio

private Room room;
ConnectOptions.Builder connectOptionsBuilder =
       new ConnectOptions.Builder(accessToken).roomName(roomName);
room = Video.connect(this, connectOptionsBuilder.build(), roomListener());

Vonage

Session.Builder builder = new Session.Builder(this, APP_ID, SESSION_ID);
mSession = builder.build();
mSession.setSessionListener(sessionListener);
mSession.connect(TOKEN);

Publishing video

Vonage Video SDKs handle video quality tuning automatically, based on network conditions and device capabilities.

That said, you can configure certain properties, such as resolution, frame rate, and audio fallback. A single publisher object can handle both audio and video. You may selectively control audio or video using methods available with the publisher object.

Add publisher

Twilio:

localVideoTrack = LocalVideoTrack.create(this, true, cameraCapturerCompat, LOCAL_VIDEO_TRACK_NAME);

Vonage:

Session.SessionListener() {
   @Override
   public void onConnected(Session session) {
       Log.d(TAG, "onConnected: Connected to session: " + session.getSessionId());
       mPublisher = new Publisher.Builder(MainActivity.this).build();
       mPublisher.setPublisherListener(publisherListener);
       mSession.publish(mPublisher);
   }
}

Audio track only

Twilio

localVideoTrack =
       LocalVideoTrack.create(this, false, cameraCapturerCompat, LOCAL_VIDEO_TRACK_NAME);

Vonage:

mPublisher = new Publisher.Builder(this).name(mUsername)
       .videoTrack(false)
       .build();

Video track only

Twilio:

localAudioTrack = LocalAudioTrack.create(this, false, LOCAL_AUDIO_TRACK_NAME);

Vonage:

mPublisher = new Publisher.Builder(this).name(mUsername)
       .audioTrack(false)
       .build();

Unpublish from session

Twilio:

localParticipant.unpublishTrack(localVideoTrack);

Vonage:

mSession.unpublish(mPublisher);

Mute Publisher Audio

Twilio:

localAudioTrack.enable(false);

Vonage:

mPublisher.setPublishAudio(false);

UnMute Publisher Audio

Twilio:

localAudioTrack.enable(true);

Vonage:

mPublisher.setPublishAudio(true);

Mute Publisher Video

Twilio:

localVideoTrack.enable(false);

Vonage:

mPublisher.setPublishVideo(false);

UnMute Publisher Video

Twilio:

localVideoTrack.enable(true);

Vonage:

mPublisher.setPublishVideo(true);

Subscribe to a stream

When a remote participant (subscriber) connects to a session, the Session.SessionListener.onStreamReceived() callback is invoked with corresponding stream object.

Twilio:

@Override
public void onConnected(Room room) {
   localParticipant = room.getLocalParticipant();
   setTitle(room.getName());


   for (RemoteParticipant remoteParticipant : room.getRemoteParticipants()) {
       addRemoteParticipant(remoteParticipant);
       break;
   }
}

Vonage:

@Override
public void onStreamReceived(Session session, Stream stream) {
       Log.d(TAG, "onStreamReceived: New Stream Received " + stream.getStreamId() + " in session: " + session.getSessionId());


       mSubscriber = new Subscriber.Builder(MainActivity.this, stream).build();
       mSubscriber.setSubscriberListener(subscriberListener);
       mSession.subscribe(mSubscriber);
   }

Disconnecting from a session

Twilio:

room.disconnect()

Vonage:

mSession.disconnect()

onPause() and onResume() methods

Vonage:

@Override
protected void onPause() {
   super.onPause();


   if (mSession != null) {
       mSession.onPause();
   }
}


@Override
protected void onResume() {
   super.onResume();
   if (mSession != null) {
       mSession.onResume();
   }
}

Ideally onPause() and onResume() should be implemented in the MainActivity Class.

Screen sharing

An example app for screen sharing.

Text chat app

An example app for sending text.

More Info