@fluxerjs/voice 1.0.5 → 1.0.7
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/index.d.mts +168 -7
- package/dist/index.d.ts +168 -7
- package/dist/index.js +991 -27
- package/dist/index.mjs +997 -29
- package/package.json +9 -4
package/dist/index.d.mts
CHANGED
|
@@ -7,6 +7,7 @@ interface VoiceConnectionEvents {
|
|
|
7
7
|
error: [err: Error];
|
|
8
8
|
disconnect: [];
|
|
9
9
|
}
|
|
10
|
+
/** Voice connection using Discord's UDP-based protocol. Emits `ready`, `error`, `disconnect`. */
|
|
10
11
|
declare class VoiceConnection extends EventEmitter {
|
|
11
12
|
readonly client: Client;
|
|
12
13
|
readonly channel: VoiceChannel;
|
|
@@ -30,7 +31,9 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
30
31
|
private audioPacketQueue;
|
|
31
32
|
private pacingInterval;
|
|
32
33
|
constructor(client: Client, channel: VoiceChannel, userId: string);
|
|
34
|
+
/** Discord voice session ID. */
|
|
33
35
|
get sessionId(): string | null;
|
|
36
|
+
/** Whether audio is currently playing. */
|
|
34
37
|
get playing(): boolean;
|
|
35
38
|
/** Called when we have both server update and state update. */
|
|
36
39
|
connect(server: GatewayVoiceServerUpdateDispatchData, state: GatewayVoiceStateUpdateDispatchData): Promise<void>;
|
|
@@ -48,42 +51,152 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
48
51
|
*/
|
|
49
52
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
50
53
|
private sendAudioFrame;
|
|
54
|
+
/** Stop playback and clear the queue. */
|
|
51
55
|
stop(): void;
|
|
56
|
+
/** Disconnect from voice (closes WebSocket and UDP). */
|
|
52
57
|
disconnect(): void;
|
|
58
|
+
/** Disconnect and remove all listeners. */
|
|
53
59
|
destroy(): void;
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
/** LiveKit-specific: emitted when server sends leave (token expiry, server policy, etc.). Emitted before disconnect. */
|
|
57
63
|
type LiveKitRtcConnectionEvents = VoiceConnectionEvents & {
|
|
58
64
|
serverLeave: [];
|
|
65
|
+
/** Emitted when voice state should be synced (self_stream/self_video). VoiceManager listens. */
|
|
66
|
+
requestVoiceStateSync: [payload: {
|
|
67
|
+
self_stream?: boolean;
|
|
68
|
+
self_video?: boolean;
|
|
69
|
+
}];
|
|
59
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Options for video playback via {@link LiveKitRtcConnection.playVideo}.
|
|
73
|
+
*
|
|
74
|
+
* @property source - Track source hint sent to LiveKit. Use `'camera'` for typical video streams
|
|
75
|
+
* (default) or `'screenshare'` for screen-share-style content. Affects how clients may display the track.
|
|
76
|
+
* @property loop - When true (default), loops the video continuously to keep the stream live. Required for
|
|
77
|
+
* LiveKit: "stream it continuously for the benefit of participants joining after the initial frame."
|
|
78
|
+
* @property useFFmpeg - When true, use FFmpeg subprocess for decoding instead of node-webcodecs.
|
|
79
|
+
* Recommended when node-webcodecs causes libc++abi crashes on macOS. Requires ffmpeg in PATH.
|
|
80
|
+
* Also set via FLUXER_VIDEO_FFMPEG=1 env.
|
|
81
|
+
* @property videoBitrate - Max video bitrate in bps (default: 2_500_000). Higher values improve quality.
|
|
82
|
+
* @property maxFramerate - Max framerate for encoding (default: 60).
|
|
83
|
+
* @property width - Output width (default: source). FFmpeg path only.
|
|
84
|
+
* @property height - Output height (default: source). FFmpeg path only.
|
|
85
|
+
*/
|
|
86
|
+
interface VideoPlayOptions {
|
|
87
|
+
/** Track source hint - camera or screenshare (default: camera). */
|
|
88
|
+
source?: 'camera' | 'screenshare';
|
|
89
|
+
/** Loop video to keep stream continuously live (default: true). */
|
|
90
|
+
loop?: boolean;
|
|
91
|
+
/** Use FFmpeg for decoding (avoids node-webcodecs; requires ffmpeg in PATH). */
|
|
92
|
+
useFFmpeg?: boolean;
|
|
93
|
+
/** Max video bitrate in bps for encoding (default: 2_500_000). */
|
|
94
|
+
videoBitrate?: number;
|
|
95
|
+
/** Max framerate for encoding (default: 60). */
|
|
96
|
+
maxFramerate?: number;
|
|
97
|
+
/** Output width for resolution override (FFmpeg path). */
|
|
98
|
+
width?: number;
|
|
99
|
+
/** Output height for resolution override (FFmpeg path). */
|
|
100
|
+
height?: number;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Voice connection using LiveKit RTC. Used when Fluxer routes voice to LiveKit.
|
|
104
|
+
*
|
|
105
|
+
* Supports both audio playback ({@link play}) and video streaming ({@link playVideo}) to voice channels.
|
|
106
|
+
* Video uses node-webcodecs for decoding (no ffmpeg subprocess). Audio uses prism-media WebM demuxer.
|
|
107
|
+
*
|
|
108
|
+
* @emits ready - When connected to the LiveKit room and ready for playback
|
|
109
|
+
* @emits disconnect - When disconnected from the room
|
|
110
|
+
* @emits serverLeave - When LiveKit server signals leave (e.g. token expiry), before disconnect
|
|
111
|
+
* @emits error - On connection, playback, or decoding errors
|
|
112
|
+
*/
|
|
60
113
|
declare class LiveKitRtcConnection extends EventEmitter {
|
|
61
114
|
readonly client: Client;
|
|
62
115
|
readonly channel: VoiceChannel;
|
|
63
116
|
readonly guildId: string;
|
|
64
117
|
private _playing;
|
|
118
|
+
private _playingVideo;
|
|
65
119
|
private _destroyed;
|
|
66
120
|
private room;
|
|
67
121
|
private audioSource;
|
|
68
122
|
private audioTrack;
|
|
123
|
+
private videoSource;
|
|
124
|
+
private videoTrack;
|
|
69
125
|
private currentStream;
|
|
126
|
+
private currentVideoStream;
|
|
127
|
+
private _videoCleanup;
|
|
70
128
|
private lastServerEndpoint;
|
|
71
129
|
private lastServerToken;
|
|
72
130
|
private _disconnectEmitted;
|
|
131
|
+
/**
|
|
132
|
+
* @param client - The Fluxer client instance
|
|
133
|
+
* @param channel - The voice channel to connect to
|
|
134
|
+
* @param _userId - The user ID (reserved for future use)
|
|
135
|
+
*/
|
|
73
136
|
constructor(client: Client, channel: VoiceChannel, _userId: string);
|
|
137
|
+
/** Whether audio is currently playing. */
|
|
74
138
|
get playing(): boolean;
|
|
75
139
|
private debug;
|
|
76
140
|
private audioDebug;
|
|
77
141
|
private emitDisconnect;
|
|
78
142
|
/** Returns true if the LiveKit room is connected and not destroyed. */
|
|
79
143
|
isConnected(): boolean;
|
|
80
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* Returns true if we're already connected to the given server (skip migration).
|
|
146
|
+
* @param endpoint - Voice server endpoint from the gateway
|
|
147
|
+
* @param token - Voice server token
|
|
148
|
+
*/
|
|
81
149
|
isSameServer(endpoint: string | null, token: string): boolean;
|
|
82
150
|
playOpus(_stream: NodeJS.ReadableStream): void;
|
|
151
|
+
/**
|
|
152
|
+
* Connect to the LiveKit room using voice server and state from the gateway.
|
|
153
|
+
* Called internally by VoiceManager; typically not used directly.
|
|
154
|
+
*
|
|
155
|
+
* @param server - Voice server update data (endpoint, token)
|
|
156
|
+
* @param _state - Voice state update data (session, channel)
|
|
157
|
+
*/
|
|
83
158
|
connect(server: GatewayVoiceServerUpdateDispatchData, _state: GatewayVoiceStateUpdateDispatchData): Promise<void>;
|
|
159
|
+
/** Whether a video track is currently playing in the voice channel. */
|
|
160
|
+
get playingVideo(): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Play video from an MP4 URL or buffer. Streams decoded frames to the LiveKit room as a video track.
|
|
163
|
+
* Uses node-webcodecs for decoding (no ffmpeg). Supports H.264 (avc1) and H.265 (hvc1/hev1) codecs.
|
|
164
|
+
*
|
|
165
|
+
* @param urlOrBuffer - Video source: HTTP(S) URL to an MP4 file, or raw ArrayBuffer/Uint8Array of MP4 data
|
|
166
|
+
* @param options - Optional playback options (see {@link VideoPlayOptions})
|
|
167
|
+
* @emits error - On fetch failure, missing video track, or decode errors
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* const conn = await voiceManager.join(channel);
|
|
172
|
+
* if (conn instanceof LiveKitRtcConnection && conn.isConnected()) {
|
|
173
|
+
* await conn.playVideo('https://example.com/video.mp4', { source: 'camera' });
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
playVideo(urlOrBuffer: string | ArrayBuffer | Uint8Array, options?: VideoPlayOptions): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* FFmpeg-based video playback. Bypasses node-webcodecs to avoid libc++abi crashes on macOS.
|
|
180
|
+
* Requires ffmpeg and ffprobe in PATH. URL input only.
|
|
181
|
+
*/
|
|
182
|
+
private playVideoFFmpeg;
|
|
183
|
+
/**
|
|
184
|
+
* Play audio from a WebM/Opus URL or readable stream. Publishes to the LiveKit room as an audio track.
|
|
185
|
+
*
|
|
186
|
+
* @param urlOrStream - Audio source: HTTP(S) URL to a WebM/Opus file, or a Node.js ReadableStream
|
|
187
|
+
* @emits error - On fetch failure or decode errors
|
|
188
|
+
*/
|
|
84
189
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Stop video playback and unpublish the video track from the LiveKit room.
|
|
192
|
+
* Safe to call even when no video is playing.
|
|
193
|
+
*/
|
|
194
|
+
stopVideo(): void;
|
|
195
|
+
/** Stop playback and clear both audio and video tracks. */
|
|
85
196
|
stop(): void;
|
|
197
|
+
/** Disconnect from the LiveKit room and stop all playback. */
|
|
86
198
|
disconnect(): void;
|
|
199
|
+
/** Disconnect from the room and remove all event listeners. */
|
|
87
200
|
destroy(): void;
|
|
88
201
|
}
|
|
89
202
|
declare module 'events' {
|
|
@@ -95,46 +208,94 @@ declare module 'events' {
|
|
|
95
208
|
|
|
96
209
|
/** Maps guild_id -> user_id -> channel_id (null if not in voice). */
|
|
97
210
|
type VoiceStateMap = Map<string, Map<string, string | null>>;
|
|
211
|
+
/**
|
|
212
|
+
* Options for creating a VoiceManager.
|
|
213
|
+
*
|
|
214
|
+
* @property shardId - Gateway shard ID to use for voice connections (default 0).
|
|
215
|
+
* Use when the client runs multiple shards and you need to target a specific one.
|
|
216
|
+
*/
|
|
98
217
|
interface VoiceManagerOptions {
|
|
99
218
|
/** Gateway shard ID to use for voice (default 0). */
|
|
100
219
|
shardId?: number;
|
|
101
220
|
}
|
|
221
|
+
/** Manages voice connections. Use `getVoiceManager(client)` to obtain an instance. */
|
|
102
222
|
declare class VoiceManager extends EventEmitter {
|
|
103
223
|
readonly client: Client;
|
|
104
224
|
private readonly connections;
|
|
225
|
+
/** guild_id -> connection_id (from VoiceServerUpdate; required for voice state updates when in channel) */
|
|
226
|
+
private readonly connectionIds;
|
|
105
227
|
/** guild_id -> user_id -> channel_id */
|
|
106
228
|
readonly voiceStates: VoiceStateMap;
|
|
107
229
|
private readonly pending;
|
|
108
230
|
private readonly shardId;
|
|
109
231
|
constructor(client: Client, options?: VoiceManagerOptions);
|
|
110
232
|
private handleVoiceStatesSync;
|
|
111
|
-
/**
|
|
233
|
+
/**
|
|
234
|
+
* Get the voice channel ID the user is currently in, or null if not in voice.
|
|
235
|
+
* @param guildId - Guild ID to look up
|
|
236
|
+
* @param userId - User ID to look up
|
|
237
|
+
*/
|
|
112
238
|
getVoiceChannelId(guildId: string, userId: string): string | null;
|
|
113
239
|
private handleVoiceStateUpdate;
|
|
114
240
|
private handleVoiceServerUpdate;
|
|
241
|
+
private storeConnectionId;
|
|
115
242
|
private registerConnection;
|
|
243
|
+
/** Upload a placeholder stream preview so the preview URL returns 200 instead of 404. */
|
|
244
|
+
private uploadStreamPreview;
|
|
116
245
|
private tryCompletePending;
|
|
117
|
-
/**
|
|
246
|
+
/**
|
|
247
|
+
* Join a voice channel. Resolves when the connection is ready.
|
|
248
|
+
* @param channel - The voice channel to join
|
|
249
|
+
* @returns The voice connection (LiveKitRtcConnection when Fluxer uses LiveKit)
|
|
250
|
+
*/
|
|
118
251
|
join(channel: VoiceChannel): Promise<VoiceConnection | LiveKitRtcConnection>;
|
|
119
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* Leave a guild's voice channel and disconnect.
|
|
254
|
+
* @param guildId - Guild ID to leave
|
|
255
|
+
*/
|
|
120
256
|
leave(guildId: string): void;
|
|
257
|
+
/**
|
|
258
|
+
* Get the active voice connection for a guild, if any.
|
|
259
|
+
* @param guildId - Guild ID to look up
|
|
260
|
+
*/
|
|
121
261
|
getConnection(guildId: string): VoiceConnection | LiveKitRtcConnection | undefined;
|
|
262
|
+
/**
|
|
263
|
+
* Update voice state (e.g. self_stream, self_video) while in a channel.
|
|
264
|
+
* Sends a VoiceStateUpdate to the gateway so the server and clients see the change.
|
|
265
|
+
* Requires connection_id (from VoiceServerUpdate); without it, the gateway would treat
|
|
266
|
+
* the update as a new join and trigger a new VoiceServerUpdate, causing connection loops.
|
|
267
|
+
* @param guildId - Guild ID
|
|
268
|
+
* @param partial - Partial voice state to update (self_stream, self_video, self_mute, self_deaf)
|
|
269
|
+
*/
|
|
270
|
+
updateVoiceState(guildId: string, partial: {
|
|
271
|
+
self_stream?: boolean;
|
|
272
|
+
self_video?: boolean;
|
|
273
|
+
self_mute?: boolean;
|
|
274
|
+
self_deaf?: boolean;
|
|
275
|
+
}): void;
|
|
122
276
|
}
|
|
123
277
|
|
|
124
278
|
/** Union of connection types (Discord-style or LiveKit). */
|
|
125
279
|
type VoiceConnectionLike = VoiceConnection | LiveKitRtcConnection;
|
|
126
280
|
/**
|
|
127
|
-
* Create a voice manager and join a channel in one call.
|
|
128
|
-
*
|
|
281
|
+
* Create a voice manager and join a voice channel in one call.
|
|
282
|
+
*
|
|
283
|
+
* @param client - The Fluxer client instance
|
|
284
|
+
* @param channel - The voice channel to join
|
|
285
|
+
* @param options - Optional options; `shardId` for the gateway shard to use (default 0)
|
|
286
|
+
* @returns The voice connection (LiveKitRtcConnection when using LiveKit)
|
|
129
287
|
*/
|
|
130
288
|
declare function joinVoiceChannel(client: Client, channel: VoiceChannel, options?: {
|
|
131
289
|
shardId?: number;
|
|
132
290
|
}): Promise<VoiceConnectionLike>;
|
|
133
291
|
/**
|
|
134
292
|
* Get or create the VoiceManager for this client.
|
|
293
|
+
*
|
|
294
|
+
* @param client - The Fluxer client instance
|
|
295
|
+
* @param options - Optional options; `shardId` for the gateway shard to use (default 0)
|
|
135
296
|
*/
|
|
136
297
|
declare function getVoiceManager(client: Client, options?: {
|
|
137
298
|
shardId?: number;
|
|
138
299
|
}): VoiceManager;
|
|
139
300
|
|
|
140
|
-
export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
|
|
301
|
+
export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, type VideoPlayOptions, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ interface VoiceConnectionEvents {
|
|
|
7
7
|
error: [err: Error];
|
|
8
8
|
disconnect: [];
|
|
9
9
|
}
|
|
10
|
+
/** Voice connection using Discord's UDP-based protocol. Emits `ready`, `error`, `disconnect`. */
|
|
10
11
|
declare class VoiceConnection extends EventEmitter {
|
|
11
12
|
readonly client: Client;
|
|
12
13
|
readonly channel: VoiceChannel;
|
|
@@ -30,7 +31,9 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
30
31
|
private audioPacketQueue;
|
|
31
32
|
private pacingInterval;
|
|
32
33
|
constructor(client: Client, channel: VoiceChannel, userId: string);
|
|
34
|
+
/** Discord voice session ID. */
|
|
33
35
|
get sessionId(): string | null;
|
|
36
|
+
/** Whether audio is currently playing. */
|
|
34
37
|
get playing(): boolean;
|
|
35
38
|
/** Called when we have both server update and state update. */
|
|
36
39
|
connect(server: GatewayVoiceServerUpdateDispatchData, state: GatewayVoiceStateUpdateDispatchData): Promise<void>;
|
|
@@ -48,42 +51,152 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
48
51
|
*/
|
|
49
52
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
50
53
|
private sendAudioFrame;
|
|
54
|
+
/** Stop playback and clear the queue. */
|
|
51
55
|
stop(): void;
|
|
56
|
+
/** Disconnect from voice (closes WebSocket and UDP). */
|
|
52
57
|
disconnect(): void;
|
|
58
|
+
/** Disconnect and remove all listeners. */
|
|
53
59
|
destroy(): void;
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
/** LiveKit-specific: emitted when server sends leave (token expiry, server policy, etc.). Emitted before disconnect. */
|
|
57
63
|
type LiveKitRtcConnectionEvents = VoiceConnectionEvents & {
|
|
58
64
|
serverLeave: [];
|
|
65
|
+
/** Emitted when voice state should be synced (self_stream/self_video). VoiceManager listens. */
|
|
66
|
+
requestVoiceStateSync: [payload: {
|
|
67
|
+
self_stream?: boolean;
|
|
68
|
+
self_video?: boolean;
|
|
69
|
+
}];
|
|
59
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Options for video playback via {@link LiveKitRtcConnection.playVideo}.
|
|
73
|
+
*
|
|
74
|
+
* @property source - Track source hint sent to LiveKit. Use `'camera'` for typical video streams
|
|
75
|
+
* (default) or `'screenshare'` for screen-share-style content. Affects how clients may display the track.
|
|
76
|
+
* @property loop - When true (default), loops the video continuously to keep the stream live. Required for
|
|
77
|
+
* LiveKit: "stream it continuously for the benefit of participants joining after the initial frame."
|
|
78
|
+
* @property useFFmpeg - When true, use FFmpeg subprocess for decoding instead of node-webcodecs.
|
|
79
|
+
* Recommended when node-webcodecs causes libc++abi crashes on macOS. Requires ffmpeg in PATH.
|
|
80
|
+
* Also set via FLUXER_VIDEO_FFMPEG=1 env.
|
|
81
|
+
* @property videoBitrate - Max video bitrate in bps (default: 2_500_000). Higher values improve quality.
|
|
82
|
+
* @property maxFramerate - Max framerate for encoding (default: 60).
|
|
83
|
+
* @property width - Output width (default: source). FFmpeg path only.
|
|
84
|
+
* @property height - Output height (default: source). FFmpeg path only.
|
|
85
|
+
*/
|
|
86
|
+
interface VideoPlayOptions {
|
|
87
|
+
/** Track source hint - camera or screenshare (default: camera). */
|
|
88
|
+
source?: 'camera' | 'screenshare';
|
|
89
|
+
/** Loop video to keep stream continuously live (default: true). */
|
|
90
|
+
loop?: boolean;
|
|
91
|
+
/** Use FFmpeg for decoding (avoids node-webcodecs; requires ffmpeg in PATH). */
|
|
92
|
+
useFFmpeg?: boolean;
|
|
93
|
+
/** Max video bitrate in bps for encoding (default: 2_500_000). */
|
|
94
|
+
videoBitrate?: number;
|
|
95
|
+
/** Max framerate for encoding (default: 60). */
|
|
96
|
+
maxFramerate?: number;
|
|
97
|
+
/** Output width for resolution override (FFmpeg path). */
|
|
98
|
+
width?: number;
|
|
99
|
+
/** Output height for resolution override (FFmpeg path). */
|
|
100
|
+
height?: number;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Voice connection using LiveKit RTC. Used when Fluxer routes voice to LiveKit.
|
|
104
|
+
*
|
|
105
|
+
* Supports both audio playback ({@link play}) and video streaming ({@link playVideo}) to voice channels.
|
|
106
|
+
* Video uses node-webcodecs for decoding (no ffmpeg subprocess). Audio uses prism-media WebM demuxer.
|
|
107
|
+
*
|
|
108
|
+
* @emits ready - When connected to the LiveKit room and ready for playback
|
|
109
|
+
* @emits disconnect - When disconnected from the room
|
|
110
|
+
* @emits serverLeave - When LiveKit server signals leave (e.g. token expiry), before disconnect
|
|
111
|
+
* @emits error - On connection, playback, or decoding errors
|
|
112
|
+
*/
|
|
60
113
|
declare class LiveKitRtcConnection extends EventEmitter {
|
|
61
114
|
readonly client: Client;
|
|
62
115
|
readonly channel: VoiceChannel;
|
|
63
116
|
readonly guildId: string;
|
|
64
117
|
private _playing;
|
|
118
|
+
private _playingVideo;
|
|
65
119
|
private _destroyed;
|
|
66
120
|
private room;
|
|
67
121
|
private audioSource;
|
|
68
122
|
private audioTrack;
|
|
123
|
+
private videoSource;
|
|
124
|
+
private videoTrack;
|
|
69
125
|
private currentStream;
|
|
126
|
+
private currentVideoStream;
|
|
127
|
+
private _videoCleanup;
|
|
70
128
|
private lastServerEndpoint;
|
|
71
129
|
private lastServerToken;
|
|
72
130
|
private _disconnectEmitted;
|
|
131
|
+
/**
|
|
132
|
+
* @param client - The Fluxer client instance
|
|
133
|
+
* @param channel - The voice channel to connect to
|
|
134
|
+
* @param _userId - The user ID (reserved for future use)
|
|
135
|
+
*/
|
|
73
136
|
constructor(client: Client, channel: VoiceChannel, _userId: string);
|
|
137
|
+
/** Whether audio is currently playing. */
|
|
74
138
|
get playing(): boolean;
|
|
75
139
|
private debug;
|
|
76
140
|
private audioDebug;
|
|
77
141
|
private emitDisconnect;
|
|
78
142
|
/** Returns true if the LiveKit room is connected and not destroyed. */
|
|
79
143
|
isConnected(): boolean;
|
|
80
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* Returns true if we're already connected to the given server (skip migration).
|
|
146
|
+
* @param endpoint - Voice server endpoint from the gateway
|
|
147
|
+
* @param token - Voice server token
|
|
148
|
+
*/
|
|
81
149
|
isSameServer(endpoint: string | null, token: string): boolean;
|
|
82
150
|
playOpus(_stream: NodeJS.ReadableStream): void;
|
|
151
|
+
/**
|
|
152
|
+
* Connect to the LiveKit room using voice server and state from the gateway.
|
|
153
|
+
* Called internally by VoiceManager; typically not used directly.
|
|
154
|
+
*
|
|
155
|
+
* @param server - Voice server update data (endpoint, token)
|
|
156
|
+
* @param _state - Voice state update data (session, channel)
|
|
157
|
+
*/
|
|
83
158
|
connect(server: GatewayVoiceServerUpdateDispatchData, _state: GatewayVoiceStateUpdateDispatchData): Promise<void>;
|
|
159
|
+
/** Whether a video track is currently playing in the voice channel. */
|
|
160
|
+
get playingVideo(): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Play video from an MP4 URL or buffer. Streams decoded frames to the LiveKit room as a video track.
|
|
163
|
+
* Uses node-webcodecs for decoding (no ffmpeg). Supports H.264 (avc1) and H.265 (hvc1/hev1) codecs.
|
|
164
|
+
*
|
|
165
|
+
* @param urlOrBuffer - Video source: HTTP(S) URL to an MP4 file, or raw ArrayBuffer/Uint8Array of MP4 data
|
|
166
|
+
* @param options - Optional playback options (see {@link VideoPlayOptions})
|
|
167
|
+
* @emits error - On fetch failure, missing video track, or decode errors
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* const conn = await voiceManager.join(channel);
|
|
172
|
+
* if (conn instanceof LiveKitRtcConnection && conn.isConnected()) {
|
|
173
|
+
* await conn.playVideo('https://example.com/video.mp4', { source: 'camera' });
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
playVideo(urlOrBuffer: string | ArrayBuffer | Uint8Array, options?: VideoPlayOptions): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* FFmpeg-based video playback. Bypasses node-webcodecs to avoid libc++abi crashes on macOS.
|
|
180
|
+
* Requires ffmpeg and ffprobe in PATH. URL input only.
|
|
181
|
+
*/
|
|
182
|
+
private playVideoFFmpeg;
|
|
183
|
+
/**
|
|
184
|
+
* Play audio from a WebM/Opus URL or readable stream. Publishes to the LiveKit room as an audio track.
|
|
185
|
+
*
|
|
186
|
+
* @param urlOrStream - Audio source: HTTP(S) URL to a WebM/Opus file, or a Node.js ReadableStream
|
|
187
|
+
* @emits error - On fetch failure or decode errors
|
|
188
|
+
*/
|
|
84
189
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Stop video playback and unpublish the video track from the LiveKit room.
|
|
192
|
+
* Safe to call even when no video is playing.
|
|
193
|
+
*/
|
|
194
|
+
stopVideo(): void;
|
|
195
|
+
/** Stop playback and clear both audio and video tracks. */
|
|
85
196
|
stop(): void;
|
|
197
|
+
/** Disconnect from the LiveKit room and stop all playback. */
|
|
86
198
|
disconnect(): void;
|
|
199
|
+
/** Disconnect from the room and remove all event listeners. */
|
|
87
200
|
destroy(): void;
|
|
88
201
|
}
|
|
89
202
|
declare module 'events' {
|
|
@@ -95,46 +208,94 @@ declare module 'events' {
|
|
|
95
208
|
|
|
96
209
|
/** Maps guild_id -> user_id -> channel_id (null if not in voice). */
|
|
97
210
|
type VoiceStateMap = Map<string, Map<string, string | null>>;
|
|
211
|
+
/**
|
|
212
|
+
* Options for creating a VoiceManager.
|
|
213
|
+
*
|
|
214
|
+
* @property shardId - Gateway shard ID to use for voice connections (default 0).
|
|
215
|
+
* Use when the client runs multiple shards and you need to target a specific one.
|
|
216
|
+
*/
|
|
98
217
|
interface VoiceManagerOptions {
|
|
99
218
|
/** Gateway shard ID to use for voice (default 0). */
|
|
100
219
|
shardId?: number;
|
|
101
220
|
}
|
|
221
|
+
/** Manages voice connections. Use `getVoiceManager(client)` to obtain an instance. */
|
|
102
222
|
declare class VoiceManager extends EventEmitter {
|
|
103
223
|
readonly client: Client;
|
|
104
224
|
private readonly connections;
|
|
225
|
+
/** guild_id -> connection_id (from VoiceServerUpdate; required for voice state updates when in channel) */
|
|
226
|
+
private readonly connectionIds;
|
|
105
227
|
/** guild_id -> user_id -> channel_id */
|
|
106
228
|
readonly voiceStates: VoiceStateMap;
|
|
107
229
|
private readonly pending;
|
|
108
230
|
private readonly shardId;
|
|
109
231
|
constructor(client: Client, options?: VoiceManagerOptions);
|
|
110
232
|
private handleVoiceStatesSync;
|
|
111
|
-
/**
|
|
233
|
+
/**
|
|
234
|
+
* Get the voice channel ID the user is currently in, or null if not in voice.
|
|
235
|
+
* @param guildId - Guild ID to look up
|
|
236
|
+
* @param userId - User ID to look up
|
|
237
|
+
*/
|
|
112
238
|
getVoiceChannelId(guildId: string, userId: string): string | null;
|
|
113
239
|
private handleVoiceStateUpdate;
|
|
114
240
|
private handleVoiceServerUpdate;
|
|
241
|
+
private storeConnectionId;
|
|
115
242
|
private registerConnection;
|
|
243
|
+
/** Upload a placeholder stream preview so the preview URL returns 200 instead of 404. */
|
|
244
|
+
private uploadStreamPreview;
|
|
116
245
|
private tryCompletePending;
|
|
117
|
-
/**
|
|
246
|
+
/**
|
|
247
|
+
* Join a voice channel. Resolves when the connection is ready.
|
|
248
|
+
* @param channel - The voice channel to join
|
|
249
|
+
* @returns The voice connection (LiveKitRtcConnection when Fluxer uses LiveKit)
|
|
250
|
+
*/
|
|
118
251
|
join(channel: VoiceChannel): Promise<VoiceConnection | LiveKitRtcConnection>;
|
|
119
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* Leave a guild's voice channel and disconnect.
|
|
254
|
+
* @param guildId - Guild ID to leave
|
|
255
|
+
*/
|
|
120
256
|
leave(guildId: string): void;
|
|
257
|
+
/**
|
|
258
|
+
* Get the active voice connection for a guild, if any.
|
|
259
|
+
* @param guildId - Guild ID to look up
|
|
260
|
+
*/
|
|
121
261
|
getConnection(guildId: string): VoiceConnection | LiveKitRtcConnection | undefined;
|
|
262
|
+
/**
|
|
263
|
+
* Update voice state (e.g. self_stream, self_video) while in a channel.
|
|
264
|
+
* Sends a VoiceStateUpdate to the gateway so the server and clients see the change.
|
|
265
|
+
* Requires connection_id (from VoiceServerUpdate); without it, the gateway would treat
|
|
266
|
+
* the update as a new join and trigger a new VoiceServerUpdate, causing connection loops.
|
|
267
|
+
* @param guildId - Guild ID
|
|
268
|
+
* @param partial - Partial voice state to update (self_stream, self_video, self_mute, self_deaf)
|
|
269
|
+
*/
|
|
270
|
+
updateVoiceState(guildId: string, partial: {
|
|
271
|
+
self_stream?: boolean;
|
|
272
|
+
self_video?: boolean;
|
|
273
|
+
self_mute?: boolean;
|
|
274
|
+
self_deaf?: boolean;
|
|
275
|
+
}): void;
|
|
122
276
|
}
|
|
123
277
|
|
|
124
278
|
/** Union of connection types (Discord-style or LiveKit). */
|
|
125
279
|
type VoiceConnectionLike = VoiceConnection | LiveKitRtcConnection;
|
|
126
280
|
/**
|
|
127
|
-
* Create a voice manager and join a channel in one call.
|
|
128
|
-
*
|
|
281
|
+
* Create a voice manager and join a voice channel in one call.
|
|
282
|
+
*
|
|
283
|
+
* @param client - The Fluxer client instance
|
|
284
|
+
* @param channel - The voice channel to join
|
|
285
|
+
* @param options - Optional options; `shardId` for the gateway shard to use (default 0)
|
|
286
|
+
* @returns The voice connection (LiveKitRtcConnection when using LiveKit)
|
|
129
287
|
*/
|
|
130
288
|
declare function joinVoiceChannel(client: Client, channel: VoiceChannel, options?: {
|
|
131
289
|
shardId?: number;
|
|
132
290
|
}): Promise<VoiceConnectionLike>;
|
|
133
291
|
/**
|
|
134
292
|
* Get or create the VoiceManager for this client.
|
|
293
|
+
*
|
|
294
|
+
* @param client - The Fluxer client instance
|
|
295
|
+
* @param options - Optional options; `shardId` for the gateway shard to use (default 0)
|
|
135
296
|
*/
|
|
136
297
|
declare function getVoiceManager(client: Client, options?: {
|
|
137
298
|
shardId?: number;
|
|
138
299
|
}): VoiceManager;
|
|
139
300
|
|
|
140
|
-
export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
|
|
301
|
+
export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, type VideoPlayOptions, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
|