JavaScript
Calls Key Functions

Key Functions

This page explains key functions of SendBird Calls consisting of how to make, receive, handle, and end a call from your client app.


Call object

Direct call in the Calls SDK refers to a one-to-one call. A connection for a direct call is established through the following steps:

  1. When a caller initiates the call, the dial event will be sent to the callee and invoke onRinging.
  2. When the callee accepts the call, WebRTC attempts to establish a media stream to connect the users. During another round of handshake between the caller and callee, information related to WebRTC will be transferred.
  3. After the handshake, a WebRTC connection is established between the caller and callee. Also, the media stream will start for the call.

For the caller, the dial() method will return a promise resolved as the call object. For the callee, the call object will be delivered through the onRinging() method as a parameter. And for both the caller and callee, the call object will be returned by the SendBirdCall.getCall(callId) method.


Make a call

Initiate a call by providing the callee’s user id into the SendBirdCall.dial() method. Use the CallOption object to choose initial call configuration, such as audio or video capabilities, video settings, and mute settings.

Light Color Skin
Copy
const dialParams = {
    userId: CALLEE_ID,
    isVideoCall: true,
    callOption: {
        localMediaView: document.getElementById('local_video_element_id'),
        remoteMediaView: document.getElementById('remote_video_element_id'),
        audioEnabled: true,
        videoEnabled: true
    }
};


const call = SendBirdCall.dial(dialParams, (call, error) => {
    if (error) {
        // Dialing failed
    }

    // Dialing succeeded
});

call.onEstablished = (call) => {
    ...
};

call.onConnected = (call) => {
    ...
};

call.onEnded = (call) => {
    ...
};

call.onRemoteAudioSettingsChanged = (call) => {
    ...
};

Note: A media viewer is a HTMLMediaElement such as <audio> and <video> to display media stream. The remoteMediaView is required for the remote media stream to be displayed. It is also recommended to set a media viewer's autoplay property to true.

Light Color Skin
Copy
<video id="remote_video_element_id" autoplay>

Note: Media viewers can also be set using the call.setLocalMediaView() or call.setRemoteMediaView() method.

Light Color Skin
Copy
//Setting media viewers lazily
call.setLocalMediaView(document.getElementById('local_video_element_id'));
call.setRemoteMediaView(document.getElementById('remote_video_element_id'));

Receive a call

To receive an incoming call, a SendBirdCallListener event handler should already be registered in the callee’s client app. Accept or decline the call using the directCall.accept() or the directCall.end() method. If the call is accepted, a media session will automatically be established by the Calls SDK.

Before accepting the call, the call-specific DirectCallListener event handler must be added to the call object. It enables the callee’s app to react to events during the call through its callback methods.

Light Color Skin
Copy
SendBirdCall.addListener(UNIQUE_HANDLER_ID, {
    onRinging: (call) => {
        call.onEstablished = (call) => {
            ...
        };

        call.onConnected = (call) => {
            ...
        };

        call.onEnded = (call) => {
            ...
        };

        call.onRemoteAudioSettingsChanged = (call) => {
            ...
        };

        /*
        interface DirectCallOption {
            remoteMediaView: HTMLElement
            audioEnabled: boolean
        }
        */

        const acceptParams = {
            callOption: {
                remoteMediaView: document.getElementById('remote_video_element_id')
            }
        };

        call.accept(acceptParams);
    }
});

Note: If media viewer elements have been set by the call.setLocalMediaView() and call.setRemoteMediaView() methods, make sure that the same media viewers are set in the acceptParam’s callOption. If not, they will be overridden during executing the call.accept() method.

Incoming calls are received via the application's persistent internal server connection, which is established by the SendBirdCall.connectWebSocket(). In the event of accidental disconnection, the application will attempt to reconnect every 2 seconds.


Handle a current call

Audio

During a current call, both the caller and callee’s audio can be muted or unmuted by the directCall.muteMicrophone() or directCall.unmuteMicrophone() method. If one party changes audio settings, the other party receives an event callback through the DirectCall.onRemoteAudioSettingsChanged() listener.

Light Color Skin
Copy
// Mute my microphone
call.muteMicrophone();
// Unmute my microphone
call.unmuteMicrophone();
 
// Receiving the event
call.onRemoteAudioSettingsChanged(call) {
    if (call.isRemoteAudioEnabled) {
        // The remote user has been unmuted.
        // TODO: Display an unmuted icon.
    } else {
        // The remote user has been muted.
        // TODO: Display and toggles a muted icon.
    }
};

Video

During a current call, both the caller and callee’s video can be enabled or disabled by the directCall.startVideo() or directCall.stopVideo() method. If one party changes audio settings, the other party receives an event callback through the DirectCall.onRemoteVideoSettingsChange() listener.

Light Color Skin
Copy
// Start my local video
call.startVideo();
// Stop my local video
call.stopVideo();
 
// Receiving the event
call.onRemoteVideoSettingsChanged(call) {
    if (call.isRemoteVideoEnabled) {
        // The remote user has started video.
    } else {
        // The remote user has stopped video.
    }
};

End a call

The directCall.end() method ends a current call of either the caller or callee’s side. If one party ends a current call, the other party receives an event callback through the DirectCallListener.onEnded() listener.

Light Color Skin
Copy
// End a call
call.end();

// Receiving the event
call.onEnded = (call) => {
    // TODO: Release or destroy call-related views from here.
};

Configure media devices

The SendBirdCall object contains a collection of methods used to configure media devices: retrieve a list of devices, retrieve the current device, select a device, and update a list of devices.

MethodDescription

useMedia(constraints)

Grants permission to access media devices.

getCurrentAudioInputDevice()

