lavalink-client 2.3.5 → 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -62,7 +62,12 @@ export const DefaultSources = {
62
62
  "http": "http",
63
63
  "https": "https",
64
64
  "link": "link",
65
- "uri": "uri"
65
+ "uri": "uri",
66
+ // jiosaavn
67
+ "jiosaavn": "jssearch",
68
+ "js": "jssearch",
69
+ "jssearch": "jssearch",
70
+ "jsrec": "jsrec"
66
71
  };
67
72
  /** Lavalink Plugins definiton */
68
73
  export const LavalinkPlugins = {
@@ -70,7 +75,9 @@ export const LavalinkPlugins = {
70
75
  LavaSrc: "lavasrc-plugin",
71
76
  GoogleCloudTTS: "tts-plugin",
72
77
  LavaSearch: "lavasearch-plugin",
73
- LavalinkFilterPlugin: "lavalink-filter-plugin"
78
+ Jiosaavn_Plugin: "jiosaavn-plugin",
79
+ LavalinkFilterPlugin: "lavalink-filter-plugin",
80
+ JavaTimedLyricsPlugin: "java-lyrics-plugin"
74
81
  };
75
82
  /** Lavalink Sources regexes for url validations */
76
83
  export const SourceLinksRegexes = {
@@ -108,6 +115,8 @@ export const SourceLinksRegexes = {
108
115
  SpotifyAlbumRegex: /(https?:\/\/)(www\.)?open\.spotify\.com\/((?<region>[a-zA-Z-]+)\/)?(user\/(?<user>[a-zA-Z0-9-_]+)\/)?album\/(?<identifier>[a-zA-Z0-9-_]+)/,
109
116
  AllSpotifyRegex: /(https?:\/\/)(www\.)?open\.spotify\.com\/((?<region>[a-zA-Z-]+)\/)?(user\/(?<user>[a-zA-Z0-9-_]+)\/)?(?<type>track|album|playlist|artist|episode|show)\/(?<identifier>[a-zA-Z0-9-_]+)/,
110
117
  appleMusic: /https?:\/\/?(?:www\.)?music\.apple\.com\/(\S+)/,
118
+ /** From jiosaavn-plugin */
119
+ jiosaavn: /(https?:\/\/)(www\.)?jiosaavn\.com\/(?<type>song|album|featured|artist)\/([a-zA-Z0-9-_\/,]+)/,
111
120
  /** FROM DUNCTE BOT PLUGIN */
112
121
  tiktok: /https:\/\/www\.tiktok\.com\//,
113
122
  mixcloud: /https:\/\/www\.mixcloud\.com\//,
@@ -3,7 +3,7 @@ import type { DestroyReasonsType } from "./Types/Player.js";
3
3
  import type { Track } from "./Types/Track.js";
4
4
  import type { Base64, InvalidLavalinkRestRequest, LavalinkPlayer, LavaSearchQuery, LavaSearchResponse, PlayerUpdateInfo, RoutePlanner, SearchQuery, SearchResult, Session } from "./Types/Utils.js";
5
5
  import type { NodeManager } from "./NodeManager.js";
6
- import type { BaseNodeStats, LavalinkInfo, LavalinkNodeOptions, ModifyRequest, NodeStats, SponsorBlockSegment } from "./Types/Node.js";
6
+ import type { BaseNodeStats, LavalinkInfo, LavalinkNodeOptions, LyricsResult, ModifyRequest, NodeStats, SponsorBlockSegment } from "./Types/Node.js";
7
7
  /**
8
8
  * Lavalink Node creator class
9
9
  */
@@ -271,6 +271,62 @@ export declare class LavalinkNode {
271
271
  */
272
272
  multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
273
273
  };
274
+ lyrics: {
275
+ /**
276
+ * Get the lyrics of a track
277
+ * @param track the track to get the lyrics for
278
+ * @param skipTrackSource wether to skip the track source or not
279
+ * @returns the lyrics of the track
280
+ * @example
281
+ *
282
+ * ```ts
283
+ * const lyrics = await player.node.lyrics.get(track, true);
284
+ * // use it of player instead:
285
+ * // const lyrics = await player.getLyrics(track, true);
286
+ * ```
287
+ */
288
+ get: (track: Track, skipTrackSource?: boolean) => Promise<LyricsResult>;
289
+ /**
290
+ * Get the lyrics of the current playing track
291
+ *
292
+ * @param guildId the guild id of the player
293
+ * @param skipTrackSource wether to skip the track source or not
294
+ * @returns the lyrics of the current playing track
295
+ * @example
296
+ * ```ts
297
+ * const lyrics = await player.node.lyrics.getCurrent(guildId);
298
+ * // use it of player instead:
299
+ * // const lyrics = await player.getCurrentLyrics();
300
+ * ```
301
+ */
302
+ getCurrent: (guildId: string, skipTrackSource?: boolean) => Promise<LyricsResult>;
303
+ /**
304
+ * subscribe to lyrics updates for a guild
305
+ * @param guildId the guild id of the player
306
+ * @returns request data of the request
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * await player.node.lyrics.subscribe(guildId);
311
+ * // use it of player instead:
312
+ * // const lyrics = await player.subscribeLyrics();
313
+ * ```
314
+ */
315
+ subscribe: (guildId: string) => Promise<any>;
316
+ /**
317
+ * unsubscribe from lyrics updates for a guild
318
+ * @param guildId the guild id of the player
319
+ * @returns request data of the request
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * await player.node.lyrics.unsubscribe(guildId);
324
+ * // use it of player instead:
325
+ * // const lyrics = await player.unsubscribeLyrics();
326
+ * ```
327
+ */
328
+ unsubscribe: (guildId: string) => Promise<any>;
329
+ };
274
330
  /**
275
331
  * Request Lavalink statistics.
276
332
  * @returns the lavalink node stats
@@ -432,4 +488,28 @@ export declare class LavalinkNode {
432
488
  deleteSponsorBlock(player: Player): Promise<void>;
433
489
  /** private util function for handling the queue end event */
434
490
  private queueEnd;
491
+ /**
492
+ * Emitted whenever a line of lyrics gets emitted
493
+ * @event
494
+ * @param {Player} player The player that emitted the event
495
+ * @param {Track} track The track that emitted the event
496
+ * @param {LyricsLineEvent} payload The payload of the event
497
+ */
498
+ private LyricsLine;
499
+ /**
500
+ * Emitted whenever the lyrics for a track got found
501
+ * @event
502
+ * @param {Player} player The player that emitted the event
503
+ * @param {Track} track The track that emitted the event
504
+ * @param {LyricsFoundEvent} payload The payload of the event
505
+ */
506
+ private LyricsFound;
507
+ /**
508
+ * Emitted whenever the lyrics for a track got not found
509
+ * @event
510
+ * @param {Player} player The player that emitted the event
511
+ * @param {Track} track The track that emitted the event
512
+ * @param {LyricsNotFoundEvent} payload The payload of the event
513
+ */
514
+ private LyricsNotFound;
435
515
  }
@@ -586,6 +586,104 @@ export class LavalinkNode {
586
586
  }).then((r) => r.map(track => this.NodeManager.LavalinkManager.utils.buildTrack(track, requester)));
587
587
  }
