lavalink-client 2.0.1 → 2.1.1

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.
@@ -86,20 +86,28 @@ export declare class FilterManager {
86
86
  * @returns
87
87
  */
88
88
  toggleLowPass(smoothing?: number): Promise<boolean>;
89
- /**
90
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
91
- * @param delay
92
- * @param decay
93
- * @returns
94
- */
95
- toggleEcho(delay?: number, decay?: number): Promise<boolean>;
96
- /**
97
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
- * @param delays
99
- * @param gains
100
- * @returns
101
- */
102
- toggleReverb(delays?: number[], gains?: number[]): Promise<boolean>;
89
+ lavalinkLavaDspxPlugin: {
90
+ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
91
+ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
92
+ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<boolean>;
93
+ toggleEcho: (decay?: number, echoLength?: number) => Promise<boolean>;
94
+ };
95
+ lavalinkFilterPlugin: {
96
+ /**
97
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
+ * @param delay
99
+ * @param decay
100
+ * @returns
101
+ */
102
+ toggleEcho: (delay?: number, decay?: number) => Promise<boolean>;
103
+ /**
104
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
105
+ * @param delays
106
+ * @param gains
107
+ * @returns
108
+ */
109
+ toggleReverb: (delays?: number[], gains?: number[]) => Promise<boolean>;
110
+ };
103
111
  /**
104
112
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
105
113
  * @param speed
@@ -160,10 +168,23 @@ export interface PlayerFilters {
160
168
  audioOutput: AudioOutputs;
161
169
  /** Lavalink Volume FILTER (not player Volume, think of it as a gain booster) */
162
170
  volume: boolean;
163
- /** only with the custom lavalink filter plugin */
164
- echo: boolean;
165
- /** only with the custom lavalink filter plugin */
166
- reverb: boolean;
171
+ /** Filters for the Lavalink Filter Plugin */
172
+ lavalinkFilterPlugin: {
173
+ /** if echo filter is enabled / not */
174
+ echo: boolean;
175
+ /** if reverb filter is enabled / not */
176
+ reverb: boolean;
177
+ };
178
+ lavalinkLavaDspxPlugin: {
179
+ /** if lowPass filter is enabled / not */
180
+ lowPass: boolean;
181
+ /** if highPass filter is enabled / not */
182
+ highPass: boolean;
183
+ /** if normalization filter is enabled / not */
184
+ normalization: boolean;
185
+ /** if echo filter is enabled / not */
186
+ echo: boolean;
187
+ };
167
188
  }
168
189
  /**
169
190
  * There are 15 bands (0-14) that can be changed.
@@ -174,9 +195,9 @@ export interface PlayerFilters {
174
195
  */
175
196
  export interface EQBand {
176
197
  /** On what band position (0-14) it should work */
177
- band: IntegerNumber;
198
+ band: IntegerNumber | number;
178
199
  /** The gain (-0.25 to 1.0) */
179
- gain: FloatNumber;
200
+ gain: FloatNumber | number;
180
201
  }
181
202
  /**
182
203
  * Uses equalization to eliminate part of a band, usually targeting vocals.
@@ -265,20 +286,6 @@ export interface LowPassFilter {
265
286
  /** The smoothing factor (1.0 < x) */
266
287
  smoothing?: number;
267
288
  }
268
- /**
269
- * A Plugin Filter
270
- */
271
- export interface EchoFilter {
272
- delay: number;
273
- decay: number;
274
- }
275
- /**
276
- * A Plugin Filter
277
- */
278
- export interface ReverbFilter {
279
- delays: number[];
280
- gains: number[];
281
- }
282
289
  /**
283
290
  * Filter Data stored in the Client and partially sent to Lavalink
284
291
  */