Returns the current audio input device.

getAvailableAudioInputDevices()

Returns a set of available audio input devices.

selectAudioInputDevice(mediaDeviceInfo)

Selects the audio input device.

getCurrentAudioOutputDevice()

Returns the current audio output device.

getAvailableAudioOutputDevices()

Returns a set of available audio input devices.

selectAudioOutputDevice(mediaDeviceInfo)

Select the audio output device.

getCurrentVideoInputDevice()

Returns the current video input device.

getAvailableVideoInputDevices()

Returns a set of available video devices.

selectVideoInputDevice(mediaDeviceInfo)

Selects the video input device.

updateMediaDevices(constraints)

Manually updates media devices.

The device specific-event handler also contains a collection of event listeners used to handle changes in media devices.

Event listenerInvoked when

onAudioInputDeviceChanged

There are changes in the system’s audio input device or the available audio input devices.

onAudioOutputDeviceChanged

There are changes in the system’s audio output device or the available audio output devices.

onVideoInputDeviceChanged

There are changes in the system’s video input device or the available video input devices.

Before using the methods and event listeners listed above, ensure that the SendBirdCall.useMedia(constraints) has been executed. Failing to do this will result in these methods causing unexpected behaviors or failed outcomes.

Light Color Skin
Copy
const mediaAccess = SendBirdCall.useMedia({audio: true, video: true});

// This code demonstrates for audio input devices. The same can also be done for audio output and video input devices.
const availableDevices = SendBirdCall.getAvilableAudioInputDevices();
const currentDevice = SendBirdCall.getCurrentAudioInputDevice();
// Populate option elements in select element
populateSelectOption(availableDevices);
// Select option which matches current device
selectOption(currentDevice);

SendBirdCall.addListener('my-listener', {
    onAudioInputDeviceChanged: (currentDevice, availableDevices) => {
        // Populate option elements in a select element
        populateSelectOption(availableDevices);
        // Select option which matches current device
        selectOption(currentDevice);
    }
});

...

SendBirdCall.removeListener('my-listener');

//on settings view closed
mediaAccess.dispose();

Make sure that the retrieved mediaAccess's dispose() method always gets called from the SendBirdCall.useMedia() method to prevent the unintended use of camera or microphone.

Note: In Chrome or Firefox, the SendBirdCall.updateMediaDevices() doesn’t need to be called if the media device event listener is used to update the view or device list. However, in Safari, those event listeners might not need to be called after a media device has been changed. In such cases, calling the SendBirdCall.updateMediaDevices() manually may be required.


Add event handlers

There are two types of event handlers that the Calls SDK provides: SendBirdCallListener and DirectCallListener.

SendBirdCallListener

Add a device-specific SendBirdCallListener event handler using the SendBirdCall.addListener() method. Once the event handler is added, responding to device events such as incoming calls can be managed as shown below.

Note: If a SendBirdCallListener event handler isn’t registered, a user can't receive an onRinging callback event, thus recommended to add this handler at the initialization of the app. Also, the SendBirdCallListener event handler is automatically removed when the app closes by default.

Light Color Skin
Copy
//The UNIQUE_HANDLER_ID below is a unique user-defined ID for a specific event handler.
SendBirdCall.addListener(UNIQUE_HANDLER_ID, {
    onRinging: (call) => {
        ...
    }
});
MethodInvoked when

onRinging()

An incoming call is notified on the callee’s device.

onAudioInputDeviceChanged()

There are changes in the system’s audio input device or the available local audio input devices.

onAudioOutputDeviceChanged()

There are changes in the system’s audio output device or the available local audio output devices.

onVideoInputDeviceChanged()

There are changes in the system’s video input device or the available local video input devices.

DirectCallListener

Before accepting the call, the call-specific DirectCallListener event handler must be added to the call object. It enables the callee’s app to react to events happening during the call through its callback methods.

Light Color Skin
Copy
// The call is a 'DirectCall' object
call.onEstablished = (call) => {
    ...
};

call.onConnected = (call) => {
    ...
};

call.onEnded = (call) => {
    ...
};

call.onRemoteAudioSettingsChanged = (call) => {
    ...
};
MethodInvoked when

onEstablished()

The callee has accepted the call by using the call.accept() method, but the media devices of caller and callee are not yet connected.

onConnected()

Media devices (for example, microphone and speakers) between the caller and callee are connected and can start the call.

onReconnecting()

The call is attempting to reconnect to SendBird server after losing connection.

onReconnected()

The call successfully reconnects to SendBird server.

onEnded()

One of the parties ends a call by using the call.end() method and a call is ended due to other reasons such as decline or connection lost.

onRemoteAudioSettingsChanged()

The other party changes their audio settings.

onRemoteVideoSettingsChanged()

The other party changes their video settings.

onCustomItemsUpdated()

The custom items of the call are updated.

onCustomItemsDeleted()

The custom items of the call are deleted.


Retrieve call information

One party’s information can be retrieved using the directCall.localUser property while the other party’s information using the directCall.remoteUser property.


Retrieve call history

A user’s call history can be retrieved using the next() method of a DirectCallLogListQuery instance which returns a list of call objects.

Light Color Skin
Copy
/*
interface DirectCallLogListQueryParams {
    myRole: string
    endResults: string[],
    limit: number
}
*/

const params = {
    myRole: 'dc_caller',
    endResults: ['DECLINED', 'COMPLETED'],
    limit: 100
};

const query = SendBirdCall.createDirectCallLogListQuery(params);

query.next((directCallLog) => {
    if (query.hasNext && !query.isLoading) {
        // The query.next() can be called once more to fetch more call logs.
    }
});