UNPKG

disrexom

Version:

A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key. Support YouTube, SoundCloud, Bandcamp, Facebook, and 700+ more sites

202 lines 7.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueueManager = void 0; const _1 = require("."); const __1 = require("../.."); /** * Queue manager */ class QueueManager extends _1.BaseManager { /** * Create a {@link Queue} * @private * @param {Discord.VoiceChannel|Discord.StageChannel} channel A voice channel * @param {Song|Song[]} song First song * @param {Discord.TextChannel} textChannel Default text channel * @returns {Promise<Queue|true>} Returns `true` if encounter an error */ async create(channel, song, textChannel) { if (this.has(channel.guild.id)) throw new __1.DisTubeError("QUEUE_EXIST"); const voice = this.voices.create(channel); const queue = new __1.Queue(this.distube, voice, song, textChannel); await queue.taskQueue.queuing(); try { await voice.join(); this._voiceEventHandler(queue); this.add(queue.id, queue); this.emit("initQueue", queue); const err = await this.playSong(queue); return err || queue; } finally { queue.taskQueue.resolve(); } } /** * Get a Queue from this QueueManager. * @method get * @memberof QueueManager# * @param {GuildIDResolvable} queue Resolvable thing from a guild * @returns {Queue?} */ /** * Listen to DisTubeVoice events and handle the Queue * @private * @param {Queue} queue Queue */ _voiceEventHandler(queue) { queue.listeners = { disconnect: error => { queue.delete(); this.emit("disconnect", queue); if (error) this.emitError(error, queue.textChannel); }, error: error => this._handlePlayingError(queue, error), finish: () => this._handleSongFinish(queue), }; for (const event of Object.keys(queue.listeners)) { queue.voice.on(event, queue.listeners[event]); } } /** * Handle the queue when a Song finish * @private * @param {Queue} queue queue * @returns {Promise<void>} */ async _handleSongFinish(queue) { this.emit("finishSong", queue, queue.songs[0]); await queue.taskQueue.queuing(); try { if (queue.stopped) return; if (queue.repeatMode === __1.RepeatMode.QUEUE && !queue.prev) queue.songs.push(queue.songs[0]); if (queue.prev) { if (queue.repeatMode === __1.RepeatMode.QUEUE) queue.songs.unshift(queue.songs.pop()); else queue.songs.unshift(queue.previousSongs.pop()); } if (queue.songs.length <= 1 && (queue.next || queue.repeatMode === __1.RepeatMode.DISABLED)) { if (queue.autoplay) { try { await queue.addRelatedSong(); } catch { this.emit("noRelated", queue); } } if (queue.songs.length <= 1) { if (this.options.leaveOnFinish) queue.voice.leave(); if (!queue.autoplay) this.emit("finish", queue); queue.delete(); return; } } const emitPlaySong = this._emitPlaySong(queue); if (!queue.prev && (queue.repeatMode !== __1.RepeatMode.SONG || queue.next)) { const prev = queue.songs.shift(); delete prev.formats; delete prev.streamURL; if (this.options.savePreviousSongs) queue.previousSongs.push(prev); else queue.previousSongs.push({ id: prev.id }); } queue.next = queue.prev = false; queue.beginTime = 0; const err = await this.playSong(queue); if (!err && emitPlaySong) this.emit("playSong", queue, queue.songs[0]); } finally { queue.taskQueue.resolve(); } } /** * Handle error while playing * @private * @param {Queue} queue queue * @param {Error} error error */ _handlePlayingError(queue, error) { const song = queue.songs.shift(); try { error.name = "PlayingError"; error.message = `${error.message}\nID: ${song.id}\nName: ${song.name}`; } catch { } this.emitError(error, queue.textChannel); if (queue.songs.length > 0) { this.playSong(queue).then(e => { if (!e) this.emit("playSong", queue, queue.songs[0]); }); } else { queue.stop(); } } /** * Play a song on voice connection * @private * @param {Queue} queue The guild queue * @returns {Promise<boolean>} error? */ async playSong(queue) { if (!queue) return true; if (!queue.songs.length) { queue.stop(); return true; } if (queue.stopped) return false; queue.playing = true; queue.paused = false; const song = queue.songs[0]; try { const { url, source, formats, streamURL } = song; if (source === "youtube" && !formats) song._patchYouTube(await this.handler.getYouTubeInfo(url)); if (source !== "youtube" && !streamURL) { for (const plugin of [...this.distube.extractorPlugins, ...this.distube.customPlugins]) { if (await plugin.validate(url)) { const info = [plugin.getStreamURL(url), plugin.getRelatedSongs(url)]; const result = await Promise.all(info); song.streamURL = result[0]; song.related = result[1]; break; } } } const stream = this.handler.createStream(queue); queue.voice.play(stream); song.streamURL = stream.url; return false; } catch (e) { this._handlePlayingError(queue, e); return true; } } /** * Whether or not emit playSong event * @param {Queue} queue Queue * @private * @returns {boolean} */ _emitPlaySong(queue) { var _a, _b; return (!this.options.emitNewSongOnly || (queue.repeatMode === __1.RepeatMode.SONG && queue.next) || (queue.repeatMode !== __1.RepeatMode.SONG && ((_a = queue.songs[0]) === null || _a === void 0 ? void 0 : _a.id) !== ((_b = queue.songs[1]) === null || _b === void 0 ? void 0 : _b.id))); } } exports.QueueManager = QueueManager; //# sourceMappingURL=QueueManager.js.map