@@ -292,15 +299,34 @@ export interface FilterData {
292
299
  distortion?: DistortionFilter;
293
300
  channelMix?: ChannelMixFilter;
294
301
  lowPass?: LowPassFilter;
295
- pluginFilters?: Record<PluginFiltersKey, PluginFiltersValues>;
296
- }
297
- export type PluginFiltersKey = "lavalink-filter-plugin" | string;
298
- export interface PluginFiltersValues extends LavalinkFiltersPlugin {
299
- [key: string]: string | number | string[] | number[] | EchoFilter | ReverbFilter;
300
- }
301
- export interface LavalinkFiltersPlugin {
302
- "echo": EchoFilter;
303
- "reverb": ReverbFilter;
302
+ pluginFilters?: {
303
+ "lavalink-filter-plugin"?: {
304
+ "echo"?: {
305
+ delay?: number;
306
+ decay?: number;
307
+ };
308
+ "reverb"?: {
309
+ delays?: number[];
310
+ gains?: number[];
311
+ };
312
+ };
313
+ "high-pass"?: {
314
+ cutoffFrequency?: number;
315
+ boostFactor?: number;
316
+ };
317
+ "low-pass"?: {
318
+ cutoffFrequency?: number;
319
+ boostFactor?: number;
320
+ };
321
+ normalization?: {
322
+ maxAmplitude?: number;
323
+ adaptive?: boolean;
324
+ };
325
+ echo?: {
326
+ echoLength?: number;
327
+ decay?: number;
328
+ };
329
+ };
304
330
  }
305
331
  /**
306
332
  * Actual Filter Data sent to Lavalink
@@ -12,13 +12,21 @@ export class FilterManager {
12
12
  vaporwave: false,
13
13
  custom: false,
14
14
  nightcore: false,
15
- echo: false,
16
- reverb: false,
17
15
  rotation: false,
18
16
  karaoke: false,
19
17
  tremolo: false,
20
18
  vibrato: false,
21
19
  lowPass: false,
20
+ lavalinkFilterPlugin: {
21
+ echo: false,
22
+ reverb: false,
23
+ },
24
+ lavalinkLavaDspxPlugin: {
25
+ lowPass: false,
26
+ highPass: false,
27
+ normalization: false,
28
+ echo: false,
29
+ },
22
30
  audioOutput: "stereo",
23
31
  };
24
32
  /** The Filter Data sent to Lavalink, only if the filter is enabled (ofc.) */
@@ -58,7 +66,23 @@ export class FilterManager {
58
66
  delays: [],
59
67
  gains: [] // [0.84, 0.83, 0.82, 0.81]
60
68
  }
61
- }
69
+ },
70
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
71
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
72
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
73
+ },
74
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
75
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
76
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
77
+ },
78
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
79
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
80
+ // "adaptive": true // false
81
+ },
82
+ "echo": { // Self-explanatory; provides an echo effect.
83
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
84
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
85
+ },
62
86
  },
63
87
  channelMix: audioOutputsData.stereo,
