discord-player 5.3.2-dev.2 → 5.3.2
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/dist/Player.js +607 -583
- package/dist/Structures/ExtractorModel.js +65 -65
- package/dist/Structures/PlayerError.js +48 -48
- package/dist/Structures/Playlist.js +108 -108
- package/dist/Structures/Queue.js +830 -795
- package/dist/Structures/Track.js +155 -155
- package/dist/VoiceInterface/StreamDispatcher.js +226 -226
- package/dist/VoiceInterface/VoiceUtils.js +65 -65
- package/dist/VoiceInterface/VolumeTransformer.js +120 -120
- package/dist/index.d.ts +1224 -1163
- package/dist/index.js +38 -34
- package/dist/smoothVolume.js +15 -15
- package/dist/types/types.js +58 -58
- package/dist/utils/AudioFilters.js +95 -97
- package/dist/utils/FFmpegStream.js +53 -53
- package/dist/utils/QueryResolver.js +68 -68
- package/dist/utils/Util.js +136 -135
- package/package.json +1 -1
package/dist/Player.js
CHANGED
|
@@ -1,583 +1,607 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
* @param {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
*
|
|
212
|
-
* @
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (!
|
|
218
|
-
throw new PlayerError_1.PlayerError("
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
case types_1.QueryType.
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
thumbnail:
|
|
329
|
-
views:
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
*
|
|
529
|
-
* @param {
|
|
530
|
-
* @
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
*
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var _Player_lastLatency;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Player = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const discord_js_1 = require("discord.js");
|
|
7
|
+
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
|
|
8
|
+
const Queue_1 = require("./Structures/Queue");
|
|
9
|
+
const VoiceUtils_1 = require("./VoiceInterface/VoiceUtils");
|
|
10
|
+
const types_1 = require("./types/types");
|
|
11
|
+
const Track_1 = tslib_1.__importDefault(require("./Structures/Track"));
|
|
12
|
+
const QueryResolver_1 = require("./utils/QueryResolver");
|
|
13
|
+
const youtube_sr_1 = tslib_1.__importDefault(require("youtube-sr"));
|
|
14
|
+
const Util_1 = require("./utils/Util");
|
|
15
|
+
const spotify_url_info_1 = tslib_1.__importDefault(require("spotify-url-info"));
|
|
16
|
+
const PlayerError_1 = require("./Structures/PlayerError");
|
|
17
|
+
const ytdl_core_1 = require("ytdl-core");
|
|
18
|
+
const soundcloud_scraper_1 = require("soundcloud-scraper");
|
|
19
|
+
const Playlist_1 = require("./Structures/Playlist");
|
|
20
|
+
const ExtractorModel_1 = require("./Structures/ExtractorModel");
|
|
21
|
+
const voice_1 = require("@discordjs/voice");
|
|
22
|
+
const soundcloud = new soundcloud_scraper_1.Client();
|
|
23
|
+
class Player extends tiny_typed_emitter_1.TypedEmitter {
|
|
24
|
+
/**
|
|
25
|
+
* Creates new Discord Player
|
|
26
|
+
* @param {Client} client The Discord Client
|
|
27
|
+
* @param {PlayerInitOptions} [options] The player init options
|
|
28
|
+
*/
|
|
29
|
+
constructor(client, options = {}) {
|
|
30
|
+
super();
|
|
31
|
+
this.options = {
|
|
32
|
+
autoRegisterExtractor: true,
|
|
33
|
+
ytdlOptions: {
|
|
34
|
+
highWaterMark: 1 << 25
|
|
35
|
+
},
|
|
36
|
+
connectionTimeout: 20000,
|
|
37
|
+
smoothVolume: true,
|
|
38
|
+
lagMonitor: 30000
|
|
39
|
+
};
|
|
40
|
+
this.queues = new discord_js_1.Collection();
|
|
41
|
+
this.voiceUtils = new VoiceUtils_1.VoiceUtils();
|
|
42
|
+
this.extractors = new discord_js_1.Collection();
|
|
43
|
+
this.requiredEvents = ["error", "connectionError"];
|
|
44
|
+
_Player_lastLatency.set(this, -1);
|
|
45
|
+
/**
|
|
46
|
+
* The discord.js client
|
|
47
|
+
* @type {Client}
|
|
48
|
+
*/
|
|
49
|
+
this.client = client;
|
|
50
|
+
if (this.client?.options?.intents && !new discord_js_1.IntentsBitField(this.client?.options?.intents).has(discord_js_1.IntentsBitField.Flags.GuildVoiceStates)) {
|
|
51
|
+
throw new PlayerError_1.PlayerError('client is missing "GuildVoiceStates" intent');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The extractors collection
|
|
55
|
+
* @type {ExtractorModel}
|
|
56
|
+
*/
|
|
57
|
+
this.options = Object.assign(this.options, options);
|
|
58
|
+
this.client.on("voiceStateUpdate", this._handleVoiceState.bind(this));
|
|
59
|
+
if (this.options?.autoRegisterExtractor) {
|
|
60
|
+
let nv; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
61
|
+
if ((nv = Util_1.Util.require("@discord-player/extractor"))) {
|
|
62
|
+
["Attachment", "Facebook", "Reverbnation", "Vimeo"].forEach((ext) => void this.use(ext, nv[ext]));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (typeof this.options.lagMonitor === "number" && this.options.lagMonitor > 0) {
|
|
66
|
+
setInterval(() => {
|
|
67
|
+
const start = performance.now();
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
tslib_1.__classPrivateFieldSet(this, _Player_lastLatency, performance.now() - start, "f");
|
|
70
|
+
}, 0).unref();
|
|
71
|
+
}, this.options.lagMonitor).unref();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Event loop lag
|
|
76
|
+
* @type {number}
|
|
77
|
+
*/
|
|
78
|
+
get eventLoopLag() {
|
|
79
|
+
return tslib_1.__classPrivateFieldGet(this, _Player_lastLatency, "f");
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generates statistics
|
|
83
|
+
*/
|
|
84
|
+
generateStatistics() {
|
|
85
|
+
return this.queues.map((m) => m.generateStatistics());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Handles voice state update
|
|
89
|
+
* @param {VoiceState} oldState The old voice state
|
|
90
|
+
* @param {VoiceState} newState The new voice state
|
|
91
|
+
* @returns {void}
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
_handleVoiceState(oldState, newState) {
|
|
95
|
+
const queue = this.getQueue(oldState.guild.id);
|
|
96
|
+
if (!queue || !queue.connection)
|
|
97
|
+
return;
|
|
98
|
+
if (oldState.channelId && !newState.channelId && newState.member.id === newState.guild.members.me.id) {
|
|
99
|
+
try {
|
|
100
|
+
queue.destroy();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* noop */
|
|
104
|
+
}
|
|
105
|
+
return void this.emit("botDisconnect", queue);
|
|
106
|
+
}
|
|
107
|
+
if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.members.me.id) {
|
|
108
|
+
if (!oldState.serverMute && newState.serverMute) {
|
|
109
|
+
// state.serverMute can be null
|
|
110
|
+
queue.setPaused(!!newState.serverMute);
|
|
111
|
+
}
|
|
112
|
+
else if (!oldState.suppress && newState.suppress) {
|
|
113
|
+
// state.suppress can be null
|
|
114
|
+
queue.setPaused(!!newState.suppress);
|
|
115
|
+
if (newState.suppress) {
|
|
116
|
+
newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (oldState.channelId === newState.channelId && newState.member.id === newState.guild.members.me.id) {
|
|
121
|
+
if (!oldState.serverMute && newState.serverMute) {
|
|
122
|
+
// state.serverMute can be null
|
|
123
|
+
queue.setPaused(!!newState.serverMute);
|
|
124
|
+
}
|
|
125
|
+
else if (!oldState.suppress && newState.suppress) {
|
|
126
|
+
// state.suppress can be null
|
|
127
|
+
queue.setPaused(!!newState.suppress);
|
|
128
|
+
if (newState.suppress) {
|
|
129
|
+
newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (queue.connection && !newState.channelId && oldState.channelId === queue.connection.channel.id) {
|
|
134
|
+
if (!Util_1.Util.isVoiceEmpty(queue.connection.channel))
|
|
135
|
+
return;
|
|
136
|
+
const timeout = setTimeout(() => {
|
|
137
|
+
if (!Util_1.Util.isVoiceEmpty(queue.connection.channel))
|
|
138
|
+
return;
|
|
139
|
+
if (!this.queues.has(queue.guild.id))
|
|
140
|
+
return;
|
|
141
|
+
if (queue.options.leaveOnEmpty)
|
|
142
|
+
queue.destroy(true);
|
|
143
|
+
this.emit("channelEmpty", queue);
|
|
144
|
+
}, queue.options.leaveOnEmptyCooldown || 0).unref();
|
|
145
|
+
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
|
|
146
|
+
}
|
|
147
|
+
if (queue.connection && newState.channelId && newState.channelId === queue.connection.channel.id) {
|
|
148
|
+
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
|
|
149
|
+
const channelEmpty = Util_1.Util.isVoiceEmpty(queue.connection.channel);
|
|
150
|
+
if (!channelEmpty && emptyTimeout) {
|
|
151
|
+
clearTimeout(emptyTimeout);
|
|
152
|
+
queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId && newState.member.id === newState.guild.members.me.id) {
|
|
156
|
+
if (queue.connection && newState.member.id === newState.guild.members.me.id)
|
|
157
|
+
queue.connection.channel = newState.channel;
|
|
158
|
+
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
|
|
159
|
+
const channelEmpty = Util_1.Util.isVoiceEmpty(queue.connection.channel);
|
|
160
|
+
if (!channelEmpty && emptyTimeout) {
|
|
161
|
+
clearTimeout(emptyTimeout);
|
|
162
|
+
queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const timeout = setTimeout(() => {
|
|
166
|
+
if (queue.connection && !Util_1.Util.isVoiceEmpty(queue.connection.channel))
|
|
167
|
+
return;
|
|
168
|
+
if (!this.queues.has(queue.guild.id))
|
|
169
|
+
return;
|
|
170
|
+
if (queue.options.leaveOnEmpty)
|
|
171
|
+
queue.destroy(true);
|
|
172
|
+
this.emit("channelEmpty", queue);
|
|
173
|
+
}, queue.options.leaveOnEmptyCooldown || 0).unref();
|
|
174
|
+
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Creates a queue for a guild if not available, else returns existing queue
|
|
180
|
+
* @param {GuildResolvable} guild The guild
|
|
181
|
+
* @param {PlayerOptions} queueInitOptions Queue init options
|
|
182
|
+
* @returns {Queue}
|
|
183
|
+
*/
|
|
184
|
+
createQueue(guild, queueInitOptions = {}) {
|
|
185
|
+
guild = this.client.guilds.resolve(guild);
|
|
186
|
+
if (!guild)
|
|
187
|
+
throw new PlayerError_1.PlayerError("Unknown Guild", PlayerError_1.ErrorStatusCode.UNKNOWN_GUILD);
|
|
188
|
+
if (this.queues.has(guild.id))
|
|
189
|
+
return this.queues.get(guild.id);
|
|
190
|
+
const _meta = queueInitOptions.metadata;
|
|
191
|
+
delete queueInitOptions["metadata"];
|
|
192
|
+
queueInitOptions.volumeSmoothness ?? (queueInitOptions.volumeSmoothness = this.options.smoothVolume ? 0.08 : 0);
|
|
193
|
+
queueInitOptions.ytdlOptions ?? (queueInitOptions.ytdlOptions = this.options.ytdlOptions);
|
|
194
|
+
const queue = new Queue_1.Queue(this, guild, queueInitOptions);
|
|
195
|
+
queue.metadata = _meta;
|
|
196
|
+
this.queues.set(guild.id, queue);
|
|
197
|
+
return queue;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Returns the queue if available
|
|
201
|
+
* @param {GuildResolvable} guild The guild id
|
|
202
|
+
* @returns {Queue | undefined}
|
|
203
|
+
*/
|
|
204
|
+
getQueue(guild) {
|
|
205
|
+
guild = this.client.guilds.resolve(guild);
|
|
206
|
+
if (!guild)
|
|
207
|
+
throw new PlayerError_1.PlayerError("Unknown Guild", PlayerError_1.ErrorStatusCode.UNKNOWN_GUILD);
|
|
208
|
+
return this.queues.get(guild.id);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Deletes a queue and returns deleted queue object
|
|
212
|
+
* @param {GuildResolvable} guild The guild id to remove
|
|
213
|
+
* @returns {Queue}
|
|
214
|
+
*/
|
|
215
|
+
deleteQueue(guild) {
|
|
216
|
+
guild = this.client.guilds.resolve(guild);
|
|
217
|
+
if (!guild)
|
|
218
|
+
throw new PlayerError_1.PlayerError("Unknown Guild", PlayerError_1.ErrorStatusCode.UNKNOWN_GUILD);
|
|
219
|
+
const prev = this.getQueue(guild);
|
|
220
|
+
try {
|
|
221
|
+
prev.destroy();
|
|
222
|
+
}
|
|
223
|
+
catch { } // eslint-disable-line no-empty
|
|
224
|
+
this.queues.delete(guild.id);
|
|
225
|
+
return prev;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @typedef {object} PlayerSearchResult
|
|
229
|
+
* @property {Playlist} [playlist] The playlist (if any)
|
|
230
|
+
* @property {Track[]} tracks The tracks
|
|
231
|
+
*/
|
|
232
|
+
/**
|
|
233
|
+
* Search tracks
|
|
234
|
+
* @param {string|Track} query The search query
|
|
235
|
+
* @param {SearchOptions} options The search options
|
|
236
|
+
* @returns {Promise<PlayerSearchResult>}
|
|
237
|
+
*/
|
|
238
|
+
async search(query, options) {
|
|
239
|
+
if (query instanceof Track_1.default)
|
|
240
|
+
return { playlist: query.playlist || null, tracks: [query] };
|
|
241
|
+
if (!options)
|
|
242
|
+
throw new PlayerError_1.PlayerError("DiscordPlayer#search needs search options!", PlayerError_1.ErrorStatusCode.INVALID_ARG_TYPE);
|
|
243
|
+
options.requestedBy = this.client.users.resolve(options.requestedBy);
|
|
244
|
+
if (!("searchEngine" in options))
|
|
245
|
+
options.searchEngine = types_1.QueryType.AUTO;
|
|
246
|
+
if (typeof options.searchEngine === "string" && this.extractors.has(options.searchEngine)) {
|
|
247
|
+
const extractor = this.extractors.get(options.searchEngine);
|
|
248
|
+
if (!extractor.validate(query))
|
|
249
|
+
return { playlist: null, tracks: [] };
|
|
250
|
+
const data = await extractor.handle(query);
|
|
251
|
+
if (data && data.data.length) {
|
|
252
|
+
const playlist = !data.playlist
|
|
253
|
+
? null
|
|
254
|
+
: new Playlist_1.Playlist(this, {
|
|
255
|
+
...data.playlist,
|
|
256
|
+
tracks: []
|
|
257
|
+
});
|
|
258
|
+
const tracks = data.data.map((m) => new Track_1.default(this, {
|
|
259
|
+
...m,
|
|
260
|
+
requestedBy: options.requestedBy,
|
|
261
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)),
|
|
262
|
+
playlist: playlist
|
|
263
|
+
}));
|
|
264
|
+
if (playlist)
|
|
265
|
+
playlist.tracks = tracks;
|
|
266
|
+
return { playlist: playlist, tracks: tracks };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
270
|
+
for (const [_, extractor] of this.extractors) {
|
|
271
|
+
if (options.blockExtractor)
|
|
272
|
+
break;
|
|
273
|
+
if (!extractor.validate(query))
|
|
274
|
+
continue;
|
|
275
|
+
const data = await extractor.handle(query);
|
|
276
|
+
if (data && data.data.length) {
|
|
277
|
+
const playlist = !data.playlist
|
|
278
|
+
? null
|
|
279
|
+
: new Playlist_1.Playlist(this, {
|
|
280
|
+
...data.playlist,
|
|
281
|
+
tracks: []
|
|
282
|
+
});
|
|
283
|
+
const tracks = data.data.map((m) => new Track_1.default(this, {
|
|
284
|
+
...m,
|
|
285
|
+
requestedBy: options.requestedBy,
|
|
286
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)),
|
|
287
|
+
playlist: playlist
|
|
288
|
+
}));
|
|
289
|
+
if (playlist)
|
|
290
|
+
playlist.tracks = tracks;
|
|
291
|
+
return { playlist: playlist, tracks: tracks };
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const qt = options.searchEngine === types_1.QueryType.AUTO ? QueryResolver_1.QueryResolver.resolve(query) : options.searchEngine;
|
|
295
|
+
switch (qt) {
|
|
296
|
+
case types_1.QueryType.YOUTUBE_VIDEO: {
|
|
297
|
+
const info = await (0, ytdl_core_1.getInfo)(query, this.options.ytdlOptions).catch(Util_1.Util.noop);
|
|
298
|
+
if (!info)
|
|
299
|
+
return { playlist: null, tracks: [] };
|
|
300
|
+
const track = new Track_1.default(this, {
|
|
301
|
+
title: info.videoDetails.title,
|
|
302
|
+
description: info.videoDetails.description,
|
|
303
|
+
author: info.videoDetails.author?.name,
|
|
304
|
+
url: info.videoDetails.video_url,
|
|
305
|
+
requestedBy: options.requestedBy,
|
|
306
|
+
thumbnail: Util_1.Util.last(info.videoDetails.thumbnails)?.url,
|
|
307
|
+
views: parseInt(info.videoDetails.viewCount.replace(/[^0-9]/g, "")) || 0,
|
|
308
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)),
|
|
309
|
+
source: "youtube",
|
|
310
|
+
raw: info
|
|
311
|
+
});
|
|
312
|
+
return { playlist: null, tracks: [track] };
|
|
313
|
+
}
|
|
314
|
+
case types_1.QueryType.YOUTUBE_SEARCH: {
|
|
315
|
+
const videos = await youtube_sr_1.default.search(query, {
|
|
316
|
+
type: "video"
|
|
317
|
+
}).catch(Util_1.Util.noop);
|
|
318
|
+
if (!videos)
|
|
319
|
+
return { playlist: null, tracks: [] };
|
|
320
|
+
const tracks = videos.map((m) => {
|
|
321
|
+
m.source = "youtube"; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
322
|
+
return new Track_1.default(this, {
|
|
323
|
+
title: m.title,
|
|
324
|
+
description: m.description,
|
|
325
|
+
author: m.channel?.name,
|
|
326
|
+
url: m.url,
|
|
327
|
+
requestedBy: options.requestedBy,
|
|
328
|
+
thumbnail: m.thumbnail?.displayThumbnailURL("maxresdefault"),
|
|
329
|
+
views: m.views,
|
|
330
|
+
duration: m.durationFormatted,
|
|
331
|
+
source: "youtube",
|
|
332
|
+
raw: m
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
return { playlist: null, tracks };
|
|
336
|
+
}
|
|
337
|
+
case types_1.QueryType.SOUNDCLOUD_TRACK:
|
|
338
|
+
case types_1.QueryType.SOUNDCLOUD_SEARCH: {
|
|
339
|
+
const result = QueryResolver_1.QueryResolver.resolve(query) === types_1.QueryType.SOUNDCLOUD_TRACK ? [{ url: query }] : await soundcloud.search(query, "track").catch(() => []);
|
|
340
|
+
if (!result || !result.length)
|
|
341
|
+
return { playlist: null, tracks: [] };
|
|
342
|
+
const res = [];
|
|
343
|
+
for (const r of result) {
|
|
344
|
+
const trackInfo = await soundcloud.getSongInfo(r.url).catch(Util_1.Util.noop);
|
|
345
|
+
if (!trackInfo)
|
|
346
|
+
continue;
|
|
347
|
+
const track = new Track_1.default(this, {
|
|
348
|
+
title: trackInfo.title,
|
|
349
|
+
url: trackInfo.url,
|
|
350
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(trackInfo.duration)),
|
|
351
|
+
description: trackInfo.description,
|
|
352
|
+
thumbnail: trackInfo.thumbnail,
|
|
353
|
+
views: trackInfo.playCount,
|
|
354
|
+
author: trackInfo.author.name,
|
|
355
|
+
requestedBy: options.requestedBy,
|
|
356
|
+
source: "soundcloud",
|
|
357
|
+
engine: trackInfo
|
|
358
|
+
});
|
|
359
|
+
res.push(track);
|
|
360
|
+
}
|
|
361
|
+
return { playlist: null, tracks: res };
|
|
362
|
+
}
|
|
363
|
+
case types_1.QueryType.SPOTIFY_SONG: {
|
|
364
|
+
const spotifyData = await (0, spotify_url_info_1.default)(await Util_1.Util.getFetch())
|
|
365
|
+
.getData(query)
|
|
366
|
+
.catch(Util_1.Util.noop);
|
|
367
|
+
if (!spotifyData)
|
|
368
|
+
return { playlist: null, tracks: [] };
|
|
369
|
+
const spotifyTrack = new Track_1.default(this, {
|
|
370
|
+
title: spotifyData.name,
|
|
371
|
+
description: spotifyData.description ?? "",
|
|
372
|
+
author: spotifyData.artists[0]?.name ?? "Unknown Artist",
|
|
373
|
+
url: spotifyData.external_urls?.spotify ?? query,
|
|
374
|
+
thumbnail: (spotifyData.coverArt?.sources?.[0]?.url ??
|
|
375
|
+
spotifyData.album?.images[0]?.url ??
|
|
376
|
+
(spotifyData.preview_url?.length && `https://i.scdn.co/image/${spotifyData.preview_url?.split("?cid=")[1]}`)) ||
|
|
377
|
+
"https://www.scdn.co/i/_global/twitter_card-default.jpg",
|
|
378
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(spotifyData.duration_ms ?? spotifyData.duration ?? spotifyData.maxDuration)),
|
|
379
|
+
views: 0,
|
|
380
|
+
requestedBy: options.requestedBy,
|
|
381
|
+
source: "spotify"
|
|
382
|
+
});
|
|
383
|
+
return { playlist: null, tracks: [spotifyTrack] };
|
|
384
|
+
}
|
|
385
|
+
case types_1.QueryType.SPOTIFY_PLAYLIST:
|
|
386
|
+
case types_1.QueryType.SPOTIFY_ALBUM: {
|
|
387
|
+
const spotifyPlaylist = await (0, spotify_url_info_1.default)(await Util_1.Util.getFetch())
|
|
388
|
+
.getData(query)
|
|
389
|
+
.catch(Util_1.Util.noop);
|
|
390
|
+
if (!spotifyPlaylist)
|
|
391
|
+
return { playlist: null, tracks: [] };
|
|
392
|
+
const playlist = new Playlist_1.Playlist(this, {
|
|
393
|
+
title: spotifyPlaylist.name ?? spotifyPlaylist.title,
|
|
394
|
+
description: spotifyPlaylist.description ?? "",
|
|
395
|
+
thumbnail: spotifyPlaylist.coverArt?.sources?.[0]?.url ?? spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
|
|
396
|
+
type: spotifyPlaylist.type,
|
|
397
|
+
source: "spotify",
|
|
398
|
+
author: spotifyPlaylist.type !== "playlist"
|
|
399
|
+
? {
|
|
400
|
+
name: spotifyPlaylist.artists[0]?.name ?? "Unknown Artist",
|
|
401
|
+
url: spotifyPlaylist.artists[0]?.external_urls?.spotify ?? null
|
|
402
|
+
}
|
|
403
|
+
: {
|
|
404
|
+
name: spotifyPlaylist.owner?.display_name ?? spotifyPlaylist.owner?.id ?? "Unknown Artist",
|
|
405
|
+
url: spotifyPlaylist.owner?.external_urls?.spotify ?? null
|
|
406
|
+
},
|
|
407
|
+
tracks: [],
|
|
408
|
+
id: spotifyPlaylist.id,
|
|
409
|
+
url: spotifyPlaylist.external_urls?.spotify ?? query,
|
|
410
|
+
rawPlaylist: spotifyPlaylist
|
|
411
|
+
});
|
|
412
|
+
if (spotifyPlaylist.type !== "playlist") {
|
|
413
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
414
|
+
playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
|
|
415
|
+
const data = new Track_1.default(this, {
|
|
416
|
+
title: m.name ?? "",
|
|
417
|
+
description: m.description ?? "",
|
|
418
|
+
author: m.artists[0]?.name ?? "Unknown Artist",
|
|
419
|
+
url: m.external_urls?.spotify ?? query,
|
|
420
|
+
thumbnail: spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
|
|
421
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration_ms)),
|
|
422
|
+
views: 0,
|
|
423
|
+
requestedBy: options.requestedBy,
|
|
424
|
+
playlist,
|
|
425
|
+
source: "spotify"
|
|
426
|
+
});
|
|
427
|
+
return data;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
432
|
+
playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
|
|
433
|
+
const data = new Track_1.default(this, {
|
|
434
|
+
title: m.track.name ?? "",
|
|
435
|
+
description: m.track.description ?? "",
|
|
436
|
+
author: m.track.artists?.[0]?.name ?? "Unknown Artist",
|
|
437
|
+
url: m.track.external_urls?.spotify ?? query,
|
|
438
|
+
thumbnail: m.track.album?.images?.[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
|
|
439
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.track.duration_ms)),
|
|
440
|
+
views: 0,
|
|
441
|
+
requestedBy: options.requestedBy,
|
|
442
|
+
playlist,
|
|
443
|
+
source: "spotify"
|
|
444
|
+
});
|
|
445
|
+
return data;
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
return { playlist: playlist, tracks: playlist.tracks };
|
|
449
|
+
}
|
|
450
|
+
case types_1.QueryType.SOUNDCLOUD_PLAYLIST: {
|
|
451
|
+
const data = await soundcloud.getPlaylist(query).catch(Util_1.Util.noop);
|
|
452
|
+
if (!data)
|
|
453
|
+
return { playlist: null, tracks: [] };
|
|
454
|
+
const res = new Playlist_1.Playlist(this, {
|
|
455
|
+
title: data.title,
|
|
456
|
+
description: data.description ?? "",
|
|
457
|
+
thumbnail: data.thumbnail ?? "https://soundcloud.com/pwa-icon-192.png",
|
|
458
|
+
type: "playlist",
|
|
459
|
+
source: "soundcloud",
|
|
460
|
+
author: {
|
|
461
|
+
name: data.author?.name ?? data.author?.username ?? "Unknown Artist",
|
|
462
|
+
url: data.author?.profile
|
|
463
|
+
},
|
|
464
|
+
tracks: [],
|
|
465
|
+
id: `${data.id}`,
|
|
466
|
+
url: data.url,
|
|
467
|
+
rawPlaylist: data
|
|
468
|
+
});
|
|
469
|
+
for (const song of data.tracks) {
|
|
470
|
+
const track = new Track_1.default(this, {
|
|
471
|
+
title: song.title,
|
|
472
|
+
description: song.description ?? "",
|
|
473
|
+
author: song.author?.username ?? song.author?.name ?? "Unknown Artist",
|
|
474
|
+
url: song.url,
|
|
475
|
+
thumbnail: song.thumbnail,
|
|
476
|
+
duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(song.duration)),
|
|
477
|
+
views: song.playCount ?? 0,
|
|
478
|
+
requestedBy: options.requestedBy,
|
|
479
|
+
playlist: res,
|
|
480
|
+
source: "soundcloud",
|
|
481
|
+
engine: song
|
|
482
|
+
});
|
|
483
|
+
res.tracks.push(track);
|
|
484
|
+
}
|
|
485
|
+
return { playlist: res, tracks: res.tracks };
|
|
486
|
+
}
|
|
487
|
+
case types_1.QueryType.YOUTUBE_PLAYLIST: {
|
|
488
|
+
const ytpl = await youtube_sr_1.default.getPlaylist(query).catch(Util_1.Util.noop);
|
|
489
|
+
if (!ytpl)
|
|
490
|
+
return { playlist: null, tracks: [] };
|
|
491
|
+
await ytpl.fetch().catch(Util_1.Util.noop);
|
|
492
|
+
const playlist = new Playlist_1.Playlist(this, {
|
|
493
|
+
title: ytpl.title,
|
|
494
|
+
thumbnail: ytpl.thumbnail,
|
|
495
|
+
description: "",
|
|
496
|
+
type: "playlist",
|
|
497
|
+
source: "youtube",
|
|
498
|
+
author: {
|
|
499
|
+
name: ytpl.channel.name,
|
|
500
|
+
url: ytpl.channel.url
|
|
501
|
+
},
|
|
502
|
+
tracks: [],
|
|
503
|
+
id: ytpl.id,
|
|
504
|
+
url: ytpl.url,
|
|
505
|
+
rawPlaylist: ytpl
|
|
506
|
+
});
|
|
507
|
+
playlist.tracks = ytpl.videos.map((video) => new Track_1.default(this, {
|
|
508
|
+
title: video.title,
|
|
509
|
+
description: video.description,
|
|
510
|
+
author: video.channel?.name,
|
|
511
|
+
url: video.url,
|
|
512
|
+
requestedBy: options.requestedBy,
|
|
513
|
+
thumbnail: video.thumbnail.url,
|
|
514
|
+
views: video.views,
|
|
515
|
+
duration: video.durationFormatted,
|
|
516
|
+
raw: video,
|
|
517
|
+
playlist: playlist,
|
|
518
|
+
source: "youtube"
|
|
519
|
+
}));
|
|
520
|
+
return { playlist: playlist, tracks: playlist.tracks };
|
|
521
|
+
}
|
|
522
|
+
default:
|
|
523
|
+
return { playlist: null, tracks: [] };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Registers extractor
|
|
528
|
+
* @param {string} extractorName The extractor name
|
|
529
|
+
* @param {ExtractorModel|any} extractor The extractor object
|
|
530
|
+
* @param {boolean} [force=false] Overwrite existing extractor with this name (if available)
|
|
531
|
+
* @returns {ExtractorModel}
|
|
532
|
+
*/
|
|
533
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
534
|
+
use(extractorName, extractor, force = false) {
|
|
535
|
+
if (!extractorName)
|
|
536
|
+
throw new PlayerError_1.PlayerError("Cannot use unknown extractor!", PlayerError_1.ErrorStatusCode.UNKNOWN_EXTRACTOR);
|
|
537
|
+
if (this.extractors.has(extractorName) && !force)
|
|
538
|
+
return this.extractors.get(extractorName);
|
|
539
|
+
if (extractor instanceof ExtractorModel_1.ExtractorModel) {
|
|
540
|
+
this.extractors.set(extractorName, extractor);
|
|
541
|
+
return extractor;
|
|
542
|
+
}
|
|
543
|
+
for (const method of ["validate", "getInfo"]) {
|
|
544
|
+
if (typeof extractor[method] !== "function")
|
|
545
|
+
throw new PlayerError_1.PlayerError("Invalid extractor data!", PlayerError_1.ErrorStatusCode.INVALID_EXTRACTOR);
|
|
546
|
+
}
|
|
547
|
+
const model = new ExtractorModel_1.ExtractorModel(extractorName, extractor);
|
|
548
|
+
this.extractors.set(model.name, model);
|
|
549
|
+
return model;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Removes registered extractor
|
|
553
|
+
* @param {string} extractorName The extractor name
|
|
554
|
+
* @returns {ExtractorModel}
|
|
555
|
+
*/
|
|
556
|
+
unuse(extractorName) {
|
|
557
|
+
if (!this.extractors.has(extractorName))
|
|
558
|
+
throw new PlayerError_1.PlayerError(`Cannot find extractor "${extractorName}"`, PlayerError_1.ErrorStatusCode.UNKNOWN_EXTRACTOR);
|
|
559
|
+
const prev = this.extractors.get(extractorName);
|
|
560
|
+
this.extractors.delete(extractorName);
|
|
561
|
+
return prev;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Generates a report of the dependencies used by the `@discordjs/voice` module. Useful for debugging.
|
|
565
|
+
* @returns {string}
|
|
566
|
+
*/
|
|
567
|
+
scanDeps() {
|
|
568
|
+
const line = "-".repeat(50);
|
|
569
|
+
const depsReport = (0, voice_1.generateDependencyReport)();
|
|
570
|
+
const extractorReport = this.extractors
|
|
571
|
+
.map((m) => {
|
|
572
|
+
return `${m.name} :: ${m.version || "0.1.0"}`;
|
|
573
|
+
})
|
|
574
|
+
.join("\n");
|
|
575
|
+
return `${depsReport}\n${line}\nLoaded Extractors:\n${extractorReport || "None"}`;
|
|
576
|
+
}
|
|
577
|
+
emit(eventName, ...args) {
|
|
578
|
+
if (this.requiredEvents.includes(eventName) && !super.eventNames().includes(eventName)) {
|
|
579
|
+
// eslint-disable-next-line no-console
|
|
580
|
+
console.error(...args);
|
|
581
|
+
process.emitWarning(`[DiscordPlayerWarning] Unhandled "${eventName}" event! Events ${this.requiredEvents.map((m) => `"${m}"`).join(", ")} must have event listeners!`);
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
return super.emit(eventName, ...args);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Resolves queue
|
|
590
|
+
* @param {GuildResolvable|Queue} queueLike Queue like object
|
|
591
|
+
* @returns {Queue}
|
|
592
|
+
*/
|
|
593
|
+
resolveQueue(queueLike) {
|
|
594
|
+
return this.getQueue(queueLike instanceof Queue_1.Queue ? queueLike.guild : queueLike);
|
|
595
|
+
}
|
|
596
|
+
*[(_Player_lastLatency = new WeakMap(), Symbol.iterator)]() {
|
|
597
|
+
yield* Array.from(this.queues.values());
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Creates `Playlist` instance
|
|
601
|
+
* @param data The data to initialize a playlist
|
|
602
|
+
*/
|
|
603
|
+
createPlaylist(data) {
|
|
604
|
+
return new Playlist_1.Playlist(this, data);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
exports.Player = Player;
|