ziplayer 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -212
- package/dist/plugins/SoundCloudPlugin.d.ts +22 -0
- package/dist/plugins/SoundCloudPlugin.d.ts.map +1 -0
- package/dist/plugins/SoundCloudPlugin.js +171 -0
- package/dist/plugins/SoundCloudPlugin.js.map +1 -0
- package/dist/plugins/SpotifyPlugin.d.ts +26 -0
- package/dist/plugins/SpotifyPlugin.d.ts.map +1 -0
- package/dist/plugins/SpotifyPlugin.js +183 -0
- package/dist/plugins/SpotifyPlugin.js.map +1 -0
- package/dist/plugins/YouTubePlugin.d.ts +25 -0
- package/dist/plugins/YouTubePlugin.d.ts.map +1 -0
- package/dist/plugins/YouTubePlugin.js +314 -0
- package/dist/plugins/YouTubePlugin.js.map +1 -0
- package/dist/structures/Player.d.ts +23 -13
- package/dist/structures/Player.d.ts.map +1 -1
- package/dist/structures/Player.js +143 -58
- package/dist/structures/Player.js.map +1 -1
- package/package.json +1 -1
- package/src/extensions/BaseExtension.ts +35 -35
- package/src/structures/Player.ts +1828 -1732
- package/src/structures/PlayerManager.ts +411 -411
- package/src/structures/Queue.ts +354 -354
- package/src/types/index.ts +470 -470
- package/src/utils/timeout.ts +10 -10
package/src/structures/Queue.ts
CHANGED
|
@@ -1,354 +1,354 @@
|
|
|
1
|
-
import { Track, LoopMode } from "../types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Manages the track queue for a player.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* // Basic queue operations
|
|
8
|
-
* const queue = player.queue;
|
|
9
|
-
*
|
|
10
|
-
* // Add single track
|
|
11
|
-
* queue.add(track);
|
|
12
|
-
*
|
|
13
|
-
* // Add multiple tracks
|
|
14
|
-
* queue.add([track1, track2, track3]);
|
|
15
|
-
*
|
|
16
|
-
* // Queue controls
|
|
17
|
-
* queue.shuffle(); // Randomize order
|
|
18
|
-
* queue.clear(); // Remove all tracks
|
|
19
|
-
* queue.autoPlay(true); // Enable auto-play
|
|
20
|
-
*
|
|
21
|
-
* // Get queue information
|
|
22
|
-
* console.log(`Queue length: ${queue.length}`);
|
|
23
|
-
* console.log(`Current track: ${queue.current?.title}`);
|
|
24
|
-
* console.log(`Is empty: ${queue.isEmpty}`);
|
|
25
|
-
* console.log(`Is playing: ${queue.isPlaying}`);
|
|
26
|
-
*
|
|
27
|
-
* // Loop modes
|
|
28
|
-
* queue.setLoopMode("track"); // Loop current track
|
|
29
|
-
* queue.setLoopMode("queue"); // Loop entire queue
|
|
30
|
-
* queue.setLoopMode("off"); // No loop
|
|
31
|
-
*
|
|
32
|
-
* // Remove specific track
|
|
33
|
-
* const removed = queue.remove(0); // Remove first track
|
|
34
|
-
* if (removed) {
|
|
35
|
-
* console.log(`Removed: ${removed.title}`);
|
|
36
|
-
* }
|
|
37
|
-
*/
|
|
38
|
-
export class Queue {
|
|
39
|
-
private tracks: Track[] = [];
|
|
40
|
-
private current: Track | null = null;
|
|
41
|
-
private history: Track[] = [];
|
|
42
|
-
private related: Track[] = [];
|
|
43
|
-
private _autoPlay = false;
|
|
44
|
-
private _loop: LoopMode = "off";
|
|
45
|
-
private willnext: Track | null = null;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Add track(s) to the queue
|
|
49
|
-
*
|
|
50
|
-
* @param {Track | Track[]} track - Track or array of tracks to add
|
|
51
|
-
* @example
|
|
52
|
-
* queue.add(track);
|
|
53
|
-
* queue.add([track1, track2, track3]);
|
|
54
|
-
*/
|
|
55
|
-
add(track: Track): void {
|
|
56
|
-
this.tracks.push(track);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Add multiple tracks to the queue
|
|
61
|
-
*
|
|
62
|
-
* @param {Track[]} tracks - Tracks to add
|
|
63
|
-
* @example
|
|
64
|
-
* queue.addMultiple([track1, track2, track3]);
|
|
65
|
-
*/
|
|
66
|
-
addMultiple(tracks: Track[]): void {
|
|
67
|
-
this.tracks.push(...tracks);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Insert a track at a specific upcoming position (0 = next)
|
|
72
|
-
*
|
|
73
|
-
* @param {Track} track - Track to insert
|
|
74
|
-
* @param {number} index - Index to insert the track at
|
|
75
|
-
* @example
|
|
76
|
-
* queue.insert(track, 0);
|
|
77
|
-
*/
|
|
78
|
-
insert(track: Track, index: number): void {
|
|
79
|
-
if (!Number.isFinite(index)) {
|
|
80
|
-
this.tracks.push(track);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
84
|
-
if (i === this.tracks.length) {
|
|
85
|
-
this.tracks.push(track);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (i <= 0) {
|
|
89
|
-
this.tracks.unshift(track);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
this.tracks.splice(i, 0, track);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Insert multiple tracks at a specific upcoming position, preserving order
|
|
97
|
-
*
|
|
98
|
-
* @param {Track[]} tracks - Tracks to insert
|
|
99
|
-
* @param {number} index - Index to insert the tracks at
|
|
100
|
-
* @example
|
|
101
|
-
* queue.insertMultiple([track1, track2, track3], 0);
|
|
102
|
-
*/
|
|
103
|
-
insertMultiple(tracks: Track[], index: number): void {
|
|
104
|
-
if (!Array.isArray(tracks) || tracks.length === 0) return;
|
|
105
|
-
if (!Number.isFinite(index)) {
|
|
106
|
-
this.tracks.push(...tracks);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
110
|
-
if (i === 0) {
|
|
111
|
-
this.tracks = [...tracks, ...this.tracks];
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (i === this.tracks.length) {
|
|
115
|
-
this.tracks.push(...tracks);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
this.tracks.splice(i, 0, ...tracks);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Remove a track from the queue
|
|
123
|
-
*
|
|
124
|
-
* @param {number} index - Index of track to remove
|
|
125
|
-
* @returns {Track | null} Removed track or null
|
|
126
|
-
* @example
|
|
127
|
-
* const removed = queue.remove(0);
|
|
128
|
-
* console.log(`Removed: ${removed?.title}`);
|
|
129
|
-
*/
|
|
130
|
-
|
|
131
|
-
remove(index: number): Track | null {
|
|
132
|
-
if (index < 0 || index >= this.tracks.length) return null;
|
|
133
|
-
return this.tracks.splice(index, 1)[0];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Get the next track in the queue
|
|
138
|
-
*
|
|
139
|
-
* @param {boolean} ignoreLoop - Ignore the loop mode
|
|
140
|
-
* @returns {Track | null} The next track or null
|
|
141
|
-
* @example
|
|
142
|
-
* const nextTrack = queue.next();
|
|
143
|
-
* console.log(`Next track: ${nextTrack?.title}`);
|
|
144
|
-
*/
|
|
145
|
-
next(ignoreLoop = false): Track | null {
|
|
146
|
-
if (this.current) {
|
|
147
|
-
if (this._loop === "track" && !ignoreLoop) {
|
|
148
|
-
return this.current;
|
|
149
|
-
}
|
|
150
|
-
this.history.push(this.current);
|
|
151
|
-
if (this.history.length > 200) {
|
|
152
|
-
this.history.shift();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
this.current = this.tracks.shift() || null;
|
|
156
|
-
if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
|
|
157
|
-
this.tracks = [...this.history];
|
|
158
|
-
this.history = [];
|
|
159
|
-
this.current = this.tracks.shift() || null;
|
|
160
|
-
}
|
|
161
|
-
return this.current;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Clear all tracks from the queue
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* queue.clear();
|
|
169
|
-
*/
|
|
170
|
-
clear(): void {
|
|
171
|
-
this.tracks = [];
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Enable or disable auto-play
|
|
176
|
-
*
|
|
177
|
-
* @param {boolean} value - Enable/disable auto-play
|
|
178
|
-
* @returns {boolean} Current auto-play state
|
|
179
|
-
* @example
|
|
180
|
-
* queue.autoPlay(true);
|
|
181
|
-
* queue.autoPlay(); // Get current auto-play state
|
|
182
|
-
*/
|
|
183
|
-
|
|
184
|
-
autoPlay(value?: boolean): boolean {
|
|
185
|
-
if (typeof value !== "undefined") {
|
|
186
|
-
this._autoPlay = value;
|
|
187
|
-
}
|
|
188
|
-
return this._autoPlay;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Set the loop mode
|
|
193
|
-
*
|
|
194
|
-
* @param {LoopMode} mode - Loop mode to set
|
|
195
|
-
* @returns {LoopMode} The loop mode
|
|
196
|
-
* @example
|
|
197
|
-
* queue.loop("track");
|
|
198
|
-
*/
|
|
199
|
-
loop(mode?: LoopMode): LoopMode {
|
|
200
|
-
if (mode) {
|
|
201
|
-
this._loop = mode;
|
|
202
|
-
}
|
|
203
|
-
return this._loop;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Shuffle the queue
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* queue.shuffle();
|
|
211
|
-
*/
|
|
212
|
-
|
|
213
|
-
shuffle(): void {
|
|
214
|
-
for (let i = this.tracks.length - 1; i > 0; i--) {
|
|
215
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
216
|
-
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get the size of the queue
|
|
222
|
-
*
|
|
223
|
-
* @returns {number} The size of the queue
|
|
224
|
-
* @example
|
|
225
|
-
* const size = queue.size;
|
|
226
|
-
* console.log(`Queue size: ${size}`);
|
|
227
|
-
*/
|
|
228
|
-
get size(): number {
|
|
229
|
-
return this.tracks.length;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Check if the queue is empty
|
|
234
|
-
*
|
|
235
|
-
* @returns {boolean} True if the queue is empty
|
|
236
|
-
* @example
|
|
237
|
-
* const empty = queue.isEmpty;
|
|
238
|
-
* console.log(`Queue is empty: ${empty}`);
|
|
239
|
-
*/
|
|
240
|
-
get isEmpty(): boolean {
|
|
241
|
-
return this.tracks.length === 0;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Get the current track
|
|
246
|
-
*
|
|
247
|
-
* @returns {Track | null} The current track or null
|
|
248
|
-
* @example
|
|
249
|
-
* const currentTrack = queue.currentTrack;
|
|
250
|
-
* console.log(`Current track: ${currentTrack?.title}`);
|
|
251
|
-
*/
|
|
252
|
-
get currentTrack(): Track | null {
|
|
253
|
-
return this.current;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Get the previous tracks
|
|
258
|
-
*
|
|
259
|
-
* @returns {Track[]} The previous tracks
|
|
260
|
-
* @example
|
|
261
|
-
* const previousTracks = queue.previousTracks;
|
|
262
|
-
* console.log(`Previous tracks: ${previousTracks.length}`);
|
|
263
|
-
*/
|
|
264
|
-
get previousTracks(): Track[] {
|
|
265
|
-
return [...this.history];
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Get the next track
|
|
270
|
-
*
|
|
271
|
-
* @returns {Track | null} The next track or null
|
|
272
|
-
* @example
|
|
273
|
-
* const nextTrack = queue.nextTrack;
|
|
274
|
-
* console.log(`Next track: ${nextTrack?.title}`);
|
|
275
|
-
*/
|
|
276
|
-
get nextTrack(): Track | null {
|
|
277
|
-
return this.tracks[0] || null;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Move back to the previously played track.
|
|
282
|
-
* Makes the current track the next upcoming track, then sets previous as current.
|
|
283
|
-
*
|
|
284
|
-
* @returns {Track | null} The previous track or null
|
|
285
|
-
* @example
|
|
286
|
-
* const previousTrack = queue.previous();
|
|
287
|
-
* console.log(`Previous track: ${previousTrack?.title}`);
|
|
288
|
-
*/
|
|
289
|
-
previous(): Track | null {
|
|
290
|
-
if (this.history.length === 0) return null;
|
|
291
|
-
if (this.current) {
|
|
292
|
-
this.tracks.unshift(this.current);
|
|
293
|
-
}
|
|
294
|
-
this.current = this.history.pop() || null;
|
|
295
|
-
return this.current;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Get the next track
|
|
300
|
-
*
|
|
301
|
-
* @param {Track} track - The next track
|
|
302
|
-
* @returns {Track | null} The next track or null
|
|
303
|
-
* @example
|
|
304
|
-
* const nextTrack = queue.willNextTrack();
|
|
305
|
-
* console.log(`Next track: ${nextTrack?.title}`);
|
|
306
|
-
*/
|
|
307
|
-
willNextTrack(track?: Track): Track | null {
|
|
308
|
-
if (track) {
|
|
309
|
-
this.willnext = track;
|
|
310
|
-
}
|
|
311
|
-
return this.willnext;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Get the related tracks
|
|
316
|
-
*
|
|
317
|
-
* @param {Track[]} track - The related tracks
|
|
318
|
-
* @returns {Track[] | null} The related tracks or null
|
|
319
|
-
* @example
|
|
320
|
-
* const relatedTracks = queue.relatedTracks();
|
|
321
|
-
* console.log(`Related tracks: ${relatedTracks?.length}`);
|
|
322
|
-
*/
|
|
323
|
-
relatedTracks(track?: Track[]): Track[] | null {
|
|
324
|
-
if (track) {
|
|
325
|
-
this.related = track;
|
|
326
|
-
}
|
|
327
|
-
return this.related;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Get the tracks
|
|
332
|
-
*
|
|
333
|
-
* @returns {Track[]} The tracks
|
|
334
|
-
* @example
|
|
335
|
-
* const tracks = queue.getTracks();
|
|
336
|
-
* console.log(`Tracks: ${tracks.length}`);
|
|
337
|
-
*/
|
|
338
|
-
getTracks(): Track[] {
|
|
339
|
-
return [...this.tracks];
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Get a track at a specific index
|
|
344
|
-
*
|
|
345
|
-
* @param {number} index - The index of the track
|
|
346
|
-
* @returns {Track | null} The track or null
|
|
347
|
-
* @example
|
|
348
|
-
* const track = queue.getTrack(0);
|
|
349
|
-
* console.log(`Track: ${track?.title}`);
|
|
350
|
-
*/
|
|
351
|
-
getTrack(index: number): Track | null {
|
|
352
|
-
return this.tracks[index] || null;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
1
|
+
import { Track, LoopMode } from "../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Manages the track queue for a player.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* // Basic queue operations
|
|
8
|
+
* const queue = player.queue;
|
|
9
|
+
*
|
|
10
|
+
* // Add single track
|
|
11
|
+
* queue.add(track);
|
|
12
|
+
*
|
|
13
|
+
* // Add multiple tracks
|
|
14
|
+
* queue.add([track1, track2, track3]);
|
|
15
|
+
*
|
|
16
|
+
* // Queue controls
|
|
17
|
+
* queue.shuffle(); // Randomize order
|
|
18
|
+
* queue.clear(); // Remove all tracks
|
|
19
|
+
* queue.autoPlay(true); // Enable auto-play
|
|
20
|
+
*
|
|
21
|
+
* // Get queue information
|
|
22
|
+
* console.log(`Queue length: ${queue.length}`);
|
|
23
|
+
* console.log(`Current track: ${queue.current?.title}`);
|
|
24
|
+
* console.log(`Is empty: ${queue.isEmpty}`);
|
|
25
|
+
* console.log(`Is playing: ${queue.isPlaying}`);
|
|
26
|
+
*
|
|
27
|
+
* // Loop modes
|
|
28
|
+
* queue.setLoopMode("track"); // Loop current track
|
|
29
|
+
* queue.setLoopMode("queue"); // Loop entire queue
|
|
30
|
+
* queue.setLoopMode("off"); // No loop
|
|
31
|
+
*
|
|
32
|
+
* // Remove specific track
|
|
33
|
+
* const removed = queue.remove(0); // Remove first track
|
|
34
|
+
* if (removed) {
|
|
35
|
+
* console.log(`Removed: ${removed.title}`);
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
export class Queue {
|
|
39
|
+
private tracks: Track[] = [];
|
|
40
|
+
private current: Track | null = null;
|
|
41
|
+
private history: Track[] = [];
|
|
42
|
+
private related: Track[] = [];
|
|
43
|
+
private _autoPlay = false;
|
|
44
|
+
private _loop: LoopMode = "off";
|
|
45
|
+
private willnext: Track | null = null;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Add track(s) to the queue
|
|
49
|
+
*
|
|
50
|
+
* @param {Track | Track[]} track - Track or array of tracks to add
|
|
51
|
+
* @example
|
|
52
|
+
* queue.add(track);
|
|
53
|
+
* queue.add([track1, track2, track3]);
|
|
54
|
+
*/
|
|
55
|
+
add(track: Track): void {
|
|
56
|
+
this.tracks.push(track);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Add multiple tracks to the queue
|
|
61
|
+
*
|
|
62
|
+
* @param {Track[]} tracks - Tracks to add
|
|
63
|
+
* @example
|
|
64
|
+
* queue.addMultiple([track1, track2, track3]);
|
|
65
|
+
*/
|
|
66
|
+
addMultiple(tracks: Track[]): void {
|
|
67
|
+
this.tracks.push(...tracks);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Insert a track at a specific upcoming position (0 = next)
|
|
72
|
+
*
|
|
73
|
+
* @param {Track} track - Track to insert
|
|
74
|
+
* @param {number} index - Index to insert the track at
|
|
75
|
+
* @example
|
|
76
|
+
* queue.insert(track, 0);
|
|
77
|
+
*/
|
|
78
|
+
insert(track: Track, index: number): void {
|
|
79
|
+
if (!Number.isFinite(index)) {
|
|
80
|
+
this.tracks.push(track);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
84
|
+
if (i === this.tracks.length) {
|
|
85
|
+
this.tracks.push(track);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (i <= 0) {
|
|
89
|
+
this.tracks.unshift(track);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.tracks.splice(i, 0, track);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Insert multiple tracks at a specific upcoming position, preserving order
|
|
97
|
+
*
|
|
98
|
+
* @param {Track[]} tracks - Tracks to insert
|
|
99
|
+
* @param {number} index - Index to insert the tracks at
|
|
100
|
+
* @example
|
|
101
|
+
* queue.insertMultiple([track1, track2, track3], 0);
|
|
102
|
+
*/
|
|
103
|
+
insertMultiple(tracks: Track[], index: number): void {
|
|
104
|
+
if (!Array.isArray(tracks) || tracks.length === 0) return;
|
|
105
|
+
if (!Number.isFinite(index)) {
|
|
106
|
+
this.tracks.push(...tracks);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
110
|
+
if (i === 0) {
|
|
111
|
+
this.tracks = [...tracks, ...this.tracks];
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (i === this.tracks.length) {
|
|
115
|
+
this.tracks.push(...tracks);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.tracks.splice(i, 0, ...tracks);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Remove a track from the queue
|
|
123
|
+
*
|
|
124
|
+
* @param {number} index - Index of track to remove
|
|
125
|
+
* @returns {Track | null} Removed track or null
|
|
126
|
+
* @example
|
|
127
|
+
* const removed = queue.remove(0);
|
|
128
|
+
* console.log(`Removed: ${removed?.title}`);
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
remove(index: number): Track | null {
|
|
132
|
+
if (index < 0 || index >= this.tracks.length) return null;
|
|
133
|
+
return this.tracks.splice(index, 1)[0];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get the next track in the queue
|
|
138
|
+
*
|
|
139
|
+
* @param {boolean} ignoreLoop - Ignore the loop mode
|
|
140
|
+
* @returns {Track | null} The next track or null
|
|
141
|
+
* @example
|
|
142
|
+
* const nextTrack = queue.next();
|
|
143
|
+
* console.log(`Next track: ${nextTrack?.title}`);
|
|
144
|
+
*/
|
|
145
|
+
next(ignoreLoop = false): Track | null {
|
|
146
|
+
if (this.current) {
|
|
147
|
+
if (this._loop === "track" && !ignoreLoop) {
|
|
148
|
+
return this.current;
|
|
149
|
+
}
|
|
150
|
+
this.history.push(this.current);
|
|
151
|
+
if (this.history.length > 200) {
|
|
152
|
+
this.history.shift();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
this.current = this.tracks.shift() || null;
|
|
156
|
+
if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
|
|
157
|
+
this.tracks = [...this.history];
|
|
158
|
+
this.history = [];
|
|
159
|
+
this.current = this.tracks.shift() || null;
|
|
160
|
+
}
|
|
161
|
+
return this.current;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Clear all tracks from the queue
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* queue.clear();
|
|
169
|
+
*/
|
|
170
|
+
clear(): void {
|
|
171
|
+
this.tracks = [];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Enable or disable auto-play
|
|
176
|
+
*
|
|
177
|
+
* @param {boolean} value - Enable/disable auto-play
|
|
178
|
+
* @returns {boolean} Current auto-play state
|
|
179
|
+
* @example
|
|
180
|
+
* queue.autoPlay(true);
|
|
181
|
+
* queue.autoPlay(); // Get current auto-play state
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
autoPlay(value?: boolean): boolean {
|
|
185
|
+
if (typeof value !== "undefined") {
|
|
186
|
+
this._autoPlay = value;
|
|
187
|
+
}
|
|
188
|
+
return this._autoPlay;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Set the loop mode
|
|
193
|
+
*
|
|
194
|
+
* @param {LoopMode} mode - Loop mode to set
|
|
195
|
+
* @returns {LoopMode} The loop mode
|
|
196
|
+
* @example
|
|
197
|
+
* queue.loop("track");
|
|
198
|
+
*/
|
|
199
|
+
loop(mode?: LoopMode): LoopMode {
|
|
200
|
+
if (mode) {
|
|
201
|
+
this._loop = mode;
|
|
202
|
+
}
|
|
203
|
+
return this._loop;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Shuffle the queue
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* queue.shuffle();
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
shuffle(): void {
|
|
214
|
+
for (let i = this.tracks.length - 1; i > 0; i--) {
|
|
215
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
216
|
+
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get the size of the queue
|
|
222
|
+
*
|
|
223
|
+
* @returns {number} The size of the queue
|
|
224
|
+
* @example
|
|
225
|
+
* const size = queue.size;
|
|
226
|
+
* console.log(`Queue size: ${size}`);
|
|
227
|
+
*/
|
|
228
|
+
get size(): number {
|
|
229
|
+
return this.tracks.length;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Check if the queue is empty
|
|
234
|
+
*
|
|
235
|
+
* @returns {boolean} True if the queue is empty
|
|
236
|
+
* @example
|
|
237
|
+
* const empty = queue.isEmpty;
|
|
238
|
+
* console.log(`Queue is empty: ${empty}`);
|
|
239
|
+
*/
|
|
240
|
+
get isEmpty(): boolean {
|
|
241
|
+
return this.tracks.length === 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get the current track
|
|
246
|
+
*
|
|
247
|
+
* @returns {Track | null} The current track or null
|
|
248
|
+
* @example
|
|
249
|
+
* const currentTrack = queue.currentTrack;
|
|
250
|
+
* console.log(`Current track: ${currentTrack?.title}`);
|
|
251
|
+
*/
|
|
252
|
+
get currentTrack(): Track | null {
|
|
253
|
+
return this.current;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get the previous tracks
|
|
258
|
+
*
|
|
259
|
+
* @returns {Track[]} The previous tracks
|
|
260
|
+
* @example
|
|
261
|
+
* const previousTracks = queue.previousTracks;
|
|
262
|
+
* console.log(`Previous tracks: ${previousTracks.length}`);
|
|
263
|
+
*/
|
|
264
|
+
get previousTracks(): Track[] {
|
|
265
|
+
return [...this.history];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Get the next track
|
|
270
|
+
*
|
|
271
|
+
* @returns {Track | null} The next track or null
|
|
272
|
+
* @example
|
|
273
|
+
* const nextTrack = queue.nextTrack;
|
|
274
|
+
* console.log(`Next track: ${nextTrack?.title}`);
|
|
275
|
+
*/
|
|
276
|
+
get nextTrack(): Track | null {
|
|
277
|
+
return this.tracks[0] || null;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Move back to the previously played track.
|
|
282
|
+
* Makes the current track the next upcoming track, then sets previous as current.
|
|
283
|
+
*
|
|
284
|
+
* @returns {Track | null} The previous track or null
|
|
285
|
+
* @example
|
|
286
|
+
* const previousTrack = queue.previous();
|
|
287
|
+
* console.log(`Previous track: ${previousTrack?.title}`);
|
|
288
|
+
*/
|
|
289
|
+
previous(): Track | null {
|
|
290
|
+
if (this.history.length === 0) return null;
|
|
291
|
+
if (this.current) {
|
|
292
|
+
this.tracks.unshift(this.current);
|
|
293
|
+
}
|
|
294
|
+
this.current = this.history.pop() || null;
|
|
295
|
+
return this.current;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Get the next track
|
|
300
|
+
*
|
|
301
|
+
* @param {Track} track - The next track
|
|
302
|
+
* @returns {Track | null} The next track or null
|
|
303
|
+
* @example
|
|
304
|
+
* const nextTrack = queue.willNextTrack();
|
|
305
|
+
* console.log(`Next track: ${nextTrack?.title}`);
|
|
306
|
+
*/
|
|
307
|
+
willNextTrack(track?: Track): Track | null {
|
|
308
|
+
if (track) {
|
|
309
|
+
this.willnext = track;
|
|
310
|
+
}
|
|
311
|
+
return this.willnext;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Get the related tracks
|
|
316
|
+
*
|
|
317
|
+
* @param {Track[]} track - The related tracks
|
|
318
|
+
* @returns {Track[] | null} The related tracks or null
|
|
319
|
+
* @example
|
|
320
|
+
* const relatedTracks = queue.relatedTracks();
|
|
321
|
+
* console.log(`Related tracks: ${relatedTracks?.length}`);
|
|
322
|
+
*/
|
|
323
|
+
relatedTracks(track?: Track[]): Track[] | null {
|
|
324
|
+
if (track) {
|
|
325
|
+
this.related = track;
|
|
326
|
+
}
|
|
327
|
+
return this.related;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Get the tracks
|
|
332
|
+
*
|
|
333
|
+
* @returns {Track[]} The tracks
|
|
334
|
+
* @example
|
|
335
|
+
* const tracks = queue.getTracks();
|
|
336
|
+
* console.log(`Tracks: ${tracks.length}`);
|
|
337
|
+
*/
|
|
338
|
+
getTracks(): Track[] {
|
|
339
|
+
return [...this.tracks];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get a track at a specific index
|
|
344
|
+
*
|
|
345
|
+
* @param {number} index - The index of the track
|
|
346
|
+
* @returns {Track | null} The track or null
|
|
347
|
+
* @example
|
|
348
|
+
* const track = queue.getTrack(0);
|
|
349
|
+
* console.log(`Track: ${track?.title}`);
|
|
350
|
+
*/
|
|
351
|
+
getTrack(index: number): Track | null {
|
|
352
|
+
return this.tracks[index] || null;
|
|
353
|
+
}
|
|
354
|
+
}
|