Installations
npm install @sendbird/calls-react-native
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
20.13.1
NPM Version
10.5.2
Score
40.6
Supply Chain
60.9
Quality
70.5
Maintenance
50
Vulnerability
93.8
License
Releases
Contributors
Unable to fetch Contributors
Languages
Kotlin (32.99%)
TypeScript (32.58%)
Swift (30.12%)
Objective-C (2.83%)
JavaScript (1.01%)
Ruby (0.47%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
Download Statistics
Total Downloads
32,731
Last Day
172
Last Week
982
Last Month
2,388
Last Year
21,896
GitHub Statistics
MIT License
2 Stars
357 Commits
1 Forks
8 Watchers
3 Branches
5 Contributors
Updated on Jan 22, 2025
Bundle Size
35.98 kB
Minified
8.39 kB
Minified + Gzipped
Package Meta Information
Latest Version
1.1.5
Package Id
@sendbird/calls-react-native@1.1.5
Unpacked Size
1.08 MB
Size
239.08 kB
File Count
306
NPM Version
10.5.2
Node Version
20.13.1
Published on
Dec 12, 2024
Total Downloads
Cumulative downloads
Total Downloads
32,731
Last Day
-16.1%
172
Compared to previous day
Last Week
91.1%
982
Compared to previous week
Last Month
88.3%
2,388
Compared to previous month
Last Year
133%
21,896
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Peer Dependencies
2
Dev Dependencies
25
Sendbird Calls SDK for React-Native
Table of contents
- Introduction
- Before getting started
- Getting started
- Configuring the application for the SDK
- Making your first call
- Implementation direct call guide
- Making your first group call
- Implementation group call guide
- Appendix
Introduction
Sendbird Calls is the latest addition to our product portfolio. It enables real-time calls between users within a Sendbird application. SDKs are provided for iOS, Android, and JavaScript. Using any one of these, developers can quickly integrate voice and video call functions into their own client apps, allowing users to make and receive web-based real-time voice and video calls on the Sendbird platform.
If you need any help in resolving any issues or have questions, please visit our community
How it works
Sendbird Calls SDK for React-Native provides a module to make and receive voice and video calls. Direct calls in the SDK refers to one-to-one calls. To make a direct voice or video call, the caller specifies the user ID of the intended callee, and dials. Upon dialing, all of the callee’s authenticated devices will receive notifications for an incoming call. The callee then can choose to accept the call from any one of the devices. When the call is accepted, a connection is established between the devices of the caller and the callee. This marks the start of a direct call.
Group calls in the SDK refers to many-to-many calls. One person creates a room, and multiple people can join the room by using the room ID of the created room.
In both Direct calls and Group calls, participants can control audio devices like mute or unmute audio and video devices such as toggle between the front and rear camera. With this, they're possible to participate in the calls using both or only one of them.
The Sendbird Dashboard displays Direct calls logs in the Calls menu for dashboard owners and admins to review. And you can see the created Group calls room information and the entering and exiting times of users who participated in the room.
More about Sendbird Calls SDK for React-Native
Find out more about Sendbird Calls for React-Native on Calls SDK for React-Native doc.
Before getting started
This section shows the prerequisites you need to check to use Sendbird Calls SDK for React-Native.
Requirements
- React-Native 0.60 or higher
- iOS 12.0 or higher
- Android 5.0 (API level 21) or higher
SDK dependencies
- Sendbird Calls SDK for iOS, which can be integrated by
CocoaPods
- Sendbird Calls SDK for Android, which can be integrated by
Gradle
Getting started
This section gives you information you need to get started with Sendbird Calls SDK for React-Native.
Install Calls SDK
React-Native
1npm i @sendbird/calls-react-native 2npx pod-install
Configuring the application for the SDK
iOS
Background Mode
To support background operation, VoIP-enabled apps must have Background Mode
enabled in the Xcode Project > Signing & Capabilities pane. Select the checkbox for Voice over IP.
To receive push notifications, the app also must have Push Notifications enabled in the Xcode Project > Signing & Capabilities pane.
For more information about VoIP push notification and PushKit, see Apple's CallKit and PushKit
Configure the app’s Info.plist File
iOS requires that apps display authorization message to grant the app access to the camera and microphone.
- Microphone-enabled apps must include the NSMicrophoneUsageDescription key in the app’s
Info.plist
file. - Camera-enabled apps must include the NSCameraUsageDescription key in the app’s
Info.plist
file.
Android
(Optional) Configure ProGuard to shrink code and resources
When you build your APK with minifyEnabled true
, add the following line to the module's ProGuard rules file.
# SendBird Calls SDK
-keep class com.sendbird.calls.** { *; }
-keep class org.webrtc.** { *; }
-dontwarn org.webrtc.**
-keepattributes InnerClasses
Getting Permissions
The SDK requires system permissions. The following permissions allow the SDK to access the microphone and use audio.
- Camera
- Microphone
- Bluetooth (Android)
We recommend react-native-permissions
library
1import Permissions, { PERMISSIONS } from 'react-native-permissions'; 2 3const CALL_PERMISSIONS = Platform.select({ 4 android: [PERMISSIONS.ANDROID.CAMERA, PERMISSIONS.ANDROID.RECORD_AUDIO, PERMISSIONS.ANDROID.BLUETOOTH_CONNECT], 5 ios: [PERMISSIONS.IOS.CAMERA, PERMISSIONS.IOS.MICROPHONE], 6 default: [], 7}); 8 9const result = await Permissions.requestMultiple(CALL_PERMISSIONS);
Making your first direct call
Follow the step-by-step instructions below to authenticate and make your first direct call.
Step 1: Initialize the SendbirdCall instance in a client app
As shown below, the SendbirdCalls
instance must be initiated when a client app is launched.
Initialize the SendbirdCalls
instance with the APP_ID
of the Sendbird application you would like to use to make a call.
1import { SendbirdCalls } from '@sendbird/calls-react-native'; 2 3SendbirdCalls.initialize(APP_ID);
Note: If another initialization with another
APP_ID
takes place, all existing data in the app will be deleted and theSendbirdCalls
instance will be initialized with the newAPP_ID
.
Step 2: Authenticate a user and register a push token
In order to make and receive calls, authenticate the user with SendBird server with the SendbirdCalls.authenticate()
method and register a push token to Sendbird.
iOS
Register a VoIP push token by using the SendbirdCalls.ios_registerVoIPPushToken()
method after authentication has completed.
VoIP Push Notification will also enable receiving calls even when the app is in the background or terminated state.
A valid APNS certificate also needs to be registered on the Sendbird Dashboard: Application > Settings > Notifications > Add certificate.
For more details on registering push tokens, refer to Calls SDK for React-Native doc.
NOTE: In order to receive incoming calls to a user's device, you must implement either VoIP notifications or remote notifications. If you want to register a APNS token, you can register APNS token by using
SendbirdCalls.registerPushToken()
methodrefer to Calls SDK for iOS doc.
Android
Register a FCM push token by using the SendbirdCalls.registerPushToken()
method after authentication has completed.
Push Notification will also enable receiving calls even when the app is in the background or closed entirely.
1import { SendbirdCalls } from '@sendbird/calls-react-native'; 2import RNVoipPushNotification from 'react-native-voip-push-notification'; 3import messaging from '@react-native-firebase/messaging'; 4 5// Authenticate 6SendbirdCalls.authenticate({ 7 userId: USER_ID, 8 accessToken: ACCESS_TOKEN, 9}) 10 .then(user => { 11 // The user has been authenticated successfully 12 }) 13 .catch(error => { 14 // error 15 }) 16 17// Update FCM push token 18if (Platform.OS === 'android') { 19 const fcmToken = await messaging().getToken(); 20 await SendbirdCalls.registerPushToken(fcmToken); 21 // The FCM Push Token has been registered successfully 22} 23 24// Update VoIP push token 25if (Platform.OS === 'ios') { 26 RNVoipPushNotification.addEventListener('register', async (voipToken) => { 27 await SendbirdCalls.ios_registerVoIPPushToken(voipToken) 28 // The VoIP Push Token has been registered successfully 29 }); 30 RNVoipPushNotification.registerVoipToken(); 31}
Step 3: Add an event handler
The SDK provides two types of event handlers for various events that client apps may respond to: SendbirdCallListener
Listener and DirectCallListener
- SendbirdCallListener
Register a device-specific onRinging
event handler using the SendbirdCalls.setListener()
method.
It is recommended to add the event handler during initialization because it is a prerequisite for detecting onRinging event.
The code below shows the way device-wide events such as incoming calls are handled once SendbirdCallListener.onRinging
is added.
1SendbirdCalls.setListener({
2 onRinging(callProps: DirectCallProperties) {
3 // Process incoming call
4 },
5});
Listener | Invoked when |
---|---|
onRinging | Incoming calls are received in the callee’s device. |
NOTE: You can set up only one SendbirdCallListener.
- DirectCallListener
Register a call-specific DirectCallListener
event handler using the DirectCall.addListener()
method.
Responding to call-specific events, such as establishing a successful call connection, is then handled as shown below:
1const unsubscribe = directCall.addListener({ 2 onEstablished: (call: DirectCallProperties) => {}, 3 4 onConnected: (call: DirectCallProperties) => {}, 5 6 onEnded: (call: DirectCallProperties) => {}, 7 8 onRemoteAudioSettingsChanged: (call: DirectCallProperties) => {}, 9 10 onRemoteVideoSettingsChanged: (call: DirectCallProperties) => {}, 11 12 onCustomItemsUpdated: (call: DirectCallProperties, updatedKeys: string[]) => {}, 13 14 onCustomItemsDeleted: (call: DirectCallProperties, deletedKeys: string[]) => {}, 15 16 onReconnecting: (call: DirectCallProperties) => {}, 17 18 onReconnected: (call: DirectCallProperties) => {}, 19 20 onAudioDeviceChanged: (call: DirectCallProperties, info: AudioDeviceChangedInfo) => {}, 21 22 onRemoteRecordingStatusChanged: (call: DirectCallProperties) => {}, 23 24 onUserHoldStatusChanged: (call: DirectCallProperties, isLocalUser: boolean, isUserOnHold: boolean) => {}, 25 26 onLocalVideoSettingsChanged: (call: DirectCallProperties) => {}, 27}); 28 29unsubscribe();
NOTE Don't forget remove the listener. For example, you can call
unsubscribe()
fromonEnded
of listener you set or clean-up ofuseEffect
.
Method | Invocation criteria |
---|---|
onEstablished() | The callee accepted the call using the method directCall.accept() . However, neither the caller or callee’s devices are connected to media devices yet. |
onConnected() | A connection is established between the caller and callee’s media devices such as microphones and speakers. The voice or video call can begin. |
onEnded() | The call is ended on either the caller or the callee’s devices. When the directCall.end() method is used from either party, a call ends. directCall.end event listener is also invoked if the call is ended for other reasons. Refer to Call results in Appendix for all possible reasons for call termination. |
onRemoteAudioSettingsChanged() | The other party changed their audio settings. |
onRemoteVideoSettingsChanged() | The other party changed their video settings. |
onCustomItemsUpdated() | One or more of DirectCall ’s custom items (metadata) have been updated. |
onCustomItemsDeleted() | One or more of DirectCall ’s custom items (metadata) have been deleted. |
onReconnecting() | DirectCall started attempting to reconnect to the other party after a media connection disruption. |
onReconnected() | The disrupted media connection reestablished. |
onAudioDeviceChanged() | The audio device used in the call has changed. |
onRemoteRecordingStatusChanged() | The other user's recording status has been changed. |
onUserHoldStatusChanged() | The local or remote user puts a call on hold or removes a hold from a call. |
onLocalVideoSettingsChanged() | The local user's video settings has been changed. |
Step 4: Make a call
First, prepare the call parameters to initiate a call.
The parameter contains the initial call configuration, such as callee’s user id, audio or video capabilities, and CallOptions
object.
Once prepared, the call parameters are then passed into the SendbirdCalls.dial()
method to start the call.
NOTE: For reduce the event delay between Native and JavaScript, SDK does not convert
DirectCallProperties
toDirectCall
onSendbirdCallListener.onRinging
orSendbirdCalls.Dial
. So you need to getDirectCall
usingSendbirdCalls.getDirectCall()
after receiving the event or call method.
1const callOptions: CallOptions = {
2 audioEnabled: true,
3 videoEnabled: true,
4 frontCamera: true,
5}
6
7const callProps = await SendbirdCalls.dial(CALLEE_ID, IS_VIDEO_CALL, callOptions);
8
9const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
10directCall.addListener({
11 // ...
12});
Step 5: Receive a call
Register SendbirdCallListener
first to receive incoming calls.
Accept or decline incoming calls using the directCall.accept()
or the directCall.end()
methods.
If the call is accepted, a media session will automatically be established by the SDK.
Before accepting any calls, the DirectCall.addListener
must be registered upfront in the SendbirdCallListener.onRinging
.
Once registered, DirectCallListener
enables reacting to in-call events through listener methods.
1SendbirdCalls.setListener({
2 async onRinging(callProps: DirectCallProperties) {
3 const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
4
5 const unsubscribe = directCall.addListener({
6 onEnded(call) {
7 unsubscribe();
8 },
9 });
10
11 directCall.accept();
12 },
13});
Implementation direct call guide
Make a call
Register SendbirdCallLisetner
first to receive incoming calls.
Accept or decline incoming calls using the directCall.accept()
or the directCall.end()
methods.
If the call is accepted, a media session will automatically be established by the SDK.
Before accepting any calls, the DirectCall.addListener
must be registered upfront in the SendbirdCallListener.onRinging
.
Once registered, DirectCallListener
enables reacting to in-call events through listener methods.
1SendbirdCalls.setListener({
2 async onRinging(callProps: DirectCallProperties) {
3 const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
4
5 const unsubscribe = directCall.addListener({
6 onEnded(call) {
7 unsubscribe();
8 },
9 });
10
11 directCall.accept();
12 },
13});
Receive a call
Register SendbirdCallListener
first to receive incoming calls.
Accept or decline incoming calls using the directCall.accept()
or the directCall.end()
methods.
If the call is accepted, a media session will automatically be established by the SDK.
Before accepting any calls, the DirectCall.addListener
must be registered upfront in the SendbirdCallListener.onRinging
.
Once registered, DirectCallListener
enables reacting to in-call events through listener methods.
1SendbirdCalls.setListener({
2 async onRinging(callProps) {
3 const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
4
5 const unsubscribe = directCall.addListener({
6 onEnded(call) {
7 unsubscribe();
8 },
9 });
10
11 directCall.accept();
12 },
13});
Receive a call in background
iOS
When the app is in the foreground, incoming call events are received through the SDK’s persistent internal server connection.
However, when the app is terminated or in the background, incoming calls are received through PushKit.
PushKit messages received by the Native iOS SDK
must be delivered to the SendBirdCall.pushRegistry(_:didReceiveIncomingPushWith:for:)
method.
NOTE: in objective-c,
[SBCSendBirdCall pushRegistry:_ didReceiveIncomingPushWith:for:]
So you should implement native features that CallKit
and PushKit(VoIP Push)
to your react-native app.
(e.g. react-native-callkeep
, react-native-voip-push-notification
)
1// AppDelegate.h 2 3#import <PushKit/PushKit.h> 4 5@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, PKPushRegistryDelegate>
1// AppDelegate.m 2 3#import <RNCallKeep.h> 4#import <SendBirdCalls/SendBirdCalls-Swift.h> 5 6// ... 7 8- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)())completion 9{ 10 [SBCSendBirdCall pushRegistry:registry didReceiveIncomingPushWith:payload for:type completionHandler:^(NSUUID * _Nullable uuid) { 11 12 // IMPORTANT: Incoming calls MUST be reported when receiving a PushKit push. 13 // If you don't report to CallKit, the app will be terminated. 14 15 if(uuid != nil) { 16 17 // Report valid call 18 19 SBCDirectCall* call = [SBCSendBirdCall callForUUID: uuid]; 20 [RNCallKeep reportNewIncomingCall: [uuid UUIDString] 21 handle: [[call remoteUser] userId] 22 handleType: @"generic" 23 hasVideo: [call isVideoCall] 24 localizedCallerName: [[call remoteUser] nickname] 25 supportsHolding: YES 26 supportsDTMF: YES 27 supportsGrouping: YES 28 supportsUngrouping: YES 29 fromPushKit: YES 30 payload: [payload dictionaryPayload] 31 withCompletionHandler: completion]; 32 } else { 33 34 // Report and end invalid call 35 36 NSUUID* uuid = [NSUUID alloc]; 37 NSString* uuidString = [uuid UUIDString]; 38 39 [RNCallKeep reportNewIncomingCall: uuidString 40 handle: @"invalid" 41 handleType: @"generic" 42 hasVideo: NO 43 localizedCallerName: @"invalid" 44 supportsHolding: NO 45 supportsDTMF: NO 46 supportsGrouping: NO 47 supportsUngrouping: NO 48 fromPushKit: YES 49 payload: [payload dictionaryPayload] 50 withCompletionHandler: completion]; 51 [RNCallKeep endCallWithUUID:uuidString reason:1]; 52 } 53 }]; 54}
1import RNCallKeep from 'react-native-callkeep';
2import RNVoipPushNotification from 'react-native-voip-push-notification';
3
4SendbirdCalls.setListener({
5 async onRinging(callProps) {
6 const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
7
8 // handle incoming call with CallKit (react-native-callkeep)
9 RNCallKeep.addEventListener('answerCall', async () => {
10 directCall.accept();
11 });
12 RNCallKeep.addEventListener('endCall', async () => {
13 directCall.end();
14 });
15
16 const unsubscribe = directCall.addListener({
17 onEnded() {
18 RNCallKeep.removeEventListener('answerCall');
19 RNCallKeep.removeEventListener('endCall');
20 RNCallKeep.endAllCalls();
21 unsubscribe();
22 },
23 });
24
25 RNCallKeep.displayIncomingCall(
26 callProps.ios_callUUID,
27 callProps.remoteUser?.userId,
28 callProps.remoteUser?.nickname ?? 'Unknown',
29 'generic',
30 callProps.isVideoCall,
31 );
32 },
33});
34
35RNVoipPushNotification.registerVoipToken();
Android
When the app is in the foreground, incoming call events are received through the SDK’s persistent internal server connection.
However, when the app is closed or in the background, incoming calls are received through the Firebase Cloud Messaging’s (FCM) push notifications.
The FCM messages received by SendbirdCalls must be delivered to the SDK through the SendbirdCalls.android_handleFirebaseMessageData()
method.
1import messaging, { FirebaseMessagingTypes } from '@react-native-firebase/messaging';
2
3SendbirdCalls.setListener({
4 async onRinging(callProps) {
5 const directCall = await SendbirdCalls.getDirectCall(callProps.callId);
6
7 // handle incoming call with what you want (e.g. Notifee foreground service)
8 },
9});
10
11const firebaseListener = async (message: FirebaseMessagingTypes.RemoteMessage) => {
12 SendbirdCalls.android_handleFirebaseMessageData(message.data);
13};
14messaging().setBackgroundMessageHandler(firebaseListener);
15messaging().onMessage(firebaseListener);
Handle a current call
During an ongoing call, a caller may mute or unmute their microphone by using the directCall.muteMicrophone()
or directCall.unmuteMicrophone()
methods.
DirectCallListener.onRemoteAudioSettingsChanged()
listener method will notify any changes that a remote user makes on audio settings to the local user.
The caller may start or stop video using the directCall.startVideo()
or directCall.stopVideo()
methods.
If the remote user changes the video settings, the local user will be notified through the DirectCallListener.onRemoteVideoSettingsChanged()
listener.
The current video device can be changed by using the directCall.selectVideoDevice()
or directCall.switchCamera()
.
1// mute my microphone
2directCall.muteMicrophone();
3
4// unmute my microphone
5directCall.unmuteMicrophone();
6
7// starts to show video
8directCall.startVideo();
9
10// stops showing video
11directCall.stopVideo();
12
13// changes current video device
14directCall.selectVideoDevice(VIDEO_DEVICE).catch(error => {
15})
16
17// receives the event
18directCall.addListener({
19 ...
20
21 onRemoteAudioSettingsChanged: (callProps: DirectCallProperties) => {
22 if (callProps.isRemoteAudioEnabled) {
23 // The peer has been unmuted.
24 // Consider displaying an unmuted icon.
25 } else {
26 // The peer has been muted.
27 // Consider displaying and toggling a muted icon.
28 }
29 },
30
31 onRemoteVideoSettingsChanged: (callProps: DirectCallProperties) => {
32 if (callProps.isRemoteVideoEnabled) {
33 // The peer has started video.
34 } else {
35 // The peer has stopped video.
36 }
37 },
38});
End a call
A caller may end a call using the directCall.end()
method. The event will then be processed through the DirectCallListener.onEnded()
listener.
This listener is also triggered if the remote user ends the call.
1// End a call 2call.end(); 3 4// receives the event 5directCall.addListener({ 6 // ... 7 8 onEnded: (callProps: DirectCallProperties) => { 9 // Consider releasing or destroying call-related view from here. 10 }, 11});
Unregister a push token and deauthenticate a user
- Unregister one or all VoIP push tokens
Warning: unregister all is not supported yet.
Users will no longer receive call notifications after the VoIP push token has been unregistered
through the unregisterPushToken(TOKEN)
or unregisterVoIPPushToken(TOKEN)
method before deauthenticate.
1const unregisterPushToken = () => {
2 SendbirdCalls.unregisterPushToken(TOKEN);
3
4 // or
5
6 SendbirdCalls.ios_unregisterVoIPPushToken(TOKEN);
7};
- Deauthenticate a user
When users log out of their call client apps, they must be deauthenticated with SendbirdCalls.deauthenticate()
method.
1const signOut = () => { 2 SendbirdCalls.deauthenticate(); 3};
Display Video
1import { DirectCallVideoView } from '@sendbird/calls-react-native'; 2 3const YourApp = () => { 4 const directCall = useDirectCall(callId); 5 6 return ( 7 <View> 8 {/* Remote video view */} 9 <DirectCallVideoView viewType={'remote'} callId={directCall.callId} /> 10 11 {/* Local video view */} 12 <DirectCallVideoView viewType={'local'} callId={directCall.callId} /> 13 </View> 14 ); 15};
Mirror a DirectCallVideoView
1const VideoView = () => { 2 return <DirectCallVideoView mirror={false} callId={'CALL_ID'} viewType={'remote'} />; 3};
Retrieve a call information
The local or remote user’s information is available via the directCall.localUser
and directCall.remoteUser
properties.
Retrieve call history
Sendbird server automatically stores details of calls, which can be retrieved later to display call history for users.
A user’s call history is available through a DirectCallLogListQuery
instance.
1import { DirectCallEndResult, DirectCallLogListQuery, SendbirdCalls } from '@sendbird/calls-react-native'; 2 3const useCallHistory = () => { 4 const [history, setHistory] = useState<DirectCallLog[]>([]); 5 const query = useRef<DirectCallLogListQuery>(); 6 7 useEffect(() => { 8 const effect = async () => { 9 query.current = await SendbirdCalls.createDirectCallLogListQuery({ 10 myRole: 'ALL', 11 endResults: [ 12 DirectCallEndResult.COMPLETED, 13 DirectCallEndResult.CANCELED, 14 DirectCallEndResult.DECLINED, 15 DirectCallEndResult.DIAL_FAILED, 16 DirectCallEndResult.ACCEPT_FAILED, 17 ], 18 limit: 20, 19 }); 20 21 const data = await query.current.next(); 22 setHistory(data); 23 }; 24 25 effect(); 26 27 return () => { 28 query.current.release(); 29 }; 30 }, []); 31 32 return { 33 next: async () => { 34 if (query.hasNext) { 35 const data = await query.current.next(); 36 setHistory((prev) => prev.concat(...data)); 37 } 38 }, 39 history, 40 }; 41};
Params | Description |
---|---|
limit | Specifies the number of call history entries to return at once. |
myRole | Returns the call history of the specified role. For example, the params.myRole = CALLEE returns only the callee’s call history.) |
endResults | Filters the results based on the call end result such as COMPLETED ,NO_ANSWER , etc. If multiple values are specified, they are processed as an OR condition. For example, for endResults: [NO_ANSWER] , only the history entries that resulted in NO_ANSWER will be returned. |
Method | Description |
---|---|
next() | Used to query the call history from Sendbird Calls server. |
hasNext | If true, there are additional call history entries yet to be retrieved. |
isLoading | If true, the call history is being retrieved from the server. |
Timeout options
Warning: Not supported yet.
The following table lists a set of methods of the SendbirdCalls
class.
Sound effects
You should add files to your native project
for Android, add your files to res/raw/{filename}.mp3
for iOS, when you add files to a project, xcode automatically added to the bundled resources (Build Phases > Copy Bundle Resources)
- Sound types
Type | Description |
---|---|
dialing | Refers to a sound that is played on a caller’s side when the caller makes a call to a callee. |
ringing | Refers to a sound that is played on a callee’s side when receiving a call. |
reconnecting | Refers to a sound that is played when a connection is lost, but immediately tries to reconnect. Users are also allowed to customize the ringtone. |
reconnnected | Refers to a sound that is played when a connection is re-established. |
- Add sound
Method | Description |
---|---|
addDirectCallSound | Adds a specific sound to a direct call such as a ringtone or an alert tone with an Android resource ID. |
Parameter | Type | Description |
---|---|---|
soundType | SoundType | Specifies the sound type to be used according to the event. |
fileName | int | Specifies the Android resource ID. |
- Remove sound
Method | Description |
---|---|
removeDirectCallSound | Removes a specific sound from a direct call. |
Parameter | Type | Description |
---|---|---|
soundType | SoundType | Specifies the sound type to be used according to the event. |
Call results
Information relating the end result of a call can be obtained at any time through the directCall.endResult
property, best invoked within the onEnded()
listener.
DirectCallEndResult | Description |
---|---|
NO_ANSWER | The callee failed to either accept or decline the call within a specific amount of time. |
CANCELED | The caller canceled the call before the callee could accept or decline. |
DECLINED | The callee declined the call. |
COMPLETED | The call ended after either party ended it |
TIMED_OUT | Sendbird Calls server failed to establish a media session between the caller and callee within a specific amount of time. |
CONNECTION_LOST | The data stream from either the caller or the callee has stopped due to a WebRTC connection issue. |
DIAL_FAILED | The dial() method call has failed. |
ACCEPT_FAILED | The accept() method call has failed. |
OTHER_DEVICE_ACCEPTED | The incoming call was accepted on a different device. This device received an incoming call notification, but the call ended when a different device accepted it. |
NONE | Default value of the endResult. |
UNKNOWN | Ended with unknown reason. |
Making your first group call
Follow the step-by-step instructions below to authenticate and make your first group call.
Step 1: Initialize the SendbirdCall instance in a client app
As shown below, the SendbirdCalls
instance must be initiated when a client app is launched.
Initialize the SendbirdCalls
instance with the APP_ID
of the Sendbird application you would like to use to make a call.
1import { SendbirdCalls } from '@sendbird/calls-react-native'; 2 3SendbirdCalls.initialize(APP_ID);
Note: If another initialization with another
APP_ID
takes place, all existing data in the app will be deleted and theSendbirdCalls
instance will be initialized with the newAPP_ID
.
Step 2: Authenticate a user
In order to participate in the group calls, authenticate the user with SendBird server with the SendbirdCalls.authenticate()
method.
1import { SendbirdCalls } from '@sendbird/calls-react-native'; 2 3// Authenticate 4SendbirdCalls.authenticate({ 5 userId: USER_ID, 6 accessToken: ACCESS_TOKEN, 7}) 8 .then((user) => { 9 // The user has been authenticated successfully 10 }) 11 .catch((error) => { 12 // error 13 });
Step 3: Create a room
By calling the SendbirdCalls.createRoom()
by passing SMALL_ROOM_FOR_VIDEO
as the parameter, you can create a room for up to 6 participants to make a video call. When a room is created, the status of the room becomes OPEN
and ROOM_ID
is generated.
1const room = await SendbirdCalls.createRoom(SendbirdCalls.RoomType.SMALL_ROOM_FOR_VIDEO);
Note: Share the room ID with other users for them to enter the room from the client app.
Step 4: Enter a room
A user can search a room with a specific ROOM_ID
to participate in a group call at any time.
- retrieve a room instance
To enter a room, you must first acquire the room instance from Sendbird server with the room ID. To fetch the most up-to-date room instance from Sendbird server, use the SendbirdCalls.fetchRoomById()
method. Also, you can use the SendbirdCalls.getCachedRoomById()
method that returns the most recently cached room instance from Sendbird Calls SDK.
1// get room instance using ROOM_ID 2const room = await SendbirdCalls.fetchRoomById(ROOM_ID); 3 4// get cached room instance using ROOM_ID 5const cachedRoom = await SendbirdCalls.getCachedRoomById(ROOM_ID);
- enter a room
Once the room is retrieved, call the enter()
method to enter the room. An object that sets whether to use video and audio is passed to enter()
as a parameter. If no parameters are passed, both audio and video are enabled as default.
When a user enters a room, a participant is created with a unique participant ID
to represent the user in the room.
If you create a room using SendbirdCalls.createRoom()
, you can use the returned room instance without needing to get a room instance.
1const enterParams: EnterParams = { 2 audioEnabled: true, 3 videoEnabled: true, 4} 5await room.enter(enterParams)
NOTE: If there is no room whose ID is room ID passed as a parameter among the cached room instances,
SendbirdCalls.getCachedRoomById()
returnsnull
. So you should need to check the returned value before callingenter()
.
Step 5: Handle events in a room
A user can receive events of a room that they are currently participating. Users will be notified when other participants enter or leave the room, change their media settings, or when the room is deleted.
- Add event listener
Add an event listener for the user to receive events that occur in a room that the user joins as a participant.
1const unsubscribe = room.addListener({ 2 onRemoteParticipantEntered: (participant: Participant) => {}, 3 4 onRemoteParticipantExited: (participant: Participant) => {}, 5 6 onRemoteParticipantStreamStarted: (participant: Participant) => {}, 7 8 onRemoteVideoSettingsChanged: (participant: Participant) => {}, 9 10 onRemoteAudioSettingsChanged: (participant: Participant) => {}, 11 12 onAudioDeviceChanged: (info: AudioDeviceChangedInfo) => {}, 13 14 onCustomItemsUpdated: (updatedKeys: string[]) => {}, 15 16 onCustomItemsDeleted: (deletedKeys: string[]) => {}, 17 18 onDeleted: () => {}, 19 20 onError: (e: SendbirdError, participant: Participant | null) => {}, 21}); 22 23unsubscribe();
NOTE Don't forget to remove the listener. For example, you can call
unsubscribe()
from clean-up ofuseEffect
.
Method | Invocation criteria |
---|---|
onRemoteParticipantEntered() | Invoked when a remote participant has entered a room. |
onRemoteParticipantExited() | Invoked when a remote participant has exited a room. |
onRemoteParticipantStreamStarted() | Invoked when a remote participant has started media streaming. |
onRemoteVideoSettingsChanged() | Invoked when a remote participant's video settings have changed. |
onRemoteAudioSettingsChanged() | Invoked when a remote participant's audio settings have changed. |
onAudioDeviceChanged() | Invoked when the audio device used in the call has changed. |
onCustomItemsUpdated() | Invoked when one or more of Room ’s custom items (metadata) have been updated. |
onCustomItemsDeleted() | Invoked when one or more of Room ’s custom items (metadata) have been deleted. |
onDeleted() | Invoked when Room is deleted. |
onError() | Invoked when a participant stream is lost due to reconnection failure. |
Step 6: Exit a room
To leave a room, call exit()
. On the room handlers of the remaining participants, the onRemoteParticipantExited()
method will be called.
1room.exit();
Implementation group call guide
Create a room
A room is a must to use a Group calls to talk to multiple people. You can create a new room using SendbirdCalls.createRoom()
. Once the room is created, you must use enter()
to enter the room. And then you have to share the ROOM_ID
of the room with other users in order for other participants can enter the room.
1const room = await SendbirdCalls.createRoom(SendbirdCalls.RoomType.SMALL_ROOM_FOR_VIDEO); 2await room.enter();
Handle events in a room
A user can receive events of a room that they are currently participating. Users will be notified when other participants enter or leave the room, change their media settings, or when the room is deleted.
You don't need to define all events method, you just need to define the methods you want to implement. And, don't forget to remove the listener. For example, you can call unsubscribe()
from clean-up of useEffect
.
1useEffect(() => { 2 const unsubscribe = room.addListener({ 3 onRemoteParticipantEntered: (participant: Participant) => {}, 4 5 onRemoteParticipantExited: (participant: Participant) => {}, 6 7 onRemoteParticipantStreamStarted: (participant: Participant) => {}, 8 9 ... 10 }); 11 12 return unsubscribe(); 13}, []);
Enter a room
Use SendbirdCalls.fetchRoomById()
with ROOM_ID
to get the room instance you want to enter. Or, if you have fetched the room before, you can use SendbirdCalls.getCachedRoomById()
to get a cached room instance. Then call the enter()
method to enter the room.
When a user enters a room, a participant is created with a unique participant ID
to represent the user in the room. When the remote user enters the room, the onRemoteParticipantEntered()
listener method is called. And then when the participant has started media streaming, onRemoteParticipantStreamStarted()
listener method is called.
NOTE: If there is no room whose ID is room ID passed as a parameter among the cached room instances,
SendbirdCalls.getCachedRoomById()
returnsnull
. So you should need to check the returned value.
1// get room instance using ROOM_ID 2const room = await SendbirdCalls.fetchRoomById(ROOM_ID); 3await room.enter() 4 5// get cached room instance using ROOM_ID 6const cachedRoom = await SendbirdCalls.getCachedRoomById(ROOM_ID); 7await cachedRoom?.enter() 8 9// receives the event 10room.addListener({ 11 onRemoteParticipantEntered: (participant: Participant) => { 12 // the remote participant entered the room 13 }, 14 15 onRemoteParticipantStreamStarted: (participant: Participant) => { 16 // the remote participant has started media streaming 17 }, 18 19 ... 20});
Handle a current call
Participants can mute or unmute their microphones using the room.localParticipant.muteMicrophone()
or room.localParticipant.unmuteMicrophone()
methods.
onRemoteAudioSettingsChanged()
listener method is invoked whenever the remote participant's audio settings change.
You can also use the room.localParticipant.startVideo()
and room.localParticipant.stopVideo()
methods to turn video off or on. onRemoteVideoSettingsChanged()
method is invoked whenever the remote participant's video settings change.
If you want to switch to using the device's front and back cameras, call room.localParticipant.switchCamera()
.
1// mute my microphone 2room.localParticipant.muteMicrophone(); 3 4// unmute my microphone 5room.localParticipant.unmuteMicrophone(); 6 7// starts to show video 8room.localParticipant.startVideo(); 9 10// stops showing video 11room.localParticipant.stopVideo(); 12 13// changes current video device 14room.localParticipant.switchCamera(); 15 16// receives the event 17room.addListener({ 18 onRemoteVideoSettingsChanged: (participant: Participant) => { 19 if (participant.isVideoEnabled) { 20 // remote Participant has started video. 21 } else { 22 // remote Participant has stopped video. 23 } 24 }, 25 26 onRemoteAudioSettingsChanged: (participant: Participant) => { 27 if (participant.isAudioEnabled) { 28 // remote Participant has been unmuted. 29 // Consider displaying an unmuted icon. 30 } else { 31 // remote Participant has been muted. 32 // Consider displaying and toggling a muted icon. 33 } 34 }, 35 36 ... 37});
Exit a room
Participants can use the exit()
method to leave the room and end the group call. When the remote participant leaves the room, the onRemoteParticipantExited()
listener method is called.
1// Exit a room 2room.exit(); 3 4// receives the event 5room.addListener({ 6 onRemoteParticipantExited: (participant: Participant) => { 7 // Consider destroying the remote participant's view. 8 }, 9 10 ... 11});
Display Video
By passing the participant
instance and ROOM_ID
to the GroupCallVideoView
component, you can display the streamed view on the screen. Group calls can have up to 6 people, so you should need to think about how to arrange views on the screen depending on the number of participants.
1import { useEffect, useState } from 'react'; 2 3import { GroupCallVideoView, Room, SendbirdCalls } from '@sendbird/calls-react-native'; 4 5const YourApp = () => { 6 const [room, setRoom] = useState<Room>(); 7 8 useEffect(() => { 9 SendbirdCalls.getCachedRoomById(ROOM_ID).then((room) => setRoom(room)); 10 }, []); 11 12 return ( 13 <View> 14 {room?.participants.map((participant) => ( 15 <GroupCallVideoView participant={participant} roomId={room.roomId} resizeMode={'contain'} /> 16 ))} 17 </View> 18 ); 19};
Props | Description |
---|---|
participant | participant instance to display on screen |
roomId | ID of the participating room |
resizeMode | how to resize the image. 'contain', 'cover', 'center' |
style | style object for component |
Retrieve a participant information
The local or remote participant’s information is available via the room.participants
or room.localParticipant
and room.remoteParticipants
properties.
Appendix
Encoding Configurations
iOS
Category | Value | Note |
---|---|---|
Frames per second | 24 fps | |
Maximum resolution | 720p | 1280x720 px; standard HD |
Audio Codec | OPUS | |
Video Codec | H.264, VP8 | H.264 is used between iOS devices as a default codec. |
Android
Category | Value | Note |
---|---|---|
Frames per second | 24 | |
Maximum resolution | 720p | 1280 x 720; standard HD |
Audio codec | OPUS | |
Video codec | VP8 |
SDK Sizes
iOS
File | Raw Files | Compiled Size |
---|---|---|
Calls SDK (1.7.0) | 77.1 MB | 2.32 MB |
WebRTC SDK (1.3.0) | 1.18 GB | 6.32 MB |
(Xcode 12.3, Any iOS Device (arm64))
Android
File | Raw files | Compiled size |
---|---|---|
Calls SDK | 1.77MB | 1.18MB |
WebRTC SDK | 26.8MB | 12MB |
Call relay protocol
Sendbird Calls is based on WebRTC to enable real-time calls between users with P2P connections, but sometimes connectivity issues may occur for users due to network policies that won’t allow WebRTC communications through Firewalls and NATs (Network Address Translators). For this, Sendbird Calls uses two different types of protocols, Session Traversal Utilities for NAT (STUN) and Traversal Using Relays around NAT (TURN). STUN and TURN are protocols that support establishing a connection between users.
Note: See our GitHub page to learn about the requirements and how to use the Calls SDKs behind a firewall.
How STUN and TURN works
Session Traversal Utilities for NAT (STUN) is a protocol that helps hosts to discover the presence of a NAT and the IP address, which eventually makes the connection between two endpoints. Traversal Using Relays around NAT (TURN) is a protocol that serves as a relay extension for data between two parties.
Sendbird Calls first try to make a P2P connection directly using the Calls SDK. If a user is behind a NAT/Firewall, Calls will discover the host's public IP address as a location to establish connection using STUN. In most cases, STUN server is only used during the connection setup and once the session has been established, media will flow directly between two users. If the NAT/Firewall still won't allow the two users to connect directly, TURN server will be used to make a connection to relay the media data between two users. Most of the WebRTC traffic is connected with STUN.
- Last Updated: June 17th, 2022

No vulnerabilities found.

No security vulnerabilities found.