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:
- When a new user joins the session
- 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-updatedevent was not fired when the web app user joined - The
peer-video-state-changeevent 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:
- First user (Desktop app) joins the session and attaches event listeners
- First user starts video stream
- Second user (Web app) joins the session at a later time
- Second user starts video stream
- Expected:
user-updatedevent should fire when second user joins - Expected:
peer-video-state-changeevent should fire when second user enables video - Actual: Neither event fires
- 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:
- Verified event listeners are attached before the second user joins
- Verified that events are attached using
zoomClient.on()method - Confirmed that the second user successfully joined the session
- Confirmed that the second user’s video stream started successfully
- Checked that event handlers are properly defined
- Verified that the issue is not with event handler logic (handlers work correctly when events do fire)
- 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-updatedandpeer-video-state-changeevents 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