Guides

Autoplay

Keep playing when the queue runs out, with the built-in function or your own.

When a queue ends, Hoshimi calls the autoplay function before emitting QueueEnd. If that function queues something, playback continues and no QueueEnd is emitted.

Enabling it

Autoplay is off by default. Turn it on globally, or per player through its storage.

enable-autoplay.ts
const  = ({
  ,
  : [{ : 'localhost', : 2333, : 'youshallnotpass' }],
  : {
    : true, // every player
  },
});

// …or per guild, which the built-in function checks first
await ..('enabledAutoplay', true);

The built-in function handles YouTube (mix radio from the last track) and Spotify (sprec recommendations seeded with recent history), and filters out anything already in the history so it does not loop over the same songs.

Writing your own

Replace it to support other sources or your own recommendation logic. It receives the player and the last track played, and is expected to push onto the queue.

custom-autoplay.ts
const  = ({
  ,
  : [{ : 'localhost', : 2333, : 'youshallnotpass' }],
  : {
    : true,
    async (, ) {
      if (!) return;

      const {  } = await .({
        : `${..} radio`,
        : .,
        : .,
      });

      const  = new (...(() => ..));
      const  = .(() => !.(..)).(0, 5);

      if (.) await ..();
    },
  },
});

Guard against runaway queues

The function runs on every queue end. Filter against player.queue.history — the built-in one does — or a bad recommendation loop will replay the same track forever.

Key Concepts

  • Both switches count: the built-in function plays when queueOptions.autoPlay is on or the player has enabledAutoplay in its storage, so users can toggle it per guild.
  • Runs before QueueEnd: queue something and the event never fires; queue nothing and the queue ends normally.
  • History is the memory: player.queue.history is capped by queueOptions.maxHistory (25 by default), which is also what autoplay dedupes against.