# Listen for video events The Video SDK for iOS fires several video-related callbacks through `ZoomVideoSDKDelegate`. Conform to the delegate and implement the callbacks below to react to video state changes in your session. If you haven't already set up a delegate, see [Integrate](/docs/video-sdk/ios/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. ```swift func onUserVideoStatusChanged(_ helper: ZoomVideoSDKVideoHelper?, user userArray: [ZoomVideoSDKUser]?) { userArray?.forEach { user in let isOn = user.getVideoCanvas()?.videoStatus()?.on // update the rendered tile or placeholder for this user } } ``` ```objectivec - (void)onUserVideoStatusChanged:(ZoomVideoSDKVideoHelper *)helper user:(NSArray *)userArray { for (ZoomVideoSDKUser *user in userArray) { BOOL isOn = [[user videoCanvas] videoStatus].on; // 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). ```swift func onSpotlightVideoChanged(_ videoHelper: ZoomVideoSDKVideoHelper?, userList: [ZoomVideoSDKUser]?) { // userList contains the current spotlighted users // re-render your gallery to reflect the new spotlight state } ``` ```objectivec - (void)onSpotlightVideoChanged:(ZoomVideoSDKVideoHelper *)videoHelper userList:(NSArray *)userList { // userList contains the current spotlighted users // re-render your gallery to reflect the new spotlight state } ``` For more on how to add and remove users from the spotlight, see [Spotlight a user](/docs/video-sdk/ios/video/spotlight/). ## 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. ```swift func onMultiCameraStreamStatusChanged(_ status: ZoomVideoSDKMultiCameraStreamStatus, parentUser user: ZoomVideoSDKUser?, videoPipe: ZoomVideoSDKRawDataPipe?) { // Raw data pipe variant — see the multi-camera and raw-data docs } func onMultiCameraStreamStatusChanged(_ status: ZoomVideoSDKMultiCameraStreamStatus, parentUser user: ZoomVideoSDKUser?, videoCanvas: ZoomVideoSDKVideoCanvas?) { // Canvas variant — subscribe a UIView to the canvas to render } ``` ```objectivec - (void)onMultiCameraStreamStatusChanged:(ZoomVideoSDKMultiCameraStreamStatus)status parentUser:(ZoomVideoSDKUser *)user videoPipe:(ZoomVideoSDKRawDataPipe *)videoPipe { // Raw data pipe variant — see the multi-camera and raw-data docs } - (void)onMultiCameraStreamStatusChanged:(ZoomVideoSDKMultiCameraStreamStatus)status parentUser:(ZoomVideoSDKUser *)user videoCanvas:(ZoomVideoSDKVideoCanvas *)videoCanvas { // Canvas variant — subscribe a UIView to the canvas to render } ``` For more on how to enable, disable, mute, and unmute multi-camera streams, see [Multiple camera support](/docs/video-sdk/ios/video/multiple-cameras/). ## Alpha channel mode `onVideoAlphaChannelStatusChanged` fires when alpha channel mode (transparent-background video) is toggled on or off. ```swift func onVideoAlphaChannelStatusChanged(_ isAlphaChannelOn: Bool) { // Adjust rendering to handle transparency } ``` ```objectivec - (void)onVideoAlphaChannelStatusChanged:(BOOL)isAlphaChannelOn { // Adjust rendering to handle transparency } ``` ## Video canvas subscription failure `onVideoCanvasSubscribeFail` fires when a call to subscribe a `UIView` to a user's video canvas fails. The reason is returned as a `ZoomVideoSDKSubscribeFailReason`. Common failure cases include exceeding the device's render limit or attempting to subscribe before the SDK has finished initializing. ```swift func onVideoCanvasSubscribeFail(_ failReason: ZoomVideoSDKSubscribeFailReason, user: ZoomVideoSDKUser?, view: UIView?) { // Surface an error in your UI, or retry after the underlying issue is resolved } ``` ```objectivec - (void)onVideoCanvasSubscribeFail:(ZoomVideoSDKSubscribeFailReason)failReason user:(ZoomVideoSDKUser *)user view:(UIView *)view { // Surface an error in your UI, or retry after the underlying issue is resolved } ``` ## Camera control requests `onCameraControlRequestResult` fires on the requesting user's side when a remote camera control request is granted or denied. For the full flow, see [Remote camera control](/docs/video-sdk/ios/video/remote-camera-control/). ```swift func onCameraControlRequestResult(_ user: ZoomVideoSDKUser?, approved isApproved: Bool) { // Update the UI based on whether the request was approved } ``` ```objectivec - (void)onCameraControlRequestResult:(ZoomVideoSDKUser *)user approved:(BOOL)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. ```swift func onCanvasSnapshotTaken(_ user: ZoomVideoSDKUser, isShare: Bool) { // The snapshot is ready — handle it in your UI } func onCanvasSnapshotIncompatible(_ user: ZoomVideoSDKUser) { // Snapshot was not possible — fall back gracefully } ``` ```objectivec - (void)onCanvasSnapshotTaken:(ZoomVideoSDKUser *)user isShare:(BOOL)isShare { // The snapshot is ready — handle it in your UI } - (void)onCanvasSnapshotIncompatible:(ZoomVideoSDKUser *)user { // Snapshot was not possible — fall back gracefully } ``` ## Network status For per-user video network quality changes, implement `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. ```swift func onUserNetworkStatusChanged(_ type: ZoomVideoSDKDataType, level: ZoomVideoSDKNetworkStatus, user: ZoomVideoSDKUser?) { // React to network quality for a specific data type (such as video) } func onUserOverallNetworkStatusChanged(_ level: ZoomVideoSDKNetworkStatus, user: ZoomVideoSDKUser?) { // React to the user's overall network quality } ``` ```objectivec - (void)onUserNetworkStatusChanged:(ZoomVideoSDKDataType)type level:(ZoomVideoSDKNetworkStatus)level user:(ZoomVideoSDKUser *)user { // React to network quality for a specific data type (such as video) } - (void)onUserOverallNetworkStatusChanged:(ZoomVideoSDKNetworkStatus)level user:(ZoomVideoSDKUser *)user { // React to the user's overall network quality } ```