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>
)
}