When more than 1 participant, video not rendering

Format Your New Topic as Follows:

Video SDK Type and Version
*videosdk 1.7.10

Description
When there is one participant in my session, video seem to render correctly, when a second participant opens the camera, this error occurs: reason: “subscribe video counts greater than maximum size (1)”
2. type: “INVALID_OPERATION”

Error?

    1. reason: “subscribe video counts greater than maximum size (1)”
  1. type: “INVALID_OPERATION”.*

Troubleshooting Routes
The troubleshooting attempt types you’ve already exhausted, including testing with the appropriate sample app (found on Zoom · GitHub).

How To Reproduce
Steps to reproduce the behavior including:
1. Authentication method or app type
2. Any errors
3. Browser/client type and version

import React, { useState, useContext, useEffect, useCallback, useRef } from ‘react’;
import { Button, Tooltip } from ‘antd’;
import { AudioOutlined, AudioMutedOutlined, VideoCameraAddOutlined, VideoCameraOutlined } from ‘@ant-design/icons’;
import { IconFont } from ‘…/component/icon-font.tsx’;
import ZoomContext from ‘…/context/zoom-context.ts’;
import MediaContext from ‘…/context/media-context.ts’;
import ‘./Video.css’;
import ‘./VideoContainer.scss’;

const VideoContainer = () => {
const client = useContext(ZoomContext);
const mediaStream = useContext(MediaContext);
const selfViewVideoRef = useRef(null);
const selfViewCanvasRef = useRef(null);
const participantVideoCanvasRef = useRef(null);
const [participants, setParticipants] = useState();
const [videoStarted, setVideoStarted] = useState(false);
const [audioStarted, setAudioStarted] = useState(false);
const [isMuted, setIsMuted] = useState(false);
const [isSAB, setIsSAB] = useState(false);

useEffect(() => {

    const HandleUserAdded = (payload) => {
        const allUsers = client.getAllUser();
        console.log(allUsers)
        setParticipants(allUsers.map(user => user.userId));
        console.log(participants)

        allUsers.forEach((user) => {
            if(user.bVideoOn) {
                const index = allUsers.indexOf(payload.userId);
                const xCoord = index * 960;
                if (index >= 0) {
                    mediaStream.renderVideo(
                        document.querySelector('#participant-videos-canvas'), 
                        user.userId, 
                        960, 
                        540, 
                        xCoord, 
                        0, 
                        2
                    );
                }
            }
        });
    };

    const handleUserRemoved = (payload) => {
            setParticipants((prevParticipants) => prevParticipants.filter(id => id !== payload.userId));
            mediaStream.stopRenderVideo(participantVideoCanvasRef.current, payload.userId);
    };

    const handleVideoStateChange = (payload) => {
        const allUsers = client.getAllUser();
        const index = allUsers.indexOf(payload.userId);
        const xCoord = index * 960;

        if (payload.action === 'Start') {
            mediaStream.renderVideo(
                document.querySelector('#participant-videos-canvas'), 
                payload.userId,
                960,
                540,
                xCoord,
                0,
                2
            );
        } else if (payload.action === 'Stop') {
            mediaStream.stopRenderVideo(participantVideoCanvasRef.current, payload.userId);
        }
    };

    
    client.on('user-added', HandleUserAdded);
    client.on('user-removed', handleUserRemoved);
    client.on('peer-video-state-change', handleVideoStateChange);

    return () => {
        client.off('user-added', HandleUserAdded);
        client.off('user-removed', handleUserRemoved);
        client.off('peer-video-state-change', handleVideoStateChange);
    };
}, [client, mediaStream, participants]);

const startVideoButton = useCallback(async () => {
    if (!videoStarted) {
        if (!!window.chrome && !(typeof SharedArrayBuffer === 'function')) {
            setIsSAB(false);
            await mediaStream.startVideo({videoElement: selfViewVideoRef.current});
        }
        else {
            setIsSAB(true);
            await mediaStream.startVideo();
            mediaStream.renderVideo(selfViewCanvasRef.current, client.getCurrentUserInfo().userId, 1920, 1080, 0, 0, 2);
        }
        setVideoStarted(true)
    }
    else {
        await mediaStream.stopVideo();
        if (isSAB) {
            mediaStream.stopRenderVideo(selfViewCanvasRef.current, client.getCurrentUserInfo().userId);
        }
        setVideoStarted(false);
    }

}, [mediaStream, videoStarted, client, isSAB])

const startAudioButton = useCallback(async () => {
    if(audioStarted) {
        if (isMuted) {
            await mediaStream.unmuteAudio();
            setIsMuted(false)
        } else {
            await mediaStream.muteAudio();
            setIsMuted(true);
        }
    } else {
        await mediaStream.startAudio();
        setAudioStarted(true);
    }
}, [mediaStream, audioStarted, isMuted])

return (
    <div className='videoContainer'>
        <div className="video-section">
            <div className="canvas-container self-view-container">
                {isSAB ?
                    <canvas ref={selfViewCanvasRef} id="self-view-canvas" className="self-video-canvas" width="1920" height="1080"></canvas> :
                    <video ref={selfViewVideoRef} id="self-view-video" className="self-video-canvas" width="1920" height="1080"></video>
                }
            </div>
            <div className="canvas-container participant-container">
                <canvas ref={participantVideoCanvasRef} id="participant-videos-canvas" className="participant-video-canvas" width="1920" height="1080"></canvas>
            </div>
        </div>
        <div className="video-footer">
            <Tooltip title={`${videoStarted ? 'Stop Camera' : 'Start Camera'}`}>
                <Button
                    className='camera-button'
                    icon={videoStarted ? <VideoCameraOutlined /> : <VideoCameraAddOutlined />}
                    shape='circle'
                    size='large'
                    onClick={startVideoButton}
                />
            </Tooltip>
            <Tooltip title={`${audioStarted ? isMuted ? 'unmute' : 'mute' : 'Start Audio'}`}>
                <Button
                    className='camera-button'
                    icon={audioStarted ? isMuted ? <AudioMutedOutlined /> : <AudioOutlined /> : <IconFont type="icon-headset" />}
                    shape="circle"
                    size='large'
                    onClick={startAudioButton}
                />
            </Tooltip>
        </div>
    </div>
)

}

export default VideoContainer;

This is the code snippet if needed.
Thanks for your help in advance.

Hi @EH2077 ,

Here is a thread on a past post where a user dealt with the same issue. Please try the solutions mentioned (involving SharedArrayBuffer) and let me know if the issue resolves,

Thanks,
Rehema

2 Likes