Discord.js voice resampling issues.

Not sure if this goes in djs-questions or other-js-ts Hello! Currently I'm trying to get voice recognition on my discord bot through voice chat using Vosk, and I'm getting there however, I do not know how to resample the voice stream I am provided via connection.receiver.subscribe. This isn't exactly to do with discord.js but any help would still be appreciated 🙂 Here's my code for context:
opusStream = connection.receiver.subscribe(userId, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 2000,
},
});

// PROBLEMS ARE HERE I BELIEVE?
const prism = await import('prism-media'); // Required for audio decoding
const pcmStream = new prism.opus.Decoder({
rate: 16000,
channels: 1,
frameSize: 320,
});

opusStream.pipe(pcmStream);
// on the discord.js voice-example gh page, the author uses pipeline(), but I think this also works?

pcmStream.on('data', (chunk) => {
// Voice detection here. This works if I'm able to fully pipe it.
});
opusStream = connection.receiver.subscribe(userId, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 2000,
},
});

// PROBLEMS ARE HERE I BELIEVE?
const prism = await import('prism-media'); // Required for audio decoding
const pcmStream = new prism.opus.Decoder({
rate: 16000,
channels: 1,
frameSize: 320,
});

opusStream.pipe(pcmStream);
// on the discord.js voice-example gh page, the author uses pipeline(), but I think this also works?

pcmStream.on('data', (chunk) => {
// Voice detection here. This works if I'm able to fully pipe it.
});
Whenever I do anything with opusStream it continually throws RangeError [ERR_OUT_OF_RANGE]: The value of "sourceEnd" is out of range. It must be >= 0 && <= 3. Received 8 at the end of the stream. After I record my audio again it throws: Error [ERR_STREAM_PUSH_AFTER_EOF]: stream.push() after EOF I think discord gives 48kHz audio back, but I need it in 16kHz. DISCORD.JS Version: 14.17.2 DISCORD.JS@Voice Version: 0.18.0
10 Replies
d.js toolkit
d.js toolkit6d 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!
pat
pat6d ago
well it doesnt make sense to decode something and tell the decoder its 16khz but its actually 48khz you are decoding /from 16khz/ here, not the other way around decode to 48khz PCM and then resample it to 16khz if that's truly necessary (idk if theres anything to do this natively so ffmpeg -ar 16000 might be the way to go)
TheUntitledGoose
TheUntitledGooseOP6d ago
I have little knowledge on how audio decoding/encoding works. Thank you for the answer, I'll try that and see how it goes. I've updated the code to both have a 48khz decoder and a resampler to 16khz, however I still get
RangeError [ERR_OUT_OF_RANGE]: The value of "sourceEnd" is out of range. It must be >= 0 && <= 3. Received 8
at validateOffset (node:buffer:123:3)
at Buffer.compare (node:buffer:940:5)
at Decoder._transform (/mnt/x/discord_date_bot/node_modules/prism-media/dist/opus/Decoder.js:19:19)
at Transform._write (node:internal/streams/transform:175:8)
at writeOrBuffer (node:internal/streams/writable:392:12)
at _write (node:internal/streams/writable:333:10)
at Writable.write (node:internal/streams/writable:337:10)
at AudioReceiveStream.ondata (node:internal/streams/readable:809:22)
at AudioReceiveStream.emit (node:events:529:35)
at addChunk (node:internal/streams/readable:368:12)
RangeError [ERR_OUT_OF_RANGE]: The value of "sourceEnd" is out of range. It must be >= 0 && <= 3. Received 8
at validateOffset (node:buffer:123:3)
at Buffer.compare (node:buffer:940:5)
at Decoder._transform (/mnt/x/discord_date_bot/node_modules/prism-media/dist/opus/Decoder.js:19:19)
at Transform._write (node:internal/streams/transform:175:8)
at writeOrBuffer (node:internal/streams/writable:392:12)
at _write (node:internal/streams/writable:333:10)
at Writable.write (node:internal/streams/writable:337:10)
at AudioReceiveStream.ondata (node:internal/streams/readable:809:22)
at AudioReceiveStream.emit (node:events:529:35)
at addChunk (node:internal/streams/readable:368:12)
opusStream = connection.receiver.subscribe(userId, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 2000,
},
});

const prism = await import('prism-media');
const pcmStream = new prism.opus.Decoder({
rate: 16000,
channels: 1,
frameSize: 320,
});


const opusDecoder = new prism.opus.Decoder({
rate: 48000, // Discord 48kHz
channels: 2,
frameSize: 960
});

const ffmpeg = new prism.FFmpeg({
args: [
'-loglevel', 'debug',
'-f', 's16le', // Input format
'-ar', '48000', // Input rate
'-ac', '2', // Input channels
'-i', 'pipe:0', // Input from pipe
'-f', 's16le', // Output format
'-ar', '16000', // Output rate
'-ac', '1', // Output channels (mono)
'pipe:1' // Output to pipe
]
});
// I'm not too sure about this FFmpeg command. The stackoverflow comment I found says this is okay?

opusStream.pipe(opusDecoder).pipe(ffmpeg)
opusStream = connection.receiver.subscribe(userId, {
end: {
behavior: EndBehaviorType.AfterSilence,
duration: 2000,
},
});

const prism = await import('prism-media');
const pcmStream = new prism.opus.Decoder({
rate: 16000,
channels: 1,
frameSize: 320,
});


const opusDecoder = new prism.opus.Decoder({
rate: 48000, // Discord 48kHz
channels: 2,
frameSize: 960
});

const ffmpeg = new prism.FFmpeg({
args: [
'-loglevel', 'debug',
'-f', 's16le', // Input format
'-ar', '48000', // Input rate
'-ac', '2', // Input channels
'-i', 'pipe:0', // Input from pipe
'-f', 's16le', // Output format
'-ar', '16000', // Output rate
'-ac', '1', // Output channels (mono)
'pipe:1' // Output to pipe
]
});
// I'm not too sure about this FFmpeg command. The stackoverflow comment I found says this is okay?

opusStream.pipe(opusDecoder).pipe(ffmpeg)
Seems like a problem with decoding the discord output stream? Is discord not 48khz?
pat
pat6d ago
prob dont need all that extra stuff in the ffmpeg args pretty sure it can infer however that is not the issue it appears, it's todo with the decoder
pat
pat6d ago
this works-on-my-machine, what version of prism-media do you have?
No description
TheUntitledGoose
TheUntitledGooseOP6d ago
2.0.0-alpha0 I think. It was used in the discord.js voice examples since they used OggDemuxer or something, so I just still have that.
pat
pat5d ago
hmm, can you try editing the source then (cause a certain pr outside of discordjs's repo is 2 years old) in decoder.js there's two if statements chunk.compare(OPUS_HEAD) and chunk.compare(OPUS_TAGS), add chunk.length >= 8 && chunk.compare ... there
TheUntitledGoose
TheUntitledGooseOP5d ago
It seems like editing the source has made the error disappear 🙏 Thank you so so much. Never would of thought to actual edit the library that I was using. Sounded to complicated I guess.
No description
pat
pat5d ago
Well yeah it was an issue fixed in the older version of the library but not in v2 - probably related to how discord abruptly changed how their voice packets were structured resulting in some unpacked fields being bigger than expected (or atleast thats my guess)
TheUntitledGoose
TheUntitledGooseOP5d ago
Hate how the v2 has ogg decoder but 1.3.5, latest, doesn't. It's either you get only ogg or you get a build that works but doesn't convert to ogg. Weird

Did you find this page helpful?