64
88
  /*distortion: {
@@ -91,10 +115,18 @@ export class FilterManager {
91
115
  delete sendData.tremolo;
92
116
  if (!this.filters.vibrato)
93
117
  delete sendData.vibrato;
94
- if (!this.filters.echo)
118
+ if (!this.filters.lavalinkFilterPlugin.echo)
95
119
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.echo;
96
- if (!this.filters.reverb)
120
+ if (!this.filters.lavalinkFilterPlugin.reverb)
97
121
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.reverb;
122
+ if (!this.filters.lavalinkLavaDspxPlugin.echo)
123
+ delete sendData.pluginFilters?.echo;
124
+ if (!this.filters.lavalinkLavaDspxPlugin.normalization)
125
+ delete sendData.pluginFilters?.normalization;
126
+ if (!this.filters.lavalinkLavaDspxPlugin.highPass)
127
+ delete sendData.pluginFilters?.["high-pass"];
128
+ if (!this.filters.lavalinkLavaDspxPlugin.lowPass)
129
+ delete sendData.pluginFilters?.["low-pass"];
98
130
  if (sendData.pluginFilters?.["lavalink-filter-plugin"] && Object.values(sendData.pluginFilters?.["lavalink-filter-plugin"]).length === 0)
99
131
  delete sendData.pluginFilters["lavalink-filter-plugin"];
100
132
  if (sendData.pluginFilters && Object.values(sendData.pluginFilters).length === 0)
@@ -118,7 +150,7 @@ export class FilterManager {
118
150
  // delete disabled filters
119
151
  if (key === "pluginFilters") {
120
152
  // for(const key of [...Object.keys(sendData.pluginFilters)]) {
121
- // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
153
+ // // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
122
154
  // }
123
155
  }
124
156
  else if (this.player.node.info && !this.player.node.info?.filters?.includes?.(key))
@@ -145,9 +177,13 @@ export class FilterManager {
145
177
  this.filters.rotation = this.data.rotation.rotationHz !== 0;
146
178
  this.filters.vibrato = this.data.vibrato.frequency !== 0 || this.data.vibrato.depth !== 0;
147
179
  this.filters.tremolo = this.data.tremolo.frequency !== 0 || this.data.tremolo.depth !== 0;
148
- const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: 0, delay: 0 }, reverb: { gains: [], delays: [] } });
149
- this.filters.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
150
- this.filters.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
180
+ const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: this.data.pluginFilters?.echo?.decay && !this.data.pluginFilters?.echo?.echoLength ? this.data.pluginFilters.echo.decay : 0, delay: this.data.pluginFilters?.echo?.delay || 0 }, reverb: { gains: [], delays: [], ...((this.data.pluginFilters.reverb) || {}) } });
181
+ this.filters.lavalinkFilterPlugin.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
182
+ this.filters.lavalinkFilterPlugin.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
183
+ this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters["high-pass"] || {}).length > 0;
184
+ this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters["low-pass"] || {}).length > 0;
185
+ this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters.normalization || {}).length > 0;
186
+ this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
151
187
  this.filters.lowPass = this.data.lowPass.smoothing !== 0;
152
188
  this.filters.karaoke = Object.values(this.data.karaoke).some(v => v !== 0);
153
189
  if ((this.filters.nightcore || this.filters.vaporwave) && oldFilterTimescale) {
@@ -163,8 +199,12 @@ export class FilterManager {
163
199
  * Reset all Filters
164
200
  */
165
201
  async resetFilters() {
166
- this.filters.echo = false;
167
- this.filters.reverb = false;
202
+ this.filters.lavalinkLavaDspxPlugin.echo = false;
203
+ this.filters.lavalinkLavaDspxPlugin.normalization = false;
204
+ this.filters.lavalinkLavaDspxPlugin.highPass = false;
205
+ this.filters.lavalinkLavaDspxPlugin.lowPass = false;
206
+ this.filters.lavalinkFilterPlugin.echo = false;
207
+ this.filters.lavalinkFilterPlugin.reverb = false;
168
208
  this.filters.nightcore = false;
169
209
  this.filters.lowPass = false;
170
210
  this.filters.rotation = false;
@@ -194,14 +234,30 @@ export class FilterManager {
194
234
  pluginFilters: {
195
235
  "lavalink-filter-plugin": {
196
236
  echo: {
197
- delay: 0,
198
- decay: 0
237
+ // delay: 0, // in seconds
238
+ // decay: 0 // 0 < 1
199
239
  },
200
240
  reverb: {
201
- delays: [],
202
- gains: []
203
- },
204
- }
241
+ // delays: [], // [0.037, 0.042, 0.048, 0.053]
242
+ // gains: [] // [0.84, 0.83, 0.82, 0.81]
243
+ }
244
+ },
245
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
246
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
247
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
248
+ },
249
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
250
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
251
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
252
+ },
253
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
254
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
255
+ // "adaptive": true // false
256
+ },
257
+ "echo": { // Self-explanatory; provides an echo effect.
258
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
259
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
260
+ },
205
261
  },
