lavacord
Version:
A simple by design lavalink wrapper made for any discord library.
1 lines • 12.9 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/lib/Player.ts"],"names":[],"mappings":"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","file":"Player.mjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { EventEmitter } from \"events\";\nimport { Rest } from \"./Rest\";\nimport type { LavalinkNode } from \"./LavalinkNode\";\nimport type { Manager } from \"./Manager\";\nimport type { PlayerUpdateVoiceState, JoinOptions, PlayerEvents } from \"./Types\";\nimport {\n\tPlayerState,\n\tTrack,\n\tVoiceState,\n\tFilters,\n\tUpdatePlayerData,\n\tUpdatePlayerResult,\n\tEqualizer,\n\tDestroyPlayerResult,\n\tPlayer as APIPlayer\n} from \"lavalink-types\";\n\n/**\n * The Player class that handles playback and audio manipulation for a specific guild.\n *\n * @remarks\n * This class is responsible for audio playback operations, including playing, stopping,\n * pausing, resuming, and applying audio filters. Each instance represents a player\n * for a specific guild.\n */\nexport class Player extends EventEmitter<PlayerEvents> {\n\t/**\n\t * The current state of this Player\n\t *\n\t * @remarks\n\t * Contains information about the player state from Lavalink, including position, filters, etc.\n\t */\n\tpublic state: PlayerState = {\n\t\ttime: 0,\n\t\tposition: 0,\n\t\tconnected: false,\n\t\tping: 0\n\t};\n\t/**\n\t * The timestamp when the current track started playing\n\t *\n\t * @remarks\n\t * This is a client-side timestamp, not synchronized with Lavalink.\n\t * Can be used to calculate approximate playback position.\n\t */\n\tpublic timestamp: number | null = null;\n\t/**\n\t * Whether the audio playback is currently paused\n\t */\n\tpublic paused = false;\n\t/**\n\t * The current volume level (0-1000)\n\t */\n\tpublic volume = 100;\n\t/**\n\t * The current track in Lavalink's base64 string form\n\t *\n\t * @remarks\n\t * This is null when no track is loaded or when playback has ended.\n\t */\n\tpublic track: Track | null = null;\n\t/**\n\t * The voice connection state from Lavalink API\n\t */\n\tpublic voice: VoiceState | null = null;\n\t/**\n\t * The current audio filters applied to this player\n\t *\n\t * @remarks\n\t * This includes effects like equalizer, karaoke, etc.\n\t */\n\tpublic filters: Filters = {};\n\n\t/**\n\t * Creates a new player instance.\n\t *\n\t * @param node - The Lavalink node this player is connected to.\n\t * @param guildId - The guild ID that this player is associated with.\n\t */\n\tpublic constructor(\n\t\t/**\n\t\t * The Lavalink node this player is connected to\n\t\t */\n\t\tpublic node: LavalinkNode,\n\t\t/**\n\t\t * The guild ID for this player\n\t\t */\n\t\tpublic guildId: string\n\t) {\n\t\tsuper();\n\t}\n\n\t/**\n\t * Updates the current player on the Lavalink node.\n\t * @see {@link https://lavalink.dev/api/rest#update-player}\n\t *\n\t * @param options - The update options to apply to the player.\n\t * @param noReplace - If true, the event will be dropped if there's a currently playing track.\n\t * @returns {Promise<APIPlayer>} The updated player information from Lavalink.\n\t */\n\tpublic async update(options: UpdatePlayerData, noReplace = false): Promise<APIPlayer> {\n\t\tconst d = await Rest.updatePlayer(this.node, this.guildId, options, noReplace);\n\n\t\t// Update local state with response data\n\t\tif (\"track\" in d) this.track = d.track;\n\t\tif (\"volume\" in d) this.volume = d.volume;\n\t\tif (\"paused\" in d) this.paused = d.paused;\n\t\tif (\"state\" in d) this.state = d.state;\n\t\tif (\"filters\" in d) this.filters = d.filters;\n\t\tif (\"voice\" in d) this.voice = d.voice;\n\n\t\treturn d;\n\t}\n\n\t/**\n\t * Plays a track using its base64 encoded string.\n\t *\n\t * @param track - The base64 encoded track string from Lavalink.\n\t * @param options - Additional options for playback.\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic async play(\n\t\ttrack: string,\n\t\toptions?: Omit<UpdatePlayerData, \"track\"> & {\n\t\t\tnoReplace?: boolean;\n\t\t\tuserData?: Record<any, any>;\n\t\t}\n\t): Promise<UpdatePlayerResult> {\n\t\tconst { userData, noReplace, ...opts } = options || {};\n\n\t\tconst d = await this.update({ track: { encoded: track, userData }, ...opts }, noReplace ?? false);\n\t\tthis.timestamp = Date.now();\n\n\t\treturn d;\n\t}\n\n\t/**\n\t * Stops the currently playing track.\n\t *\n\t * @remarks\n\t * This will trigger a \"TrackEndEvent\" with reason \"STOPPED\".\n\t *\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic stop(): Promise<UpdatePlayerResult> {\n\t\treturn this.update({ track: { encoded: null } });\n\t}\n\n\t/**\n\t * Pauses or resumes the current track.\n\t *\n\t * @param pause - Whether to pause (true) or resume (false) playback.\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic async pause(pause: boolean): Promise<UpdatePlayerResult> {\n\t\tconst d = await this.update({ paused: pause });\n\t\tif (this.listenerCount(\"pause\")) this.emit(\"pause\", pause);\n\t\tif (this.manager.listenerCount(\"playerPause\")) this.manager.emit(\"playerPause\", this, pause);\n\t\treturn d;\n\t}\n\n\t/**\n\t * Changes the volume of the current playback.\n\t *\n\t * @param volume - The volume level as a number between 0 and 1000\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic async setVolume(volume: number): Promise<UpdatePlayerResult> {\n\t\tconst d = await this.update({ volume });\n\t\tif (this.listenerCount(\"volume\")) this.emit(\"volume\", volume);\n\t\tif (this.manager.listenerCount(\"playerVolume\")) this.manager.emit(\"playerVolume\", this, volume);\n\t\treturn d;\n\t}\n\n\t/**\n\t * Seeks to a specific position in the current track.\n\t *\n\t * @param position - The position to seek to in milliseconds.\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic async seek(position: number): Promise<UpdatePlayerResult> {\n\t\tconst d = await this.update({ position });\n\t\tif (this.listenerCount(\"seek\")) this.emit(\"seek\", position);\n\t\tif (this.manager.listenerCount(\"playerSeek\")) this.manager.emit(\"playerSeek\", this, position);\n\t\treturn d;\n\t}\n\n\t/**\n\t * Applies audio filters to the current playback.\n\t *\n\t * @param options - The filter options to apply.\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic async setFilters(options: Filters): Promise<UpdatePlayerResult> {\n\t\tconst d = await this.update({ filters: options });\n\t\tif (this.listenerCount(\"filters\")) this.emit(\"filters\", options);\n\t\tif (this.manager.listenerCount(\"playerFilters\")) this.manager.emit(\"playerFilters\", this, options);\n\t\treturn d;\n\t}\n\n\t/**\n\t * Sets the equalizer effect for the current playback.\n\t *\n\t * @param bands - An array of equalizer bands to adjust.\n\t * @returns A promise resolving to the updated player information.\n\t *\n\t * @remarks\n\t * Each band is an object with 'band' (0-14) and 'gain' (-0.25 to 1.0) properties.\n\t */\n\tpublic async setEqualizer(bands: Equalizer[]): Promise<UpdatePlayerResult> {\n\t\treturn this.setFilters({ equalizer: bands });\n\t}\n\n\t/**\n\t * Destroys the player on the Lavalink node.\n\t *\n\t * @remarks\n\t * This sends a destroy signal to Lavalink to clean up resources for this guild ID.\n\t * It doesn't affect the Discord voice connection - use {@link Manager.leave} for that.\n\t *\n\t * @returns {Promise<DestroyPlayerResult>} A promise resolving to the destroy result.\n\t */\n\tpublic async destroy(): Promise<DestroyPlayerResult> {\n\t\treturn Rest.destroyPlayer(this.node, this.guildId);\n\t}\n\n\t/**\n\t * Provides voice server update information to Lavalink to establish a connection.\n\t *\n\t * @param data - The voice update state containing session ID and voice server information.\n\t * @returns A promise resolving to the updated player information.\n\t */\n\tpublic connect(data: PlayerUpdateVoiceState): Promise<UpdatePlayerResult> {\n\t\treturn this.update({\n\t\t\tvoice: {\n\t\t\t\ttoken: data.event.token,\n\t\t\t\tendpoint: data.event.endpoint,\n\t\t\t\tsessionId: data.sessionId,\n\t\t\t\tchannelId: data.channelId\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Switches the player to a different voice channel.\n\t *\n\t * @param channel - The ID of the voice channel to switch to.\n\t * @param options - Options for joining the channel (selfMute, selfDeaf).\n\t * @returns Does not return anything, but sends a WebSocket message to the Lavalink node.\n\t */\n\tpublic switchChannel(channel: string, options: JoinOptions = {}): unknown {\n\t\treturn this.manager.sendWS(this.guildId, channel, options);\n\t}\n\n\t/**\n\t * Gets the manager instance that created this player.\n\t *\n\t * @returns {Manager} The manager instance.\n\t */\n\tpublic get manager(): Manager {\n\t\treturn this.node.manager;\n\t}\n}\n"]}