Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple remote users gets unpublished on unpublishing one remote user #359

Open
ahmedbashir-veraio opened this issue Apr 7, 2023 · 2 comments

Comments

@ahmedbashir-veraio
Copy link

This is my useEffect code. I have subscribed to the user-joined, user-unpublished events. When multiple remote users join the channel, their video gets published successfully. When any of the remote user leaves the channel, all remote users get unpublished somehow.
useEffect(() => {
let initClientCallbacks = () => {
videoCallContext.client.on("user-published", async (remoteUser, mediaType) => {
await videoCallContext.client.subscribe(remoteUser, mediaType);
if (mediaType == "video") {
console.log("subscribe video success");
// remoteUser.videoTrack.play(document.getElementById("subscriber"));
setUsers((prevUsers) => {
return [...prevUsers, remoteUser];
});
}
if (mediaType == "audio") {
console.log("subscribe audio success");
remoteUser.audioTrack.play();
}
const p = document.getElementById('publisher');
p.style.width = '30%';
p.style.height = '30%';
p.style.left = '10px';
p.style.bottom = '10px';
})

        videoCallContext.client.on("user-unpublished", async (user, type) => {
            if (user.uid === leavingUserUidRef.current) {
                return;
            }

            console.log("unpublished", user, type);

            if (type === "audio") {
                user.audioTrack?.stop();
            }

            if (type === "video") {
                setUsers((prevUsers) => {
                    return prevUsers.filter((User) => User.uid !== user.uid);
                });
            }

            setInitiatePolling(true);
        });

        videoCallContext.client.on("user-left", (user) => {
            console.log("leaving", user);
            console.log("leaving id", user.uid);
            leavingUserUidRef.current = user.uid;
            setUsers((prevUsers) => {
                return prevUsers.filter((User) => User.uid !== user.uid);
            });
            setInitiatePolling(true);
        });


    }

    initClientCallbacks();


}, [appointmentInformation?.id]);
@plutoless
Copy link
Contributor

looks like an application issue. could you pls help provide a minimal reproducible project?

@ahmedbashir-veraio
Copy link
Author

Sure. Let me share with you the config and other details.
I am using agora-rtc-sdk-ng 4.16.1
RTC Client configuration is mode: "rtc", codec: "vp8"

React component markup:

`<Draggable
id="my-draggable-element"
disabled={isExpanded === true ? true : false}
position={controlledPosition}
onDrag={handleDrag}
bounds="body">
<div id="videos" className="no-select" style={{
visibility: videoOpenState === false ? "hidden" : "visible",
// height: '75%',
// width: '75%'
}}>



{users.length > 0 &&
users.map((user) => {
if (user.videoTrack) {
return (

);
} else return null;
})}

                    <div ref={publisherRef} id="publisher" className='video-publisher'></div>
                </div>
            </div>
        </Draggable>`

AgoraVideoPlayer Component

const AgoraVideoPlayer = props => {
    const vidDiv = useRef(null)
    const { videoTrack, config, ...other } = props
    useLayoutEffect(() => {
        if (vidDiv.current !== null) videoTrack.play(vidDiv.current, config)
        return () => {
            videoTrack.stop()
        }
    }, [videoTrack])

    return <div {...other} ref={vidDiv} />
}

Here's a complete minimal component

VideoCall.js

const client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

const VideoCall = () => {
  const [users, setUsers] = useState([]);
  
  //functions to get session id and token id from backend
....

  //After getting the session id and token id following function is called
  function join(apiKey, sessionId, token){
     client.join(apiKey, session, token)
     .then(()=>{ client.publish([localAudioTrack, localVideoTrack])}) //these tracks are available in ref
  }

//The events for remote users are registered in useEffect
  useEffect(()=>{
       client.on("user-published", async (remoteUser, mediaType) => {
                client.subscribe(remoteUser, mediaType);
                if (mediaType == "video") {
                    console.log("subscribe video success");
                    // remoteUser.videoTrack.play(document.getElementById("subscriber"));
                    setUsers((prevUsers) => {
                        return [...prevUsers, remoteUser];
                    });
                }
                if (mediaType == "audio") {
                    console.log("subscribe audio success");
                    remoteUser.audioTrack.play();
                }
     }

     client.on("user-unpublished", async (user, type) => {
         
                console.log("unpublished", user, type);

                if (type === "audio") {
                    user.audioTrack?.stop();
                }

                if (type === "video") {
                    setUsers((prevUsers) => {
                        return prevUsers.filter((User) => User.uid !== user.uid);
                    });
                }
            });

     client.on("user-left", (user) => {

                leavingUserUidRef.current = user.uid;
                setUsers((prevUsers) => {
                    return prevUsers.filter((User) => User.uid !== user.uid);
                });
            });



  });

return (
<div id="videos">
                    <div id="subscriber">
                      
                        {users.length > 0 &&
                            users.map((user) => {
                                if (user.videoTrack) {
                                    return (
                                        <AgoraVideoPlayer className='vid' videoTrack={user.videoTrack} key={user.uid} />
                                    );
                                } else return null;
                            })}

                        <div ref={publisherRef} id="publisher" className='video-publisher'></div>
                    </div>
                </div>
)



}

Everything works fine while publishing. Suppose there are 4 users in a call. If any 1 remote user unpublishes the video or leaves the call, the unpublish event is triggered for the other users also with their unique uid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants