all repos — simple-discord-music-bot @ 11618de1e7166cedd87a510b2bab1d52ff1c5744

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, { YouTubeVideo } from 'play-dl';
 3
 4async function resourceFromYTUrl(url: string) {
 5    const stream = await play.stream(url);
 6    return createAudioResource(stream.stream, { inputType: stream.type })
 7}
 8
 9export default class MyQueue {
10    #nowPlaying: YouTubeVideo;
11    #queue: Array<YouTubeVideo>;
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 = null;
28        this.connection = null;
29        this.#queue = Array<YouTubeVideo>();
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            this.connection.disconnect();
35        });
36    }
37
38    clear() {
39        this.#queue = Array<YouTubeVideo>();
40    }
41
42    stop() {
43        this.clear();
44        this.#nowPlaying = null;
45        if (this.player) return this.player.stop();
46        return false;
47    }
48
49    async next() {
50        if (this.#queue.length == 0)
51            return this.stop();
52        this.#nowPlaying = this.#queue.shift();
53        const resource = await resourceFromYTUrl(this.#nowPlaying.url);
54        this.player.play(resource);
55        this.connection.subscribe(this.player);
56    }
57
58    add(video: YouTubeVideo, position=this.#queue.length) {
59        const l = this.#queue.length;
60        const normalizedPosition = position % (l + 1);
61        this.#queue.splice(normalizedPosition, 0, video);
62        if (l == 0) this.next();
63    }
64
65    async addArray(urls: YouTubeVideo[]) {
66        const l = this.#queue.length;
67        this.#queue.push(...urls);
68        if (l == 0 && this.player.state.status == AudioPlayerStatus.Idle) this.next();
69        return urls;
70    }
71
72    pause() {
73        this.player.pause();
74    }
75
76    resume() {
77        this.player.unpause();
78        this.connection.subscribe(this.player);
79    }
80
81    async outro(url: string) {
82        this.player.pause();
83        const resource = await resourceFromYTUrl(url);
84
85        const p = createAudioPlayer();
86        p.on(AudioPlayerStatus.Idle, () => {
87            if (this.player.state.status == AudioPlayerStatus.Paused) {
88                this.resume();
89                return
90            }
91            this.connection.disconnect();
92        });
93
94        p.play(resource);
95        this.connection.subscribe(p);
96    }
97}
98
99(module).exports = MyQueue;