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.
- package/README.md +18 -0
- package/dist/cjs/structures/LavalinkManagerStatics.d.ts +2 -0
- package/dist/cjs/structures/LavalinkManagerStatics.js +11 -2
- package/dist/cjs/structures/Node.d.ts +81 -1
- package/dist/cjs/structures/Node.js +137 -0
- package/dist/cjs/structures/Player.d.ts +43 -0
- package/dist/cjs/structures/Player.js +50 -0
- package/dist/cjs/structures/Types/Manager.d.ts +19 -1
- package/dist/cjs/structures/Types/Node.d.ts +23 -0
- package/dist/cjs/structures/Types/Utils.d.ts +64 -6
- package/dist/cjs/structures/Utils.js +9 -0
- package/dist/esm/structures/LavalinkManagerStatics.d.ts +2 -0
- package/dist/esm/structures/LavalinkManagerStatics.js +11 -2
- package/dist/esm/structures/Node.d.ts +81 -1
- package/dist/esm/structures/Node.js +137 -0
- package/dist/esm/structures/Player.d.ts +43 -0
- package/dist/esm/structures/Player.js +50 -0
- package/dist/esm/structures/Types/Manager.d.ts +19 -1
- package/dist/esm/structures/Types/Node.d.ts +23 -0
- package/dist/esm/structures/Types/Utils.d.ts +64 -6
- package/dist/esm/structures/Utils.js +9 -0
- package/dist/types/structures/LavalinkManagerStatics.d.ts +2 -0
- package/dist/types/structures/Node.d.ts +81 -1
- package/dist/types/structures/Player.d.ts +43 -0
- package/dist/types/structures/Types/Manager.d.ts +19 -1
- package/dist/types/structures/Types/Node.d.ts +23 -0
- package/dist/types/structures/Types/Utils.d.ts +64 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -722,3 +722,21 @@ if(previousTrack) {
|
|
|
722
722
|
- FIXED autoplay not working :: Accidentally added an invalid if statement, which made autoplay not working anymore (during the if statement to not prevent autoplay spam)
|
|
723
723
|
- Added a new AutoplayExecution Debug Log
|
|
724
724
|
- Added more samples to the Testbot related configuration
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
## **Version 2.3.6
|
|
728
|
+
- Added Lyrics Support:
|
|
729
|
+
- New Player Functions:
|
|
730
|
+
- **` const lyrics = await player.getCurrentLyrics(false); `** -> *Get lyrics of current playing track*
|
|
731
|
+
- **` const lyrics = await player.getLyrics(track, true); `** -> *Get lyrics of a specific track with ignoring it's sources*
|
|
732
|
+
- **` player.subscribeLyrics(); `** -> *Subscribe this guild to retrieve "live lyrics" as the song is *playing
|
|
733
|
+
- **` player.unsubscribeLyrics(); `** -> *Unsubscribe from lyrics
|
|
734
|
+
- New Node Functions ( same as from player, just so you can access it without player too ):*
|
|
735
|
+
- **` const lyrics = await player.node.lyrics.getCurrent(player.guildId, false); `**
|
|
736
|
+
- **` const lyrics = await player.node.lyrics.get(track, true); `**
|
|
737
|
+
- **` player.node.lyrics.subscribe(player.guildId); `**
|
|
738
|
+
- **` player.node.lyrics.unsubscribe(player.guildId); `**
|
|
739
|
+
- New Manager Event sfor Lyrics:
|
|
740
|
+
- **` lavalink.on("LyricsLine", (player, track, lyricsLine) => {}); `**
|
|
741
|
+
- **` lavalink.on("LyricsFound", (player, track, data) => {}); `**
|
|
742
|
+
- **` lavalink.on("LyricsNotFound", (player, track, lyricsLine) => {}); `**
|
|
@@ -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>;
|
|
@@ -65,7 +65,12 @@ exports.DefaultSources = {
|
|
|
65
65
|
"http": "http",
|
|
66
66
|
"https": "https",
|
|
67
67
|
"link": "link",
|
|
68
|
-
"uri": "uri"
|
|
68
|
+
"uri": "uri",
|
|
69
|
+
// jiosaavn
|
|
70
|
+
"jiosaavn": "jssearch",
|
|
71
|
+
"js": "jssearch",
|
|
72
|
+
"jssearch": "jssearch",
|
|
73
|
+
"jsrec": "jsrec"
|
|
69
74
|
};
|
|
70
75
|
/** Lavalink Plugins definiton */
|
|
71
76
|
exports.LavalinkPlugins = {
|
|
@@ -73,7 +78,9 @@ exports.LavalinkPlugins = {
|
|
|
73
78
|
LavaSrc: "lavasrc-plugin",
|
|
74
79
|
GoogleCloudTTS: "tts-plugin",
|
|
75
80
|
LavaSearch: "lavasearch-plugin",
|
|
76
|
-
|
|
81
|
+
Jiosaavn_Plugin: "jiosaavn-plugin",
|
|
82
|
+
LavalinkFilterPlugin: "lavalink-filter-plugin",
|
|
83
|
+
JavaTimedLyricsPlugin: "java-lyrics-plugin"
|
|
77
84
|
};
|
|
78
85
|
/** Lavalink Sources regexes for url validations */
|
|
79
86
|
exports.SourceLinksRegexes = {
|
|
@@ -111,6 +118,8 @@ exports.SourceLinksRegexes = {
|
|
|
111
118
|
SpotifyAlbumRegex: /(https?:\/\/)(www\.)?open\.spotify\.com\/((?<region>[a-zA-Z-]+)\/)?(user\/(?<user>[a-zA-Z0-9-_]+)\/)?album\/(?<identifier>[a-zA-Z0-9-_]+)/,
|
|
112
119
|
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-_]+)/,
|
|
113
120
|
appleMusic: /https?:\/\/?(?:www\.)?music\.apple\.com\/(\S+)/,
|
|
121
|
+
/** From jiosaavn-plugin */
|
|
122
|
+
jiosaavn: /(https?:\/\/)(www\.)?jiosaavn\.com\/(?<type>song|album|featured|artist)\/([a-zA-Z0-9-_\/,]+)/,
|
|
114
123
|
/** FROM DUNCTE BOT PLUGIN */
|
|
115
124
|
tiktok: /https:\/\/www\.tiktok\.com\//,
|
|
116
125
|
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
|
}
|
|
@@ -590,6 +590,104 @@ class LavalinkNode {
|
|
|
590
590
|
}).then((r) => r.map(track => this.NodeManager.LavalinkManager.utils.buildTrack(track, requester)));
|
|
591
591
|
}
|
|
592
592
|
};
|
|
593
|
+
lyrics = {
|
|
594
|
+
/**
|
|
595
|
+
* Get the lyrics of a track
|
|
596
|
+
* @param track the track to get the lyrics for
|
|
597
|
+
* @param skipTrackSource wether to skip the track source or not
|
|
598
|
+
* @returns the lyrics of the track
|
|
599
|
+
* @example
|
|
600
|
+
*
|
|
601
|
+
* ```ts
|
|
602
|
+
* const lyrics = await player.node.lyrics.get(track, true);
|
|
603
|
+
* // use it of player instead:
|
|
604
|
+
* // const lyrics = await player.getLyrics(track, true);
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
get: async (track, skipTrackSource = false) => {
|
|
608
|
+
if (!this.sessionId)
|
|
609
|
+
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
610
|
+
if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
|
|
611
|
+
throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
|
|
612
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
|
|
613
|
+
!this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
|
|
614
|
+
throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
|
|
615
|
+
const url = `/lyrics?track=${track.encoded}&skipTrackSource=${skipTrackSource}`;
|
|
616
|
+
return (await this.request(url));
|
|
617
|
+
},
|
|
618
|
+
/**
|
|
619
|
+
* Get the lyrics of the current playing track
|
|
620
|
+
*
|
|
621
|
+
* @param guildId the guild id of the player
|
|
622
|
+
* @param skipTrackSource wether to skip the track source or not
|
|
623
|
+
* @returns the lyrics of the current playing track
|
|
624
|
+
* @example
|
|
625
|
+
* ```ts
|
|
626
|
+
* const lyrics = await player.node.lyrics.getCurrent(guildId);
|
|
627
|
+
* // use it of player instead:
|
|
628
|
+
* // const lyrics = await player.getCurrentLyrics();
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
631
|
+
getCurrent: async (guildId, skipTrackSource = false) => {
|
|
632
|
+
if (!this.sessionId)
|
|
633
|
+
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
634
|
+
if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
|
|
635
|
+
throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
|
|
636
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
|
|
637
|
+
!this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
|
|
638
|
+
throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
|
|
639
|
+
const url = `/sessions/${this.sessionId}/players/${guildId}/track/lyrics?skipTrackSource=${skipTrackSource}`;
|
|
640
|
+
return (await this.request(url));
|
|
641
|
+
},
|
|
642
|
+
/**
|
|
643
|
+
* subscribe to lyrics updates for a guild
|
|
644
|
+
* @param guildId the guild id of the player
|
|
645
|
+
* @returns request data of the request
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* await player.node.lyrics.subscribe(guildId);
|
|
650
|
+
* // use it of player instead:
|
|
651
|
+
* // const lyrics = await player.subscribeLyrics();
|
|
652
|
+
* ```
|
|
653
|
+
*/
|
|
654
|
+
subscribe: async (guildId) => {
|
|
655
|
+
if (!this.sessionId)
|
|
656
|
+
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
657
|
+
if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
|
|
658
|
+
throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
|
|
659
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
|
|
660
|
+
!this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
|
|
661
|
+
throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
|
|
662
|
+
return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe`, (options) => {
|
|
663
|
+
options.method = "POST";
|
|
664
|
+
}).catch(() => { });
|
|
665
|
+
},
|
|
666
|
+
/**
|
|
667
|
+
* unsubscribe from lyrics updates for a guild
|
|
668
|
+
* @param guildId the guild id of the player
|
|
669
|
+
* @returns request data of the request
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* await player.node.lyrics.unsubscribe(guildId);
|
|
674
|
+
* // use it of player instead:
|
|
675
|
+
* // const lyrics = await player.unsubscribeLyrics();
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
unsubscribe: async (guildId) => {
|
|
679
|
+
if (!this.sessionId)
|
|
680
|
+
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
681
|
+
if (!this.info.plugins.find(v => v.name === "lavalyrics-plugin"))
|
|
682
|
+
throw new RangeError(`there is no lavalyrics-plugin available in the lavalink node (required for lyrics): ${this.id}`);
|
|
683
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
|
|
684
|
+
!this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
|
|
685
|
+
throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
|
|
686
|
+
return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/unsubscribe`, (options) => {
|
|
687
|
+
options.method = "DELETE";
|
|
688
|
+
}).catch(() => { });
|
|
689
|
+
},
|
|
690
|
+
};
|
|
593
691
|
/**
|
|
594
692
|
* Request Lavalink statistics.
|
|
595
693
|
* @returns the lavalink node stats
|
|
@@ -986,6 +1084,15 @@ class LavalinkNode {
|
|
|
986
1084
|
case "ChapterStarted":
|
|
987
1085
|
this.SponsorBlockChapterStarted(player, player.queue.current, payload);
|
|
988
1086
|
break;
|
|
1087
|
+
case "LyricsLineEvent":
|
|
1088
|
+
this.LyricsLine(player, player.queue.current, payload);
|
|
1089
|
+
break;
|
|
1090
|
+
case "LyricsFoundEvent":
|
|
1091
|
+
this.LyricsFound(player, player.queue.current, payload);
|
|
1092
|
+
break;
|
|
1093
|
+
case "LyricsNotFoundEvent":
|
|
1094
|
+
this.LyricsNotFound(player, player.queue.current, payload);
|
|
1095
|
+
break;
|
|
989
1096
|
default:
|
|
990
1097
|
this.NodeManager.emit("error", this, new Error(`Node#event unknown event '${payload.type}'.`), payload);
|
|
991
1098
|
break;
|
|
@@ -1326,5 +1433,35 @@ class LavalinkNode {
|
|
|
1326
1433
|
}
|
|
1327
1434
|
return this.NodeManager.LavalinkManager.emit("queueEnd", player, track, payload);
|
|
1328
1435
|
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Emitted whenever a line of lyrics gets emitted
|
|
1438
|
+
* @event
|
|
1439
|
+
* @param {Player} player The player that emitted the event
|
|
1440
|
+
* @param {Track} track The track that emitted the event
|
|
1441
|
+
* @param {LyricsLineEvent} payload The payload of the event
|
|
1442
|
+
*/
|
|
1443
|
+
LyricsLine(player, track, payload) {
|
|
1444
|
+
return this.NodeManager.LavalinkManager.emit("LyricsLine", player, track, payload);
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Emitted whenever the lyrics for a track got found
|
|
1448
|
+
* @event
|
|
1449
|
+
* @param {Player} player The player that emitted the event
|
|
1450
|
+
* @param {Track} track The track that emitted the event
|
|
1451
|
+
* @param {LyricsFoundEvent} payload The payload of the event
|
|
1452
|
+
*/
|
|
1453
|
+
LyricsFound(player, track, payload) {
|
|
1454
|
+
return this.NodeManager.LavalinkManager.emit("LyricsFound", player, track, payload);
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Emitted whenever the lyrics for a track got not found
|
|
1458
|
+
* @event
|
|
1459
|
+
* @param {Player} player The player that emitted the event
|
|
1460
|
+
* @param {Track} track The track that emitted the event
|
|
1461
|
+
* @param {LyricsNotFoundEvent} payload The payload of the event
|
|
1462
|
+
*/
|
|
1463
|
+
LyricsNotFound(player, track, payload) {
|
|
1464
|
+
return this.NodeManager.LavalinkManager.emit("LyricsNotFound", player, track, payload);
|
|
1465
|
+
}
|
|
1329
1466
|
}
|
|
1330
1467
|
exports.LavalinkNode = LavalinkNode;
|
|
@@ -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
|
|
@@ -574,6 +574,56 @@ class Player {
|
|
|
574
574
|
// return smt
|
|
575
575
|
return this;
|
|
576
576
|
}
|
|
577
|
+
/**
|
|
578
|
+
* Get the current lyrics of the track currently playing on the guild
|
|
579
|
+
* @param guildId The guild id to get the current lyrics for
|
|
580
|
+
* @param skipTrackSource If true, it will not try to get the lyrics from the track source
|
|
581
|
+
* @returns The current lyrics
|
|
582
|
+
* @example
|
|
583
|
+
* ```ts
|
|
584
|
+
* const lyrics = await player.getCurrentLyrics();
|
|
585
|
+
* ```
|
|
586
|
+
*/
|
|
587
|
+
async getCurrentLyrics(skipTrackSource) {
|
|
588
|
+
return await this.node.lyrics.getCurrent(this.guildId, skipTrackSource);
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Get the lyrics of a specific track
|
|
592
|
+
* @param track The track to get the lyrics for
|
|
593
|
+
* @param skipTrackSource If true, it will not try to get the lyrics from the track source
|
|
594
|
+
* @returns The lyrics of the track
|
|
595
|
+
* @example
|
|
596
|
+
* ```ts
|
|
597
|
+
* const lyrics = await player.getLyrics(player.queue.tracks[0], true);
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
async getLyrics(track, skipTrackSource) {
|
|
601
|
+
return await this.node.lyrics.get(track, skipTrackSource);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Subscribe to the lyrics event on a specific guild to active live lyrics events
|
|
605
|
+
* @param guildId The guild id to subscribe to
|
|
606
|
+
* @returns The unsubscribe function
|
|
607
|
+
* @example
|
|
608
|
+
* ```ts
|
|
609
|
+
* const lyrics = await player.subscribeLyrics();
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
subscribeLyrics() {
|
|
613
|
+
return this.node.lyrics.subscribe(this.guildId);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Unsubscribe from the lyrics event on a specific guild to disable live lyrics events
|
|
617
|
+
* @param guildId The guild id to unsubscribe from
|
|
618
|
+
* @returns The unsubscribe function
|
|
619
|
+
* @example
|
|
620
|
+
* ```ts
|
|
621
|
+
* const lyrics = await player.unsubscribeLyrics();
|
|
622
|
+
* ```
|
|
623
|
+
*/
|
|
624
|
+
unsubscribeLyrics(guildId) {
|
|
625
|
+
return this.node.lyrics.unsubscribe(guildId);
|
|
626
|
+
}
|
|
577
627
|
/**
|
|
578
628
|
* Move the player on a different Audio-Node
|
|
579
629
|
* @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 */
|
|
@@ -306,6 +306,9 @@ class ManagerUtils {
|
|
|
306
306
|
if (LavalinkManagerStatics_1.SourceLinksRegexes.musicYandex.test(queryString) && !node.info?.sourceManagers?.includes("yandexmusic")) {
|
|
307
307
|
throw new Error("Query / Link Provided for this Source but Lavalink Node has not 'yandexmusic' enabled");
|
|
308
308
|
}
|
|
309
|
+
if (LavalinkManagerStatics_1.SourceLinksRegexes.jiosaavn.test(queryString) && !node.info?.sourceManagers?.includes("jiosaavn")) {
|
|
310
|
+
throw new Error("Query / Link Provided for this Source but Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled");
|
|
311
|
+
}
|
|
309
312
|
return;
|
|
310
313
|
}
|
|
311
314
|
transformQuery(query) {
|
|
@@ -361,6 +364,12 @@ class ManagerUtils {
|
|
|
361
364
|
if (source === "dzsearch" && node.info?.sourceManagers?.includes("deezer") && !node.info?.sourceManagers?.includes("http")) {
|
|
362
365
|
throw new Error("Lavalink Node has not 'http' enabled, which is required to have 'dzsearch' to work");
|
|
363
366
|
}
|
|
367
|
+
if (source === "jsrec" && !node.info?.sourceManagers?.includes("jiosaavn")) {
|
|
368
|
+
throw new Error("Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled, which is required to have 'jsrec' to work");
|
|
369
|
+
}
|
|
370
|
+
if (source === "jssearch" && !node.info?.sourceManagers?.includes("jiosaavn")) {
|
|
371
|
+
throw new Error("Lavalink Node has not 'jiosaavn' (via jiosaavn-plugin) enabled, which is required to have 'jssearch' to work");
|
|
372
|
+
}
|
|
364
373
|
if (source === "scsearch" && !node.info?.sourceManagers?.includes("soundcloud")) {
|
|
365
374
|
throw new Error("Lavalink Node has not 'soundcloud' enabled, which is required to have 'scsearch' work");
|
|
366
375
|
}
|
|
@@ -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>;
|