Missing user-updated and peer-video-state-change Events

Description

During a video call, the user-updated and peer-video-state-change events are not fired when a new user joins the session or when a user’s video state changes. This prevents the application from detecting:

  1. When a new user joins the session
  2. When a user’s video is turned on/off

As a result, the application cannot properly attach video streams for users who join after the initial connection, or detect when video states change during the call.

In the specific incident:

  • Desktop app joined the session and attached events before 21:16:52 UTC
  • Web app joined the session at 21:16:55 UTC
  • Video started at 21:16:56 UTC
  • The user-updated event was not fired when the web app user joined
  • The peer-video-state-change event was not fired when the web app user’s video was enabled
  • Result: Second user’s video feed did not load on the first user’s application side

Additionally, the log on desktop app shows “No users with video enabled found in the room” which is related - when we join the session, we check for users already present. If another user is already there with video on, we try to attach that video. If no user or no video is on, we log this message. However, in this case, the events should have fired when the second user joined and enabled video.

Timestamp: 4:16 PM ET (21:16:47 UTC)

Session ID: hyxWa6wSSKqUxAvuSoxlfA==

Browser Console Error

No errors are shown in the logs. The events simply do not fire.

Which Web Video SDK version?

2.1.10

Video SDK Code Snippets

The code snippets that are causing the error / issue so we can reproduce:

Desktop Application (Electron):

const initializeSDKAndJoinCall = async () => {
  try {
    const usersInRoom = await videoCallSetUp(signature, session, agentName);

    if (zoomClient) {
      // Event listeners are attached
      zoomClient.on('peer-video-state-change', peerVideoListener);
      zoomClient.on('user-updated', onUserUpdated);
      zoomClient.on('user-removed', onUserRemoved);
    }

    await stream?.startAudio();
    await stream?.startVideo({ hd: true, videoElement });

    // Check for users already in room with video enabled
    if (usersInRoom && usersInRoom.length > 0) {
      for (const user of usersInRoom) {
        if (user.bVideoOn) {
          peerVideoListener({ action: 'Start', userId: user.userId });
          return;
        }
      }
      // This log appears when no users with video are found
      console.log('initializeSDKAndJoinCall: No users with video enabled found in the room');
    }
  } catch (error) {
    console.error('error occurred: initializeSDKAndJoinCall', error);
  }
};

// Event handler for peer video state changes
const peerVideoListener = async (payload: { action: string; userId: number }) => {
  // This handler should be called when peer video state changes
  // but it's not being called when the second user joins
  if (payload.action === 'Start') {
    await setVideoElement(payload.userId);
  }
};

// Event handler for user updates
const onUserUpdated = async (payload: { user: any }) => {
  // This handler should be called when a user joins/updates
  // but it's not being called when the second user joins
  // Handle user update logic
};

Web Application:

const videoCallSetUp = async (data: { signature: string; session: string }, imgURL: string) => {
  try {
    zoomClient = ZoomVideo.createClient();
    
    await zoomClient?.init('en-US', 'CDN', {
      stayAwake: true,
      enforceVirtualBackground: true
    });

    await zoomClient?.join(
      data.session,
      data.signature,
      `User Display Name`
    );

    const mediaStream = zoomClient?.getMediaStream();
    stream = mediaStream;
    
    // Event listeners are attached
    if (zoomClient) {
      console.log('Attaching listener for peer video');
      zoomClient.on('peer-video-state-change', peerVideoLister);
      zoomClient.on('user-updated', onUserUpdated);
      zoomClient.on('user-removed', onUserRemoved);
    }

    await mediaStream?.startAudio();
    await mediaStream?.startVideo({
      hd: true,
      videoElement,
      virtualBackground: { imageUrl: imgURL }
    });
  } catch (error) {
    console.error('error occurred', error);
  }
};

// Event handlers
const peerVideoLister = async (payload: { action: string; userId: number }) => {
  // Should fire when peer video state changes
};

const onUserUpdated = async (payload: { user: any }) => {
  // Should fire when a user joins or updates
};

To Reproduce

Steps to reproduce the behavior:

  1. First user (Desktop app) joins the session and attaches event listeners
  2. First user starts video stream
  3. Second user (Web app) joins the session at a later time
  4. Second user starts video stream
  5. Expected: user-updated event should fire when second user joins
  6. Expected: peer-video-state-change event should fire when second user enables video
  7. Actual: Neither event fires
  8. Result: First user cannot see second user’s video

Timeline from logs:

  • Desktop app joined session & attached events: before 21:16:52 UTC
  • Web app joined session: 21:16:55 UTC
  • Video started: 21:16:56 UTC
  • Events should have fired but did not

Troubleshooting Routes

The troubleshooting attempt types you’ve already exhausted:

  1. Verified event listeners are attached before the second user joins
  2. Verified that events are attached using zoomClient.on() method
  3. Confirmed that the second user successfully joined the session
  4. Confirmed that the second user’s video stream started successfully
  5. Checked that event handlers are properly defined
  6. Verified that the issue is not with event handler logic (handlers work correctly when events do fire)
  7. Confirmed this is an intermittent issue (events work correctly in other calls)

Device:

Desktop Application:

  • Device: Windows Desktop Application
  • OS: Windows 10
  • Browser: Electron (Chromium-based)
  • Browser Version: Electron 38.2.2

Web Application:

  • Device: Desktop/Laptop
  • OS: Windows 10 / macOS
  • Browser: Chrome
  • Browser Version: Latest

Additional context

  • The user-updated and peer-video-state-change events are critical for detecting when users join and when their video states change
  • When these events don’t fire, the application cannot properly manage video streams for users who join after the initial connection
  • This creates a poor user experience where one side cannot see the other’s video
  • The issue is intermittent - events work correctly in most calls
  • We are using Zoom Video SDK version 2.1.10
  • The log message “initializeSDKAndJoinCall: No users with video enabled found in the room” is expected when checking initial state, but events should fire when users join later
  • In this specific case: Desktop app joined first, Web app joined 3 seconds later, but events were not fired to notify the Desktop app of the Web app user’s presence and video state
1 Like

Hey @meet-jeavio

Thanks for your feedback.

It looks like this is the same issue as in the other thread, and I’ve already replied there.

Thanks
Vic