How can I persist active cameras as it is, and update only added/removed user's camera on each new connection?

I’m developing a Video chat app with React, Redux and Zoom Web SDK.

What I’m trying to do is create camera (canvas API) for each user on room enter, then removing on room leave.

I implemented the feature above, but every time new participants enter or current participants leave, all cameras reset and turn off.

I think this has something to do with states, and rerendering.

Here’s my core code snippet of the feature.

const Session = () => {
    ... otherStates
    const stream = useRef({})
    const [ sessionUsers, setSessionUsers ] = useState([]) // This is the state for currentParticipants.

    useEffect(() => {
    ... otherListeners.

        client.on('peer-video-state-change',async(payload) => {
                const { action, userId } = payload
            
                try {
                    await participantsRender(action,userId)
                } catch (error) {
                    console.log(error)
                }
         })

         client.on('user-added', (user) => {
                const participants = client.getAllUser();
                setSessionUsers(participants)
         })

         client.on('user-removed', (user) => {
                const participants = client.getAllUser();
                setSessionUsers(participants)
         })
    
    },[client])

    const participantsRender = async(action,userId) => {
        if (!action || !userId) return console.log('Empty Param')

        const canvas = document.querySelector(`.canvas[data-canvas_id="${userId}"]`)

        if (action === 'Start'){
            await stream.current.renderVideo(canvas, userId, 640, 360, 0, 0, 2);
        } else if (action === 'Stop') {

            await stream.current.stopRenderVideo(canvas, userId);
        } else {
            console.log('error')
        }
    }

    const toggleVideo = async() => { // This is a feature to start/stop video for the user.

        if (!stream) return

        const uid = client.getCurrentUserInfo().userId
        const canvas = document.querySelector(`.canvas[data-canvas_id="${uid}"]`)

        if(!stream.current?.isCapturingVideo()) {

            try {

                await stream.current?.startVideo();
                stream.current?.renderVideo(canvas, uid, 640, 360, 0, 0, 2);

            } catch (error) {
                console.log(error)
            }
        } else if (stream.current.isCapturingVideo()){
            try {
                await stream.current.stopVideo()
                stream.current?.stopRenderVideo(canvas, uid)
            } catch (error) {
                console.log(error)
            }
        }
    }

    const CanvasRenderer = React.memo(( { state } ) => {
        if (!state) return <></>

        return state.map((item,index) => (
            <div className = "canvas_container" key = {item.userId}>
                <span className = "canvas_name_container">
                    <p className = "canvas_name_self">{item.userId || ''}</p>
                </span>
                <canvas className = "canvas" data-canvas_id = {item.userId}></canvas>
            </div>
        ))
    })
    
   return (
       <div>
         <div className = "canvas_list_container">
                <CanvasRenderer state = {sessionUsers} /> // This is the renderer for cameras.
           </div>
       </div>
   )
}

Hey @younuskorai345

Thanks for your feedback.

It seems that you are using multiple canvases for video rendering. This is not recommended. If you need to manage multiple participants in a session, we suggest that you can maintain a participant list, use a single canvas, and programmatically decide which should draw on the canvas. If you are familiar with React, you can refer to the react-sample-app.

Thanks
Vic

Thanks for the response.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.