Video SDK sometimes shows host info under participants video and vice versa

Description
A Host is already joined and it shows both the video and info of host correctly. When a participant joins sometimes it shows host video in place of participants video and vice versa i.e it shows host video with participant’s video and vice versa. But when I resize the Browser it then shows the correct video layout and info.

Browser Console Error
No Error or warning in Console.

Which Web Video SDK version?
@zoom/videosdk”: “^1.11.0”

Video SDK Code Snippets

/**
   * position for self video
   */
  const currentUserIndex = visibleParticipants.findIndex(
    (user) => user.userId === zmClient.getCurrentUserInfo()?.userId
  );
  let selfVideoLayout = null;
  if (currentUserIndex > -1) {
    const item = videoLayout[currentUserIndex];
    if (item && canvasDimension) {
      selfVideoLayout = { ...item, y: canvasDimension.height - item.y - item.height };
    }
  }
  const avatarActionState = useAvatarAction(zmClient, visibleParticipants);
  const networkQuality = useNetworkQuality(zmClient);

 

  const onHostRemoveUser = useCallback((payload: any) => {
    const { reason } = payload;
    console.log(`onHostRemoveUser`, payload);
    setRemovedUserId(payload[0].userId);
    message.error('Host has removed you.');
    setUserRemoved(true);

  }, []);


  const onPhoneCall = async (code: string, phoneNumber: string, name: string, option: DialOutOption) => {
    try {
      await mediaStream?.inviteByPhone(code, phoneNumber, name, option);
    } catch (error) {
      console.log('onPhoneCall ERR', error);
    }
  };
  const onPhoneCallCancel = async (code: string, phoneNumber: string, option: { callMe: boolean }) => {
    if ([DialoutState.Calling, DialoutState.Ringing, DialoutState.Accepted].includes(phoneCallStatus as any)) {
      try {
        await mediaStream?.cancelInviteByPhone(code, phoneNumber, option);
        await new Promise((resolve) => {
          setTimeout(() => {
            resolve(true);
          }, 3000);
        });
      } catch (error) {
        console.log('onPhoneCallCancel ERR', error);
      }
    }
    return Promise.resolve();
  };

  useMount(() => {
    if (mediaStream) {
      console.log('mediaStream.isSupportPhoneFeature()', mediaStream.isSupportPhoneFeature());
      // setIsSupportPhone(!!mediaStream.isSupportPhoneFeature());
      setPhoneCountryList(mediaStream.getSupportCountryInfo() || []);
    }
  });

  console.log('visibleParticipants', visibleParticipants, isRecieveSharing);

  return (
    <div className="viewport">
      <ShareView ref={shareViewRef} onRecieveSharingChange={setIsRecieveSharing} />
      <div
        className={classnames('video-container', {
          'video-container-in-sharing': isRecieveSharing
        })}
      >
        <canvas className="video-canvas" id="video-canvas" width="800" height="600" ref={videoRef} />
        {/* {selfVideoLayout && mediaStream?.isRenderSelfViewWithVideoElement() && ( */}
        <video
          id={SELF_VIDEO_ID}
          className="self-video-tag"
          playsInline
          // muted
          autoPlay
          style={{
            display: 'block',
            width: `${selfVideoLayout?.width}px`,
            height: `${selfVideoLayout?.height}px`,
            top: `${selfVideoLayout?.y}px`,
            left: `${selfVideoLayout?.x}px`,
            pointerEvents: 'none'
          }}
        />
        {/* )} */}
        <AvatarActionContext.Provider value={avatarActionState}>
          <ul className="avatar-list">
            {visibleParticipants.map((user, index) => {
              if (index > videoLayout.length - 1) {
                return null;
              }
              const dimension = videoLayout[index];
              const { width, height, x, y } = dimension;
              const { height: canvasHeight } = canvasDimension;
              return (
                <Avatar
                  participant={user}
                  key={user.userId}
                  isActive={activeVideo === user.userId}
                  networkQuality={networkQuality[`${user.userId}`]}
                  style={{
                    width: `${width}px`,
                    height: `${height}px`,
                    top: `${canvasHeight - y - height}px`,
                    left: `${x}px`
                  }}
                />
              );
            })}
          </ul>
          <RemoteCameraControlPanel />
        </AvatarActionContext.Provider>
      </div>
      <VideoFooter
        className="video-operations"
        sharing
        selfShareCanvas={shareViewRef.current?.selfShareRef}
        isChat={isChat}
        setIsChat={setIsChat}
        showParticipants={showParticipants}
        setShowParticipants={setShowParticipants}
        showSmsModal={showSmsModal}
        setShowSmsModal={setShowSmsModal}
        showPatientCallSmsModal={showPatientCallSmsModal}
        setShowPatientCallSmsModal={setShowPatientCallSmsModal}
        showPhoneCallModal={showPhoneCallModal}
        setShowPhoneCallModal={setShowPhoneCallModal}
        setIsLoading={props?.props?.setIsLoading}
        setLoadingText={props?.props?.setLoadingText}
        setRefresh={props?.props?.setRefresh}
      />

      {totalPage > 1 && <Pagination page={page} totalPage={totalPage} setPage={setPage} inSharing={isRecieveSharing} />}
      <ReportBtn />

      <ChatModal isChat={isChat} setIsChat={setIsChat} />

      <Participants
        showParticipants={showParticipants}
        setShowParticipants={setShowParticipants}
        mediaStream={mediaStream}
        isVideoDecodeReady={isVideoDecodeReady}
        videoRef={videoRef}
        canvasDimension={canvasDimension}
        zmClient={zmClient}
      />

      <Sms
        showSmsModal={showSmsModal}
        setShowSmsModal={setShowSmsModal}
        mediaStream={mediaStream}
        isVideoDecodeReady={isVideoDecodeReady}
        videoRef={videoRef}
        canvasDimension={canvasDimension}
        zmClient={zmClient}
      />

      <PatientCallSms
        showPatientCallSmsModal={showPatientCallSmsModal}
        setShowPatientCallSmsModal={setShowPatientCallSmsModal}
        mediaStream={mediaStream}
        isVideoDecodeReady={isVideoDecodeReady}
        videoRef={videoRef}
        canvasDimension={canvasDimension}
        zmClient={zmClient}
        onPhoneCallClick={onPhoneCall}
        phoneCallStatus={getPhoneCallStatusDescription(phoneCallStatus)}
      />

      <CallOutModal
        visible={showPhoneCallModal}
        setVisible={(visible: boolean) => setShowPhoneCallModal(visible)}
        phoneCallStatus={getPhoneCallStatusDescription(phoneCallStatus)}
        phoneCountryList={phoneCountryList}
        onPhoneCallCancel={onPhoneCallCancel}
        onPhoneCallClick={onPhoneCall}
      />

      {/* {isChat && */}
      {/* <Modal
        open={isChat}
        // className="video-mask-setting-dialog"
        title="Chat"
        footer={null}
        closable
        onCancel={() => setIsChat(false)}
        width={270}
      >
        {' '}
        <Chat />
      </Modal> */}
      {/* } */}
    </div>
  );
};

export default VideoContainer;

Device (please complete the following information):

  • Browser: [e.g. Chrome]

Hey @wajahat

Thanks for your feedback.

This could be an issue with overlapping video coordinates, arising during the calculation of video sizes and coordinates.

Did you refer to our sample app? We recently updated it, and if possible, we recommend using the Individual HTML element rendering method to render video, as it is more convenient.

Thanks
Vic