undefined

Video Calling

ConnectyCube Video Calling P2P API is built on top of WebRTC protocol and based on top of WebRTC Mesh architecture.

Max people per P2P call is 4.

To get a difference between P2P calling and Conference calling please read our ConnectyCube Calling API comparison blog page.

Get started with SDK

Follow the Getting Started guide on how to connect ConnectyCube SDK and start building your first app.

Code sample

There is ready-to-go FREE P2P Calls Sample to help you better understand how to integrate video calling capabilities in your apps.

Preparations

Required preparations for mobile platforms

iOS

Add the following entry to your Info.plist file, located in <project root>/ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) Camera Usage!</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) Microphone Usage!</string>

This entry allows your app to access camera and microphone.

Android

Ensure the following permission is present in your Android Manifest file, located in <project root>/android/app/src/main/AndroidManifest.xml:

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

The Flutter project template adds it, so it may already be there.

Also you will need to set your build settings to Java 8, because official WebRTC jar now uses static methods in EglBase interface. Just add this to your app level build.gradle:

android {
    //...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

If necessary, in the same build.gradle you will need to increase minSdkVersion of defaultConfig up to 18 (currently default Flutter generator set it to 16).

P2PClient setup

ConnectyCube Chat API is used as a signaling transport for Video Calling API, so in order to start using Video Calling API you need to connect to Chat.

To manage P2P calls in flutter you should use P2PClient. Please see code below to find out possible functionality.

P2PClient callClient = P2PClient.instance; // returns instance of P2PClient

callClient.init(); // starts listening of incoming calls
callClient.destroy(); // stops listening incoming calls and clears callbacks

// calls when P2PClient receives new incoming call
callClient.onReceiveNewSession = (incomingCallSession) {

};

// calls when any callSession closed
callClient.onSessionClosed = (closedCallSession) {

};

// creates new P2PSession 
callClient.createCallSession(callType, opponentsIds);

Create call session

In order to use Video Calling API you need to create a session object - choose your opponents with whom you will have a call and a type of session (VIDEO or AUDIO). P2PSession creates via P2PClient:

P2PClient callClient; //callClient created somewhere

Set<int> opponentsIds = {};
int callType = CallType.VIDEO_CALL; // or CallType.AUDIO_CALL

P2PSession callSession = callClient.createCallSession(callType, opponentsIds);

Add listeners

Below described main helpful callbacks and listeners:

callSession.onLocalStreamReceived = (mediaStream) {
  // called when local media stream completely prepared 
};

callSession.onRemoteStreamReceived = (callSession, opponentId, mediaStream) {
  // called when remote media stream received from opponent
};

callSession.onRemoteStreamRemoved = (callSession, opponentId, mediaStream) {
  // called when remote media was removed
};

callSession.onUserNoAnswer = (callSession, opponentId) {
  // called when did not receive an answer from opponent during timeout (default timeout is 60 seconds)
};

callSession.onCallRejectedByUser = (callSession, opponentId, [userInfo]) {
  // called when received 'reject' signal from opponent
};

callSession.onCallAcceptedByUser = (callSession, opponentId, [userInfo]){
  // called when received 'accept' signal from opponent
};

callSession.onReceiveHungUpFromUser = (callSession, opponentId, [userInfo]){
  // called when received 'hungUp' signal from opponent
};

callSession.onSessionClosed = (callSession){
  // called when current session was closed
};

Initiate a call

Map<String, String> userInfo = {};

callSession.startCall(userInfo);

The userInfo is used to pass any extra parameters in the request to your opponents.

After this, your opponents will receive a new call session in callback:

callClient.onReceiveNewSession = (incomingCallSession) {

};

Accept a call

To accept a call the following code snippet is used:

Map<String, String> userInfo = {}; // additional info for other call members
callSession.acceptCall(userInfo);

After this, your opponents will get a confirmation in the following callback:

callSession.onCallAcceptedByUser = (callSession, opponentId, [userInfo]){

};

Also, both the caller and opponents will get a special callback with the remote stream:

callSession.onRemoteStreamReceived = (callSession, opponentId, mediaStream) {
  // create video renderer and set media stream to it
  RTCVideoRenderer streamRender = RTCVideoRenderer();
  await streamRender.initialize();
  streamRender.srcObject = mediaStream;
  streamRender.objectFit = RTCVideoViewObjectFit.RTCVideoViewObjectFitCover;

  // create view to put it somewhere on screen
  RTCVideoView videoView = RTCVideoView(streamRender);
};

From this point, you and your opponents should start seeing each other.

Reject a call

Map<String, String> userInfo = {}; // additional info for other call members

callSession.reject(userInfo);

After this, the caller will get a confirmation in the following callback:

callSession.onCallRejectedByUser = (callSession, opponentId, [userInfo]) {

};

End a call

Map<String, String> userInfo = {}; // additional info for other call members

callSession.hungUp(userInfo);

After this, the opponents will get a confirmation in the following callback:

callSession.onReceiveHungUpFromUser = (callSession, opponentId, [userInfo]){

};

Monitor session connections state

(coming soon)

Mute audio

bool mute = true; // false - to unmute, default value is false
callSession.setMicrophoneMute(mute);

Switch audio output

bool enabled = false; // true - to switch to sreakerphone, default value is false
callSession.enableSpeakerphone(enable);

Mute video

bool enabled = false; // true - to enable local video track, default value for video calls is true
callSession.setVideoEnabled(enabled);

Switch video cameras

callSession.switchCamera().then((isFrontCameraSelected){
  if(isFrontCameraSelected) {
    // front camera selected
  } else {
    // back camera selected
  }
}).catchError((error) {
  // switching camera failed
});

Configurations

ConnectyCube Flutter SDK provides possibility to change some default parameters for call session.

Media stream configurations

Use instance of RTCMediaConfig class to change some default media stream configs.

RTCMediaConfig mediaConfig = RTCMediaConfig.instance;
mediaConfig.minHeight = 720; // sets preferred minimal height for local video stream, default value is 360 
mediaConfig.minWidth = 1280; // sets preferred minimal width for local video stream, default value is 640 
mediaConfig.minFrameRate = 30; // sets preferred minimal framerate for local video stream, default value is 30 

Call connection configurations

Use instance of RTCConfig class to change some default call connection configs.

RTCConfig config = RTCConfig.instance;
config.noAnswerTimeout = 90; // sets timeout in seconds before stop dilling to opponents, default value is 60
config.dillingTimeInterval = 5; // time interval in seconds between 'invite call' packages, default value is 3 seconds, min value is 3 seconds

Recording

(coming soon)