0 purchases
social live one on one call
social_live_one_on_one_call (SDK) #
Latest version 1.0.4 #
Platform Support #
Android
iOS
✅
✅
Installation #
Add 'social_live_one_on_one_call' in pubspec.yaml
or
flutter pub add social_live_one_on_one_call
copied to clipboard
Import library
import 'package:social_live_one_on_one_call/social_live_one_on_one_call.dart';
copied to clipboard
NOTE: 'social_live_one_on_one_call' required dart 3.4.0 and later, please upgrade your dart as needed.
*** IMPORTANT ***
On Android, add following permission (if not available) in 'android/app/src/main/AndroidManifest.xml'
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
copied to clipboard
To maintain audio call when app go background, please start foreground service using package 'flutter_foreground_service'
void main() {
runApp(MyApp());
startForegroundService();
}
void startForegroundService() async {
ForegroundService().start();
debugPrint("Started service");
}
copied to clipboard
On iOS
open Info.plist on iOS Project, then add following description for microphone and camera feature (if not available)
<string>Use camera for Video Call.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Use microphone for Voice Call.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
copied to clipboard
open Podfile of Pods project, then add following script to add camera and microphone configurations
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# You can remove unused permissions here
# e.g. when you don't need camera permission,
just add 'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
]
end
end
end
copied to clipboard
And to let call run in background, you need to set background mode to Voice over IP
Flow #
Step 1: Obtain Authentication token #
To use the SDK, you need an authentication token and an AppID.
To get AppID, please contact us.
To get Authentication Token, please read this documentation Authentication Flow.
The example simulate a simple flow to obtain authentication via phone number regsiter.
final phoneToken = await NetworkUtils().createToken(number: myNumber, appId: appId);
copied to clipboard
After you got AppID and Authentication Token, the CallSDK is ready to use now.
Step 2: Start SDK #
Start the SDK with AppID and token from previous step.
void startSDK({
required String appId,
required String token,
required Function(CallEvent eventName, Map<String,dynamic>? data) callEvent,
Function(bool)? completion})
copied to clipboard
The callEvent will emit call-related event, for example when call 'connecting', 'connected', 'ended'. The 'CallEvent.audio' will emit when audio route change, for example when user plugin headphone or turn on/off speaker. Based on these events, you can update your Call UI appropriately.
enum CallEvent {
connecting,
connected,
ended,
audio,
// For testing call flow only, remove on distribute this library
notify,
busy,
}
copied to clipboard
The 'CallEvent.notify' and 'CallEvent.busy' is just for demo.
'CallEvent.notify' used for notify when someone call-in. You can follow our example to implement your own notify event. The 'call_id' is necessary for the call. You can also put in other information like 'caller_name'.
if (event == CallEvent.notify) {
if (data != null) {
final inputCallId = BaseEntity.stringValue(data, "call_id");
final callerName = BaseEntity.stringValue(data, "caller_name");
if (inputCallId != null) {
handleReceiveCall(callId: inputCallId, callerNumber: callerName);
}
}
}
copied to clipboard
'CallEvent.busy' used for response caller whether callee is busy or available.
if (name == "busy") {
final inputCallId = BaseEntity.stringValue(info, "call_id");
final status = BaseEntity.stringValue(info, "status");
if (inputCallId == widget.callId && status == "busy") {
_doEndCall();
}
}
copied to clipboard
Step 3: Call Feature (Make, Cancel, Accept, Decline, End) #
MAKE CALL
To make call, you need to get a CallID. Please read this documentation Call Flow
The example also simulate flow to get CallId via phone number, just enter your number and the number you want to call.
final newCallId = await NetworkUtils().createCall(appId: appId, callerNumber: registeredPhoneNumber, calleeNumber: calleeNumber);
copied to clipboard
After you get CallId, just call 'startCall'. You can put 'callerName' and 'calleeName' if needed.
void startCall({
required String callId,
bool videoCall = false,
String? callerName,
String? calleeName,
Function()? completion
})
copied to clipboard
CANCEL CALL
To Cancel the call on caller-side (before callee accept call), just call cancelCall
CallSDK().cancelCall();
copied to clipboard
ACCEPT CALL
On the Callee-side, you need to implement mechanism to notify Callee client about the callId, so that they can join the call and start communicate. The example use the CallEvent.notify to get notification and callId.
if (event == CallEvent.notify) {
if (data != null) {
final inputCallId = BaseEntity.stringValue(data, "call_id");
final callerName = BaseEntity.stringValue(data, "caller_name");
if (inputCallId != null) {
handleReceiveCall(callId: inputCallId, callerNumber: callerName);
}
}
copied to clipboard
When receive notify about the call. First, 'startCall' just like the caller do to connect with our server. When 'startCall' completed, you can now show incoming-call screen to the user.
void handleReceiveCall({required String callId}) async {
CallSDK().startCall(callId: callId, callerName: callerNumber, calleeName: registeredPhoneNumber, completion: () {
goToCallScreen(
newRole: "callee",
inputCallId: callId,
callerNumber: callerNumber,
calleeNumber: registeredPhoneNumber,
);
});
}
copied to clipboard
On the incoming-call screen, to accept call on Callee, just call acceptCall
void handleAcceptButton() async {
await stopRingSound();
if (widget.role == "callee") {
CallSDK().acceptCall(completion: (result) {
if (mounted) {
if (result == true) {
callAccepted = true;
setState(() {
});
} else {
NetworkUtils.showAlertDialog(
context: context,
alertMsg: "Cannot accept call, please allow microphone",
);
}
}
});
}
}
copied to clipboard
Within seconds, both caller and callee will connect and the you can start talking.
DECLINE CALL
To Decline the call on Callee-side, just call declineCall
CallSDK().declineCall();
copied to clipboard
END CALL
To stop the on-going call, just call terminateCall. Below code check the current call status and decide which action to do.
final callReady = CallSDK().isCallConnected();
if (callReady) {
CallSDK().terminateCall();
} else {
CallSDK().cancelCall();
}
_closeCallView();
copied to clipboard
You receive 'CallEvent.ended' in following cases:
Call was connected, and the other end the call.
The callee decline the call.
The caller cancel the call before you make any decision (Decline/Accept).
Step 4: Handle Microphone and Speaker #
The SDK provide enough function to handle microphone and speaker when in-call
AudioDevice? getCurrentAudioInput();
bool currentDeviceIsSpeaker();
bool currentDeviceIsBluetooth();
bool currentDeviceIsHeadphone();
Future<void> turnOnSpeaker();
Future<void> turnOffSpeaker();
bool haveBluetooth();
bool microMuted();
void setMicroMuted({required bool muted});
copied to clipboard
'turnOnSpeaker' turn the loud speaker on device
'turnOffSpeaker' turn off loud speaker and use either in-ear speaker or external device (headphone/bluetooth) if available.
void handleSpeakerButton() async {
final isCurrentSpeaker = CallSDK().currentDeviceIsSpeaker();
if (isCurrentSpeaker == true) {
await CallSDK().turnOffSpeaker();
} else {
await CallSDK().turnOnSpeaker();
}
setState(() {
});
}
copied to clipboard
'microMuted' and 'setMicroMuted' to handle microphone when in-call
void handleMicrophoneButton() async {
final isMuted = CallSDK().microMuted();
CallSDK().setMicroMuted(muted: !isMuted);
await Future.delayed(const Duration(milliseconds: 200));
setState(() {
});
}
copied to clipboard
Step 5: Stop SDK #
When not used anymore especially when logout, you can stop CallSDK
await CallSDK().stopSDK(completion: () {
}
copied to clipboard
VIDEO CALL #
This SDK also support video call. To make a video call or a call that can be turn on video later, pass true to parameter 'videoCall' when startCall (both caller and callee). In practice, you should notify callee about the video call.
Get started to video call #
CallSDK().startCall(callId: newCallId,
videoCall: true,
videoOnStart: true,
callerName: registeredPhoneNumber,
calleeName: calleeNumber,
completion: () {
if (mounted) {
goToCallScreen(newRole: "caller",
inputCallId: newCallId,
videoCall: videoCall,
calleeNumber: calleeNumber,
callerNumber: registeredPhoneNumber);
}
}
);
copied to clipboard
Set the 'videoCall' parameter to true if you want a video call or an audio call that can be switch to video call later. Pass 'false' if you only want audio call only. Note that you can't turn on video later if you set 'videoCall' to false.
Set the 'videoOnStart' to true if you want to turn on local camera on waiting call to connected and when call started.
Outgoing video call
Incoming video call
In call video call
Listen to video events #
Obviously you want to display your local video and remote video (video of the other). To do that, just handle CallEvent.videoAdded and CallEvent.videoRemoved
enum CallEvent {
connecting,
connected,
ended,
audio,
videoAdded,
videoRemoved,
}
copied to clipboard
The data in CallEvent.videoAdded and CallEvent.videoRemoved contain video information as a map object, including 3 main key
Map<String, dynamic> videoInfo = {
"renderer": renderer,
"is_local": true,
"name":_getName(),
};
copied to clipboard
- 'renderer' is a RTCVideoRenderer object that you can add to your widget to display video
- 'is_local' tell you this video is your local video or not.
- 'name' name of the video, in this case the name of caller or callee
copied to clipboard
Other value you can get from video information is 'video_width', 'video_height' which tells you the size of the video.
Controlling video #
The SDK provide enough function to handle camera when in-call
bool currentCameraOn(); // check if camera is on or off
void switchCameraOn(); // turn on camera, front is default
void switchCameraOff(); // turn off camera
void switchCamera(); // change camera from front to back or vice versa
void switchCameraFront(); // switch to front camera
void switchCameraBack(); // switch to back camera
copied to clipboard
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.