Video Call

Last Updated on : 2024-04-26 08:49:27download

This topic describes the video call capability comprising local video features and call management. It enables two-way video calls for control panels and IPCs with screens.

How it works

With the app, users can make and receive video calls to and from an IPC.

  1. Check if the device supports two-way video calls.
  2. Initialize the two-way video call SDK and register the message listener.
  3. The SDK initiates or receives a video call and creates a P2P connection to start live streaming.
  4. Listen for and synchronize the call status.
  5. End the call.
  6. Free the resource.

Check two-way video call support

Check if the device supports two-way video calls.

API description

 fun fetchSupportVideoCall(devId: String, callback: IThingResultCallback<Boolean>?)

Parameters

Parameter Description
devId The device ID.
callback The callback. A Boolean value is returned, with true for support.

Example

ThingIPCSdk.getVideoCall()?.fetchSupportVideoCall(mDevId, object : IThingResultCallback<Boolean> {
                override fun onSuccess(result: Boolean?) {
                    TODO("Not yet implemented")
                }

                override fun onError(errorCode: String?, errorMessage: String?) {
                    TODO("Not yet implemented")
                }
            })

Initialize video call

Initialize the video call module to manage call status.

It is recommended to perform the initialization after the user login. Before using the methods in the SDK, you must initialize the video call module.

API description

fun registerCallModuleProvider(category: String, interfaceProvider: ICallInterfaceProvider )

Parameters

Parameter Description
category The identifier of the registered module to match video call messages. Currently, only screen_ipc is supported.
interfaceProvider The callback ICallInterfaceProvider for the video call SDK.

ICallInterfaceProvider

When the app receives or makes a call, the launchUI method will be called back with the ThingCall object.

The system push messages will not proactively trigger this method. After receiving a system push message, invoke receiveCallMessage to pass ThingCall to the SDK for status checking and synchronization management. When the status check is normal, launchUI will be called back.

fun launchUI(call: ThingCall)

ThingCall

The video call model, including information about call participants and call status.

Parameter Description
appDeviceId The encrypted mobile identification information.
callType The call type, an enum of ThingCallType. For the mobile app, set the value to oneToOne(1).
curId The caller ID.
targetId The recipient ID.
sessionId The ID of the call session.
timeout The timeout period.
extra The additional parameters in map type, converted into JSON as follows: {"bizType":"screen_ipc","channelType":2,"category":"sp_dpsxj"}
targetState The call status, an enum of ThingTargetState.
outgoing Specifies whether the app initiates the call.

ThingTargetState

Call status enumeration.

enum class ThingTargetState(
    val value: Int
) {
    /** Unknown */
    UNKNOWN(0),
    // Status for outgoing calls
    /** Initiate a call */
    INITIATING(1001),
    /** Call is accepted */
    ANSWER(1002),
    /** Call is declined */
    REJECT(1003),

    // Status for incoming calls
    /** Ringing */
    RINGING(2001),
    /** Line busy */
    BUSY(2002),
    /** The other party receives an answer response message */
    ALREADY_ANSWERED(2003),
    /** Call is answered */
    OTHER_ANSWERED(2004),
    /** Call is canceled */
    CANCEL(2005),
    /** Call is declined */
    ALREADY_REJECTED(2006),

    // General status
    /** On a call */
    CALLING(3001),
    /** Call is hung up */
    HANG_UP(3002),
    /** Call is ended */
    STOP(3003),
    /** Call error */
    ERROR(3004),
    /** Call timed out */
    TIMEOUT(3005),
}

Example

ThingIPCSdk.getVideoCall()?.registerCallModuleProvider("screen_ipc", ScreenCameraProvider())

...

class ScreenCameraProvider : ICallInterfaceProvider {

    override fun launchUI(thingCall: ThingCall) {
       // start Activity
    }
}

Register message module

Register the video call message processing module to monitor and handle video messages delivered over MQTT. It is recommended to initialize the video call module with registerCallModuleProvider after user login, and then register the message module with registerMessageHandler().

API description

fun registerMessageHandler()

Unregister message module

Unregister the video call message processing module to release the listener and resource. It is recommended to invoke this method after the user login.

API description

fun unRegisterMessageHandler()

Initiate call

The IPC SDK initiates a video call.

API description

fun launchCall(
        targetId: String,
        timeout: Long,
        extra: Map<String, Any>,
        success: SuccessCallback,
        failure: FailureCallback,
    )

Parameters

Parameter Description
targetId The recipient ID, which is usually the device ID.
timeout The timeout period.
extra The additional parameters in map type, converted into JSON as follows: {"bizType":"screen_ipc","channelType":2,"category":"sp_dpsxj","keepConnect":false}
success The success callback.
failure The failure callback, with ThingCallError returned.

ThingCallError

enum class ThingCallError(
    val value: Int
) {
    /** Common errors */
    GENERAL(-1),
    /** Call is declined (line busy) */
    REJECT(1001),
    /** The other party is on a call (line busy) */
    BUSY(1002),
    /** Call is missed */
    NOT_ANSWER(1003),
    /** Call is declined */
    ALREADY_REJECTED(2001),
    /** Call is answered */
    ALREADY_ANSWERED(2002),
    /** Call timed out */
    TIMEOUT(3001),
    /** Failed to create a video call stream (call exception) */
    CONNECT_FAIL(3002),
    /** Video call stream is disconnected (call exception) */
    DISCONNECT(3003),
    /** Call exception */
    STOP(3004),
}

