Avaya Client SDK

< Back to Package Overview

Making a video call

Using the Avaya Client SDK, you can easily integrate the ability for users of your application to make and receive audio or video calls.

To make a video call, you must complete the following activities:

  • Create a call object and initialize the details for the call
  • Implement the call listener to monitor for call progress events
  • Obtain resources for the video stream
  • Assign video and start the call
  • Activate the video resources
  • End the call

Create a call object

Creating a Call object allows you to set various properties for the call before the call is actually placed. The call object is created from the Call Service.

CallService callService = mUser.getCallService();
Call call = callService.createCall();

You can specify the phone number to dial by setting the remote address.

call.setRemoteAddress(callNumber);

Implement the call listener

To monitor call progress events, the CallListener interface provided by the Call object can be used. This interface provides notification as the call state changes.

Your application can define an object that implements the CallListener interface and can add it to the Call object to receive callback notifications.

Video calls use the same core notifications as audio calls, but additional ones exist for video.

class AppCallHandler implements CallListener
{
    // persistent data for video calls   
    VideoCamera mCameraForCall;

    @Override
    public void onCallStarted(Call call) {
    ...
    @Override
    public void onCallVideoChannelsUpdated(Call call, List list) {
    // adjust render surface and camera usage to match the final video direction
    }
    ...
};

You can instantiate an application call handler and add that as a listener to the call.

AppCallHandler callHandler = new AppCallHandler();
call.addListener(callHandler);

Obtain resources for the video stream

The application needs to obtain two resources when making a call with video. A video camera. Camera availability is verified through the VideoCaptureController class. This class manages most aspects of camera operation, including verification of available hardware. A video interface.

VideoInterface videoInterface = mUser.getMediaEngine().getVideoInterface();

if (video-transmission-desired) {

    VideoCaptureController() videoCapControl = new VideoCaptureController();
    // Assign a default camera; this could be user selectable according 
    // to your implementation
    callHandler.mCameraForCall = VideoCamera.Front;

    if (!videoCaptureController.hasVideoCamera(callHandler.mCameraForCall)) {
    // No camera. Reset to null.
    callHandler.mCurrentCamera = null;

    // The app will have to recover somehow. In this case, assume that video
    // reception is desired instead.
    }
}

Assign video and start the call

The application specifies a video call by setting video mode prior to invoking call.start() or when using call.accept().

// Set the desired direction on the video channel
if (video-transmission-desired && callHandler.mCurrentCamera != null) {
    call.setVideoMode(VideoMode.SEND_RECEIVE);
}
else {
    call.setVideoMode(VideoMode.RECEIVE_ONLY);
}

// send the call to the remote address. There's no guarantee that it will 
// answer with bi-directional (or even any) video

call.start();

Activate video resources

One video-related callback must be implemented on the Call's CallListener to allow your application to transmit or receive video with directions matching the one negotiated by the remote endpoint. Although bi-directional video is requested by the local application, the remote may support only uni-directional video, or it may not support video at all.

public void onCallVideoChannelsUpdated(Call call,  List list) {

// adjust render surface and camera usage to match the final video direction. This
// is done by examining the final video direction that was returned from the
// remote address

if (list.size() > 0) {
    VideoChannel channel = list.get(0);
    int channelId = channel.getChannelId();
    MediaDirection mediaDirection = channel.getNegotiatedDirection();

    if (mediaDirection == MediaDirection.SEND_RECEIVE || 
        mediaDirection == MediaDirection.SEND_ONLY) {
        // These two video directions imply that video transmission
        // must be started locally.
        // As such, create a surface to render local video,
        // attach the surface to the camera, 
        // attach the camera to the video channel,
        // and activate the camera.

        // Start video transmission
        final VideoSink videoSink;
        videoSink = videoInterface.getLocalVideoSink(channelId);
        videoCapControl.getVideoSource().setVideoSink(videoSink);
        videoCapControl.setLocalVideoLayer(localVideoLayer);

        if (callHandler.mCameraForCall != null) {
            videoCapControl.useVideoCamera(callHandler.mCameraForCall, null);
        }
    }
    if (mediaDirection == MediaDirection.SEND_RECEIVE || 
        mediaDirection == MediaDirection.RECEIVE_ONLY) {
        // These two video directions imply that video reception
        // must be started locally.
        // Create a surface to render remote video
        // and attach the surface to the video channel.
        // Start video rendering
        if (videoInterface.getRemoteVideoSource(channelId) != null) {
            remoteVideoLayer = new VideoLayerRemote();
            videoInterface.getRemoteVideoSource(channelId)
            .setVideoSink(remoteVideoLayer);
        }
    }  
    // Any other video direction implies video is not available
    // If the call has video before this update it should be stopped.
}

End the call

To terminate the call from the application, you can use the end() function on the call object.

call.end();

The onCallEnded callback event is sent to the call listener when the call has been ended. Use this event to update the UI of your application. Ending the call will deallocate the video channel and release the video camera automatically, but any render surface allocated by the application will need to be released by it. Again, see SdkSampleApp for the steps.