ziplayer 0.2.7 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-Guide.md +624 -956
- package/README.md +277 -10
- package/dist/extensions/BaseExtension.d.ts +1 -0
- package/dist/extensions/BaseExtension.d.ts.map +1 -1
- package/dist/extensions/BaseExtension.js.map +1 -1
- package/dist/extensions/index.d.ts +38 -3
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +259 -41
- package/dist/extensions/index.js.map +1 -1
- package/dist/persistence/PersistenceManager.d.ts +95 -0
- package/dist/persistence/PersistenceManager.d.ts.map +1 -0
- package/dist/persistence/PersistenceManager.js +975 -0
- package/dist/persistence/PersistenceManager.js.map +1 -0
- package/dist/plugins/BasePlugin.js +1 -1
- package/dist/plugins/BasePlugin.js.map +1 -1
- package/dist/plugins/index.d.ts +74 -8
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +657 -116
- package/dist/plugins/index.js.map +1 -1
- package/dist/structures/FilterManager.js +3 -3
- package/dist/structures/FilterManager.js.map +1 -1
- package/dist/structures/PersistenceManager.d.ts +96 -0
- package/dist/structures/PersistenceManager.d.ts.map +1 -0
- package/dist/structures/PersistenceManager.js +1008 -0
- package/dist/structures/PersistenceManager.js.map +1 -0
- package/dist/structures/Player.d.ts +158 -14
- package/dist/structures/Player.d.ts.map +1 -1
- package/dist/structures/Player.js +1175 -188
- package/dist/structures/Player.js.map +1 -1
- package/dist/structures/PlayerManager.d.ts +106 -91
- package/dist/structures/PlayerManager.d.ts.map +1 -1
- package/dist/structures/PlayerManager.js +365 -124
- package/dist/structures/PlayerManager.js.map +1 -1
- package/dist/structures/Queue.d.ts +136 -31
- package/dist/structures/Queue.d.ts.map +1 -1
- package/dist/structures/Queue.js +265 -46
- package/dist/structures/Queue.js.map +1 -1
- package/dist/structures/StreamManager.d.ts +137 -0
- package/dist/structures/StreamManager.d.ts.map +1 -0
- package/dist/structures/StreamManager.js +420 -0
- package/dist/structures/StreamManager.js.map +1 -0
- package/dist/types/index.d.ts +181 -8
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/persistence.d.ts +77 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/persistence.js +3 -0
- package/dist/types/persistence.js.map +1 -0
- package/package.json +3 -2
- package/src/extensions/BaseExtension.ts +1 -0
- package/src/extensions/index.ts +320 -37
- package/src/plugins/BasePlugin.ts +1 -1
- package/src/plugins/index.ts +809 -139
- package/src/structures/FilterManager.ts +3 -3
- package/src/structures/Player.ts +2810 -1693
- package/src/structures/PlayerManager.ts +438 -129
- package/src/structures/Queue.ts +300 -55
- package/src/structures/StreamManager.ts +524 -0
- package/src/types/extension.ts +129 -129
- package/src/types/fillter.ts +264 -264
- package/src/types/index.ts +187 -12
- package/src/types/plugin.ts +59 -59
- package/tsconfig.json +0 -1
package/src/types/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Player } from "../structures/Player";
|
|
|
3
3
|
import type { PlayerManager } from "../structures/PlayerManager";
|
|
4
4
|
import type { AudioFilter } from "./fillter";
|
|
5
5
|
import type { SourcePluginLike } from "./plugin";
|
|
6
|
-
|
|
6
|
+
import type { AudioResource } from "@discordjs/voice";
|
|
7
7
|
/**
|
|
8
8
|
* Represents a music track with metadata and streaming information.
|
|
9
9
|
*
|
|
@@ -60,6 +60,7 @@ export interface Track {
|
|
|
60
60
|
requestedBy: string;
|
|
61
61
|
source: string;
|
|
62
62
|
metadata?: Record<string, any>;
|
|
63
|
+
isLive?: boolean;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
/**
|
|
@@ -88,11 +89,20 @@ export interface SearchResult {
|
|
|
88
89
|
tracks: Track[];
|
|
89
90
|
playlist?: {
|
|
90
91
|
name: string;
|
|
91
|
-
url
|
|
92
|
+
url?: string;
|
|
92
93
|
thumbnail?: string;
|
|
93
|
-
};
|
|
94
|
+
} | null;
|
|
95
|
+
query?: string;
|
|
96
|
+
score?: SearchScore;
|
|
97
|
+
source?: string;
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
export interface SearchScore {
|
|
101
|
+
score: number; // 0-100
|
|
102
|
+
reason: string; // Lý do đạt điểm
|
|
103
|
+
matchedBy: "url" | "title" | "partial" | "none" | "playlist";
|
|
104
|
+
exactMatch: boolean;
|
|
105
|
+
}
|
|
96
106
|
/**
|
|
97
107
|
* Contains streaming information for audio playback.
|
|
98
108
|
*
|
|
@@ -129,7 +139,7 @@ export interface StreamInfo {
|
|
|
129
139
|
* createPlayer: true,
|
|
130
140
|
* interrupt: true,
|
|
131
141
|
* volume: 1.0,
|
|
132
|
-
*
|
|
142
|
+
* maxTimeTts: 30000
|
|
133
143
|
* }
|
|
134
144
|
* };
|
|
135
145
|
*/
|
|
@@ -160,7 +170,7 @@ export interface PlayerOptions {
|
|
|
160
170
|
/** Default TTS volume multiplier 1 => 100% */
|
|
161
171
|
volume?: number;
|
|
162
172
|
/** Max time tts playback Duration */
|
|
163
|
-
|
|
173
|
+
maxTimeTts?: number;
|
|
164
174
|
};
|
|
165
175
|
/**
|
|
166
176
|
* Optional per-player extension selection. When provided, only these
|
|
@@ -177,16 +187,131 @@ export interface PlayerOptions {
|
|
|
177
187
|
* - Multiple filters can be combined
|
|
178
188
|
*/
|
|
179
189
|
filters?: (string | AudioFilter)[];
|
|
190
|
+
/**
|
|
191
|
+
* Enable low performance mode.
|
|
192
|
+
* When enabled, heavy features such as preload and crossfade can be auto-disabled.
|
|
193
|
+
*/
|
|
194
|
+
lowPerformance?: boolean;
|
|
195
|
+
/**
|
|
196
|
+
* Preload behavior configuration.
|
|
197
|
+
*/
|
|
198
|
+
preload?: {
|
|
199
|
+
/**
|
|
200
|
+
* Enable/disable preload explicitly.
|
|
201
|
+
* Default: true
|
|
202
|
+
*/
|
|
203
|
+
enabled?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Auto disable preload when lowPerformance is enabled.
|
|
206
|
+
* Default: true
|
|
207
|
+
*/
|
|
208
|
+
autoDisableInLowPerformance?: boolean;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Crossfade behavior configuration.
|
|
212
|
+
*/
|
|
213
|
+
crossfade?: {
|
|
214
|
+
/**
|
|
215
|
+
* Enable/disable crossfade explicitly.
|
|
216
|
+
* If omitted and autoEnable=true, ZiPlayer may enable it automatically.
|
|
217
|
+
*/
|
|
218
|
+
enabled?: boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Auto enable crossfade if runtime profile allows.
|
|
221
|
+
* Default: true
|
|
222
|
+
*/
|
|
223
|
+
autoEnable?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Auto disable crossfade when lowPerformance is enabled.
|
|
226
|
+
* Default: true
|
|
227
|
+
*/
|
|
228
|
+
autoDisableInLowPerformance?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Target crossfade duration in milliseconds.
|
|
231
|
+
* Default: 5000
|
|
232
|
+
*/
|
|
233
|
+
durationMs?: number;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Smart transition engine settings.
|
|
237
|
+
*/
|
|
238
|
+
smartTransition?: {
|
|
239
|
+
enabled?: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Prefer genre-aware fade duration when metadata.genre is available.
|
|
242
|
+
*/
|
|
243
|
+
genreAware?: boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Try to align transition with beat boundary using metadata.bpm.
|
|
246
|
+
*/
|
|
247
|
+
beatAlign?: boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Base duration in milliseconds when no specific profile matched.
|
|
250
|
+
*/
|
|
251
|
+
baseDurationMs?: number;
|
|
252
|
+
minDurationMs?: number;
|
|
253
|
+
maxDurationMs?: number;
|
|
254
|
+
/**
|
|
255
|
+
* Genre profiles in milliseconds (e.g. chill, edm, pop, rock).
|
|
256
|
+
*/
|
|
257
|
+
genreDurations?: Record<string, number>;
|
|
258
|
+
/**
|
|
259
|
+
* Max wait time while trying to align to beat boundary.
|
|
260
|
+
*/
|
|
261
|
+
beatAlignMaxWaitMs?: number;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Recovery strategy for stream/player failures.
|
|
265
|
+
*/
|
|
266
|
+
antiStuck?: {
|
|
267
|
+
enabled?: boolean;
|
|
268
|
+
maxRetries?: number;
|
|
269
|
+
retryDelayMs?: number;
|
|
270
|
+
/**
|
|
271
|
+
* Reuse preload/current cached stream before hard retries.
|
|
272
|
+
*/
|
|
273
|
+
reusePreloadFirst?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Temporarily force low quality during retry attempts.
|
|
276
|
+
*/
|
|
277
|
+
reduceQualityOnRetry?: boolean;
|
|
278
|
+
/**
|
|
279
|
+
* If consecutive failures exceed this threshold, allow skipping track.
|
|
280
|
+
*/
|
|
281
|
+
controlledSkipThreshold?: number;
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Loudness normalization and limiter.
|
|
285
|
+
*/
|
|
286
|
+
loudnessNormalization?: {
|
|
287
|
+
enabled?: boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Target LUFS (integrated). Track metadata.lufs is used if available.
|
|
290
|
+
*/
|
|
291
|
+
targetLUFS?: number;
|
|
292
|
+
/**
|
|
293
|
+
* Cap gain boost to avoid over-amplification.
|
|
294
|
+
*/
|
|
295
|
+
maxBoostDb?: number;
|
|
296
|
+
/**
|
|
297
|
+
* Cap attenuation.
|
|
298
|
+
*/
|
|
299
|
+
maxCutDb?: number;
|
|
300
|
+
/**
|
|
301
|
+
* Output ceiling multiplier (<= 1.0), acts as soft limiter ceiling.
|
|
302
|
+
*/
|
|
303
|
+
limiterCeiling?: number;
|
|
304
|
+
};
|
|
180
305
|
}
|
|
181
306
|
|
|
182
307
|
export interface PlayerManagerOptions {
|
|
183
308
|
plugins?: SourcePluginLike[];
|
|
184
309
|
extensions?: any[];
|
|
185
|
-
/**
|
|
186
|
-
* Timeout in milliseconds for manager-level operations (e.g. search)
|
|
187
|
-
* when running without a Player instance.
|
|
188
|
-
*/
|
|
189
310
|
extractorTimeout?: number;
|
|
311
|
+
autoCleanup?: boolean; // Auto cleanup inactive players
|
|
312
|
+
cleanupInterval?: number; // Cleanup interval in ms
|
|
313
|
+
enableSearchCache?: boolean; // Enable search result caching
|
|
314
|
+
enableStatsCollection?: boolean; // Enable stats collection events
|
|
190
315
|
}
|
|
191
316
|
|
|
192
317
|
/**
|
|
@@ -200,9 +325,13 @@ export interface PlayerManagerOptions {
|
|
|
200
325
|
* };
|
|
201
326
|
*/
|
|
202
327
|
export interface ProgressBarOptions {
|
|
203
|
-
size?: number;
|
|
204
|
-
barChar?: string;
|
|
205
|
-
progressChar?: string;
|
|
328
|
+
size?: number; // Bar length (default: 20)
|
|
329
|
+
barChar?: string; // Character for empty bar (default: "▬")
|
|
330
|
+
progressChar?: string; // Character for progress pointer (default: "🔘")
|
|
331
|
+
timeFormat?: "compact" | "full"; // Time format style (default: "compact")
|
|
332
|
+
showPercentage?: boolean; // Show percentage at end (default: false)
|
|
333
|
+
showTime?: boolean; // Show time labels (default: true)
|
|
334
|
+
hideProgressChar?: boolean; // Hide progress character (default: false)
|
|
206
335
|
}
|
|
207
336
|
|
|
208
337
|
/**
|
|
@@ -229,6 +358,46 @@ export interface SaveOptions {
|
|
|
229
358
|
/** Seek position in milliseconds to start saving from */
|
|
230
359
|
seek?: number;
|
|
231
360
|
}
|
|
361
|
+
export interface PlayerSession {
|
|
362
|
+
guildId: string;
|
|
363
|
+
queue: Track[];
|
|
364
|
+
currentTrack: Track | null;
|
|
365
|
+
volume: number;
|
|
366
|
+
loopMode: LoopMode;
|
|
367
|
+
autoPlay: boolean;
|
|
368
|
+
position: number | null;
|
|
369
|
+
extensions: string[];
|
|
370
|
+
plugins: string[];
|
|
371
|
+
userdata?: Record<string, any>;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export interface PreloadState {
|
|
375
|
+
resource: AudioResource | null;
|
|
376
|
+
track: Track | null;
|
|
377
|
+
abortController: AbortController | null;
|
|
378
|
+
timeoutId: NodeJS.Timeout | null;
|
|
379
|
+
isValid: boolean;
|
|
380
|
+
streamId?: string;
|
|
381
|
+
isBeingUsed: boolean;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export interface PlayerStats {
|
|
385
|
+
totalPlayers: number;
|
|
386
|
+
activePlayers: number;
|
|
387
|
+
pausedPlayers: number;
|
|
388
|
+
connectedPlayers: number;
|
|
389
|
+
totalTracksInQueue: number;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface StreamSlot {
|
|
393
|
+
resource: AudioResource | null;
|
|
394
|
+
track: Track | null;
|
|
395
|
+
streamId: string | null;
|
|
396
|
+
abortController: AbortController | null;
|
|
397
|
+
isValid: boolean;
|
|
398
|
+
isLoading: boolean;
|
|
399
|
+
loadPromise: Promise<void> | null;
|
|
400
|
+
}
|
|
232
401
|
|
|
233
402
|
export type LoopMode = "off" | "track" | "queue";
|
|
234
403
|
|
|
@@ -337,6 +506,8 @@ export interface ManagerEvents {
|
|
|
337
506
|
lyricsCreate: [player: Player, track: Track, lyrics: any];
|
|
338
507
|
lyricsChange: [player: Player, track: Track, lyrics: any];
|
|
339
508
|
voiceCreate: [player: Player, evt: any];
|
|
509
|
+
stats: [stats: PlayerStats];
|
|
510
|
+
streamError: [error: Error, track: Track | null];
|
|
340
511
|
}
|
|
341
512
|
export interface PlayerEvents {
|
|
342
513
|
debug: [message: string, ...args: any[]];
|
|
@@ -366,6 +537,10 @@ export interface PlayerEvents {
|
|
|
366
537
|
filterRemoved: [filter: AudioFilter];
|
|
367
538
|
/** Emitted when all filters are cleared */
|
|
368
539
|
filtersCleared: [];
|
|
540
|
+
trackStuck: [track: Track | null];
|
|
541
|
+
streamError: [error: Error, track: Track | null];
|
|
542
|
+
/** Emitted when player stats are updated (if enabled) */
|
|
543
|
+
stats: [stats: PlayerStats];
|
|
369
544
|
}
|
|
370
545
|
|
|
371
546
|
export * from "./fillter";
|
package/src/types/plugin.ts
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import type { SearchResult, StreamInfo, Track } from ".";
|
|
2
|
-
/**
|
|
3
|
-
* Plugin interface
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* const plugin: SourcePlugin = {
|
|
7
|
-
* name: "YouTube",
|
|
8
|
-
* version: "1.0.0"
|
|
9
|
-
* priority: 0, // Optional, default is 0. Lower priority plugins are tried first in getStream fallback.
|
|
10
|
-
* };
|
|
11
|
-
*/
|
|
12
|
-
export interface SourcePlugin {
|
|
13
|
-
name: string;
|
|
14
|
-
version: string;
|
|
15
|
-
priority?: number;
|
|
16
|
-
canHandle(query: string): boolean;
|
|
17
|
-
search(query: string, requestedBy: string): Promise<SearchResult>;
|
|
18
|
-
getStream(track: Track): Promise<StreamInfo>;
|
|
19
|
-
getRelatedTracks?(track: Track, opts?: { limit?: number; offset?: number }): Promise<Track[]>;
|
|
20
|
-
validate?(url: string): boolean;
|
|
21
|
-
extractPlaylist?(url: string, requestedBy: string): Promise<Track[]>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Constructor for a SourcePlugin
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* const plugin = new YouTubePlugin();
|
|
29
|
-
* console.log(`Plugin: ${plugin.name}`);
|
|
30
|
-
*/
|
|
31
|
-
export type SourcePluginCtor<T extends SourcePlugin = SourcePlugin> = new (...args: any[]) => T;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* SourcePlugin or SourcePluginCtor
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* const plugin = new YouTubePlugin();
|
|
38
|
-
* console.log(`Plugin: ${plugin.name}`);
|
|
39
|
-
*/
|
|
40
|
-
export type SourcePluginLike = SourcePlugin | SourcePluginCtor;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Configuration options for creating a PlayerManager instance.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* const managerOptions: PlayerManagerOptions = {
|
|
47
|
-
* plugins: [
|
|
48
|
-
* new YouTubePlugin(),
|
|
49
|
-
* new SoundCloudPlugin(),
|
|
50
|
-
* new SpotifyPlugin(),
|
|
51
|
-
* new TTSPlugin({ defaultLang: "en" })
|
|
52
|
-
* ],
|
|
53
|
-
* extensions: [
|
|
54
|
-
* new voiceExt(null, { lang: "en-US" }),
|
|
55
|
-
* new lavalinkExt(null, { nodes: [...] })
|
|
56
|
-
* ],
|
|
57
|
-
* extractorTimeout: 10000
|
|
58
|
-
* };
|
|
59
|
-
*/
|
|
1
|
+
import type { SearchResult, StreamInfo, Track } from ".";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin interface
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const plugin: SourcePlugin = {
|
|
7
|
+
* name: "YouTube",
|
|
8
|
+
* version: "1.0.0"
|
|
9
|
+
* priority: 0, // Optional, default is 0. Lower priority plugins are tried first in getStream fallback.
|
|
10
|
+
* };
|
|
11
|
+
*/
|
|
12
|
+
export interface SourcePlugin {
|
|
13
|
+
name: string;
|
|
14
|
+
version: string;
|
|
15
|
+
priority?: number; // Higher = run first, default is 0. Lower priority plugins are tried first in getStream fallback.
|
|
16
|
+
canHandle(query: string): boolean;
|
|
17
|
+
search(query: string, requestedBy: string): Promise<SearchResult>;
|
|
18
|
+
getStream(track: Track): Promise<StreamInfo>;
|
|
19
|
+
getRelatedTracks?(track: Track, opts?: { limit?: number; offset?: number }): Promise<Track[]>;
|
|
20
|
+
validate?(url: string): boolean;
|
|
21
|
+
extractPlaylist?(url: string, requestedBy: string): Promise<Track[]>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Constructor for a SourcePlugin
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const plugin = new YouTubePlugin();
|
|
29
|
+
* console.log(`Plugin: ${plugin.name}`);
|
|
30
|
+
*/
|
|
31
|
+
export type SourcePluginCtor<T extends SourcePlugin = SourcePlugin> = new (...args: any[]) => T;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* SourcePlugin or SourcePluginCtor
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const plugin = new YouTubePlugin();
|
|
38
|
+
* console.log(`Plugin: ${plugin.name}`);
|
|
39
|
+
*/
|
|
40
|
+
export type SourcePluginLike = SourcePlugin | SourcePluginCtor;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Configuration options for creating a PlayerManager instance.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* const managerOptions: PlayerManagerOptions = {
|
|
47
|
+
* plugins: [
|
|
48
|
+
* new YouTubePlugin(),
|
|
49
|
+
* new SoundCloudPlugin(),
|
|
50
|
+
* new SpotifyPlugin(),
|
|
51
|
+
* new TTSPlugin({ defaultLang: "en" })
|
|
52
|
+
* ],
|
|
53
|
+
* extensions: [
|
|
54
|
+
* new voiceExt(null, { lang: "en-US" }),
|
|
55
|
+
* new lavalinkExt(null, { nodes: [...] })
|
|
56
|
+
* ],
|
|
57
|
+
* extractorTimeout: 10000
|
|
58
|
+
* };
|
|
59
|
+
*/
|