@fluxerjs/voice 1.0.6 → 1.0.8

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 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,153 @@ 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
- /** Returns true if we're already connected to the given server (skip migration). */
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
+ private _videoCleaning;
195
+ stopVideo(): void;
196
+ /** Stop playback and clear both audio and video tracks. */
85
197
  stop(): void;
198
+ /** Disconnect from the LiveKit room and stop all playback. */
86
199
  disconnect(): void;
200
+ /** Disconnect from the room and remove all event listeners. */
87
201
  destroy(): void;
88
202
  }
89
203
  declare module 'events' {
@@ -95,46 +209,94 @@ declare module 'events' {
95
209
 
96
210
  /** Maps guild_id -> user_id -> channel_id (null if not in voice). */
97
211
  type VoiceStateMap = Map<string, Map<string, string | null>>;
212
+ /**
213
+ * Options for creating a VoiceManager.
214
+ *
215
+ * @property shardId - Gateway shard ID to use for voice connections (default 0).
216
+ * Use when the client runs multiple shards and you need to target a specific one.
217
+ */
98
218
  interface VoiceManagerOptions {
99
219
  /** Gateway shard ID to use for voice (default 0). */
100
220
  shardId?: number;
101
221
  }
222
+ /** Manages voice connections. Use `getVoiceManager(client)` to obtain an instance. */
102
223
  declare class VoiceManager extends EventEmitter {
103
224
  readonly client: Client;
104
225
  private readonly connections;
226
+ /** guild_id -> connection_id (from VoiceServerUpdate; required for voice state updates when in channel) */
227
+ private readonly connectionIds;
105
228
  /** guild_id -> user_id -> channel_id */
106
229
  readonly voiceStates: VoiceStateMap;
107
230
  private readonly pending;
108
231
  private readonly shardId;
109
232
  constructor(client: Client, options?: VoiceManagerOptions);
110
233
  private handleVoiceStatesSync;
111
- /** Get the voice channel ID the user is in, or null. */
234
+ /**
235
+ * Get the voice channel ID the user is currently in, or null if not in voice.
236
+ * @param guildId - Guild ID to look up
237
+ * @param userId - User ID to look up
238
+ */
112
239
  getVoiceChannelId(guildId: string, userId: string): string | null;
113
240
  private handleVoiceStateUpdate;
114
241
  private handleVoiceServerUpdate;
242
+ private storeConnectionId;
115
243
  private registerConnection;
244
+ /** Upload a placeholder stream preview so the preview URL returns 200 instead of 404. */
245
+ private uploadStreamPreview;
116
246
  private tryCompletePending;
117
- /** Join a voice channel. Resolves when the connection is ready. */
247
+ /**
248
+ * Join a voice channel. Resolves when the connection is ready.
249
+ * @param channel - The voice channel to join
250
+ * @returns The voice connection (LiveKitRtcConnection when Fluxer uses LiveKit)
251
+ */
118
252
  join(channel: VoiceChannel): Promise<VoiceConnection | LiveKitRtcConnection>;
119
- /** Leave a guild's voice channel. */
253
+ /**
254
+ * Leave a guild's voice channel and disconnect.
255
+ * @param guildId - Guild ID to leave
256
+ */
120
257
  leave(guildId: string): void;
258
+ /**
259
+ * Get the active voice connection for a guild, if any.
260
+ * @param guildId - Guild ID to look up
261
+ */
121
262
  getConnection(guildId: string): VoiceConnection | LiveKitRtcConnection | undefined;
263
+ /**
264
+ * Update voice state (e.g. self_stream, self_video) while in a channel.
265
+ * Sends a VoiceStateUpdate to the gateway so the server and clients see the change.
266
+ * Requires connection_id (from VoiceServerUpdate); without it, the gateway would treat
267
+ * the update as a new join and trigger a new VoiceServerUpdate, causing connection loops.
268
+ * @param guildId - Guild ID
269
+ * @param partial - Partial voice state to update (self_stream, self_video, self_mute, self_deaf)
270
+ */
271
+ updateVoiceState(guildId: string, partial: {
272
+ self_stream?: boolean;
273
+ self_video?: boolean;
274
+ self_mute?: boolean;
275
+ self_deaf?: boolean;
276
+ }): void;
122
277
  }
123
278
 
124
279
  /** Union of connection types (Discord-style or LiveKit). */
125
280
  type VoiceConnectionLike = VoiceConnection | LiveKitRtcConnection;
126
281
  /**
127
- * Create a voice manager and join a channel in one call.
128
- * Uses the default shard (0).
282
+ * Create a voice manager and join a voice channel in one call.
283
+ *
284
+ * @param client - The Fluxer client instance
285
+ * @param channel - The voice channel to join
286
+ * @param options - Optional options; `shardId` for the gateway shard to use (default 0)
287
+ * @returns The voice connection (LiveKitRtcConnection when using LiveKit)
129
288
  */
130
289
  declare function joinVoiceChannel(client: Client, channel: VoiceChannel, options?: {
131
290
  shardId?: number;
132
291
  }): Promise<VoiceConnectionLike>;
133
292
  /**
134
293
  * Get or create the VoiceManager for this client.
294
+ *
295
+ * @param client - The Fluxer client instance
296
+ * @param options - Optional options; `shardId` for the gateway shard to use (default 0)
135
297
  */
136
298
  declare function getVoiceManager(client: Client, options?: {
137
299
  shardId?: number;
138
300
  }): VoiceManager;
139
301
 
140
- export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
302
+ 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,153 @@ 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
- /** Returns true if we're already connected to the given server (skip migration). */
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
+ private _videoCleaning;
195
+ stopVideo(): void;
196
+ /** Stop playback and clear both audio and video tracks. */
85
197
  stop(): void;
198
+ /** Disconnect from the LiveKit room and stop all playback. */
86
199
  disconnect(): void;
200
+ /** Disconnect from the room and remove all event listeners. */
87
201
  destroy(): void;
88
202
  }
89
203
  declare module 'events' {
@@ -95,46 +209,94 @@ declare module 'events' {
95
209
 
96
210
  /** Maps guild_id -> user_id -> channel_id (null if not in voice). */
97
211
  type VoiceStateMap = Map<string, Map<string, string | null>>;
212
+ /**
213
+ * Options for creating a VoiceManager.
214
+ *
215
+ * @property shardId - Gateway shard ID to use for voice connections (default 0).
216
+ * Use when the client runs multiple shards and you need to target a specific one.
217
+ */
98
218
  interface VoiceManagerOptions {
99
219
  /** Gateway shard ID to use for voice (default 0). */
100
220
  shardId?: number;
101
221
  }
222
+ /** Manages voice connections. Use `getVoiceManager(client)` to obtain an instance. */
102
223
  declare class VoiceManager extends EventEmitter {
103
224
  readonly client: Client;
104
225
  private readonly connections;
226
+ /** guild_id -> connection_id (from VoiceServerUpdate; required for voice state updates when in channel) */
227
+ private readonly connectionIds;
105
228
  /** guild_id -> user_id -> channel_id */
106
229
  readonly voiceStates: VoiceStateMap;
107
230
  private readonly pending;
108
231
  private readonly shardId;
109
232
  constructor(client: Client, options?: VoiceManagerOptions);
110
233
  private handleVoiceStatesSync;
111
- /** Get the voice channel ID the user is in, or null. */
234
+ /**
235
+ * Get the voice channel ID the user is currently in, or null if not in voice.
236
+ * @param guildId - Guild ID to look up
237
+ * @param userId - User ID to look up
238
+ */
112
239
  getVoiceChannelId(guildId: string, userId: string): string | null;
113
240
  private handleVoiceStateUpdate;
114
241
  private handleVoiceServerUpdate;
242
+ private storeConnectionId;
115
243
  private registerConnection;
244
+ /** Upload a placeholder stream preview so the preview URL returns 200 instead of 404. */
245
+ private uploadStreamPreview;
116
246
  private tryCompletePending;
117
- /** Join a voice channel. Resolves when the connection is ready. */
247
+ /**
248
+ * Join a voice channel. Resolves when the connection is ready.
249
+ * @param channel - The voice channel to join
250
+ * @returns The voice connection (LiveKitRtcConnection when Fluxer uses LiveKit)
251
+ */
118
252
  join(channel: VoiceChannel): Promise<VoiceConnection | LiveKitRtcConnection>;
119
- /** Leave a guild's voice channel. */
253
+ /**
254
+ * Leave a guild's voice channel and disconnect.
255
+ * @param guildId - Guild ID to leave
256
+ */
120
257
  leave(guildId: string): void;
258
+ /**
259
+ * Get the active voice connection for a guild, if any.
260
+ * @param guildId - Guild ID to look up
261
+ */
121
262
  getConnection(guildId: string): VoiceConnection | LiveKitRtcConnection | undefined;
263
+ /**
264
+ * Update voice state (e.g. self_stream, self_video) while in a channel.
265
+ * Sends a VoiceStateUpdate to the gateway so the server and clients see the change.
266
+ * Requires connection_id (from VoiceServerUpdate); without it, the gateway would treat
267
+ * the update as a new join and trigger a new VoiceServerUpdate, causing connection loops.
268
+ * @param guildId - Guild ID
269
+ * @param partial - Partial voice state to update (self_stream, self_video, self_mute, self_deaf)
270
+ */
271
+ updateVoiceState(guildId: string, partial: {
272
+ self_stream?: boolean;
273
+ self_video?: boolean;
274
+ self_mute?: boolean;
275
+ self_deaf?: boolean;
276
+ }): void;
122
277
  }
123
278
 
124
279
  /** Union of connection types (Discord-style or LiveKit). */
125
280
  type VoiceConnectionLike = VoiceConnection | LiveKitRtcConnection;
126
281
  /**
127
- * Create a voice manager and join a channel in one call.
128
- * Uses the default shard (0).
282
+ * Create a voice manager and join a voice channel in one call.
283
+ *
284
+ * @param client - The Fluxer client instance
285
+ * @param channel - The voice channel to join
286
+ * @param options - Optional options; `shardId` for the gateway shard to use (default 0)
287
+ * @returns The voice connection (LiveKitRtcConnection when using LiveKit)
129
288
  */
130
289
  declare function joinVoiceChannel(client: Client, channel: VoiceChannel, options?: {
131
290
  shardId?: number;
132
291
  }): Promise<VoiceConnectionLike>;
133
292
  /**
134
293
  * Get or create the VoiceManager for this client.
294
+ *
295
+ * @param client - The Fluxer client instance
296
+ * @param options - Optional options; `shardId` for the gateway shard to use (default 0)
135
297
  */
136
298
  declare function getVoiceManager(client: Client, options?: {
137
299
  shardId?: number;
138
300
  }): VoiceManager;
139
301
 
140
- export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };
302
+ export { LiveKitRtcConnection, type LiveKitRtcConnectionEvents, type VideoPlayOptions, VoiceConnection, type VoiceConnectionEvents, type VoiceConnectionLike, VoiceManager, type VoiceManagerOptions, type VoiceStateMap, getVoiceManager, joinVoiceChannel };