Discord Player
Getting started

4. Control playback

Add pause, resume, skip, stop, and queue commands.

You are reading the v8 docsDev

Add more commands to src/commands.ts. Each one looks up the guild's queue, because a queue exists only after something has been played.

src/commands.ts
import { player } from './player.ts';

/** Builds a command that needs an existing queue and replies with its result. */
function queueCommand(
  name: string,
  description: string,
  action: (queue: NonNullable<ReturnType<typeof player.getQueue>>) => Promise<string> | string,
): Command {
  return {
    data: { name, description },

    async run(interaction) {
      const queue = player.getQueue(interaction.guildId);

      if (!queue?.currentTrack) {
        return interaction.reply({ content: 'Nothing is playing.', flags: MessageFlags.Ephemeral });
      }

      return interaction.reply(await action(queue));
    },
  };
}

const pause = queueCommand('pause', 'Pause playback', async (queue) => {
  await queue.node.pause();

  return 'Paused.';
});

const resume = queueCommand('resume', 'Resume playback', async (queue) => {
  await queue.node.resume();

  return 'Resumed.';
});

const skip = queueCommand('skip', 'Skip the current track', async (queue) => {
  const next = await queue.skip();

  return next ? `Skipped. Now playing **${next.title}**.` : 'Skipped. The queue is empty.';
});

const stop = queueCommand('stop', 'Stop playback and keep the queue', async (queue) => {
  await queue.stop();

  return 'Stopped.';
});

const nowPlaying = queueCommand('queue', 'Show what is playing', (queue) => {
  const upcoming = queue.tracks
    .toArray()
    .slice(0, 10)
    .map((track, index) => `${index + 1}. ${track.title}`);

  return [`Now playing: **${queue.currentTrack?.title}**`, ...upcoming].join('\n');
});

export const commands: Command[] = [play, pause, resume, skip, stop, nowPlaying];

Replace the commands export from the previous step with the last line above. Restart the bot to register the new commands.

What the controls do

CallEffect
queue.node.pause() and resume()Pause or resume the current track
queue.skip()End the current track and start the next one. Returns the next track or null
queue.stop()Stop playback. Upcoming tracks stay in the queue
queue.tracksThe upcoming tracks, not including the current one. Call toArray() for an array
queue.currentTrackThe playing or paused track, or null

Each control is asynchronous. Await it before you reply, so the reply reflects what happened.

Keep building

Continue reading

Manage queues

On this page