discord.js
discord.js copied to clipboard
AudioPlayer does not emit 'playing' when AudioResource is a Readable/Stream
Which package is this bug report for?
voice
Issue description
- Connect bot to voice channel like normal and create an audio player.
- Get an audio stream which is of type Readable.
- Create an audio resource by doing
createAudioResource(<readable stream here>)
- Listen to
player.on('playing')
orplayer.on('stateChange')
- Observe that the 'playing' event is never emitted despite the audio being played.
Other packages: "@discordjs/opus": "^0.9.0" "sodium-native": "^3.4.1"
Code sample
/******minimal******/
const connection = joinVoiceChannel({
channelId: voiceChannelId,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false
});
const player = createAudioPlayer();
connection.subscribe(player)
const url = 'audio url'
const res = await fetch(url);
if (!res) return;
const audio = Readable.fromWeb(res.body);
const resource = createAudioResource(audio);
player.play(resource);
player.on(AudioPlayerStatus.Playing, () => {
console.log('playing event has been emitted') // this will never log
});
/******minimal******/
/******full example******/
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_VOICE_STATES,
Intents.FLAGS.GUILD_MEMBERS,
Intents.FLAGS.GUILD_INTEGRATIONS,
Intents.FLAGS.GUILD_MESSAGES,
],
});
let playAsStream = true;
client.on('messageCreate', (message: Message) => {
if (message.member?.voice?.channel) {
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.member.voice.guild.id,
adapterCreator: message.member.voice.guild.voiceAdapterCreator,
selfDeaf: false,
});
const player = createAudioPlayer();
connection.subscribe(player);
let resource: AudioResource;
if (playAsStream) {
resource = createAudioResource(createReadStream('myPath/to/my/file.mp3'));
playAsStream = false;
} else {
resource = createAudioResource('myPath/to/my/file.mp3');
}
player.play(resource);
player.on('playing', () => {
console.log('playing event emitted') // this will never log when player is a stream
})
}
});
client.login('token');
/******full example******/
// this last full example was taken from a similar issue and modified to showcase this problem
Package version
0.14.0
Node.js version
v18.12.1
Operating system
Windows 10
Priority this issue should have
Medium (should be fixed soon)
Which partials do you have configured?
Not applicable (subpackage bug)
Which gateway intents are you subscribing to?
Guilds, GuildVoiceStates
I have tested this issue on a development release
No response
is the issue only after playing something else before? your code sample is confusing and doesn't reproduce the bug
@nyapat the 'playing' event should be emitted when the bot starts playing something in a voice channel. The issue here is that the event is not being emitted when the stream type is a Readable. In this case, the event is never emitted when the stream type is a Readable. Let me know if there is anything else I can clarify.
@dzlandis It looks like the player.on event handler is not being called because it is not attached to the correct object. In the first code snippet, player is defined and assigned to the result of calling createAudioPlayer(). However, in the second code snippet, player is defined and assigned within the messageCreate event handler, so it is not the same object as the one in the first code snippet.
To fix this, you can move the player.on event handler inside the messageCreate event handler so that it is attached to the correct player object. Here is an example of how the code could be modified:
client.on('messageCreate', (message: Message) => { if (message.member?.voice?.channel) { const connection = joinVoiceChannel({ channelId: message.member.voice.channel.id, guildId: message.member.voice.guild.id, adapterCreator: message.member.voice.guild.voiceAdapterCreator, selfDeaf: false, }); const player = createAudioPlayer(); connection.subscribe(player); let resource: AudioResource; if (playAsStream) { resource = createAudioResource(createReadStream('myPath/to/my/file.mp3')); playAsStream = false; } else { resource = createAudioResource('myPath/to/my/file.mp3'); } player.play(resource);
player.on('playing', () => {
console.log('playing event emitted');
});
} });
This way, the player.on event handler is attached to the player object that is created and used within the messageCreate event handler. This should ensure that the playing event is handled correctly.
Hi there @VirginGingerKid
Sorry for the confusion around the examples. The first code snippet I took from my actual code. It is in a command handler environment, and so it should be under, in this case, the interactionCreate event. I shortened it so it would be easier to see what's happening. The second example I took from a similar issue relating to Readable audio streams.
I don't believe the information you have provided will fix my problem.
I can't repro with the first minimal sample and the second one just never gets to playing, it's closer to the linked issue though imo
@nyapat I updated the code slightly, please try again. If you are still unable to reproduce, if you could describe the behavior you see, that would be great.