588
588
  };
589
+ lyrics = {
590
+ /**
591
+ * Get the lyrics of a track
592
+ * @param track the track to get the lyrics for
593
+ * @param skipTrackSource wether to skip the track source or not
594
+ * @returns the lyrics of the track
595
+ * @example
596
+ *
597
+ * ```ts
598
+ * const lyrics = await player.node.lyrics.get(track, true);
599
+ * // use it of player instead:
600
+ * // const lyrics = await player.getLyrics(track, true);
601
+ * ```
602
+ */
603
+ get: async (track, skipTrackSource = false) => {
604
+ if (!this.sessionId)
605
+ throw new Error("the Lavalink-Node is either not ready, or not up to date!");
606
+ if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
607
+ throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
608
+ if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
609
+ !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
610
+ throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
611
+ const url = `/lyrics?track=${track.encoded}&skipTrackSource=${skipTrackSource}`;
612
+ return (await this.request(url));
613
+ },
614
+ /**
615
+ * Get the lyrics of the current playing track
616
+ *
617
+ * @param guildId the guild id of the player
618
+ * @param skipTrackSource wether to skip the track source or not
619
+ * @returns the lyrics of the current playing track
620
+ * @example
621
+ * ```ts
622
+ * const lyrics = await player.node.lyrics.getCurrent(guildId);
623
+ * // use it of player instead:
624
+ * // const lyrics = await player.getCurrentLyrics();
625
+ * ```
626
+ */
627
+ getCurrent: async (guildId, skipTrackSource = false) => {
628
+ if (!this.sessionId)
629
+ throw new Error("the Lavalink-Node is either not ready, or not up to date!");
630
+ if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
631
+ throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
632
+ if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
633
+ !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
634
+ throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
635
+ const url = `/sessions/${this.sessionId}/players/${guildId}/track/lyrics?skipTrackSource=${skipTrackSource}`;
636
+ return (await this.request(url));
637
+ },
638
+ /**
639
+ * subscribe to lyrics updates for a guild
640
+ * @param guildId the guild id of the player
641
+ * @returns request data of the request
642
+ *
643
+ * @example
644
+ * ```ts
645
+ * await player.node.lyrics.subscribe(guildId);
646
+ * // use it of player instead:
647
+ * // const lyrics = await player.subscribeLyrics();
648
+ * ```
649
+ */
650
+ subscribe: async (guildId) => {
651
+ if (!this.sessionId)
652
+ throw new Error("the Lavalink-Node is either not ready, or not up to date!");
653
+ if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
654
+ throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
655
+ if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
656
+ !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
657
+ throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
658
+ return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe`, (options) => {
659
+ options.method = "POST";
660
+ }).catch(() => { });
661
+ },
662
+ /**
663
+ * unsubscribe from lyrics updates for a guild
664
+ * @param guildId the guild id of the player
665
+ * @returns request data of the request
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * await player.node.lyrics.unsubscribe(guildId);
670
+ * // use it of player instead:
671
+ * // const lyrics = await player.unsubscribeLyrics();
672
+ * ```
673
+ */
674
+ unsubscribe: async (guildId) => {
675
+ if (!this.sessionId)
676
+ throw new Error("the Lavalink-Node is either not ready, or not up to date!");
677
+ if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
678
+ throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
679
+ if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
680
+ !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
681
+ throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
682
+ return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/unsubscribe`, (options) => {
683
+ options.method = "DELETE";
684
+ }).catch(() => { });
685
+ },
686
+ };
589
687
  /**
590
688
  * Request Lavalink statistics.
591
689
  * @returns the lavalink node stats
@@ -982,6 +1080,15 @@ export class LavalinkNode {
982
1080
  case "ChapterStarted":
983
1081
  this.SponsorBlockChapterStarted(player, player.queue.current, payload);
984
1082
  break;
1083
+ case "LyricsLineEvent":
1084
+ this.LyricsLine(player, player.queue.current, payload);
1085
+ break;
1086
+ case "LyricsFoundEvent":
1087
+ this.LyricsFound(player, player.queue.current, payload);
1088
+ break;
1089
+ case "LyricsNotFoundEvent":
1090
+ this.LyricsNotFound(player, player.queue.current, payload);
1091
+ break;
985
1092
  default:
986
1093
  this.NodeManager.emit("error", this, new Error(`Node#event unknown event '${payload.type}'.`), payload);
987
1094
  break;
@@ -1322,4 +1429,34 @@ export class LavalinkNode {
1322
1429
  }
1323
1430
  return this.NodeManager.LavalinkManager.emit("queueEnd", player, track, payload);
1324
1431
  }
1432
+ /**
1433
+ * Emitted whenever a line of lyrics gets emitted
1434
+ * @event
1435
+ * @param {Player} player The player that emitted the event
1436
+ * @param {Track} track The track that emitted the event
1437
+ * @param {LyricsLineEvent} payload The payload of the event
1438
+ */
1439
+ LyricsLine(player, track, payload) {
1440
+ return this.NodeManager.LavalinkManager.emit("LyricsLine", player, track, payload);
1441
+ }
1442
+ /**
1443
+ * Emitted whenever the lyrics for a track got found
1444
+ * @event
1445
+ * @param {Player} player The player that emitted the event
1446
+ * @param {Track} track The track that emitted the event
1447
+ * @param {LyricsFoundEvent} payload The payload of the event
1448
+ */
1449
+ LyricsFound(player, track, payload) {
1450
+ return this.NodeManager.LavalinkManager.emit("LyricsFound", player, track, payload);
1451
+ }
1452
+ /**
1453
+ * Emitted whenever the lyrics for a track got not found
1454
+ * @event
1455
+ * @param {Player} player The player that emitted the event
1456
+ * @param {Track} track The track that emitted the event
1457
+ * @param {LyricsNotFoundEvent} payload The payload of the event
1458
+ */
1459
+ LyricsNotFound(player, track, payload) {
1460
+ return this.NodeManager.LavalinkManager.emit("LyricsNotFound", player, track, payload);
1461
+ }
1325
1462
  }
@@ -1,6 +1,7 @@
1
1
  import { FilterManager } from "./Filters.js";
2
2
  import { Queue } from "./Queue.js";
3
3
  import type { DestroyReasons } from "./Constants.js";
4
+ import type { Track } from "./Types/Track.js";
4
5
  import type { LavalinkNode } from "./Node.js";
5
6
  import type { SponsorBlockSegment } from "./Types/Node.js";
6
7
  import type { PlayerJson, PlayerOptions, PlayOptions, RepeatMode } from "./Types/Player.js";
@@ -164,6 +165,48 @@ export declare class Player {
164
165
  * Destroy the player and disconnect from the voice channel
165
166
  */
166
167
  destroy(reason?: DestroyReasons | string, disconnect?: boolean): Promise<this>;
168
+ /**
169
+ * Get the current lyrics of the track currently playing on the guild
170
+ * @param guildId The guild id to get the current lyrics for
171
+ * @param skipTrackSource If true, it will not try to get the lyrics from the track source
172
+ * @returns The current lyrics
173
+ * @example
174
+ * ```ts
175
+ * const lyrics = await player.getCurrentLyrics();
176
+ * ```
177
+ */
178
+ getCurrentLyrics(skipTrackSource?: boolean): Promise<import("./Types/Node.js").LyricsResult>;
179
+ /**
180
+ * Get the lyrics of a specific track
181
+ * @param track The track to get the lyrics for
182
+ * @param skipTrackSource If true, it will not try to get the lyrics from the track source
183
+ * @returns The lyrics of the track
184
+ * @example
185
+ * ```ts
186
+ * const lyrics = await player.getLyrics(player.queue.tracks[0], true);
187
+ * ```
188
+ */
189
+ getLyrics(track: Track, skipTrackSource?: boolean): Promise<import("./Types/Node.js").LyricsResult>;
190
+ /**
191
+ * Subscribe to the lyrics event on a specific guild to active live lyrics events
192
+ * @param guildId The guild id to subscribe to
193
+ * @returns The unsubscribe function
194
+ * @example
195
+ * ```ts
196
+ * const lyrics = await player.subscribeLyrics();
197
+ * ```
198
+ */
199
+ subscribeLyrics(): Promise<any>;
200
+ /**
201
+ * Unsubscribe from the lyrics event on a specific guild to disable live lyrics events
202
+ * @param guildId The guild id to unsubscribe from
203
+ * @returns The unsubscribe function
204
+ * @example
205
+ * ```ts
206
+ * const lyrics = await player.unsubscribeLyrics();
207
+ * ```
208
+ */
209
+ unsubscribeLyrics(guildId: string): Promise<any>;
167
210
  /**
168
211
  * Move the player on a different Audio-Node
169
212
  * @param newNode New Node / New Node Id
@@ -571,6 +571,56 @@ export class Player {
571
571
  // return smt
572
572
  return this;
573
573
  }
574
+ /**
575
+ * Get the current lyrics of the track currently playing on the guild
576
+ * @param guildId The guild id to get the current lyrics for
577
+ * @param skipTrackSource If true, it will not try to get the lyrics from the track source
578
+ * @returns The current lyrics
579
+ * @example
580
+ * ```ts
581
+ * const lyrics = await player.getCurrentLyrics();
582
+ * ```
583
+ */
584
+ async getCurrentLyrics(skipTrackSource) {
585
+ return await this.node.lyrics.getCurrent(this.guildId, skipTrackSource);
586
+ }
587
+ /**
588
+ * Get the lyrics of a specific track
589
+ * @param track The track to get the lyrics for
590
+ * @param skipTrackSource If true, it will not try to get the lyrics from the track source
591
+ * @returns The lyrics of the track
592
+ * @example
593
+ * ```ts
594
+ * const lyrics = await player.getLyrics(player.queue.tracks[0], true);
595
+ * ```
596
+ */
597
+ async getLyrics(track, skipTrackSource) {
598
+ return await this.node.lyrics.get(track, skipTrackSource);
599
+ }
600
+ /**
601
+ * Subscribe to the lyrics event on a specific guild to active live lyrics events
602
+ * @param guildId The guild id to subscribe to
603
+ * @returns The unsubscribe function
604
+ * @example
605
+ * ```ts
606
+ * const lyrics = await player.subscribeLyrics();
607
+ * ```
608
+ */
609
+ subscribeLyrics() {
610
+ return this.node.lyrics.subscribe(this.guildId);
611
+ }
612
+ /**
613
+ * Unsubscribe from the lyrics event on a specific guild to disable live lyrics events
614
+ * @param guildId The guild id to unsubscribe from
615
+ * @returns The unsubscribe function
616
+ * @example
617
+ * ```ts
618
+ * const lyrics = await player.unsubscribeLyrics();
619
+ * ```
620
+ */
621
+ unsubscribeLyrics(guildId) {
622
+ return this.node.lyrics.unsubscribe(guildId);
623
+ }
574
624
  /**
575
625
  * Move the player on a different Audio-Node
576
626
  * @param newNode New Node / New Node Id
@@ -4,7 +4,7 @@ import type { LavalinkNodeOptions } from "./Node.js";
4
4
  import type { DestroyReasonsType, PlayerJson } from "./Player.js";
5
5
  import type { ManagerQueueOptions } from "./Queue.js";
6
6
  import type { Track, UnresolvedTrack } from "./Track.js";
7
- import type { GuildShardPayload, SearchPlatform, SponsorBlockChaptersLoaded, SponsorBlockChapterStarted, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, TrackExceptionEvent, TrackEndEvent, TrackStuckEvent, WebSocketClosedEvent, TrackStartEvent } from "./Utils.js";
7
+ import type { GuildShardPayload, SearchPlatform, SponsorBlockChaptersLoaded, SponsorBlockChapterStarted, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, TrackExceptionEvent, TrackEndEvent, TrackStuckEvent, WebSocketClosedEvent, TrackStartEvent, LyricsFoundEvent, LyricsNotFoundEvent, LyricsLineEvent } from "./Utils.js";
8
8
  /**
9
9
  * The events from the lavalink Manager
10
10
  */
@@ -114,6 +114,24 @@ export interface LavalinkManagerEvents {
114
114
  error?: Error | string;
115
115
  functionLayer: string;
116
116
  }) => void;
117
+ /**
118
+ * Emitted when a Lyrics line is received
119
+ * @link https://github.com/topi314/LavaLyrics
120
+ * @event Manager#LyricsLine
121
+ */
122
+ "LyricsLine": (player: Player, track: Track | UnresolvedTrack | null, payload: LyricsLineEvent) => void;
123
+ /**
124
+ * Emitted when a Lyrics is found
125
+ * @link https://github.com/topi314/LavaLyrics
126
+ * @event Manager#LyricsFound
127
+ */
128
+ "LyricsFound": (player: Player, track: Track | UnresolvedTrack | null, payload: LyricsFoundEvent) => void;
129
+ /**
130
+ * Emitted when a Lyrics is not found
131
+ * @link https://github.com/topi314/LavaLyrics
132
+ * @event Manager#LyricsNotFound
133
+ */
134
+ "LyricsNotFound": (player: Player, track: Track | UnresolvedTrack | null, payload: LyricsNotFoundEvent) => void;
117
135
  }
