Speaking 'start'/'end' events trigger continuously - Caused by while loop?

I have two ts at global level: let startedSpeakingTimestamp; let stoppedSpeakingTimestamp; then as part of my VoiceConnection/VoiceReceiver setup, I have my speaking event listeners below: botConnection.receiver.speaking.on('start', (userId) => { if (!startedSpeakingTimestamp) { client.users.fetch(userId) .then(user => { startedSpeakingTimestamp = Date.now(); const startedDate = new Date(startedSpeakingTimestamp) console.log(${user.displayName} started speaking at ${startedDate}); }) } }); botConnection.receiver.speaking.on('end', (userId) => { if ((!stoppedSpeakingTimestamp || Date.now() > stoppedSpeakingTimestamp) && userActive) { client.users.fetch(userId) .then(user => { stoppedSpeakingTimestamp = Date.now(); const stoppedDate = new Date(stoppedSpeakingTimestamp) console.log(${user.displayName} finished speaking at ${stoppedDate}); }); } }); Continued below
18 Replies
d.js toolkit
d.js toolkit3mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
geeks
geeks3mo ago
and I also have an async function that is triggered as part of the core flow, which has a while loop async function startTimer() { .......... while (userActive) { elapsedTime = Date.now() - unmuteTimestamp; silenceTime = remainingTime = speakTime - elapsedTime if (!startedSpeakingTimestamp && elapsedTime >= startedSpeakingLimit) { console.log("${currentMember.displayName} did not start speaking."); await muteUser(currentMember); queue.push(queue.shift()); userActive = false; } else if (remainingTime < speakTimeAlert && !timeAlert) { timeAlert = true; const remainingSecs = Math.round(remainingTime/1000) const nextMember = queue[1] const msgText = "${currentMember.displayName} has ${String(remainingSecs)} seconds left. ${nextMember.displayName} is next up to speak." const channel = client.channels.cache.get(textChannelId); if (channel && channel.isTextBased) { await channel.send(msgText); } else { console.error('Text channel not found!'); } } else if (elapsedTime >= speakTime) { console.log("${currentMember.displayName} reached maximum speak time."); await muteUser(currentMember); queue.push(queue.shift()); userActive = false; timeAlert = false; } await new Promise(resolve => setTimeout(resolve, userSwitchInterval)); } continued below My logs are showing that I'm constantly triggering the start/end events for speaking: 2024-05-05T22:09:27.857Z geeks started speaking at Sun May 05 2024 23:09:28 GMT+0100 (British Summer Time) geeks finished speaking at Sun May 05 2024 23:09:29 GMT+0100 (British Summer Time) geeks finished speaking at Sun May 05 2024 23:09:29 GMT+0100 (British Summer Time) geeks finished speaking at Sun May 05 2024 23:09:30 GMT+0100 (British Summer Time) geeks finished speaking at Sun May 05 2024 23:09:30 GMT+0100 (British Summer Time) (the started speaking I've handled, but still showing the end speaking triggers continuously) My question is - Is this due to the while loop I have? Is it likely 'cutting off' the voice stream, thus triggering an 'end' speaking state? Or could it be due to something else? Thx
d.js docs
d.js docs3mo ago
To share long code snippets, use a service like gist, sourcebin, starbin, or similar instead of posting them as large code blocks or files.
geeks
geeks3mo ago
Gist
Stick Room
Stick Room. GitHub Gist: instantly share code, notes, and snippets.
ThePedroo
ThePedroo3mo ago
Using a setTimeout and clearing when a user speaks would be easier, no? I'll see if I can try that code out once I get home Seems more like an issue with your ifs in start and end event You should both not use setTimeout to wait for it to get ready -- djs/voice has helpers for that And not rely on a while loop to listen for changes -- events exist for that
ThePedroo
ThePedroo3mo ago
removing those ifs gave the proper results
No description
geeks
geeks3mo ago
Thanks for the info, am looking at what happens when I remove the ifs in start and end regarding the setTimeout/while loop.... are you referring to this block? async function waitForConnectionStatus(botConnection) { while (botConnection._state.status !== 'ready') { // Adjust the property and condition as needed await new Promise(resolve => setTimeout(resolve, 1000)); // Adjust the delay as needed } }
ThePedroo
ThePedroo3mo ago
Correct One of them being that one And the other the biggest while loop
geeks
geeks3mo ago
I'm still getting repeated start/end triggers.... geeks started speaking at Wed May 08 2024 02:37:20 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:21 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) But I still have the while/set timeout loop/block in my startTimer function... (the biggest while loop) You mentioned events exist that could better handle the requirements to consistently check for changes - how would I modify the below to do that? https://gist.github.com/lucromano/72456246a763b844776b7111b6919ef4
Gist
gist:72456246a763b844776b7111b6919ef4
GitHub Gist: instantly share code, notes, and snippets.
ThePedroo
ThePedroo3mo ago
setting a timeout when a user starts to speak and clear when it stops it
ThePedroo
ThePedroo3mo ago
discord.js
discord.js
discord.js is a powerful Node.js module that allows you to interact with the Discord API very easily. It takes a much more object-oriented approach than most other JS Discord libraries, making your bot's code significantly tidier and easier to comprehend.
ThePedroo
ThePedroo3mo ago
And this
geeks
geeks3mo ago
i think this is the state for the VoiceConnection object when it's initialising no? ie. when it's going through signalling, connecting, ready etc? Nothing to do with tracking the receiver.speaking events (start or end)
ThePedroo
ThePedroo3mo ago
That's for this
geeks
geeks3mo ago
The thing is that my while loop is actually checking for Timestamps, not the start/end events. The start/end events are updating the Timestamps which are then referred to I'll try without any while loops to see what happens So, I still get erroneous 'end' events triggering, even without any while loops. It's nothing to do with my microphone or setup, because it happens with all users. It must be something to do with the configuration of sensitivity or something else regarding listening to the speaking user.
ThePedroo
ThePedroo3mo ago
Could you be a little more specific with ettoneous end events?
geeks
geeks2mo ago
geeks started speaking at Wed May 08 2024 02:37:20 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:21 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks finished speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) geeks started speaking at Wed May 08 2024 02:37:23 GMT+0100 (British Summer Time) But thats genuinely not happening. It's continuous voice... There must be an option to delay the trigger, such that regular speech can be considered ongoing.
ThePedroo
ThePedroo2mo ago
Yep, it uses a setTimeout in end basically But even continuous voice gets little "ends" sometimes