discord.js
discord.js copied to clipboard
AudioPlayer does not play local files if a stream was played before
Which package is this bug report for?
voice
Issue description
Playing local files is working but there is a corner-case where it isn't.
- Play a file or something else via a stream
- Play a file via file path
=> result: player is stuck in buffering
Current workaround: Always provide files via a stream.
Other package versions:
- @discordjs/opus:
0.7.0
- sodium:
3.0.2
Installed:
- ffmpeg:
4.3.3-0
Code sample
/******minimal******/
// first:
const resource = createAudioResource(createReadstream(filePath))
player.play(resource);
// second
const resource = createAudioResource(filePath);
player.play(resource);
/******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);
}
});
client.login('token');
/******full example******/
Package version
13.4.0 (voice 0.7.5)
Node.js version
16.13.1
Operating system
Ubuntu 20.04.3 (WSL)
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, GUILD_MEMBERS, GUILD_INTEGRATIONS, GUILD_VOICE_STATES, GUILD_MESSAGES
I have tested this issue on a development release
No response
Also got this just now! I looked everywhere for a solution and your workaround is great.
Thanks for the workaround! This bugged me for months.
For those wondering, createReadStream
comes from fs
const { createReadStream } = require('fs')
Thanks for the workaround!! Just spent a good few hours wondering what was wrong with my code
Thank you, that bug bothered me for the last five days
The workaround in OP's post solves the initial problem for me, but now some of the files I try to play don't play at all, while others work perfectly fine 😢
It mainly looks like audio from Apple's MOV files and larger AAC files don't work when streamed (I can try to submit examples soon) while they work perfectly fine when passed in as file paths (since the voice module then uses FFMPEG magic to make them work).
This is an ongoing issue for me, so I'll try around more and might post a workaround snippet soon or even a PR if I find a good solution 😀
Hi there, just popping in here to say I am also experiencing this issue!
This issue does not appear to only be related to local files. I've been trying to play audio from a stream and then switch to playing audio from a URL and I am getting the same issue.
If this could be fixed soon, that would be awesome!
Hello,
Thank you so much OP for the workaround, it worked perfectly for local files (as far as I can tell for now).
However as @dzlandis said, it is indeed also a problem with playing audio from a URL after playing audio from a stream. A quick fix would be more than welcome!
I just created a similar issue which also has to do with Readable audio streams here: #8905
I'm putting this here to suggest that these two issues may somewhat be connected. However, they are different enough that I created two separate issues for them.
Also seeing this issue with voice package v0.16.0
and @discordjs/opus v0.9.0
Looking at the command line ffmpeg is started with, the issue seems to be a problem with an additional input flag getting appended to any ffmpeg calls post streamed audio conversion. Specifically, it's an -i -
input param getting added, telling ffmpeg to get the input audio from STDIN (which is what the streamed audio call does); so it sits there waiting for data instead of reading from the file it was also passed.
Streamed ffmpeg conversion:
ffmpeg -i - -analyzeduration 0 -loglevel 0 -f s16le -ar 48000 -ac 2 pipe:1
Successful file ffmpeg conversion:
ffmpeg -i /path/to/file.mp3 -analyzeduration 0 -loglevel 0 -f s16le -ar 48000 -ac 2 pipe:1
Failed/Hanging file ffmpeg conversion (post-streamed conversion):
ffmpeg -i /path/to/file.mp3 -i - -analyzeduration 0 -loglevel 0 -f s16le -ar 48000 -ac 2 pipe:1
AHA, which comes from letting prism add the -i -
for the readable input. Prism adds it to the passed args (if there was no input arg found), and the args are a direct reference to the FFMPEG_PCM_ARGUMENTS
const for readable input (instead of when the input is a string, where it constructs a new array and spreads the contents of the const array into that new array), which results in the constant getting permanently modified to have -i -
.
Will put in a PR in a bit.