multiple event listeners

so this is the code i have
async create({
channel,
member,
}: {
channel: discord.VoiceChannel;
member: discord.GuildMember;
}) {
// first join the channel.
const connection: VoiceConnection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator,
selfDeaf: false,
});

// get the receiver.
const receiver: VoiceReceiver = connection.receiver;
// start listener loop
const opusStream = receiver.subscribe(member.user.id, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 1500,
},
});

// initiate the buffer chunks.
let buffers: Uint8Array[] = [];

// start listening on the decoder now.
opusStream
.pipe(
new prism.opus.Decoder({
frameSize: 960,
channels: 2,
rate: 48000,
})
)
.on("data", (chunk: Uint8Array) => {
buffers.push(chunk);
});

// Now finally when the data stream ends, run STT.
opusStream.on("end", async () => {
// Create specialID for this recording.
const id = this.client.random.id();
// Using concat create the full buffer.
const buffer = Buffer.concat(buffers);
buffers = [];

// Write to file
await fs.promises.writeFile(`./audio/${id}.pcm`, buffer);
pcmToWav(`./audio/${id}.pcm`, `./audio/${id}.wav`, 48000, 2);

console.log(id);
});
}
async create({
channel,
member,
}: {
channel: discord.VoiceChannel;
member: discord.GuildMember;
}) {
// first join the channel.
const connection: VoiceConnection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator,
selfDeaf: false,
});

// get the receiver.
const receiver: VoiceReceiver = connection.receiver;
// start listener loop
const opusStream = receiver.subscribe(member.user.id, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 1500,
},
});

// initiate the buffer chunks.
let buffers: Uint8Array[] = [];

// start listening on the decoder now.
opusStream
.pipe(
new prism.opus.Decoder({
frameSize: 960,
channels: 2,
rate: 48000,
})
)
.on("data", (chunk: Uint8Array) => {
buffers.push(chunk);
});

// Now finally when the data stream ends, run STT.
opusStream.on("end", async () => {
// Create specialID for this recording.
const id = this.client.random.id();
// Using concat create the full buffer.
const buffer = Buffer.concat(buffers);
buffers = [];

// Write to file
await fs.promises.writeFile(`./audio/${id}.pcm`, buffer);
pcmToWav(`./audio/${id}.pcm`, `./audio/${id}.wav`, 48000, 2);

console.log(id);
});
}
for some reason the end listener count is 2?, and it seems to increase every time i speak?
17 Replies
d.js toolkit
d.js toolkit4mo 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!
six
six4mo ago
No description
ThePedroo
ThePedroo4mo ago
Maybe because you're not removeAllListerners'ing? Could you give this a try? Also, not related directly to djs/voice, but anyway
six
six4mo ago
already did doesnt work, but that suggestion doesnt even make sense to do cuz why would i want to remove the listeners when im not even the one creating a new listener?
ThePedroo
ThePedroo4mo ago
Depending of djs/voice, it can re-utilize the same EventEmitter and cause that
six
six4mo ago
not sure abt it but isnt the object returned by receiver.subscribe a part of djs/voice
ThePedroo
ThePedroo4mo ago
If this is true, yep It's a Node.js EventEmitter
six
six4mo ago
ok wait lemme you give my mental model of whats happening, the code is creating a object with the receiver.subscribe by passing a userId and a end param, this object is named opusStream and then im pipeing the data being recieved from this stream into a decoder, the decoder then emits data chunks whch i accumulate in the buffers array, then when the conditions for the end param are met the opusStream finally runs the callback function passed into the end event, and once this is executed somehow the end listener is doubled that does not make any sense..
ThePedroo
ThePedroo4mo ago
Nvm, it's 2 because of the decoder Didn't see it there It's mostly also reading the end event
six
six4mo ago
oh huh ok but in that case everytime i stop speaking the end event should only run twice am i right? but everytime i speak it doubles from last time
ThePedroo
ThePedroo4mo ago
Probably because djs/voice re-utilizes the same EventEmitter
six
six4mo ago
for example i just started the bot i speak then stop speaking: end runs 2 times i speak then stop speaking: end runs 4 times ....
ThePedroo
ThePedroo4mo ago
(Probably === I'm unsure if djs/voice does that, but if it does, it's because of that)
six
six4mo ago
yea it most likely does but that just seems like a design flaw bcs who would want that? hmm that makes things alot harder
ThePedroo
ThePedroo4mo ago
Not really, but the opposite It boils to you to clean the listeners anyway, as it's not djs/voice internally that is listening to it It's far better than keep re-creating emitters
duck
duck4mo ago
I imagine it's more for performance it's not as if there needs to be multiple streams containing the same data, nor should djs/voice need to copy the data to a new stream for you if you want multiple streams containing the same data, you are free to copy the data yourself the flip side is that it's also up to you to determine whether you've already subscribed to a user's audio (and added event listeners to the stream)
ThePedroo
ThePedroo4mo ago
.. so yeah, you'll need to remove the listeners