Example

ThingIPCSdk.getVideoCall()?.launchCall(devId, 30L, extra,
        object : SuccessCallback {
            override fun invoke() {
            }
        }, object : FailureCallback {
            override fun invoke(error: ThingCallError) {
            }
        })

Receive incoming call

Push incoming calls delivered over other channels to the video call SDK for status check and management.

  • If an exception occurs, the SDK returns the error code through ThingCallError.
  • If the status check is normal, launchUI will be called back.

API description

 fun receiveCallMessage(
        call: ThingCall,
        success: SuccessCallback,
        failure: FailureCallback,
    )

Parameters

Parameter Description
call The video call model.
success The success callback.
failure The failure callback, with ThingCallError returned.

Example

 thingCall?.let { call ->
                    L.d(TAG, "receive receiveCall")
                    if (callEvent == ThingCallEvent.CALL) {
                        ThingIPCSdk.getVideoCall()?.receiveCallMessage(
                            call,
                            {   //Success },
                            {
                              // Failure
                            })
                    }

Call management

After opening the call UI with ICallInterfaceProvider#launchUI(call: ThingCall), invoke launchUISuccess to notify the SDK for status synchronization and management. Only one session is allowed at a time.

API description

fun launchUISuccess(call: ThingCall, callInterface: ICallInterface?)

Parameters

Parameter Description
call The video call model.
callInterface Register the listener for ICallInterface and bidirectionally bind the video call operations with the SDK.

ICallInterface

Manage call status.

interface ICallInterface {

    var call: ThingCall?

    var listener: ICallInterfaceListener?

    /**
     * Callback for receiving video call messages over MQTT. Note that this method will not be called if the user is already on a call.
     */
    fun callStart(call: ThingCall)

    /**
     * Callback for receiving video call messages over MQTT. The user is on a call so the callback is rejected.
     */
    fun callCancel(call: ThingCall)

    /**
     * Update the call status. [ThingCall.targetState] field identifies the status of the call object.
     */
    fun callUpdate(call: ThingCall)

    /**
     * Timeout. See [Timer] for details.
     */
    fun timeout()
}

ICallInterfaceListener

Synchronize the video call action with the SDK to manage the session status.

interface ICallInterfaceListener {
 /**
     * Video call is ringing.
     */
    fun onRing()
    /**
     * Video call is hung up.
     */
    fun hangupClick()
    /**
     * Video call is accepted.
     */
    fun acceptClick()
    fun onStartConnect()
    /**
     * The connection status of the video call. If an exception occurs, such as unexpected P2P disconnection, the status is set to false.
     */
    fun onConnect(result: Boolean)
    fun onDisconnect()
    fun onException()
    /**
     * Video call is ended.
     */
    fun onViewDestroy()
}

Example

class VideoCallFragment : BaseFragment(), ICallInterface {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        ...
        var call = arguments?.getParcelable(BUNDLE_CALL_KEY)
        call?.let {
            ThingIPCSdk.getVideoCall()?.launchUISuccess(it, this)
        }
         ...
        return inflater.inflate(R.layout.xxx,container,false)
    }

    override fun onDestroyView() {
        ...
        super.onDestroyView()
    }

    override var call: ThingCall? = null
    override var listener: ICallInterfaceListener? = null
        set(value) {
            L.d(TAG, "setInterfaceListener $value")
        }

    override fun callStart(call: ThingCall) {

    }

    override fun callCancel(call: ThingCall) {
    }

    override fun callUpdate(call: ThingCall) {
        ...
        when (call.targetState) {
            ThingTargetState.INITIATING -> {
            }
            ThingTargetState.RINGING -> {
            }
            ThingTargetState.CALLING -> {
            }
            ThingTargetState.ANSWER,
            ThingTargetState.ALREADY_ANSWERED,
            -> {
            }
            ThingTargetState.CANCEL -> {
                showToast(R.string.call_cancel_error)
            }
            ThingTargetState.REJECT -> {
                showToast(R.string.call_busy)
            }
            ThingTargetState.OTHER_ANSWERED -> {
                showToast(R.string.call_already_answered)
            }
            ThingTargetState.ALREADY_REJECTED -> {
                showToast(R.string.call_already_rejected)
            }
            ThingTargetState.BUSY -> {
                showToast(R.string.call_busy)
            }
            ThingTargetState.HANG_UP,
            -> {
                showToast(R.string.call_call_finish)
            }
            ThingTargetState.ERROR,
            ThingTargetState.STOP,
            -> {
                showToast(R.string.call_execption)
            }
            ThingTargetState.TIMEOUT -> {
                showToast(R.string.call_timeout)
            }
            else -> {}
        }
    }

    override fun timeout() {
        L.w(TAG, "timeout called")
        ...
    }

}

Check ongoing video call

Check if the SDK is already on a video call. Only one session is allowed at a time. If the SDK is on a call, it will return true. No more video calls can be created.

API description

fun isCalling(): Boolean