all repos — simple-discord-music-bot @ ee48e4f6561bef07c4fda9326fd805761a0030fd

A Discord bot making use of discord.js and play-yt.

src/functions/myqueue.ts (view raw)

  1import { createAudioResource, createAudioPlayer, NoSubscriberBehavior, AudioPlayerStatus, VoiceConnection, AudioPlayer } from '@discordjs/voice';
  2import play from 'play-dl';
  3
  4async function resourceFromUrl(url) {
  5    const stream = await play.stream(url);
  6    return createAudioResource(stream.stream, { inputType: stream.type })
  7}
  8
  9export default class MyQueue {
 10    #nowPlaying = null;
 11    #queue = Array();
 12    connection: VoiceConnection;
 13    player: AudioPlayer;
 14    static _instance: MyQueue;
 15    get queue() {
 16        if (this.#nowPlaying)
 17            return [this.#nowPlaying].concat(this.#queue);
 18        return null
 19    }
 20
 21    constructor() {
 22        if (MyQueue._instance) {
 23            return MyQueue._instance
 24        }
 25        MyQueue._instance = this;
 26
 27        this.#nowPlaying = "";
 28        this.connection = null;
 29        this.#queue = Array();
 30        this.player = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Stop } });
 31        this.player.on(AudioPlayerStatus.Idle, () => {
 32            if (this.#queue.length > 0) 
 33                return this.next();
 34            //@ts-expect-error
 35            this.player.subscribers.forEach((e) => e.connection.disconnect());
 36        });
 37    }
 38
 39    clear() {
 40        this.#queue = Array();
 41    }
 42
 43    stop() {
 44        this.clear();
 45        this.#nowPlaying = null;
 46        if (this.player) return this.player.stop();
 47        return false;
 48    }
 49
 50    async next() {
 51        if (this.#queue.length == 0)
 52            return this.stop();
 53        this.#nowPlaying = this.#queue.shift();
 54        const resource = await resourceFromUrl(this.#nowPlaying);
 55        this.player.play(resource);
 56        this.connection.subscribe(this.player);
 57    }
 58
 59    add(url, position=this.#queue.length) {
 60        const l = this.#queue.length;
 61        const normalizedPosition = position % (l + 1);
 62        this.#queue.splice(normalizedPosition, 0, url);
 63        if (l == 0) this.next();
 64    }
 65
 66    async addArray(urls) {
 67        const l = this.#queue.length;
 68        this.#queue.push(...urls);
 69        if (l == 0 && this.player.state.status == AudioPlayerStatus.Idle) this.next();
 70        return l != this.#queue.length;
 71    }
 72
 73    pause() {
 74        this.player.pause();
 75    }
 76
 77    resume() {
 78        this.player.unpause();
 79        this.connection.subscribe(this.player);
 80    }
 81
 82    async outro(url) {
 83        this.player.pause();
 84        const resource = await resourceFromUrl(url);
 85
 86        const p = createAudioPlayer();
 87        p.on(AudioPlayerStatus.Idle, () => {
 88            if (this.player.state.status == AudioPlayerStatus.Paused) {
 89                this.resume();
 90                return
 91            }
 92            //@ts-expect-error
 93            p.subscribers.forEach((e) => e.connection.disconnect());
 94        });
 95
 96        p.play(resource);
 97        this.connection.subscribe(p);
 98    }
 99}
100
101(module).exports = MyQueue;