Two-Way Calling
Pre-requisite
- The user has to be signed in to perform the following operations.
- The camera supports calling —
device.supportsTwoWayCalling()(clusterVideoCall,0xFC1F, with attribute0xFC1F:0x00).- A
LiveStreamClientfor the camera is connected.
A call has two halves: a call record on the backend (initiateVideoCall / updateVideoCallStatus on deviceServices) and the media on the stream (LiveStreamClient). client.callState (StateFlow<CallState?>, null before any call activity) publishes where the call is — CallState: Calling, Accepted, OnCall, Disconnected (Missed is defined but never produced by the stream) — with helpers isCalling(), isAccepted(), isDisconnected().
viewModelScope.launch {
client.callState.collectLatest { state ->
// Drive the call UI from the state
}
}
Initiate a video call with a device
To initiate a video call with a device, The following method can be used:
device(required): The device object on which the operation has to be performed.request(required): The request object containing the start time of the video call.
val request = InitiateVideoCallRequest(startTime = System.currentTimeMillis())
InstaVision.deviceServices.initiateVideoCall(
device = device,
request = request,
onSuccess = { eventId ->
// The id of the video call event
},
onError = { error ->
// The error object contains the error code and message
},
)
Update the status of a video call
To update the status of an ongoing video call, The following method can be used:
device(required): The device object on which the operation has to be performed.eventId(required): The id of the video call event.request(required): The request object containing the new status of the video call.
val request = UpdateVideoCallStatusRequest(status = "ended")
InstaVision.deviceServices.updateVideoCallStatus(
device = device,
eventId = "eventId",
request = request,
onSuccess = {
// The video call status was updated successfully
},
onError = { error ->
// The error object contains the error code and message
},
)
Start the call on the stream
Once initiateVideoCall has returned the eventId, hand it to the stream. To answer a call the camera raised (a doorbell press with EventTag.CALL), use acceptCall with that event’s id instead.
client.initiateCall(eventId = eventId) // outgoing
client.acceptCall(eventId = eventId) // answering a camera-initiated call
Send the phone’s video
The camera preview for the local video is published as client.cameraViewRenderer (StateFlow<TextureViewRenderer?> — null on cameras without calling and after close()); attach it to your layout, then start capture.
client.startCapturingLocalVideo(cameraFacingFront = true)
client.toggleUpstreamVideo(cameraFacingFront = true, enable = false) // stop / start sending video (releases the capturer)
client.stopCapturingLocalVideo()
Audio follows the microphone controls on Audio Interactions; keep InstaVision.setAppInForeground(...) up to date or the microphone is released in the background.
End the call
client.disconnectCall()
client.clearCallStatus() // resets callState to null (its initial value)
Then report the outcome with updateVideoCallStatus (above).