⚠ Warning
|
Before using Stringee Call2 API for the first time, you must have a Stringee account.
If you do not have a Stringee account, sign up for free here: https://developer.stringee.com/account/register
Create a Project on Stringee Dashboard
Buy a Number (optional)
For app-to-phone, phone-to-app calling, buy a Number from Dashboard. If you only need app-to-app calling, skip this step.
Configure answer_url
For more information about answer_url, read Stringee Call API Overview. You can view answer_url sample code here: https://github.com/stringeecom/server-samples/tree/master/answer_url
If you do not have answer_url, you can use the following Project's answer_url to accelerate the process:
Project's answer_url for App-to-App call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=false
Project's answer_url for App-to-Phone call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=true
(Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/project_answer_url.php)
When building an application, you should use your own answer_url.
If you do not have answer_url, you can use the following Number's answer_url to accelerate the process:
Number's answer_url for Phone-to-App call (The call is routed to Your App which authenticated by USER_ID):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=false&to_number=USER_ID
Number's answer_url for Phone-to-Phone call (The call is routed to TO_NUMBER):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=true&stringeeNumber=STRINGEE_NUMBER&to_number=TO_NUMBER
(Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/number_answer_url.php)
In your terminal (Command Prompt in Windows), change into your React Native project's directory
In your terminal (Command Prompt in Windows), run $ npm install stringee-react-native-v2 --save
Permissions
The Stringee Android SDK requires some permissions from your AndroidManifest
android/app/src/main/AndroidManifest.xml
<!--Internet-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--Record-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--Audio-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!--Camera-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!--Bluetooth-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!--Require for android 12 or higher-->
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="false" />
Proguard
If your project uses ProGuard, you may have to add the following settings to the ProGuard configuration file to make sure Stringee builds correctly:
proguard-rules.pro
in your app/
dir and insert inside:-dontwarn org.webrtc.**
-keep class org.webrtc.** { *; }
-keep class com.stringee.** { *; }
/app/buidl.gradle
:android {
buildTypes {
release {
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Add volley library
In your file build.gradle
add this line:
dependencies {
implementation 'com.android.volley:volley:1.2.1'
}
In you terminal, change into your ios directory, from the command line run following command:
pod install --repo-update
After run cocoapods command, open project file .xcworkspace
In the "Build Settings" tab -> "Other linker flags" add "$(inherited)" flag
In the "Build Settings" tab -> "Enable bitcode" select "NO"
Right-click the information property list file (Info.plist) and select Open As -> Source Code. Then insert the following XML snippet into the body of your file just before the final element:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) uses Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses Microphone</string>
In the "Build Settings" tab -> "Allow Non-modular includes in Framework Modules" select "YES"
In order to connect to Stringee Server, 3-parties authentication is required as described here: Client authentication
For testing purpose, go to Dashboard -> Tools -> Generate Access token and generates an access_token. In production, the access_token should be generated by your server, sample code generates access token here: https://github.com/stringeecom/server-samples/tree/master/access_token
Initialize StringeeClient:
import {StringeeClient} from 'stringee-react-native-v2';
...
const stringeeClient: StringeeClient = new StringeeClient();
Register the client's events
// Listen for the StringeeClient event
const stringeeClientListener: StringeeClientListener = new StringeeClientListener();
// Invoked when the StringeeClient is connected
stringeeClientListener.onConnect = (stringeeClient, userId) => {
console.log('onConnect: ', userId);
}
// Invoked when the StringeeClient is disconnected
stringeeClientListener.onDisConnect = (stringeeClient) => {
console.log('onDisConnect');
}
// Invoked when StringeeClient connect false
stringeeClientListener.onFailWithError = (stringeeClient, code, message) => {
console.log('onFailWithError: ', message);
}
// Invoked when your token is expired
stringeeClientListener.onRequestAccessToken = (stringeeClient) => {
console.log('onRequestAccessToken');
}
// Invoked when receive an incoming of StringeeCall
stringeeClientListener.onIncomingCall = (stringeeClient, stringeeCall) => {
console.log('onIncomingCall: ', JSON.stringify(stringeeCall));
}
// Invoked when receive an incoming of StringeeCall2
stringeeClientListener.onIncomingCall2 = (stringeeClient, stringeeCall2) => {
console.log('onIncomingCall2: ', JSON.stringify(stringeeCall2));
}
stringeeClient.setListener(stringeeClientListener);
Connect
...
token: string = 'PUT YOUR TOKEN HERE'
...
stringeeClient.connect(token);
After the client connects to Stringee server, follows these steps to make a call:
Initialize StringeeCall2
import {StringeeCall2} from 'stringee-react-native-v2';
...
stringeeCall2: StringeeCall2 = new StringeeCall2({
stringeeClient: stringeeClient, /// stringeeClient using to connect
from: 'caller_userId', /// caller identifier
to: 'callee_userId', /// callee identifier
});
Register the call's events
// Listen for the StringeeCall2 event
const stringeeCall2Listener: StringeeCall2Listener = new StringeeCall2Listener();
// Invoked when the call's signaling state changes
stringeeCall2Listener.onChangeSignalingState = (stringeeCall2, signalingState, reason, sipCode, sipReason) => {
console.log('onChangeSignalingState', signalingState);
}
// Invoked when the call's media state changes
stringeeCall2Listener.onChangeMediaState = (stringeeCall2, mediaState, description) => {
console.log('onChangeMediaState', mediaState);
}
// Invoked when receive call info
stringeeCall2Listener.onReceiveCallInfo = (stringeeCall2, callInfo) => {
console.log('onReceiveCallInfo', callInfo);
}
// Invoked when an incoming call is handle on another device
stringeeCall2Listener.onHandleOnAnotherDevice = (stringeeCall2, signalingState, description) => {
console.log('onHandleOnAnotherDevice', signalingState);
}
// Invoked when the local track is initialized and available to be rendered to a view.
stringeeCall2Listener.onReceiveLocalTrack = (stringeeCall2, stringeeVideoTrack) => {
console.log('onReceiveLocalTrack');
}
// Invoked when the remote track is initialized and available to be rendered to a view.
stringeeCall2Listener.onReceiveRemoteTrack = (stringeeCall2, stringeeVideoTrack) => {
console.log('onReceiveRemoteTrack');
}
// Invoked when the current audio device changes in android
stringeeCall2Listener.onAudioDeviceChange = (stringeeCall2, selectedAudioDevice, availableAudioDevices) => {
console.log('onAudioDeviceChange', selectedAudioDevice);
}
stringeeCall2.setListener(stringeeCall2Listener);
Make a call
stringeeCall2.makeCall()
.then(() => {
console.log('makeCall success');
})
.catch(console.error);
After the client receives an incoming call from onIncomingCall2(). Following these steps:
Initialize the answer
stringeeCall2.initAnswer()
.then(() => {
console.log('initAnswer success');
})
.catch(console.error);
Answer
stringeeCall2.answer()
.then(() => {
console.log('answer success');
})
.catch(console.error);
isVideoCall
of StringeeCall2
to true
.
stringeeCall2.isVideoCall = true;
Receive and display the local video and the remote video
Using our StringeeVideoView
to display the video
...
// Invoked when the local track is initialized and available to be rendered to a view.
stringeeCall2Listener.onReceiveLocalTrack = (stringeeCall2, stringeeVideoTrack) => {
console.log('onReceiveLocalTrack');
this.setState({
hasReceivedLocalTrack: true,
localTrack: stringeeVideoTrack,
});
}
// Invoked when the remote track is initialized and available to be rendered to a view.
stringeeCall2Listener.onReceiveRemoteTrack = (stringeeCall2, stringeeVideoTrack) => {
console.log('onReceiveRemoteTrack');
this.setState({
hasReceivedRemoteTrack: true,
remoteTrack: stringeeVideoTrack,
});
}
...
render () {
return (
<View>
...
{stringeeCall2.isVideoCall &&
this.localTrack &&
this.state.hasReceivedLocalTrack && (
<StringeeVideoView
style={styles.localView}
videoTrack={this.state.localTrack}
local={true}
/>
)
}
{stringeeCall2.isVideoCall &&
this.remoteTrack &&
this.state.hasReceivedRemoteTrack && (
<StringeeVideoView
style={{flex: 1}}
videoTrack={this.state.remoteTrack}
local={false}
/>
)
}
...
</View>
);
}
Hang up a call:
stringeeCall2.hangup()
.then(() => {
console.log('hangup success');
})
.catch(console.error);
Reject a call:
stringeeCall2.reject()
.then(() => {
console.log('reject success');
})
.catch(console.error);
Mute the local sound:
mute: boolean = true; // true: mute, false: unmute
stringeeCall2.mute(mute)
.then(() => {
console.log('mute success');
})
.catch(console.error);
Switch to speakerphone or earpiece:
isSpeaker: boolean = true; // true: speakerphone, false: earpiece
stringeeCall2.setSpeakerphoneOn(isSpeaker)
.then(() => {
console.log('setSpeakerphoneOn success');
})
.catch(console.error);
Switch the local camera:
stringeeCall2.switchCamera()
.then(() => {
console.log('switchCamera success');
})
.catch(console.error);
Turn on/off video:
enableVideo: boolean = true; // true: turn on, false: turn off
stringeeCall2.enableVideo(enableVideo)
.then(() => {
console.log('enableVideo success');
})
.catch(console.error);
You can view a full version of this sample app on GitHub: https://github.com/stringeecom/react-native-samples/tree/master/CallSampleHook