Skip to content

Commit

Permalink
feat(player): add option stopOnEnd to enable bot to stay connected …
Browse files Browse the repository at this point in the history
…when audio playback ends, default: `true`
  • Loading branch information
larsrickert committed Aug 6, 2022
1 parent 0ed25f4 commit 78fe5ed
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
9 changes: 8 additions & 1 deletion docs/api/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Gets the player for the given guildId if it exists. Does not create a player.

### remove()

Removes and destroys the player for the given guildId (if any). Will stop playing audio and leave voice channel if connected.
Removes and stops the player for the given guildId (if any).

- **Type**

Expand Down Expand Up @@ -667,6 +667,13 @@ interface PlayerOptions {
*
*/
allowSwitchChannels?: boolean;
/**
* When `true`, player will be stopped when there is nothing more to play (track ends, queue is empty and no repeat mode has been set).
* Otherwise, the player will stay connected to the voice channel and will not play anything.
*
* @default `true`
*/
stopOnEnd?: boolean;
}
````

Expand Down
2 changes: 1 addition & 1 deletion src/player-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class PlayerManager extends TypedEmitter<PlayerManagerEvents> {
}

/**
* Removes and destroys the player for the given guildId (if any). Will stop playing audio and leave voice channel if connected.
* Removes and stops the player for the given guildId (if any).
*/
remove(guildId: string): void {
const player = this.find(guildId);
Expand Down
20 changes: 13 additions & 7 deletions src/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,27 @@ export class Player extends TypedEmitter<PlayerEvents> {
this.emit("trackEnd", oldTrack);
}

// play next queued track if available or stop player (disconnect from voice channel) if nothing more to play
// when track ends, play next queued track if available
if (
oldState.status !== AudioPlayerStatus.Idle &&
newState.status === AudioPlayerStatus.Idle
) {
const nextTrack = await this.getNextTrack();
const currentVoiceChannel = this.getVoiceChannel();

if (!nextTrack) {
this.stop();
} else if (currentVoiceChannel) {
if (nextTrack) {
const voiceChannel = (
oldState.resource as AudioResource<AudioPlayerMetadata>
).metadata.channel;

await this.play({
channel: currentVoiceChannel,
channel: voiceChannel,
tracks: [nextTrack],
});
}

if (!nextTrack && (this.options.stopOnEnd ?? true)) {
this.stop();
}
}
});
}
Expand Down Expand Up @@ -304,6 +309,7 @@ export class Player extends TypedEmitter<PlayerEvents> {
skip(): Track | undefined {
const currentTrack = this.getCurrentTrack();
const stopped = this.audioPlayer.stop();
if (stopped) this.audioResource = undefined;
return stopped ? currentTrack : undefined;
}

Expand Down Expand Up @@ -385,8 +391,8 @@ export class Player extends TypedEmitter<PlayerEvents> {
* Stops the player, clears the current queue and disconnects from the voice channel if connected.
*/
stop(): void {
const connection = getVoiceConnection(this.guildId);
this.clear();
const connection = getVoiceConnection(this.guildId);
connection?.destroy();
}

Expand Down
10 changes: 8 additions & 2 deletions src/types/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export interface PlayerEvents {
*/
trackEnd: (track: Track) => void;
/**
* Emitted after the player was destroyed/player left voice channel.
* Since the player is being destroyed when the queue is empty, this event can also be seen as `queueEnd` event.
* Emitted after the player was stopped/destroyed/player left voice channel.
*/
destroyed: () => void;
/** Emitted before a player error is thrown. */
Expand Down Expand Up @@ -79,6 +78,13 @@ export interface PlayerOptions {
*
*/
allowSwitchChannels?: boolean;
/**
* When `true`, player will be stopped when there is nothing more to play (track ends, queue is empty and no repeat mode has been set).
* Otherwise, the player will stay connected to the voice channel and will not play anything.
*
* @default `true`
*/
stopOnEnd?: boolean;
}

export interface PlayerManagerOptions {
Expand Down

0 comments on commit 78fe5ed

Please sign in to comment.