ziplayer 0.0.7 → 0.0.9
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/structures/Player.d.ts +14 -0
- package/dist/structures/Player.d.ts.map +1 -1
- package/dist/structures/Player.js +132 -72
- package/dist/structures/Player.js.map +1 -1
- package/dist/structures/PlayerManager.d.ts +9 -1
- package/dist/structures/PlayerManager.d.ts.map +1 -1
- package/dist/structures/PlayerManager.js +34 -3
- package/dist/structures/PlayerManager.js.map +1 -1
- package/dist/structures/Queue.d.ts +5 -0
- package/dist/structures/Queue.d.ts.map +1 -1
- package/dist/structures/Queue.js +13 -0
- package/dist/structures/Queue.js.map +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/structures/Player.ts +141 -78
- package/src/structures/PlayerManager.ts +38 -4
- package/src/structures/Queue.ts +160 -147
- package/src/types/index.ts +131 -126
package/src/structures/Queue.ts
CHANGED
|
@@ -1,147 +1,160 @@
|
|
|
1
|
-
import { Track, LoopMode } from "../types";
|
|
2
|
-
|
|
3
|
-
export class Queue {
|
|
4
|
-
private tracks: Track[] = [];
|
|
5
|
-
private current: Track | null = null;
|
|
6
|
-
private history: Track[] = [];
|
|
7
|
-
private related: Track[] = [];
|
|
8
|
-
private _autoPlay = false;
|
|
9
|
-
private _loop: LoopMode = "off";
|
|
10
|
-
private willnext: Track | null = null;
|
|
11
|
-
|
|
12
|
-
add(track: Track): void {
|
|
13
|
-
this.tracks.push(track);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
addMultiple(tracks: Track[]): void {
|
|
17
|
-
this.tracks.push(...tracks);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Insert a track at a specific upcoming position (0 = next) */
|
|
21
|
-
insert(track: Track, index: number): void {
|
|
22
|
-
if (!Number.isFinite(index)) {
|
|
23
|
-
this.tracks.push(track);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
27
|
-
if (i === this.tracks.length) {
|
|
28
|
-
this.tracks.push(track);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (i <= 0) {
|
|
32
|
-
this.tracks.unshift(track);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
this.tracks.splice(i, 0, track);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Insert multiple tracks at a specific upcoming position, preserving order */
|
|
39
|
-
insertMultiple(tracks: Track[], index: number): void {
|
|
40
|
-
if (!Array.isArray(tracks) || tracks.length === 0) return;
|
|
41
|
-
if (!Number.isFinite(index)) {
|
|
42
|
-
this.tracks.push(...tracks);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
46
|
-
if (i === 0) {
|
|
47
|
-
this.tracks = [...tracks, ...this.tracks];
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (i === this.tracks.length) {
|
|
51
|
-
this.tracks.push(...tracks);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
this.tracks.splice(i, 0, ...tracks);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
remove(index: number): Track | null {
|
|
58
|
-
if (index < 0 || index >= this.tracks.length) return null;
|
|
59
|
-
return this.tracks.splice(index, 1)[0];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
next(ignoreLoop = false): Track | null {
|
|
63
|
-
if (this.current) {
|
|
64
|
-
if (this._loop === "track" && !ignoreLoop) {
|
|
65
|
-
return this.current;
|
|
66
|
-
}
|
|
67
|
-
this.history.push(this.current);
|
|
68
|
-
if (this.history.length > 200) {
|
|
69
|
-
this.history.shift();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
this.current = this.tracks.shift() || null;
|
|
73
|
-
if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
|
|
74
|
-
this.tracks = [...this.history];
|
|
75
|
-
this.history = [];
|
|
76
|
-
this.current = this.tracks.shift() || null;
|
|
77
|
-
}
|
|
78
|
-
return this.current;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
clear(): void {
|
|
82
|
-
this.tracks = [];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
autoPlay(value?: boolean): boolean {
|
|
86
|
-
if (typeof value !== "undefined") {
|
|
87
|
-
this._autoPlay = value;
|
|
88
|
-
}
|
|
89
|
-
return this._autoPlay;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
loop(mode?: LoopMode): LoopMode {
|
|
93
|
-
if (mode) {
|
|
94
|
-
this._loop = mode;
|
|
95
|
-
}
|
|
96
|
-
return this._loop;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
shuffle(): void {
|
|
100
|
-
for (let i = this.tracks.length - 1; i > 0; i--) {
|
|
101
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
102
|
-
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get size(): number {
|
|
107
|
-
return this.tracks.length;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
get isEmpty(): boolean {
|
|
111
|
-
return this.tracks.length === 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
get currentTrack(): Track | null {
|
|
115
|
-
return this.current;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
get previousTracks(): Track[] {
|
|
119
|
-
return [...this.history];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
get nextTrack(): Track | null {
|
|
123
|
-
return this.tracks[0] || null;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
1
|
+
import { Track, LoopMode } from "../types";
|
|
2
|
+
|
|
3
|
+
export class Queue {
|
|
4
|
+
private tracks: Track[] = [];
|
|
5
|
+
private current: Track | null = null;
|
|
6
|
+
private history: Track[] = [];
|
|
7
|
+
private related: Track[] = [];
|
|
8
|
+
private _autoPlay = false;
|
|
9
|
+
private _loop: LoopMode = "off";
|
|
10
|
+
private willnext: Track | null = null;
|
|
11
|
+
|
|
12
|
+
add(track: Track): void {
|
|
13
|
+
this.tracks.push(track);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
addMultiple(tracks: Track[]): void {
|
|
17
|
+
this.tracks.push(...tracks);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Insert a track at a specific upcoming position (0 = next) */
|
|
21
|
+
insert(track: Track, index: number): void {
|
|
22
|
+
if (!Number.isFinite(index)) {
|
|
23
|
+
this.tracks.push(track);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
27
|
+
if (i === this.tracks.length) {
|
|
28
|
+
this.tracks.push(track);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (i <= 0) {
|
|
32
|
+
this.tracks.unshift(track);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.tracks.splice(i, 0, track);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Insert multiple tracks at a specific upcoming position, preserving order */
|
|
39
|
+
insertMultiple(tracks: Track[], index: number): void {
|
|
40
|
+
if (!Array.isArray(tracks) || tracks.length === 0) return;
|
|
41
|
+
if (!Number.isFinite(index)) {
|
|
42
|
+
this.tracks.push(...tracks);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
|
|
46
|
+
if (i === 0) {
|
|
47
|
+
this.tracks = [...tracks, ...this.tracks];
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (i === this.tracks.length) {
|
|
51
|
+
this.tracks.push(...tracks);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.tracks.splice(i, 0, ...tracks);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
remove(index: number): Track | null {
|
|
58
|
+
if (index < 0 || index >= this.tracks.length) return null;
|
|
59
|
+
return this.tracks.splice(index, 1)[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
next(ignoreLoop = false): Track | null {
|
|
63
|
+
if (this.current) {
|
|
64
|
+
if (this._loop === "track" && !ignoreLoop) {
|
|
65
|
+
return this.current;
|
|
66
|
+
}
|
|
67
|
+
this.history.push(this.current);
|
|
68
|
+
if (this.history.length > 200) {
|
|
69
|
+
this.history.shift();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.current = this.tracks.shift() || null;
|
|
73
|
+
if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
|
|
74
|
+
this.tracks = [...this.history];
|
|
75
|
+
this.history = [];
|
|
76
|
+
this.current = this.tracks.shift() || null;
|
|
77
|
+
}
|
|
78
|
+
return this.current;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
clear(): void {
|
|
82
|
+
this.tracks = [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
autoPlay(value?: boolean): boolean {
|
|
86
|
+
if (typeof value !== "undefined") {
|
|
87
|
+
this._autoPlay = value;
|
|
88
|
+
}
|
|
89
|
+
return this._autoPlay;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
loop(mode?: LoopMode): LoopMode {
|
|
93
|
+
if (mode) {
|
|
94
|
+
this._loop = mode;
|
|
95
|
+
}
|
|
96
|
+
return this._loop;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
shuffle(): void {
|
|
100
|
+
for (let i = this.tracks.length - 1; i > 0; i--) {
|
|
101
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
102
|
+
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get size(): number {
|
|
107
|
+
return this.tracks.length;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get isEmpty(): boolean {
|
|
111
|
+
return this.tracks.length === 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get currentTrack(): Track | null {
|
|
115
|
+
return this.current;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get previousTracks(): Track[] {
|
|
119
|
+
return [...this.history];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get nextTrack(): Track | null {
|
|
123
|
+
return this.tracks[0] || null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Move back to the previously played track.
|
|
128
|
+
* Makes the current track the next upcoming track, then sets previous as current.
|
|
129
|
+
*/
|
|
130
|
+
previous(): Track | null {
|
|
131
|
+
if (this.history.length === 0) return null;
|
|
132
|
+
if (this.current) {
|
|
133
|
+
this.tracks.unshift(this.current);
|
|
134
|
+
}
|
|
135
|
+
this.current = this.history.pop() || null;
|
|
136
|
+
return this.current;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
willNextTrack(track?: Track): Track | null {
|
|
140
|
+
if (track) {
|
|
141
|
+
this.willnext = track;
|
|
142
|
+
}
|
|
143
|
+
return this.willnext;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
relatedTracks(track?: Track[]): Track[] | null {
|
|
147
|
+
if (track) {
|
|
148
|
+
this.related = track;
|
|
149
|
+
}
|
|
150
|
+
return this.related;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
getTracks(): Track[] {
|
|
154
|
+
return [...this.tracks];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
getTrack(index: number): Track | null {
|
|
158
|
+
return this.tracks[index] || null;
|
|
159
|
+
}
|
|
160
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,126 +1,131 @@
|
|
|
1
|
-
import { VoiceConnection } from "@discordjs/voice";
|
|
2
|
-
import { Readable } from "stream";
|
|
3
|
-
import { Player } from "../structures/Player";
|
|
4
|
-
|
|
5
|
-
export interface Track {
|
|
6
|
-
id: string;
|
|
7
|
-
title: string;
|
|
8
|
-
url: string;
|
|
9
|
-
duration: number;
|
|
10
|
-
thumbnail?: string;
|
|
11
|
-
requestedBy: string;
|
|
12
|
-
source: string;
|
|
13
|
-
metadata?: Record<string, any>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface SearchResult {
|
|
17
|
-
tracks: Track[];
|
|
18
|
-
playlist?: {
|
|
19
|
-
name: string;
|
|
20
|
-
url: string;
|
|
21
|
-
thumbnail?: string;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface StreamInfo {
|
|
26
|
-
stream: Readable;
|
|
27
|
-
type: "webm/opus" | "ogg/opus" | "arbitrary";
|
|
28
|
-
metadata?: Record<string, any>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface PlayerOptions {
|
|
32
|
-
leaveOnEnd?: boolean;
|
|
33
|
-
leaveOnEmpty?: boolean;
|
|
34
|
-
leaveTimeout?: number;
|
|
35
|
-
volume?: number;
|
|
36
|
-
quality?: "high" | "low";
|
|
37
|
-
selfDeaf?: boolean;
|
|
38
|
-
selfMute?: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* Timeout in milliseconds for plugin operations (search, streaming, etc.)
|
|
41
|
-
* to prevent long-running tasks from blocking the player.
|
|
42
|
-
*/
|
|
43
|
-
extractorTimeout?: number;
|
|
44
|
-
userdata?: Record<string, any>;
|
|
45
|
-
/**
|
|
46
|
-
* Text-to-Speech settings. When enabled, the player can create a
|
|
47
|
-
* dedicated AudioPlayer to play TTS while pausing the music player
|
|
48
|
-
* then resume the music after TTS finishes.
|
|
49
|
-
*/
|
|
50
|
-
tts?: {
|
|
51
|
-
/** Create a dedicated tts AudioPlayer at construction time */
|
|
52
|
-
createPlayer?: boolean;
|
|
53
|
-
/** Pause music and swap subscription to play TTS */
|
|
54
|
-
interrupt?: boolean;
|
|
55
|
-
/** Default TTS volume multiplier 1 => 100% */
|
|
56
|
-
volume?: number;
|
|
57
|
-
/** Max time tts playback Duration */
|
|
58
|
-
Max_Time_TTS?: number;
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Optional per-player extension selection. When provided, only these
|
|
62
|
-
* extensions will be activated for the created player.
|
|
63
|
-
* - Provide instances or constructors to use them explicitly
|
|
64
|
-
* - Or provide names (string) to select from manager-registered extensions
|
|
65
|
-
*/
|
|
66
|
-
extensions?: any[] | string[];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export type SourcePluginCtor<T extends SourcePlugin = SourcePlugin> = new (...args: any[]) => T;
|
|
70
|
-
export type SourcePluginLike = SourcePlugin | SourcePluginCtor;
|
|
71
|
-
|
|
72
|
-
export interface PlayerManagerOptions {
|
|
73
|
-
plugins?: SourcePluginLike[];
|
|
74
|
-
extensions?: any[];
|
|
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
|
-
|
|
1
|
+
import { VoiceConnection } from "@discordjs/voice";
|
|
2
|
+
import { Readable } from "stream";
|
|
3
|
+
import { Player } from "../structures/Player";
|
|
4
|
+
|
|
5
|
+
export interface Track {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
url: string;
|
|
9
|
+
duration: number;
|
|
10
|
+
thumbnail?: string;
|
|
11
|
+
requestedBy: string;
|
|
12
|
+
source: string;
|
|
13
|
+
metadata?: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SearchResult {
|
|
17
|
+
tracks: Track[];
|
|
18
|
+
playlist?: {
|
|
19
|
+
name: string;
|
|
20
|
+
url: string;
|
|
21
|
+
thumbnail?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StreamInfo {
|
|
26
|
+
stream: Readable;
|
|
27
|
+
type: "webm/opus" | "ogg/opus" | "arbitrary";
|
|
28
|
+
metadata?: Record<string, any>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface PlayerOptions {
|
|
32
|
+
leaveOnEnd?: boolean;
|
|
33
|
+
leaveOnEmpty?: boolean;
|
|
34
|
+
leaveTimeout?: number;
|
|
35
|
+
volume?: number;
|
|
36
|
+
quality?: "high" | "low";
|
|
37
|
+
selfDeaf?: boolean;
|
|
38
|
+
selfMute?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Timeout in milliseconds for plugin operations (search, streaming, etc.)
|
|
41
|
+
* to prevent long-running tasks from blocking the player.
|
|
42
|
+
*/
|
|
43
|
+
extractorTimeout?: number;
|
|
44
|
+
userdata?: Record<string, any>;
|
|
45
|
+
/**
|
|
46
|
+
* Text-to-Speech settings. When enabled, the player can create a
|
|
47
|
+
* dedicated AudioPlayer to play TTS while pausing the music player
|
|
48
|
+
* then resume the music after TTS finishes.
|
|
49
|
+
*/
|
|
50
|
+
tts?: {
|
|
51
|
+
/** Create a dedicated tts AudioPlayer at construction time */
|
|
52
|
+
createPlayer?: boolean;
|
|
53
|
+
/** Pause music and swap subscription to play TTS */
|
|
54
|
+
interrupt?: boolean;
|
|
55
|
+
/** Default TTS volume multiplier 1 => 100% */
|
|
56
|
+
volume?: number;
|
|
57
|
+
/** Max time tts playback Duration */
|
|
58
|
+
Max_Time_TTS?: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Optional per-player extension selection. When provided, only these
|
|
62
|
+
* extensions will be activated for the created player.
|
|
63
|
+
* - Provide instances or constructors to use them explicitly
|
|
64
|
+
* - Or provide names (string) to select from manager-registered extensions
|
|
65
|
+
*/
|
|
66
|
+
extensions?: any[] | string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type SourcePluginCtor<T extends SourcePlugin = SourcePlugin> = new (...args: any[]) => T;
|
|
70
|
+
export type SourcePluginLike = SourcePlugin | SourcePluginCtor;
|
|
71
|
+
|
|
72
|
+
export interface PlayerManagerOptions {
|
|
73
|
+
plugins?: SourcePluginLike[];
|
|
74
|
+
extensions?: any[];
|
|
75
|
+
/**
|
|
76
|
+
* Timeout in milliseconds for manager-level operations (e.g. search)
|
|
77
|
+
* when running without a Player instance.
|
|
78
|
+
*/
|
|
79
|
+
extractorTimeout?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ProgressBarOptions {
|
|
83
|
+
size?: number;
|
|
84
|
+
barChar?: string;
|
|
85
|
+
progressChar?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type LoopMode = "off" | "track" | "queue";
|
|
89
|
+
|
|
90
|
+
export interface PlayerEvents {
|
|
91
|
+
debug: [message: string, ...args: any[]];
|
|
92
|
+
willPlay: [track: Track, upcomingTracks: Track[]];
|
|
93
|
+
trackStart: [track: Track];
|
|
94
|
+
trackEnd: [track: Track];
|
|
95
|
+
queueEnd: [];
|
|
96
|
+
playerError: [error: Error, track?: Track];
|
|
97
|
+
connectionError: [error: Error];
|
|
98
|
+
volumeChange: [oldVolume: number, newVolume: number];
|
|
99
|
+
queueAdd: [track: Track];
|
|
100
|
+
queueAddList: [tracks: Track[]];
|
|
101
|
+
queueRemove: [track: Track, index: number];
|
|
102
|
+
playerPause: [track: Track];
|
|
103
|
+
playerResume: [track: Track];
|
|
104
|
+
playerStop: [];
|
|
105
|
+
playerDestroy: [];
|
|
106
|
+
/** Emitted when TTS starts playing (interruption mode) */
|
|
107
|
+
ttsStart: [payload: { text?: string; track?: Track }];
|
|
108
|
+
/** Emitted when TTS finished (interruption mode) */
|
|
109
|
+
ttsEnd: [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Plugin interfaces
|
|
113
|
+
export interface SourcePlugin {
|
|
114
|
+
name: string;
|
|
115
|
+
version: string;
|
|
116
|
+
canHandle(query: string): boolean;
|
|
117
|
+
search(query: string, requestedBy: string): Promise<SearchResult>;
|
|
118
|
+
getStream(track: Track): Promise<StreamInfo>;
|
|
119
|
+
getRelatedTracks?(track: string | number, opts?: { limit?: number; offset?: number }): Promise<Track[]>;
|
|
120
|
+
validate?(url: string): boolean;
|
|
121
|
+
extractPlaylist?(url: string, requestedBy: string): Promise<Track[]>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Extension interfaces
|
|
125
|
+
export interface SourceExtension {
|
|
126
|
+
name: string;
|
|
127
|
+
version: string;
|
|
128
|
+
connection?: VoiceConnection;
|
|
129
|
+
player: Player | null;
|
|
130
|
+
active(alas: any): boolean;
|
|
131
|
+
}
|