UNPKG

dismusic

Version:

An easy music package for discord.js version 14

180 lines (172 loc) 7 kB
/** * @typedef {Object} SpotifyAuth The auth codes for spotify * @property {string} clientId The client ID of your spotify application * @property {string} clientSecret The client secret of your spotify application * @property {string} refresh_token the refresh token for your spotify application * @property {string|undefined} market the market to search on spotify */ /** * @typedef {Object} AuthCodes The auth codes for the client * @property {SpotifyAuth} spotify The Spotify Auth codes */ const EventEmiter = require('node:events') const regexpConstants = require('./constants/regex') const search = require('./utils/search') const play = require('play-dl') const QueueBuilder = require('./utils/Queue.js') const { getVoiceConnection } = require('@discordjs/voice') class Player extends EventEmiter { /** * Create a new Dismusic Player * @param {Object} client The discord.js Client you want to use * @param {AuthCodes|undefined} authCodes The auth code for spotify */ constructor(client, authCodes) { if(!client) throw new Error('[ Dismusic Error ] A valid discord client is required to create a player') super() this.client = client this.queues = {} this.queues.players = {} if(authCodes?.spotify) { play.getFreeClientID().then(async (id) => { play.setToken({ soundcloud: { client_id: id }, spotify: { client_id: authCodes.clientId, client_secret: authCodes.clientSecret, refresh_token: authCodes.refresh_token, market: authCodes?.market || 'US' } }) this.hasSpotifyToken = true }) } else { console.log('[ Dismusic Warning ] Spotify data was not provided! This is required to fall back to play-dl when spotify-url-info returns undefined') } } /** * Search a track * @param {String} query The query you want to search * @param {String} engine The place where you want to search. Can be 'YouTube' or 'SoundCloud' */ async search(query, engine) { if(!query) throw new Error('[ Dismusic Error ] A valid query must be provided') if(typeof query != 'string') throw new Error(`[ Dismusic Error ] Query must be a type of String. Got ${typeof query}`) // validate the string const isYTUrl = String(query).match(regexpConstants.youtube) const isSpotifyUrl = String(query).match(regexpConstants.spotify) const isSoundCloudUrl = String(query).match(regexpConstants.soundCloud) const isSpotifyPlaylistUrl = String(query).match(regexpConstants.spotifyPlaylist) if(isYTUrl) { const searchResults = await search.YouTube(query) return searchResults } if(isSpotifyUrl) { const searchResults = await search.Spotify(query) return searchResults } if(isSoundCloudUrl) { const searchResults = await search.SoundCloud(query) return searchResults } if(isSpotifyPlaylistUrl) { const spotifyPlaylistData = await search.SpotifyPlaylist(query) return spotifyPlaylistData } if(!engine || engine === 'YouTube') { const searchResults = await search.YouTubeSearch(query) return searchResults } if(engine === 'SoundCloud') { const searchResults = await search.SoundCloudSearch(query) return searchResults } } /** * Get the existing Queue of a guild * @param {object} guild The guild of the queue you want to get * @returns {QueueBuilder} The queue of guild */ async getQueue(guild) { const queue = this.queues[guild.id] return queue } /** * Check if the queue exists in a guild * @param {object} guild the guild you want to validate * @returns {boolean} true if the guild exists in the queue, false otherwise */ existsQueue(guild) { const queue = this?.queues[guild.id] return queue ? true : false } /** * Create a new queue * @param {object} guild the guild you want to create a queue for * @param {object} options The options for creating a queue * @returns {QueueBuilder} The queue you just created */ async createQueue(guild, options) { let queueFunctions = new QueueBuilder(guild, options) queueFunctions.on('EmitTrackStart', async (track) => { const queue = await this.getQueue(guild) this.emit('trackStart', queue, track) }) queueFunctions.on('emitQueueEnded', async () => { const queue = await this.getQueue(guild) const connection = getVoiceConnection(guild.id) || undefined try { connection.destroy() } catch (error) { // no? } this.emit('queueEnded', queue) try { queueFunctions.removeAllListeners() } catch { try { this.queues[guild.id].removeAllListeners() } catch (error) { // no? } } delete this.queues.players[guild.id] delete this.queues[guild.id] }) const queue = queueFunctions const player = queueFunctions.player this.queues[guild.id] = queue this.queues.players[guild.id] = player this.queues[guild.id].metadata = options?.metadata || undefined this.queues.players[guild.id] this.queues[guild.id].kill = async () => { const connection = getVoiceConnection(guild.id) || undefined const status = this.queues.players[guild.id].state if(connection && status !== 'idle') { this.queues.players[guild.id].stop() connection.destroy() } else if(status === 'idle') { connection.destroy() } else if(connection) { connection.destroy() } delete this.queues[guild.id] delete this.queues.players[guild.id] queueFunctions = undefined } return this.queues[guild.id] } /** * Inject custom data to your tracks * @param {object} param target: "the target you want to inject", key: "the key that will be injected into the target", value: "the value that will be injected into the target" * @returns {any} injected target */ injectCustomData({ target, key, value }) { if(!target || !key || !value) throw new Error("[ Dismusic Error ] Target, key or value cannot be undefined") target[key] = value return target } } module.exports = Player