Open ahmedbashir-veraio opened 1 year ago
looks like an application issue. could you pls help provide a minimal reproducible project?
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 (
<AgoraVideoPlayer className='vid' videoTrack={user.videoTrack} key={user.uid} />
);
} 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.
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'; })