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/Structures/Queue.js
CHANGED
|
@@ -1,795 +1,830 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _Queue_instances, _Queue_destroyed, _Queue_watchDestroyed, _Queue_getBufferingTimeout;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.Queue = void 0;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
6
|
-
const discord_js_1 = require("discord.js");
|
|
7
|
-
const Track_1 = tslib_1.__importDefault(require("./Track"));
|
|
8
|
-
const types_1 = require("../types/types");
|
|
9
|
-
const ytdl_core_1 = tslib_1.__importDefault(require("ytdl-core"));
|
|
10
|
-
const voice_1 = require("@discordjs/voice");
|
|
11
|
-
const Util_1 = require("../utils/Util");
|
|
12
|
-
const youtube_sr_1 = tslib_1.__importDefault(require("youtube-sr"));
|
|
13
|
-
const AudioFilters_1 = tslib_1.__importDefault(require("../utils/AudioFilters"));
|
|
14
|
-
const PlayerError_1 = require("./PlayerError");
|
|
15
|
-
const FFmpegStream_1 = require("../utils/FFmpegStream");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
* @param {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
this
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
this.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
this._filtersUpdate
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
this.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (this.repeatMode === types_1.QueueRepeatMode.
|
|
199
|
-
this.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (this.
|
|
212
|
-
return;
|
|
213
|
-
if (this.
|
|
214
|
-
|
|
215
|
-
this.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
*
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (this.
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
this.connection
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
return
|
|
251
|
-
this.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
*
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
this.
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
*
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (
|
|
291
|
-
return
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
*
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (
|
|
303
|
-
return;
|
|
304
|
-
if (
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
*
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
return
|
|
318
|
-
this.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
*
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
this.repeatMode
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (
|
|
344
|
-
return
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (
|
|
358
|
-
return
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
this.
|
|
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
|
-
if (
|
|
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
|
-
if (
|
|
434
|
-
return
|
|
435
|
-
if (
|
|
436
|
-
|
|
437
|
-
if (position
|
|
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
|
-
this
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (
|
|
484
|
-
return
|
|
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
|
-
if (
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
*
|
|
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
|
-
if (
|
|
564
|
-
|
|
565
|
-
if (
|
|
566
|
-
throw new PlayerError_1.PlayerError(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
* @
|
|
574
|
-
* @property {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
const
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
*
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
*
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var _Queue_instances, _Queue_destroyed, _Queue_watchDestroyed, _Queue_getBufferingTimeout;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Queue = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const discord_js_1 = require("discord.js");
|
|
7
|
+
const Track_1 = tslib_1.__importDefault(require("./Track"));
|
|
8
|
+
const types_1 = require("../types/types");
|
|
9
|
+
const ytdl_core_1 = tslib_1.__importDefault(require("ytdl-core"));
|
|
10
|
+
const voice_1 = require("@discordjs/voice");
|
|
11
|
+
const Util_1 = require("../utils/Util");
|
|
12
|
+
const youtube_sr_1 = tslib_1.__importDefault(require("youtube-sr"));
|
|
13
|
+
const AudioFilters_1 = tslib_1.__importDefault(require("../utils/AudioFilters"));
|
|
14
|
+
const PlayerError_1 = require("./PlayerError");
|
|
15
|
+
const FFmpegStream_1 = require("../utils/FFmpegStream");
|
|
16
|
+
const os_1 = tslib_1.__importDefault(require("os"));
|
|
17
|
+
const worker_threads_1 = require("worker_threads");
|
|
18
|
+
class Queue {
|
|
19
|
+
/**
|
|
20
|
+
* Queue constructor
|
|
21
|
+
* @param {Player} player The player that instantiated this queue
|
|
22
|
+
* @param {Guild} guild The guild that instantiated this queue
|
|
23
|
+
* @param {PlayerOptions} [options] Player options for the queue
|
|
24
|
+
*/
|
|
25
|
+
constructor(player, guild, options = {}) {
|
|
26
|
+
_Queue_instances.add(this);
|
|
27
|
+
this.tracks = [];
|
|
28
|
+
this.previousTracks = [];
|
|
29
|
+
this.playing = false;
|
|
30
|
+
this.metadata = null;
|
|
31
|
+
this.repeatMode = 0;
|
|
32
|
+
this.id = discord_js_1.SnowflakeUtil.generate().toString();
|
|
33
|
+
this._streamTime = 0;
|
|
34
|
+
this._cooldownsTimeout = new discord_js_1.Collection();
|
|
35
|
+
this._activeFilters = []; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
36
|
+
this._filtersUpdate = false;
|
|
37
|
+
_Queue_destroyed.set(this, false);
|
|
38
|
+
this.onBeforeCreateStream = null;
|
|
39
|
+
/**
|
|
40
|
+
* The player that instantiated this queue
|
|
41
|
+
* @type {Player}
|
|
42
|
+
* @readonly
|
|
43
|
+
*/
|
|
44
|
+
this.player = player;
|
|
45
|
+
/**
|
|
46
|
+
* The guild that instantiated this queue
|
|
47
|
+
* @type {Guild}
|
|
48
|
+
* @readonly
|
|
49
|
+
*/
|
|
50
|
+
this.guild = guild;
|
|
51
|
+
/**
|
|
52
|
+
* The player options for this queue
|
|
53
|
+
* @type {PlayerOptions}
|
|
54
|
+
*/
|
|
55
|
+
this.options = {};
|
|
56
|
+
/**
|
|
57
|
+
* Queue repeat mode
|
|
58
|
+
* @type {QueueRepeatMode}
|
|
59
|
+
* @name Queue#repeatMode
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Queue metadata
|
|
63
|
+
* @type {any}
|
|
64
|
+
* @name Queue#metadata
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Previous tracks
|
|
68
|
+
* @type {Track[]}
|
|
69
|
+
* @name Queue#previousTracks
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* Regular tracks
|
|
73
|
+
* @type {Track[]}
|
|
74
|
+
* @name Queue#tracks
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* The connection
|
|
78
|
+
* @type {StreamDispatcher}
|
|
79
|
+
* @name Queue#connection
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* The ID of this queue
|
|
83
|
+
* @type {Snowflake}
|
|
84
|
+
* @name Queue#id
|
|
85
|
+
*/
|
|
86
|
+
Object.assign(this.options, {
|
|
87
|
+
leaveOnEnd: true,
|
|
88
|
+
leaveOnStop: true,
|
|
89
|
+
leaveOnEmpty: true,
|
|
90
|
+
leaveOnEndCooldown: 1000,
|
|
91
|
+
leaveOnEmptyCooldown: 1000,
|
|
92
|
+
autoSelfDeaf: true,
|
|
93
|
+
ytdlOptions: {
|
|
94
|
+
highWaterMark: 1 << 25
|
|
95
|
+
},
|
|
96
|
+
initialVolume: 100,
|
|
97
|
+
bufferingTimeout: 3000,
|
|
98
|
+
spotifyBridge: true,
|
|
99
|
+
disableVolume: false
|
|
100
|
+
}, options);
|
|
101
|
+
if ("onBeforeCreateStream" in this.options)
|
|
102
|
+
this.onBeforeCreateStream = this.options.onBeforeCreateStream;
|
|
103
|
+
this.player.emit("debug", this, `Queue initialized:\n\n${this.player.scanDeps()}`);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Forces next play
|
|
107
|
+
* @returns {Promise<void>}
|
|
108
|
+
*/
|
|
109
|
+
async forceNext() {
|
|
110
|
+
if (this.connection.audioResource) {
|
|
111
|
+
this.connection.emit("finish", this.connection.audioResource);
|
|
112
|
+
}
|
|
113
|
+
else if (this.tracks.length) {
|
|
114
|
+
await this.play();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns current track
|
|
119
|
+
* @type {Track}
|
|
120
|
+
*/
|
|
121
|
+
get current() {
|
|
122
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
123
|
+
return;
|
|
124
|
+
return this.connection.audioResource?.metadata ?? this.tracks[0];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* If this queue is destroyed
|
|
128
|
+
* @type {boolean}
|
|
129
|
+
*/
|
|
130
|
+
get destroyed() {
|
|
131
|
+
return tslib_1.__classPrivateFieldGet(this, _Queue_destroyed, "f");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Returns current track
|
|
135
|
+
* @returns {Track}
|
|
136
|
+
*/
|
|
137
|
+
nowPlaying() {
|
|
138
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
139
|
+
return;
|
|
140
|
+
return this.current;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Connects to a voice channel
|
|
144
|
+
* @param {GuildChannelResolvable} channel The voice/stage channel
|
|
145
|
+
* @returns {Promise<Queue>}
|
|
146
|
+
*/
|
|
147
|
+
async connect(channel) {
|
|
148
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
149
|
+
return;
|
|
150
|
+
const _channel = this.guild.channels.resolve(channel);
|
|
151
|
+
if (![discord_js_1.ChannelType.GuildStageVoice, discord_js_1.ChannelType.GuildVoice].includes(_channel?.type))
|
|
152
|
+
throw new PlayerError_1.PlayerError(`Channel type must be GuildVoice or GuildStageVoice, got ${_channel?.type}!`, PlayerError_1.ErrorStatusCode.INVALID_ARG_TYPE);
|
|
153
|
+
const connection = await this.player.voiceUtils.connect(_channel, {
|
|
154
|
+
deaf: this.options.autoSelfDeaf
|
|
155
|
+
});
|
|
156
|
+
this.connection = connection;
|
|
157
|
+
if (_channel.type === discord_js_1.ChannelType.GuildStageVoice) {
|
|
158
|
+
await _channel.guild.members.me.voice.setSuppressed(false).catch(async () => {
|
|
159
|
+
return await _channel.guild.members.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
this.connection.on("error", (err) => {
|
|
163
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this, false))
|
|
164
|
+
return;
|
|
165
|
+
this.player.emit("connectionError", this, err);
|
|
166
|
+
});
|
|
167
|
+
this.connection.on("debug", (msg) => {
|
|
168
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this, false))
|
|
169
|
+
return;
|
|
170
|
+
this.player.emit("debug", this, msg);
|
|
171
|
+
});
|
|
172
|
+
this.player.emit("connectionCreate", this, this.connection);
|
|
173
|
+
this.connection.on("start", (resource) => {
|
|
174
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this, false))
|
|
175
|
+
return;
|
|
176
|
+
this.playing = true;
|
|
177
|
+
if (!this._filtersUpdate)
|
|
178
|
+
this.player.emit("trackStart", this, resource?.metadata ?? this.current);
|
|
179
|
+
this._filtersUpdate = false;
|
|
180
|
+
});
|
|
181
|
+
this.connection.on("finish", async (resource) => {
|
|
182
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this, false))
|
|
183
|
+
return;
|
|
184
|
+
this.playing = false;
|
|
185
|
+
if (this._filtersUpdate)
|
|
186
|
+
return;
|
|
187
|
+
this._streamTime = 0;
|
|
188
|
+
if (resource?.metadata)
|
|
189
|
+
this.previousTracks.push(resource.metadata);
|
|
190
|
+
this.player.emit("trackEnd", this, resource.metadata);
|
|
191
|
+
if (!this.tracks.length && this.repeatMode === types_1.QueueRepeatMode.OFF) {
|
|
192
|
+
this.emitEnd();
|
|
193
|
+
}
|
|
194
|
+
else if (!this.tracks.length && this.repeatMode === types_1.QueueRepeatMode.AUTOPLAY) {
|
|
195
|
+
this._handleAutoplay(Util_1.Util.last(this.previousTracks));
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (this.repeatMode === types_1.QueueRepeatMode.TRACK)
|
|
199
|
+
return void this.play(Util_1.Util.last(this.previousTracks), { immediate: true });
|
|
200
|
+
if (this.repeatMode === types_1.QueueRepeatMode.QUEUE)
|
|
201
|
+
this.tracks.push(Util_1.Util.last(this.previousTracks));
|
|
202
|
+
const nextTrack = this.tracks.shift();
|
|
203
|
+
this.play(nextTrack, { immediate: true });
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
emitEnd() {
|
|
210
|
+
const timeout = setTimeout(() => {
|
|
211
|
+
if (!this.player.queues.has(this.guild.id))
|
|
212
|
+
return;
|
|
213
|
+
if (this.tracks.length || this.current)
|
|
214
|
+
return;
|
|
215
|
+
if (this.options.leaveOnEnd)
|
|
216
|
+
this.destroy();
|
|
217
|
+
this.player.emit("queueEnd", this);
|
|
218
|
+
}, this.options.leaveOnEndCooldown || 0).unref();
|
|
219
|
+
this._cooldownsTimeout.set(`queueEnd_${this.guild.id}`, timeout);
|
|
220
|
+
}
|
|
221
|
+
refreshEndCooldown() {
|
|
222
|
+
const existingTimeout = this._cooldownsTimeout.get(`queueEnd_${this.guild.id}`);
|
|
223
|
+
if (this.tracks.length || this.current) {
|
|
224
|
+
clearTimeout(existingTimeout);
|
|
225
|
+
this._cooldownsTimeout.delete(`queueEnd_${this.guild.id}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Destroys this queue
|
|
230
|
+
* @param {boolean} [disconnect=this.options.leaveOnStop] If it should leave on destroy
|
|
231
|
+
* @returns {void}
|
|
232
|
+
*/
|
|
233
|
+
destroy(disconnect = this.options.leaveOnStop) {
|
|
234
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
235
|
+
return;
|
|
236
|
+
if (this.connection)
|
|
237
|
+
this.connection.end();
|
|
238
|
+
if (disconnect)
|
|
239
|
+
this.connection?.disconnect();
|
|
240
|
+
this.player.queues.delete(this.guild.id);
|
|
241
|
+
this.player.voiceUtils.cache.delete(this.guild.id);
|
|
242
|
+
tslib_1.__classPrivateFieldSet(this, _Queue_destroyed, true, "f");
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Skips current track
|
|
246
|
+
* @returns {boolean}
|
|
247
|
+
*/
|
|
248
|
+
skip() {
|
|
249
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
250
|
+
return;
|
|
251
|
+
if (!this.connection)
|
|
252
|
+
return false;
|
|
253
|
+
this._filtersUpdate = false;
|
|
254
|
+
this.connection.end();
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Adds single track to the queue
|
|
259
|
+
* @param {Track} track The track to add
|
|
260
|
+
* @returns {void}
|
|
261
|
+
*/
|
|
262
|
+
addTrack(track) {
|
|
263
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
264
|
+
return;
|
|
265
|
+
if (!(track instanceof Track_1.default))
|
|
266
|
+
throw new PlayerError_1.PlayerError("invalid track", PlayerError_1.ErrorStatusCode.INVALID_TRACK);
|
|
267
|
+
this.tracks.push(track);
|
|
268
|
+
this.refreshEndCooldown();
|
|
269
|
+
this.player.emit("trackAdd", this, track);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Adds multiple tracks to the queue
|
|
273
|
+
* @param {Track[]} tracks Array of tracks to add
|
|
274
|
+
*/
|
|
275
|
+
addTracks(tracks) {
|
|
276
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
277
|
+
return;
|
|
278
|
+
if (!tracks.every((y) => y instanceof Track_1.default))
|
|
279
|
+
throw new PlayerError_1.PlayerError("invalid track", PlayerError_1.ErrorStatusCode.INVALID_TRACK);
|
|
280
|
+
this.tracks.push(...tracks);
|
|
281
|
+
this.refreshEndCooldown();
|
|
282
|
+
this.player.emit("tracksAdd", this, tracks);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Sets paused state
|
|
286
|
+
* @param {boolean} paused The paused state
|
|
287
|
+
* @returns {boolean}
|
|
288
|
+
*/
|
|
289
|
+
setPaused(paused) {
|
|
290
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
291
|
+
return;
|
|
292
|
+
if (!this.connection)
|
|
293
|
+
return false;
|
|
294
|
+
return paused ? this.connection.pause(true) : this.connection.resume();
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Sets bitrate
|
|
298
|
+
* @param {number|auto} bitrate bitrate to set
|
|
299
|
+
* @returns {void}
|
|
300
|
+
*/
|
|
301
|
+
setBitrate(bitrate) {
|
|
302
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
303
|
+
return;
|
|
304
|
+
if (!this.connection?.audioResource?.encoder)
|
|
305
|
+
return;
|
|
306
|
+
if (bitrate === "auto")
|
|
307
|
+
bitrate = this.connection.channel?.bitrate ?? 64000;
|
|
308
|
+
this.connection.audioResource.encoder.setBitrate(bitrate);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Sets volume
|
|
312
|
+
* @param {number} amount The volume amount
|
|
313
|
+
* @returns {boolean}
|
|
314
|
+
*/
|
|
315
|
+
setVolume(amount) {
|
|
316
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
317
|
+
return;
|
|
318
|
+
if (!this.connection)
|
|
319
|
+
return false;
|
|
320
|
+
this.options.initialVolume = amount;
|
|
321
|
+
return this.connection.setVolume(amount);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Sets repeat mode
|
|
325
|
+
* @param {QueueRepeatMode} mode The repeat mode
|
|
326
|
+
* @returns {boolean}
|
|
327
|
+
*/
|
|
328
|
+
setRepeatMode(mode) {
|
|
329
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
330
|
+
return;
|
|
331
|
+
if (![types_1.QueueRepeatMode.OFF, types_1.QueueRepeatMode.QUEUE, types_1.QueueRepeatMode.TRACK, types_1.QueueRepeatMode.AUTOPLAY].includes(mode))
|
|
332
|
+
throw new PlayerError_1.PlayerError(`Unknown repeat mode "${mode}"!`, PlayerError_1.ErrorStatusCode.UNKNOWN_REPEAT_MODE);
|
|
333
|
+
if (mode === this.repeatMode)
|
|
334
|
+
return false;
|
|
335
|
+
this.repeatMode = mode;
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The current volume amount
|
|
340
|
+
* @type {number}
|
|
341
|
+
*/
|
|
342
|
+
get volume() {
|
|
343
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
344
|
+
return;
|
|
345
|
+
if (!this.connection)
|
|
346
|
+
return 100;
|
|
347
|
+
return this.connection.volume;
|
|
348
|
+
}
|
|
349
|
+
set volume(amount) {
|
|
350
|
+
this.setVolume(amount);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* The stream time of this queue
|
|
354
|
+
* @type {number}
|
|
355
|
+
*/
|
|
356
|
+
get streamTime() {
|
|
357
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
358
|
+
return;
|
|
359
|
+
if (!this.connection)
|
|
360
|
+
return 0;
|
|
361
|
+
const playbackTime = this._streamTime + this.connection.streamTime;
|
|
362
|
+
const NC = this._activeFilters.includes("nightcore") ? 1.25 : null;
|
|
363
|
+
const VW = this._activeFilters.includes("vaporwave") ? 0.8 : null;
|
|
364
|
+
if (NC && VW)
|
|
365
|
+
return playbackTime * (NC + VW);
|
|
366
|
+
return NC ? playbackTime * NC : VW ? playbackTime * VW : playbackTime;
|
|
367
|
+
}
|
|
368
|
+
set streamTime(time) {
|
|
369
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
370
|
+
return;
|
|
371
|
+
this.seek(time);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Returns enabled filters
|
|
375
|
+
* @returns {AudioFilters}
|
|
376
|
+
*/
|
|
377
|
+
getFiltersEnabled() {
|
|
378
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
379
|
+
return;
|
|
380
|
+
return AudioFilters_1.default.names.filter((x) => this._activeFilters.includes(x));
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Returns disabled filters
|
|
384
|
+
* @returns {AudioFilters}
|
|
385
|
+
*/
|
|
386
|
+
getFiltersDisabled() {
|
|
387
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
388
|
+
return;
|
|
389
|
+
return AudioFilters_1.default.names.filter((x) => !this._activeFilters.includes(x));
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Sets filters
|
|
393
|
+
* @param {QueueFilters} filters Queue filters
|
|
394
|
+
* @returns {Promise<void>}
|
|
395
|
+
*/
|
|
396
|
+
async setFilters(filters) {
|
|
397
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
398
|
+
return;
|
|
399
|
+
if (!filters || !Object.keys(filters).length) {
|
|
400
|
+
// reset filters
|
|
401
|
+
const streamTime = this.streamTime;
|
|
402
|
+
this._activeFilters = [];
|
|
403
|
+
return await this.play(this.current, {
|
|
404
|
+
immediate: true,
|
|
405
|
+
filtersUpdate: true,
|
|
406
|
+
seek: streamTime,
|
|
407
|
+
encoderArgs: []
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
const _filters = []; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
411
|
+
for (const filter in filters) {
|
|
412
|
+
if (filters[filter] === true)
|
|
413
|
+
_filters.push(filter);
|
|
414
|
+
}
|
|
415
|
+
if (this._activeFilters.join("") === _filters.join(""))
|
|
416
|
+
return;
|
|
417
|
+
const newFilters = AudioFilters_1.default.create(_filters).trim();
|
|
418
|
+
const streamTime = this.streamTime;
|
|
419
|
+
this._activeFilters = _filters;
|
|
420
|
+
return await this.play(this.current, {
|
|
421
|
+
immediate: true,
|
|
422
|
+
filtersUpdate: true,
|
|
423
|
+
seek: streamTime,
|
|
424
|
+
encoderArgs: !_filters.length ? undefined : ["-af", newFilters]
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Seeks to the given time
|
|
429
|
+
* @param {number} position The position
|
|
430
|
+
* @returns {boolean}
|
|
431
|
+
*/
|
|
432
|
+
async seek(position) {
|
|
433
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
434
|
+
return;
|
|
435
|
+
if (!this.playing || !this.current)
|
|
436
|
+
return false;
|
|
437
|
+
if (position < 1)
|
|
438
|
+
position = 0;
|
|
439
|
+
if (position >= this.current.durationMS)
|
|
440
|
+
return this.skip();
|
|
441
|
+
await this.play(this.current, {
|
|
442
|
+
immediate: true,
|
|
443
|
+
filtersUpdate: true,
|
|
444
|
+
seek: position
|
|
445
|
+
});
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Plays previous track
|
|
450
|
+
* @returns {Promise<void>}
|
|
451
|
+
*/
|
|
452
|
+
async back() {
|
|
453
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
454
|
+
return;
|
|
455
|
+
const prev = this.previousTracks[this.previousTracks.length - 2]; // because last item is the current track
|
|
456
|
+
if (!prev)
|
|
457
|
+
throw new PlayerError_1.PlayerError("Could not find previous track", PlayerError_1.ErrorStatusCode.TRACK_NOT_FOUND);
|
|
458
|
+
return await this.play(prev, { immediate: true });
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Clear this queue
|
|
462
|
+
*/
|
|
463
|
+
clear() {
|
|
464
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
465
|
+
return;
|
|
466
|
+
this.tracks = [];
|
|
467
|
+
this.previousTracks = [];
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Stops the player
|
|
471
|
+
* @returns {void}
|
|
472
|
+
*/
|
|
473
|
+
stop() {
|
|
474
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
475
|
+
return;
|
|
476
|
+
return this.destroy();
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Shuffles this queue
|
|
480
|
+
* @returns {boolean}
|
|
481
|
+
*/
|
|
482
|
+
shuffle() {
|
|
483
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
484
|
+
return;
|
|
485
|
+
if (!this.tracks.length || this.tracks.length < 2)
|
|
486
|
+
return false;
|
|
487
|
+
for (let i = this.tracks.length - 1; i > 0; i--) {
|
|
488
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
489
|
+
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
|
490
|
+
}
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Removes a track from the queue
|
|
495
|
+
* @param {Track|string|number} track The track to remove
|
|
496
|
+
* @returns {Track}
|
|
497
|
+
*/
|
|
498
|
+
remove(track) {
|
|
499
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
500
|
+
return;
|
|
501
|
+
let trackFound = null;
|
|
502
|
+
if (typeof track === "number") {
|
|
503
|
+
trackFound = this.tracks[track];
|
|
504
|
+
if (trackFound) {
|
|
505
|
+
this.tracks = this.tracks.filter((t) => t.id !== trackFound.id);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
trackFound = this.tracks.find((s) => s.id === (track instanceof Track_1.default ? track.id : track));
|
|
510
|
+
if (trackFound) {
|
|
511
|
+
this.tracks = this.tracks.filter((s) => s.id !== trackFound.id);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return trackFound;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Returns the index of the specified track. If found, returns the track index else returns -1.
|
|
518
|
+
* @param {number|Track|string} track The track
|
|
519
|
+
* @returns {number}
|
|
520
|
+
*/
|
|
521
|
+
getTrackPosition(track) {
|
|
522
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
523
|
+
return;
|
|
524
|
+
if (typeof track === "number")
|
|
525
|
+
return this.tracks[track] != null ? track : -1;
|
|
526
|
+
return this.tracks.findIndex((pred) => pred.id === (track instanceof Track_1.default ? track.id : track));
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Jumps to particular track
|
|
530
|
+
* @param {Track|number} track The track
|
|
531
|
+
* @returns {void}
|
|
532
|
+
*/
|
|
533
|
+
jump(track) {
|
|
534
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
535
|
+
return;
|
|
536
|
+
const foundTrack = this.remove(track);
|
|
537
|
+
if (!foundTrack)
|
|
538
|
+
throw new PlayerError_1.PlayerError("Track not found", PlayerError_1.ErrorStatusCode.TRACK_NOT_FOUND);
|
|
539
|
+
this.tracks.splice(0, 0, foundTrack);
|
|
540
|
+
return void this.skip();
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Jumps to particular track, removing other tracks on the way
|
|
544
|
+
* @param {Track|number} track The track
|
|
545
|
+
* @returns {void}
|
|
546
|
+
*/
|
|
547
|
+
skipTo(track) {
|
|
548
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
549
|
+
return;
|
|
550
|
+
const trackIndex = this.getTrackPosition(track);
|
|
551
|
+
const removedTrack = this.remove(track);
|
|
552
|
+
if (!removedTrack)
|
|
553
|
+
throw new PlayerError_1.PlayerError("Track not found", PlayerError_1.ErrorStatusCode.TRACK_NOT_FOUND);
|
|
554
|
+
this.tracks.splice(0, trackIndex, removedTrack);
|
|
555
|
+
return void this.skip();
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Inserts the given track to specified index
|
|
559
|
+
* @param {Track} track The track to insert
|
|
560
|
+
* @param {number} [index=0] The index where this track should be
|
|
561
|
+
*/
|
|
562
|
+
insert(track, index = 0) {
|
|
563
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
564
|
+
return;
|
|
565
|
+
if (!track || !(track instanceof Track_1.default))
|
|
566
|
+
throw new PlayerError_1.PlayerError("track must be the instance of Track", PlayerError_1.ErrorStatusCode.INVALID_TRACK);
|
|
567
|
+
if (typeof index !== "number" || index < 0 || !Number.isFinite(index))
|
|
568
|
+
throw new PlayerError_1.PlayerError(`Invalid index "${index}"`, PlayerError_1.ErrorStatusCode.INVALID_ARG_TYPE);
|
|
569
|
+
this.tracks.splice(index, 0, track);
|
|
570
|
+
this.player.emit("trackAdd", this, track);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* @typedef {object} PlayerTimestamp
|
|
574
|
+
* @property {string} current The current progress
|
|
575
|
+
* @property {string} end The total time
|
|
576
|
+
* @property {number} progress Progress in %
|
|
577
|
+
*/
|
|
578
|
+
/**
|
|
579
|
+
* Returns player stream timestamp
|
|
580
|
+
* @returns {PlayerTimestamp}
|
|
581
|
+
*/
|
|
582
|
+
getPlayerTimestamp() {
|
|
583
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
584
|
+
return;
|
|
585
|
+
const currentStreamTime = this.streamTime;
|
|
586
|
+
const totalTime = this.current.durationMS;
|
|
587
|
+
const currentTimecode = Util_1.Util.buildTimeCode(Util_1.Util.parseMS(currentStreamTime));
|
|
588
|
+
const endTimecode = Util_1.Util.buildTimeCode(Util_1.Util.parseMS(totalTime));
|
|
589
|
+
return {
|
|
590
|
+
current: currentTimecode,
|
|
591
|
+
end: endTimecode,
|
|
592
|
+
progress: Math.round((currentStreamTime / totalTime) * 100)
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Creates progress bar string
|
|
597
|
+
* @param {PlayerProgressbarOptions} options The progress bar options
|
|
598
|
+
* @returns {string}
|
|
599
|
+
*/
|
|
600
|
+
createProgressBar(options = { timecodes: true }) {
|
|
601
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
602
|
+
return;
|
|
603
|
+
const length = typeof options.length === "number" ? (options.length <= 0 || options.length === Infinity ? 15 : options.length) : 15;
|
|
604
|
+
const index = Math.round((this.streamTime / this.current.durationMS) * length);
|
|
605
|
+
const indicator = typeof options.indicator === "string" && options.indicator.length > 0 ? options.indicator : "🔘";
|
|
606
|
+
const line = typeof options.line === "string" && options.line.length > 0 ? options.line : "▬";
|
|
607
|
+
if (index >= 1 && index <= length) {
|
|
608
|
+
const bar = line.repeat(length - 1).split("");
|
|
609
|
+
bar.splice(index, 0, indicator);
|
|
610
|
+
if (options.timecodes) {
|
|
611
|
+
const timestamp = this.getPlayerTimestamp();
|
|
612
|
+
return `${timestamp.current} ┃ ${bar.join("")} ┃ ${timestamp.end}`;
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
return `${bar.join("")}`;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
if (options.timecodes) {
|
|
620
|
+
const timestamp = this.getPlayerTimestamp();
|
|
621
|
+
return `${timestamp.current} ┃ ${indicator}${line.repeat(length - 1)} ┃ ${timestamp.end}`;
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
return `${indicator}${line.repeat(length - 1)}`;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Total duration
|
|
630
|
+
* @type {Number}
|
|
631
|
+
*/
|
|
632
|
+
get totalTime() {
|
|
633
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
634
|
+
return;
|
|
635
|
+
return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Generates statistics
|
|
639
|
+
*/
|
|
640
|
+
generateStatistics() {
|
|
641
|
+
return {
|
|
642
|
+
guild: this.guild.id,
|
|
643
|
+
memory: process.memoryUsage(),
|
|
644
|
+
tracks: this.tracks.length,
|
|
645
|
+
os: {
|
|
646
|
+
cpuCount: os_1.default.cpus().length,
|
|
647
|
+
totalMem: os_1.default.totalmem(),
|
|
648
|
+
freeMem: os_1.default.freemem(),
|
|
649
|
+
platform: process.platform
|
|
650
|
+
},
|
|
651
|
+
isShard: typeof process.send === "function" || worker_threads_1.parentPort != null,
|
|
652
|
+
latency: {
|
|
653
|
+
client: this.player.client.ws.ping,
|
|
654
|
+
udp: this.connection.voiceConnection.ping.udp,
|
|
655
|
+
ws: this.connection.voiceConnection.ping.ws,
|
|
656
|
+
eventLoop: this.player.eventLoopLag
|
|
657
|
+
},
|
|
658
|
+
subscribers: this.player.queues.size,
|
|
659
|
+
connections: this.player.queues.filter((x) => x.connection?.voiceConnection != null).size,
|
|
660
|
+
extractors: this.player.extractors.size
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Voice connection latency in ms
|
|
665
|
+
* @type {number}
|
|
666
|
+
*/
|
|
667
|
+
get ping() {
|
|
668
|
+
return this.connection.voiceConnection.ping.udp;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Play stream in a voice/stage channel
|
|
672
|
+
* @param {Track} [src] The track to play (if empty, uses first track from the queue)
|
|
673
|
+
* @param {PlayOptions} [options] The options
|
|
674
|
+
* @returns {Promise<void>}
|
|
675
|
+
*/
|
|
676
|
+
async play(src, options = {}) {
|
|
677
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this, false))
|
|
678
|
+
return;
|
|
679
|
+
if (!this.connection || !this.connection.voiceConnection)
|
|
680
|
+
throw new PlayerError_1.PlayerError("Voice connection is not available, use <Queue>.connect()!", PlayerError_1.ErrorStatusCode.NO_CONNECTION);
|
|
681
|
+
if (src && (this.playing || this.tracks.length) && !options.immediate)
|
|
682
|
+
return this.addTrack(src);
|
|
683
|
+
const track = options.filtersUpdate && !options.immediate ? src || this.current : src ?? this.tracks.shift();
|
|
684
|
+
if (!track)
|
|
685
|
+
return;
|
|
686
|
+
this.player.emit("debug", this, "Received play request");
|
|
687
|
+
if (!options.filtersUpdate) {
|
|
688
|
+
this.previousTracks = this.previousTracks.filter((x) => x.id !== track.id);
|
|
689
|
+
this.previousTracks.push(track);
|
|
690
|
+
}
|
|
691
|
+
let stream = null;
|
|
692
|
+
const hasCustomDownloader = typeof this.onBeforeCreateStream === "function";
|
|
693
|
+
if (["youtube", "spotify"].includes(track.raw.source)) {
|
|
694
|
+
let spotifyResolved = false;
|
|
695
|
+
if (this.options.spotifyBridge && track.raw.source === "spotify" && !track.raw.engine) {
|
|
696
|
+
track.raw.engine = await youtube_sr_1.default.search(`${track.author} ${track.title}`, { type: "video" })
|
|
697
|
+
.then((res) => res[0].url)
|
|
698
|
+
.catch(() => {
|
|
699
|
+
/* void */
|
|
700
|
+
});
|
|
701
|
+
spotifyResolved = true;
|
|
702
|
+
}
|
|
703
|
+
const url = track.raw.source === "spotify" ? track.raw.engine : track.url;
|
|
704
|
+
if (!url)
|
|
705
|
+
return void this.play(this.tracks.shift(), { immediate: true });
|
|
706
|
+
if (hasCustomDownloader) {
|
|
707
|
+
stream = (await this.onBeforeCreateStream(track, spotifyResolved ? "youtube" : track.raw.source, this)) || null;
|
|
708
|
+
}
|
|
709
|
+
if (!stream) {
|
|
710
|
+
stream = (0, ytdl_core_1.default)(url, this.options.ytdlOptions);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
const arbitraryStream = (hasCustomDownloader && (await this.onBeforeCreateStream(track, track.raw.source || track.raw.engine, this))) || null;
|
|
715
|
+
stream =
|
|
716
|
+
arbitraryStream || (track.raw.source === "soundcloud" && typeof track.raw.engine?.downloadProgressive === "function")
|
|
717
|
+
? await track.raw.engine.downloadProgressive()
|
|
718
|
+
: typeof track.raw.engine === "function"
|
|
719
|
+
? await track.raw.engine()
|
|
720
|
+
: track.raw.engine;
|
|
721
|
+
}
|
|
722
|
+
const ffmpegStream = (0, FFmpegStream_1.createFFmpegStream)(stream, {
|
|
723
|
+
encoderArgs: options.encoderArgs || this._activeFilters.length ? ["-af", AudioFilters_1.default.create(this._activeFilters)] : [],
|
|
724
|
+
seek: options.seek ? options.seek / 1000 : 0,
|
|
725
|
+
fmt: "s16le"
|
|
726
|
+
}).on("error", (err) => {
|
|
727
|
+
if (!`${err}`.toLowerCase().includes("premature close"))
|
|
728
|
+
this.player.emit("error", this, err);
|
|
729
|
+
});
|
|
730
|
+
const resource = this.connection.createStream(ffmpegStream, {
|
|
731
|
+
type: voice_1.StreamType.Raw,
|
|
732
|
+
data: track,
|
|
733
|
+
disableVolume: Boolean(this.options.disableVolume)
|
|
734
|
+
});
|
|
735
|
+
if (options.seek)
|
|
736
|
+
this._streamTime = options.seek;
|
|
737
|
+
this._filtersUpdate = options.filtersUpdate;
|
|
738
|
+
const volumeTransformer = resource.volume;
|
|
739
|
+
if (volumeTransformer && typeof this.options.initialVolume === "number")
|
|
740
|
+
volumeTransformer.setVolume(Math.pow(this.options.initialVolume / 100, 1.660964));
|
|
741
|
+
if (volumeTransformer?.hasSmoothness && typeof this.options.volumeSmoothness === "number") {
|
|
742
|
+
if (typeof volumeTransformer.setSmoothness === "function")
|
|
743
|
+
volumeTransformer.setSmoothness(this.options.volumeSmoothness || 0);
|
|
744
|
+
}
|
|
745
|
+
setTimeout(() => {
|
|
746
|
+
this.connection.playStream(resource);
|
|
747
|
+
}, tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_getBufferingTimeout).call(this)).unref();
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Private method to handle autoplay
|
|
751
|
+
* @param {Track} track The source track to find its similar track for autoplay
|
|
752
|
+
* @returns {Promise<void>}
|
|
753
|
+
* @private
|
|
754
|
+
*/
|
|
755
|
+
async _handleAutoplay(track) {
|
|
756
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
757
|
+
return;
|
|
758
|
+
if (!track || ![track.source, track.raw?.source].includes("youtube")) {
|
|
759
|
+
return this.emitEnd();
|
|
760
|
+
}
|
|
761
|
+
let info = await youtube_sr_1.default.getVideo(track.url)
|
|
762
|
+
.then((x) => x.videos[0])
|
|
763
|
+
.catch(Util_1.Util.noop);
|
|
764
|
+
// fallback
|
|
765
|
+
if (!info)
|
|
766
|
+
info = await youtube_sr_1.default.search(track.author)
|
|
767
|
+
.then((x) => x[0])
|
|
768
|
+
.catch(Util_1.Util.noop);
|
|
769
|
+
if (!info) {
|
|
770
|
+
return this.emitEnd();
|
|
771
|
+
}
|
|
772
|
+
const nextTrack = new Track_1.default(this.player, {
|
|
773
|
+
title: info.title,
|
|
774
|
+
url: `https://www.youtube.com/watch?v=${info.id}`,
|
|
775
|
+
duration: info.durationFormatted ? Util_1.Util.buildTimeCode(Util_1.Util.parseMS(info.duration * 1000)) : "0:00",
|
|
776
|
+
description: "",
|
|
777
|
+
thumbnail: typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url,
|
|
778
|
+
views: info.views,
|
|
779
|
+
author: info.channel.name,
|
|
780
|
+
requestedBy: track.requestedBy,
|
|
781
|
+
source: "youtube"
|
|
782
|
+
});
|
|
783
|
+
this.play(nextTrack, { immediate: true });
|
|
784
|
+
}
|
|
785
|
+
*[(_Queue_destroyed = new WeakMap(), _Queue_instances = new WeakSet(), Symbol.iterator)]() {
|
|
786
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
787
|
+
return;
|
|
788
|
+
yield* this.tracks;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* JSON representation of this queue
|
|
792
|
+
* @returns {object}
|
|
793
|
+
*/
|
|
794
|
+
toJSON() {
|
|
795
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
796
|
+
return;
|
|
797
|
+
return {
|
|
798
|
+
id: this.id,
|
|
799
|
+
guild: this.guild.id,
|
|
800
|
+
voiceChannel: this.connection?.channel?.id,
|
|
801
|
+
options: this.options,
|
|
802
|
+
tracks: this.tracks.map((m) => m.toJSON())
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* String representation of this queue
|
|
807
|
+
* @returns {string}
|
|
808
|
+
*/
|
|
809
|
+
toString() {
|
|
810
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_instances, "m", _Queue_watchDestroyed).call(this))
|
|
811
|
+
return;
|
|
812
|
+
if (!this.tracks.length)
|
|
813
|
+
return "No songs available to display!";
|
|
814
|
+
return `**Upcoming Songs:**\n${this.tracks.map((m, i) => `${i + 1}. **${m.title}**`).join("\n")}`;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
exports.Queue = Queue;
|
|
818
|
+
_Queue_watchDestroyed = function _Queue_watchDestroyed(emit = true) {
|
|
819
|
+
if (tslib_1.__classPrivateFieldGet(this, _Queue_destroyed, "f")) {
|
|
820
|
+
if (emit)
|
|
821
|
+
this.player.emit("error", this, new PlayerError_1.PlayerError("Cannot use destroyed queue", PlayerError_1.ErrorStatusCode.DESTROYED_QUEUE));
|
|
822
|
+
return true;
|
|
823
|
+
}
|
|
824
|
+
return false;
|
|
825
|
+
}, _Queue_getBufferingTimeout = function _Queue_getBufferingTimeout() {
|
|
826
|
+
const timeout = this.options.bufferingTimeout;
|
|
827
|
+
if (isNaN(timeout) || timeout < 0 || !Number.isFinite(timeout))
|
|
828
|
+
return 1000;
|
|
829
|
+
return timeout;
|
|
830
|
+
};
|