Listen for video events

The Video SDK for Android fires several video-related callbacks through ZoomVideoSDKDelegate. Implement the delegate and override the callbacks below to react to video state changes in your session.

If you haven't already set up a delegate, see Integrate for details.

User video status

onUserVideoStatusChanged fires when any user starts or stops their video. Use this callback to update your UI. For example, swap a "video off" placeholder for the rendered video, or vice versa.

override fun onUserVideoStatusChanged(videoHelper: ZoomVideoSDKVideoHelper?, userList: MutableList<ZoomVideoSDKUser>) {
    userList.forEach { user ->
        val isOn = user.videoStatus.isOn
        // update the rendered tile or placeholder for this user
    }
}
@Override
public void onUserVideoStatusChanged(ZoomVideoSDKVideoHelper videoHelper, List<ZoomVideoSDKUser> userList) {
    for (ZoomVideoSDKUser user : userList) {
        boolean isOn = user.getVideoStatus().isOn();
        // update the rendered tile or placeholder for this user
    }
}

Spotlight list changes

onSpotlightVideoChanged fires whenever the spotlighted user list changes, either because a user was added to or removed from the spotlight. Use this to re-render your gallery layout (for example, to enlarge the spotlighted user's tile).

override fun onSpotlightVideoChanged(videoHelper: ZoomVideoSDKVideoHelper?, userList: MutableList<ZoomVideoSDKUser>) {
    // userList contains the current spotlighted users
    // re-render your gallery to reflect the new spotlight state
}
@Override
public void onSpotlightVideoChanged(ZoomVideoSDKVideoHelper videoHelper, List<ZoomVideoSDKUser> userList) {
    // userList contains the current spotlighted users
    // re-render your gallery to reflect the new spotlight state
}

For more information on how to add and remove users from the spotlight, see Spotlight a user.

Multi-camera stream status

onMultiCameraStreamStatusChanged fires when a user enables, disables, mutes, or unmutes a multi-camera stream. The delegate exposes two overloads, one for the raw-data-pipe approach and one for the canvas approach.

override fun onMultiCameraStreamStatusChanged(
    status: ZoomVideoSDKMultiCameraStreamStatus?,
    user: ZoomVideoSDKUser?,
    videoPipe: ZoomVideoSDKRawDataPipe?
) {
    // Raw data pipe variant — see the multi-camera and raw-data docs
}
override fun onMultiCameraStreamStatusChanged(
    status: ZoomVideoSDKMultiCameraStreamStatus?,
    user: ZoomVideoSDKUser?,
    canvas: ZoomVideoSDKVideoCanvas?
) {
    // Canvas variant — subscribe a ZoomVideoSDKVideoView to the canvas to render
}
@Override
public void onMultiCameraStreamStatusChanged(ZoomVideoSDKMultiCameraStreamStatus status,
                                             ZoomVideoSDKUser user,
                                             ZoomVideoSDKRawDataPipe videoPipe) {
    // Raw data pipe variant — see the multi-camera and raw-data docs
}
@Override
public void onMultiCameraStreamStatusChanged(ZoomVideoSDKMultiCameraStreamStatus status,
                                             ZoomVideoSDKUser user,
                                             ZoomVideoSDKVideoCanvas canvas) {
    // Canvas variant — subscribe a ZoomVideoSDKVideoView to the canvas to render
}

For more on how to enable, disable, mute, and unmute multi-camera streams, see Multiple camera support.

External USB camera connected or disconnected

onUVCCameraStatusChange fires when an external USB Video Class (UVC) camera is plugged into or removed from the device. This is useful on tablets that support USB cameras. Surface a "new camera available" UI when a camera is connected, and refresh your camera list when one is removed.

override fun onUVCCameraStatusChange(cameraId: String?, status: UVCCameraStatus?) {
    // Refresh your camera list and update any settings UI
}
@Override
public void onUVCCameraStatusChange(String cameraId, UVCCameraStatus status) {
    // Refresh your camera list and update any settings UI
}

Alpha channel mode

onVideoAlphaChannelStatusChanged fires when alpha channel mode (transparent-background video) is toggled on or off.

override fun onVideoAlphaChannelStatusChanged(isAlphaModeOn: Boolean) {
    // Adjust rendering to handle transparency
}
@Override
public void onVideoAlphaChannelStatusChanged(boolean isAlphaModeOn) {
    // Adjust rendering to handle transparency
}

Video canvas subscription failure

onVideoCanvasSubscribeFail fires when a call to subscribe a ZoomVideoSDKVideoView to a user's video canvas fails. The reason is returned as a ZoomVideoSDKVideoSubscribeFailReason. Common failure cases include exceeding the device's render limit or attempting to subscribe before the SDK has finished initializing.

override fun onVideoCanvasSubscribeFail(
    failReason: ZoomVideoSDKVideoSubscribeFailReason?,
    user: ZoomVideoSDKUser?,
    view: ZoomVideoSDKVideoView?
) {
    // Surface an error in your UI, or retry after the underlying issue is resolved
}
@Override
public void onVideoCanvasSubscribeFail(ZoomVideoSDKVideoSubscribeFailReason failReason,
                                       ZoomVideoSDKUser user,
                                       ZoomVideoSDKVideoView view) {
    // Surface an error in your UI, or retry after the underlying issue is resolved
}

Camera control requests

A remote user can request control of the current user's camera. Two callbacks cover the request/response cycle.

onCameraControlRequestReceived fires when another user requests control. Use the requestHandler parameter to approve or decline.

override fun onCameraControlRequestReceived(
    user: ZoomVideoSDKUser?,
    requestType: ZoomVideoSDKCameraControlRequestType?,
    requestHandler: ZoomVideoSDKCameraControlRequestHandler?
) {
    // Show a confirmation dialog, then call requestHandler.approve() or .decline()
}
@Override
public void onCameraControlRequestReceived(ZoomVideoSDKUser user,
                                           ZoomVideoSDKCameraControlRequestType requestType,
                                           ZoomVideoSDKCameraControlRequestHandler requestHandler) {
    // Show a confirmation dialog, then call requestHandler.approve() or .decline()
}

onCameraControlRequestResult fires on the requesting user's side, with the approval result.

override fun onCameraControlRequestResult(user: ZoomVideoSDKUser?, isApproved: Boolean) {
    // Update the UI based on whether the request was approved
}
@Override
public void onCameraControlRequestResult(ZoomVideoSDKUser user, boolean isApproved) {
    // Update the UI based on whether the request was approved
}

Canvas snapshots

onCanvasSnapshotTaken fires when a snapshot of a video canvas is successfully captured. onCanvasSnapshotIncompatible fires when a snapshot fails because the target user's stream is not compatible with snapshots.

override fun onCanvasSnapshotTaken(user: ZoomVideoSDKUser?, isShare: Boolean) {
    // The snapshot is ready — handle it in your UI
}
override fun onCanvasSnapshotIncompatible(user: ZoomVideoSDKUser?) {
    // Snapshot was not possible — fall back gracefully
}
@Override
public void onCanvasSnapshotTaken(ZoomVideoSDKUser user, boolean isShare) {
    // The snapshot is ready — handle it in your UI
}
@Override
public void onCanvasSnapshotIncompatible(ZoomVideoSDKUser user) {
    // Snapshot was not possible — fall back gracefully
}

Network status

For per-user video network quality changes, listen to onUserNetworkStatusChanged and check for the video-specific data type, or use onUserOverallNetworkStatusChanged for the user's overall quality across all data types.

Note

The dedicated onUserVideoNetworkStatusChanged callback is deprecated in favor of the more general onUserNetworkStatusChanged and onUserOverallNetworkStatusChanged callbacks.