118
136
  /**
119
137
  * The Bot client Options needed for the manager
@@ -3,6 +3,7 @@ import type internal from "stream";
3
3
  import type { LavalinkNode } from "../Node.js";
4
4
  import type { DestroyReasonsType } from "./Player.js";
5
5
  import type { InvalidLavalinkRestRequest, LavalinkPlayer } from "./Utils.js";
6
+ import type { PluginInfo } from "./Track.js";
6
7
  /** Ability to manipulate fetch requests */
7
8
  export type ModifyRequest = (options: RequestInit & {
8
9
  path: string;
@@ -157,6 +158,28 @@ export interface PluginObject {
157
158
  /** The version of the plugin */
158
159
  version: string;
159
160
  }
161
+ export interface LyricsResult {
162
+ /**The name of the source */
163
+ sourceName: string;
164
+ /**The name of the provider */
165
+ provider: string;
166
+ /**The result text */
167
+ text: string | null;
168
+ /**The lyrics lines */
169
+ lines: LyricsLine[];
170
+ /**Information about the plugin */
171
+ plugin: PluginInfo;
172
+ }
173
+ export interface LyricsLine {
174
+ /**The millisecond timestamp */
175
+ timestamp: number;
176
+ /**The line duration in milliseconds */
177
+ duration: number | null;
178
+ /**The line text */
179
+ line: string;
180
+ /**Information about the plugin */
181
+ plugin: PluginInfo;
182
+ }
160
183
  export type LavalinkNodeIdentifier = string;
161
184
  export interface NodeManagerEvents {
162
185
  /**
@@ -1,6 +1,6 @@
1
1
  import type { MiniMap } from "../Utils.js";
2
2
  import type { LavalinkFilterData } from "./Filters.js";
3
- import type { NodeStats } from "./Node.js";
3
+ import type { LyricsLine, LyricsResult, NodeStats } from "./Node.js";
4
4
  import type { LavalinkPlayOptions } from "./Player.js";
5
5
  import type { LavalinkTrack, PluginInfo, Track, UnresolvedTrack } from "./Track.js";
6
6
  /** Helper for generating Opaque types. */
@@ -13,15 +13,16 @@ export type IntegerNumber = Opaque<number, 'Int'>;
13
13
  export type FloatNumber = Opaque<number, 'Float'>;
14
14
  export type LavaSrcSearchPlatformBase = "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ymsearch";
15
15
  export type LavaSrcSearchPlatform = LavaSrcSearchPlatformBase | "ftts";
16
+ export type JioSaavnSearchPlatform = "jssearch" | "jsrec";
16
17
  export type DuncteSearchPlatform = "speak" | "phsearch" | "pornhub" | "porn" | "tts";
17
18
  export type LavalinkClientSearchPlatform = "bcsearch";
18
19
  export type LavalinkClientSearchPlatformResolve = "bandcamp" | "bc";
19
- export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "bcsearch" | LavaSrcSearchPlatform | DuncteSearchPlatform | LavalinkClientSearchPlatform;
20
+ export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "bcsearch" | LavaSrcSearchPlatform | DuncteSearchPlatform | JioSaavnSearchPlatform | LavalinkClientSearchPlatform;
20
21
  export type ClientCustomSearchPlatformUtils = "local" | "http" | "https" | "link" | "uri";
21
22
  export type ClientSearchPlatform = ClientCustomSearchPlatformUtils | // for file/link requests
22
- "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "musicyoutube" | "music youtube" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "musicapple" | "music apple" | "sp" | "spsuggestion" | "spotify" | "spotify.com" | "spotifycom" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic" | "flowerytts" | "flowery" | "flowery.tts" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform;
23
+ "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "musicyoutube" | "music youtube" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "musicapple" | "music apple" | "sp" | "spsuggestion" | "spotify" | "spotify.com" | "spotifycom" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic" | "flowerytts" | "flowery" | "flowery.tts" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform | "js" | "jiosaavn";
23
24
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
24
- export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "appleMusic" | "TwitchTv" | "vimeo";
25
+ export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "jiosaavn" | "appleMusic" | "TwitchTv" | "vimeo";
25
26
  export interface PlaylistInfo {
26
27
  /** The playlist name */
27
28
  name: string;
@@ -62,7 +63,7 @@ export interface MiniMapConstructor {
62
63
  readonly prototype: MiniMap<unknown, unknown>;
63
64
  readonly [Symbol.species]: MiniMapConstructor;
64
65
  }
65
- export type PlayerEvents = TrackStartEvent | TrackEndEvent | TrackStuckEvent | TrackExceptionEvent | WebSocketClosedEvent | SponsorBlockSegmentEvents;
66
+ export type PlayerEvents = TrackStartEvent | TrackEndEvent | TrackStuckEvent | TrackExceptionEvent | WebSocketClosedEvent | SponsorBlockSegmentEvents | LyricsEvent;
66
67
  export type Severity = "COMMON" | "SUSPICIOUS" | "FAULT";
67
68
  export interface Exception {
68
69
  /** Severity of the error */
@@ -148,9 +149,66 @@ export interface SponsorBlockChaptersLoaded extends PlayerEvent {
148
149
  duration: number;
149
150
  }[];
150
151
  }
152
+ /**
153
+ * Types & Events for Lyrics plugin from Lavalink: https://github.com/topi314/LavaLyrics
154
+ */
155
+ export type LyricsEvent = LyricsFoundEvent | LyricsNotFoundEvent | LyricsLineEvent;
156
+ export type LyricsEventType = "LyricsFoundEvent" | "LyricsNotFoundEvent" | "LyricsLineEvent";
157
+ export interface LyricsFoundEvent extends PlayerEvent {
158
+ /** The lyricsfound event */
159
+ type: "LyricsFoundEvent";
160
+ /** The guildId */
161
+ guildId: string;
162
+ /** The lyrics */
163
+ lyrics: LyricsResult;
164
+ }
165
+ export interface LyricsNotFoundEvent extends PlayerEvent {
166
+ /**The lyricsnotfound event*/
167
+ type: "LyricsNotFoundEvent";
168
+ /**The guildId*/
169
+ guildId: string;
170
+ }
171
+ export interface LyricsLineEvent extends PlayerEvent {
172
+ /**The lyricsline event*/
173
+ type: "LyricsLineEvent";
174
+ /** The guildId */
175
+ guildId: string;
176
+ /** The line number */
177
+ lineIndex: number;
178
+ /** The line */
179
+ line: LyricsLine;
180
+ /**skipped is true if the line was skipped */
181
+ skipped: boolean;
182
+ }
183
+ export interface LyricsFoundEvent extends PlayerEvent {
184
+ /** The lyricsfound event */
185
+ type: "LyricsFoundEvent";
186
+ /** The guildId */
187
+ guildId: string;
188
+ /** The lyrics */
189
+ lyrics: LyricsResult;
190
+ }
191
+ export interface LyricsNotFoundEvent extends PlayerEvent {
192
+ /**The lyricsnotfound event*/
193
+ type: "LyricsNotFoundEvent";
194
+ /**The guildId*/
195
+ guildId: string;
196
+ }
197
+ export interface LyricsLineEvent extends PlayerEvent {
198
+ /**The lyricsline event*/
199
+ type: "LyricsLineEvent";
200
+ /** The guildId */
201
+ guildId: string;
202
+ /** The line number */
203
+ lineIndex: number;
204
+ /** The line */
205
+ line: LyricsLine;
206
+ /**skipped is true if the line was skipped */
207
+ skipped: boolean;
208
+ }
151
209
  export type LoadTypes = "track" | "playlist" | "search" | "error" | "empty";
152
210
  export type State = "CONNECTED" | "CONNECTING" | "DISCONNECTED" | "DISCONNECTING" | "DESTROYING";
153
- export type PlayerEventType = "TrackStartEvent" | "TrackEndEvent" | "TrackExceptionEvent" | "TrackStuckEvent" | "WebSocketClosedEvent" | SponsorBlockSegmentEventType;
211
+ export type PlayerEventType = "TrackStartEvent" | "TrackEndEvent" | "TrackExceptionEvent" | "TrackStuckEvent" | "WebSocketClosedEvent" | SponsorBlockSegmentEventType | LyricsEventType;
154
212
  export type TrackEndReason = "finished" | "loadFailed" | "stopped" | "replaced" | "cleanup";
155
213
  export interface InvalidLavalinkRestRequest {
156
214
  /** Rest Request Data for when it was made */
@@ -302,6 +302,9 @@ export class ManagerUtils {
302
302
  if (SourceLinksRegexes.musicYandex.test(queryString) && !node.info?.sourceManagers?.includes("yandexmusic")) {
303
303
  throw new Error("Query / Link Provided for this Source but Lavalink Node has not 'yandexmusic' enabled");
304
304
  }
305
+ if (SourceLinksRegexes.jiosaavn.test(queryString) && !node.info?.sourceManagers?.includes("jiosaavn")) {
306
+ throw new Error("Query / Link Provided for this Source but Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled");
307
+ }
305
308
  return;
306
309
  }
307
310
  transformQuery(query) {
@@ -357,6 +360,12 @@ export class ManagerUtils {
357
360
  if (source === "dzsearch" && node.info?.sourceManagers?.includes("deezer") && !node.info?.sourceManagers?.includes("http")) {
358
361
  throw new Error("Lavalink Node has not 'http' enabled, which is required to have 'dzsearch' to work");
359
362
  }
363
+ if (source === "jsrec" && !node.info?.sourceManagers?.includes("jiosaavn")) {
364
+ throw new Error("Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled, which is required to have 'jsrec' to work");
365
+ }
366
+ if (source === "jssearch" && !node.info?.sourceManagers?.includes("jiosaavn")) {
367
+ throw new Error("Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled, which is required to have 'jssearch' to work");
368
+ }
360
369
  if (source === "scsearch" && !node.info?.sourceManagers?.includes("soundcloud")) {
361
370
  throw new Error("Lavalink Node has not 'soundcloud' enabled, which is required to have 'scsearch' work");
362
371
  }
@@ -7,7 +7,9 @@ export declare const LavalinkPlugins: {
7
7
  LavaSrc: string;
8
8
  GoogleCloudTTS: string;
9
9
  LavaSearch: string;
10
+ Jiosaavn_Plugin: string;
10
11
  LavalinkFilterPlugin: string;
12
+ JavaTimedLyricsPlugin: string;
11
13
  };
12
14
  /** Lavalink Sources regexes for url validations */
13
15
  export declare const SourceLinksRegexes: Record<SourcesRegex, RegExp>;