206
262
  rotation: {
207
263
  rotationHz: 0
@@ -369,52 +425,156 @@ export class FilterManager {
369
425
  await this.applyPlayerFilters();
370
426
  return this.filters.lowPass;
371
427
  }
372
- /**
373
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
374
- * @param delay
375
- * @param decay
376
- * @returns
377
- */
378
- async toggleEcho(delay = 4, decay = 0.8) {
379
- if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
380
- throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
381
- if (!this.data)
382
- this.data = {};
383
- if (!this.data.pluginFilters)
384
- this.data.pluginFilters = {};
385
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
386
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
387
- if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
388
- this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
389
- this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.echo ? 0 : delay;
390
- this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.echo ? 0 : decay;
391
- this.filters.echo = !this.filters.echo;
392
- await this.applyPlayerFilters();
393
- return this.filters.echo;
394
- }
395
- /**
396
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
397
- * @param delays
398
- * @param gains
399
- * @returns
400
- */
401
- async toggleReverb(delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) {
402
- if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
403
- throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
404
- if (!this.data)
405
- this.data = {};
406
- if (!this.data.pluginFilters)
407
- this.data.pluginFilters = {};
408
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
409
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
410
- if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
411
- this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
412
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.reverb ? [] : delays;
413
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.reverb ? [] : gains;
414
- this.filters.reverb = !this.filters.reverb;
415
- await this.applyPlayerFilters();
416
- return this.filters.reverb;
417
- }
428
+ lavalinkLavaDspxPlugin = {
429
+ toggleLowPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
430
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
431
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
432
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("low-pass"))
433
+ throw new Error("Node#Info#filters does not include the 'low-pass' Filter (Node has it not enable)");
434
+ if (!this.data)
435
+ this.data = {};
436
+ if (!this.data.pluginFilters)
437
+ this.data.pluginFilters = {};
438
+ if (!this.data.pluginFilters["low-pass"])
439
+ this.data.pluginFilters["low-pass"] = {};
440
+ if (this.filters.lavalinkLavaDspxPlugin.lowPass) {
441
+ delete this.data.pluginFilters["low-pass"];
442
+ }
443
+ else {
444
+ this.data.pluginFilters["low-pass"] = {
445
+ boostFactor: boostFactor,
446
+ cutoffFrequency: cutoffFrequency
447
+ };
448
+ }
449
+ this.filters.lavalinkLavaDspxPlugin.lowPass = !this.filters.lavalinkLavaDspxPlugin.lowPass;
450
+ await this.applyPlayerFilters();
451
+ return this.filters.lavalinkLavaDspxPlugin.lowPass;
452
+ },
453
+ toggleHighPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
454
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
455
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
456
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("high-pass"))
457
+ throw new Error("Node#Info#filters does not include the 'high-pass' Filter (Node has it not enable)");
458
+ if (!this.data)
459
+ this.data = {};
460
+ if (!this.data.pluginFilters)
461
+ this.data.pluginFilters = {};
462
+ if (!this.data.pluginFilters["high-pass"])
463
+ this.data.pluginFilters["high-pass"] = {};
464
+ if (this.filters.lavalinkLavaDspxPlugin.highPass) {
465
+ delete this.data.pluginFilters["high-pass"];
466
+ }
467
+ else {
468
+ this.data.pluginFilters["high-pass"] = {
469
+ boostFactor: boostFactor,
470
+ cutoffFrequency: cutoffFrequency
471
+ };
472
+ }
473
+ this.filters.lavalinkLavaDspxPlugin.highPass = !this.filters.lavalinkLavaDspxPlugin.highPass;
474
+ await this.applyPlayerFilters();
475
+ return this.filters.lavalinkLavaDspxPlugin.highPass;
476
+ },
477
+ toggleNormalization: async (maxAmplitude = 0.75, adaptive = true) => {
478
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
479
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
480
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("normalization"))
481
+ throw new Error("Node#Info#filters does not include the 'normalization' Filter (Node has it not enable)");
482
+ if (!this.data)
483
+ this.data = {};
484
+ if (!this.data.pluginFilters)
485
+ this.data.pluginFilters = {};
486
+ if (!this.data.pluginFilters.normalization)
487
+ this.data.pluginFilters.normalization = {};
488
+ if (this.filters.lavalinkLavaDspxPlugin.normalization) {
489
+ delete this.data.pluginFilters.normalization;
490
+ }
491
+ else {
492
+ this.data.pluginFilters.normalization = {
493
+ adaptive: adaptive,
494
+ maxAmplitude: maxAmplitude
495
+ };
496
+ }
497
+ this.filters.lavalinkLavaDspxPlugin.normalization = !this.filters.lavalinkLavaDspxPlugin.normalization;
498
+ await this.applyPlayerFilters();
499
+ return this.filters.lavalinkLavaDspxPlugin.normalization;
500
+ },
501
+ toggleEcho: async (decay = 0.5, echoLength = 0.5) => {
502
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
503
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
504
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
505
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable)");
506
+ if (!this.data)
507
+ this.data = {};
508
+ if (!this.data.pluginFilters)
509
+ this.data.pluginFilters = {};
510
+ if (!this.data.pluginFilters.echo)
511
+ this.data.pluginFilters.echo = {};
512
+ if (this.filters.lavalinkLavaDspxPlugin.echo) {
513
+ delete this.data.pluginFilters.echo;
514
+ }
515
+ else {
516
+ this.data.pluginFilters.echo = {
517
+ decay: decay,
518
+ echoLength: echoLength
519
+ };
520
+ }
521
+ this.filters.lavalinkLavaDspxPlugin.echo = !this.filters.lavalinkLavaDspxPlugin.echo;
522
+ await this.applyPlayerFilters();
523
+ return this.filters.lavalinkLavaDspxPlugin.echo;
524
+ }
525
+ };
526
+ lavalinkFilterPlugin = {
527
+ /**
528
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
529
+ * @param delay
530
+ * @param decay
531
+ * @returns
532
+ */
533
+ toggleEcho: async (delay = 4, decay = 0.8) => {
534
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
535
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
536
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
537
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
538
+ if (!this.data)
539
+ this.data = {};
540
+ if (!this.data.pluginFilters)
541
+ this.data.pluginFilters = {};
542
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
543
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
544
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
545
+ this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
546
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.lavalinkFilterPlugin.echo ? 0 : delay;
547
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.lavalinkFilterPlugin.echo ? 0 : decay;
548
+ this.filters.lavalinkFilterPlugin.echo = !this.filters.lavalinkFilterPlugin.echo;
549
+ await this.applyPlayerFilters();
550
+ return this.filters.lavalinkFilterPlugin.echo;
551
+ },
552
+ /**
553
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
554
+ * @param delays
555
+ * @param gains
556
+ * @returns
557
+ */
558
+ toggleReverb: async (delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) => {
559
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
560
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
561
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
562
+ throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
563
+ if (!this.data)
564
+ this.data = {};
565
+ if (!this.data.pluginFilters)
566
+ this.data.pluginFilters = {};
567
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
568
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
569
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
570
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
571
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.lavalinkFilterPlugin.reverb ? [] : delays;
572
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.lavalinkFilterPlugin.reverb ? [] : gains;
573
+ this.filters.lavalinkFilterPlugin.reverb = !this.filters.lavalinkFilterPlugin.reverb;
574
+ await this.applyPlayerFilters();
575
+ return this.filters.lavalinkFilterPlugin.reverb;
576
+ }
577
+ };
418
578
  /**
419
579
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
420
580
  * @param speed
@@ -173,7 +173,7 @@ export interface LavalinkManager {
173
173
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
174
174
  }
175
175
  export declare class LavalinkManager extends EventEmitter {
176
- static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform>;
176
+ static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform | import("./Utils").ClientCustomSearchPlatformUtils>;
177
177
  static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
178
178
  initiated: boolean;
179
179
  readonly players: MiniMap<string, Player>;
@@ -1,5 +1,5 @@
1
- import { LavalinkSearchPlatform, SearchPlatform, SourcesRegex } from "./Utils";
2
- export declare const DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform>;
1
+ import { ClientCustomSearchPlatformUtils, LavalinkSearchPlatform, SearchPlatform, SourcesRegex } from "./Utils";
2
+ export declare const DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform | ClientCustomSearchPlatformUtils>;
3
3
  export declare const LavalinkPlugins: {
4
4
  DuncteBot_Plugin: string;
5
5
  LavaSrc: string;
@@ -44,10 +44,20 @@ export const DefaultSources = {
44
44
  "speak": "speak",
45
45
  "tts": "tts",
46
46
  "ftts": "ftts",
47
+ "flowery": "ftts",
48
+ "flowery.tts": "ftts",
49
+ "flowerytts": "ftts",
47
50
  // Client sided search platforms
48
51
  "bandcamp": "bcsearch",
49
52
  "bc": "bcsearch",
50
53
  "bcsearch": "bcsearch",
54
+ // local files
55
+ "local": "local",
56
+ // http requests
57
+ "http": "http",
58
+ "https": "https",
59
+ "link": "link",
60
+ "uri": "uri"
51
61
  };
52
62
  export const LavalinkPlugins = {
53
63
  DuncteBot_Plugin: "DuncteBot-plugin",
@@ -120,12 +120,17 @@ export class LavalinkNode {
120
120
  throw new Error("Bandcamp Search only works on the player!");
121
121
  }
122
122
  let uri = `/loadtracks?identifier=`;
123
- if (!/^https?:\/\//.test(Query.query))
124
- uri += `${Query.source}:`;
125
- if (Query.source === "ftts")
126
- uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
127
- else
123
+ if (/^https?:\/\//.test(Query.query) || ["http", "https", "link", "uri"].includes(Query.source)) { // if it's a link simply encode it
128
124
  uri += encodeURIComponent(decodeURIComponent(Query.query));
125
+ }
126
+ else { // if not make a query out of it
127
+ if (Query.source !== "local")
128
+ uri += `${Query.source}:`; // only add the query source string if it's not a local track
129
+ if (Query.source === "ftts")
130
+ uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
131
+ else
132
+ uri += encodeURIComponent(decodeURIComponent(Query.query));
133
+ }
129
134
  const res = await this.request(uri);
130
135
  // transform the data which can be Error, Track or Track[] to enfore [Track]
131
136
  const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
@@ -659,7 +664,7 @@ export class LavalinkNode {
659
664
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
660
665
  }
661
666
  // remove tracks from the queue
662
- if (player.repeatMode !== "track")
667
+ if (player.repeatMode !== "track" || player.get("internal_skipped"))
663
668
  await queueTrackEnd(player);
664
669
  else if (player.queue.current) { // If there was a current Track already and repeatmode === true, add it to the queue.
665
670
  player.queue.previous.unshift(player.queue.current);
@@ -667,6 +672,7 @@ export class LavalinkNode {
667
672
  player.queue.previous.splice(player.queue.options.maxPreviousTracks, player.queue.previous.length);
668
673
  await player.queue.utils.save();
669
674
  }
675
+ player.set("internal_skipped", false);
670
676
  // if no track available, end queue
671
677
  if (!player.queue.current)
672
678
  return this.queueEnd(player, track, payload);
@@ -330,6 +330,7 @@ export class Player {
330
330
  if (!this.playing)
331
331
  return await this.play();
332
332
  const now = performance.now();
333
+ this.set("internal_skipped", true);
333
334
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
334
335
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
335
336
  return this;
@@ -18,7 +18,9 @@ export type DuncteSearchPlatform = "speak" | "tts";
18
18
  export type LavalinkClientSearchPlatform = "bcsearch";
19
19
  export type LavalinkClientSearchPlatformResolve = "bandcamp" | "bc";
20
20
  export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | LavaSrcSearchPlatform | DuncteSearchPlatform | LavalinkClientSearchPlatform;
21
- export type ClientSearchPlatform = "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" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform;
21
+ export type ClientCustomSearchPlatformUtils = "local" | "http" | "https" | "link" | "uri";
22
+ export type ClientSearchPlatform = ClientCustomSearchPlatformUtils | // for file/link requests
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;
22
24
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
23
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" | "appleMusic" | "TwitchTv" | "vimeo";
24
26
  export interface PlaylistInfo {