The /skip command puts the bot's queue into an invalid state
What's happening? The skip command can put the bot's queue into an invalid state. Setup:
- Add at least 2 songs into the queue
- The first song starts playing
- The /queue command shows the first song as now playing and the second+ songs as in the queue
Then send the /skip command (without specifying any amount).
The observed behavior is as follows:
- The bots starts playing the next song
- The /queue command shows the third song (or "🚫 ope: queue is empty" if there is none) as now playing and the fourth+ songs as in the queue
The expected behavior would be:
- The bots starts playing the next song
- The /queue command shows the second song as now playing and the third+ songs as in the queue
Note: I had cases where it worked fine, but it more often than not displays the incorrect behavior.
Logs N/A - No relevant logs are printed
Screenshots N/A
Additional context I've debugged this locally and here is what I found happens internally:
- The skip commands calls the
services/Player.ts::forwardmethod - This advances the
queuePositionby 1 - The
playmethod is called - The
playmethod gets the new song to play - The
playmethod calls thegetStreammethod - The
getStreammethod stops theaudioPlayer - This usually leads to the
onAudioPlayerIdlemethod being called - The
onAudioPlayerIdlemethod then callsthis.forward(1)again, which then does not call theplaymethod, but does increment thequeuePositionby 1 again - Then the
playmethod continues and actually starts playing the previously acquired new song to play - The skip command then finishes
So the main problem is that the skip command leads to the queuePosition being incremented twice instead of only once.
I do not have sufficient knowledge of this project to suggest a concrete fix for this, but I'd suggest adding a check in the respective third if-statement of the onAudioPlayerIdle method to only call this.forward(1) when the idling was not caused by a skip/seek. One approach that works for the specific scenario I listed:
if (this.getCurrent() === this.nowPlaying) {
await this.forward(1);
}
Runtime I'm running Muse:
- [x] Directly from the cloned repository
- [x] Inside a Docker container
- [ ] Something else (please elaborate)
Versions
- Muse: latest (Docker) / master branch
- Docker: 26.1.4
- OS: Debian / macOS
- Node.js: 23.7.0
- ffmpeg: 7.1
it seems both /skip and /next have the exact issue