@harmonia-audio/voice 0.1.0
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.cjs +936 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +638 -0
- package/dist/index.d.ts +638 -0
- package/dist/index.js +919 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/encryption.ts","../src/errors.ts","../src/store.ts","../src/types.ts","../src/receiver.ts","../src/connection.ts","../src/player.ts","../src/join.ts","../src/resource.ts"],"names":["EncryptionMode","VoiceConnectionState","AudioPlayerState","parseRtpHeader","EventEmitter","buildRtpHeader","Readable"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tsecretboxEncrypt,\n\tsecretboxDecrypt,\n\txchacha20Encrypt,\n\txchacha20Decrypt,\n\trandomBytes,\n\tbuildRtpHeader,\n\tparseRtpHeader,\n\ttype RtpHeader as NativeRtpHeader,\n} from \"@harmonia-audio/native\";\n\nconst NONCE_SIZE_XSALSA20 = 24;\nconst NONCE_SIZE_LITE = 4;\n\n/**\n * Available encryption modes for voice connections.\n *\n * @example\n * ```ts\n * connection.setEncryptionMode(EncryptionMode.XSalsa20Poly1305);\n * ```\n */\nexport enum EncryptionMode {\n\tXSalsa20Poly1305 = \"xsalsa20_poly1305\",\n\tXSalsa20Poly1305Suffix = \"xsalsa20_poly1305_suffix\",\n\tXSalsa20Poly1305Lite = \"xsalsa20_poly1305_lite\",\n\tAeadAes256Gcm = \"aead_aes256_gcm\",\n\tAeadXChaCha20Poly1305 = \"aead_xchacha20_poly1305_rtpsize\",\n}\n\n/** Parsed RTP packet. */\nexport interface RtpPacket {\n\theader: NativeRtpHeader;\n\tpayload: Buffer;\n\tnonce: Buffer;\n}\n\nconst PREFERRED_MODES: EncryptionMode[] = [\n\tEncryptionMode.AeadXChaCha20Poly1305,\n\tEncryptionMode.AeadAes256Gcm,\n\tEncryptionMode.XSalsa20Poly1305Lite,\n\tEncryptionMode.XSalsa20Poly1305Suffix,\n\tEncryptionMode.XSalsa20Poly1305,\n];\n\n/**\n * Select the best available encryption mode from a list of supported modes.\n *\n * @example\n * ```ts\n * const mode = selectEncryptionMode(['xsalsa20_poly1305', 'xsalsa20_poly1305_suffix']);\n * ```\n */\nexport function selectEncryptionMode(\n\tavailable: readonly string[],\n): EncryptionMode {\n\tfor (const preferred of PREFERRED_MODES) {\n\t\tif (available.includes(preferred)) {\n\t\t\treturn preferred;\n\t\t}\n\t}\n\tconst first = available[0];\n\tif (first !== undefined) {\n\t\treturn first as EncryptionMode;\n\t}\n\treturn EncryptionMode.XSalsa20Poly1305;\n}\n\n/**\n * Encrypt an RTP payload.\n *\n * @example\n * ```ts\n * const encrypted = encryptOpusPacket(header, payload, key, mode, nonceCounter);\n * ```\n */\nexport function encryptOpusPacket(\n\trtpHeader: Buffer,\n\tpayload: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n\tnonceCounter: number,\n): Buffer {\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = randomBytes(NONCE_SIZE_XSALSA20);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonce]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\tconst nonceAppend = Buffer.alloc(NONCE_SIZE_LITE);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = xchacha20Encrypt(payload, nonce, secretKey, rtpHeader);\n\t\t\tconst nonceAppend = Buffer.alloc(4);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tdefault:\n\t\t\treturn Buffer.concat([rtpHeader, payload]);\n\t}\n}\n\n/**\n * Decrypt an RTP packet payload.\n *\n * @example\n * ```ts\n * const decrypted = decryptOpusPacket(packet, secretKey, mode);\n * ```\n */\nexport function decryptOpusPacket(\n\tpacket: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n): Buffer {\n\tconst rtpHeader = packet.subarray(0, 12);\n\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst ciphertext = packet.subarray(12);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = packet.subarray(packet.length - NONCE_SIZE_XSALSA20);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_XSALSA20);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - NONCE_SIZE_LITE);\n\t\t\tnonceFragment.copy(nonce, 0, 0, NONCE_SIZE_LITE);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_LITE);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - 4);\n\t\t\tnonceFragment.copy(nonce, 0, 0, 4);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - 4);\n\t\t\treturn xchacha20Decrypt(ciphertext, nonce, secretKey, rtpHeader);\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn packet.subarray(12);\n\t\t}\n\t}\n}\n","/**\n * Error class for all voice-related errors in harmonia.\n *\n * @example\n * ```ts\n * try {\n * await connection.connect();\n * } catch (error) {\n * if (error instanceof HarmoniaVoiceError) {\n * console.error(error.code);\n * }\n * }\n * ```\n */\nexport class HarmoniaVoiceError extends Error {\n\tpublic readonly code: string;\n\tpublic readonly context: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"HarmoniaVoiceError\";\n\t\tthis.code = code;\n\t\tthis.context = context;\n\t}\n}\n","import type { VoiceConnection } from \"./connection.js\";\n\nconst connections = new Map<string, VoiceConnection>();\n\n/**\n * Get a voice connection by guild ID.\n *\n * @example\n * ```ts\n * const connection = getVoiceConnection('guild-id');\n * ```\n */\nexport function getVoiceConnection(guildId: string): VoiceConnection | undefined {\n\treturn connections.get(guildId);\n}\n\n/**\n * Get all active voice connections.\n *\n * @example\n * ```ts\n * const all = getVoiceConnections();\n * ```\n */\nexport function getVoiceConnections(): ReadonlyMap<string, VoiceConnection> {\n\treturn connections;\n}\n\n/** @internal */\nexport function setVoiceConnection(guildId: string, connection: VoiceConnection): void {\n\tconnections.set(guildId, connection);\n}\n\n/** @internal */\nexport function removeVoiceConnection(guildId: string): void {\n\tconnections.delete(guildId);\n}\n","import type { EventEmitter } from \"node:events\";\n\n/**\n * Voice connection states.\n *\n * @example\n * ```ts\n * if (connection.state === VoiceConnectionState.Ready) {\n * // connection is ready\n * }\n * ```\n */\nexport enum VoiceConnectionState {\n\tIdle = \"idle\",\n\tSignalling = \"signalling\",\n\tConnecting = \"connecting\",\n\tReady = \"ready\",\n\tResuming = \"resuming\",\n\tDisconnected = \"disconnected\",\n\tDestroyed = \"destroyed\",\n}\n\n/**\n * Audio player states.\n *\n * @example\n * ```ts\n * if (player.state === AudioPlayerState.Playing) {\n * player.pause();\n * }\n * ```\n */\nexport enum AudioPlayerState {\n\tIdle = \"idle\",\n\tBuffering = \"buffering\",\n\tPlaying = \"playing\",\n\tPaused = \"paused\",\n\tAutoPaused = \"autopaused\",\n}\n\n/**\n * Events emitted by a voice connection.\n *\n * @example\n * ```ts\n * connection.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface VoiceConnectionEvents {\n\tstateChange: [oldState: VoiceConnectionState, newState: VoiceConnectionState];\n\tready: [];\n\tdisconnected: [];\n\tdestroyed: [];\n\terror: [error: Error];\n}\n\n/**\n * Events emitted by an audio player.\n *\n * @example\n * ```ts\n * player.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface AudioPlayerEvents {\n\tstateChange: [oldState: AudioPlayerState, newState: AudioPlayerState];\n\tidle: [];\n\terror: [error: Error];\n}\n","import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { OpusDecoder } from \"@harmonia-audio/codec\";\nimport { parseRtpHeader } from \"@harmonia-audio/native\";\nimport type { VoiceConnection } from \"./connection.js\";\n\n/**\n * Options for the audio receiver.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * ```\n */\nexport interface AudioReceiverOptions {\n\treadonly autoDecodeOpus?: boolean;\n}\n\ninterface SsrcState {\n\tuserId: string | undefined;\n\tdecoder: OpusDecoder;\n\tstream: UserAudioStream;\n}\n\n/**\n * A readable stream of audio from a specific user.\n *\n * @example\n * ```ts\n * const stream = receiver.subscribe('user-id');\n * stream.on('data', (pcm) => { ... });\n * ```\n */\nexport class UserAudioStream extends Readable {\n\tpublic readonly userId: string;\n\n\tconstructor(userId: string) {\n\t\tsuper({ objectMode: false });\n\t\tthis.userId = userId;\n\t}\n\n\toverride _read(): void {\n\t\t// Data is pushed from the receiver\n\t}\n}\n\n/**\n * Receives and routes incoming audio from voice connections.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * const stream = receiver.subscribe('user-id');\n *\n * stream.on('data', (pcm: Buffer) => {\n * // Process received audio\n * });\n * ```\n */\nexport class AudioReceiver extends EventEmitter {\n\tprivate readonly connection: VoiceConnection;\n\tprivate readonly ssrcMap = new Map<number, SsrcState>();\n\tprivate readonly userSsrcMap = new Map<string, number>();\n\tprivate readonly subscriptions = new Map<string, UserAudioStream>();\n\n\tconstructor(connection: VoiceConnection) {\n\t\tsuper();\n\t\tthis.connection = connection;\n\t}\n\n\t/**\n\t * Subscribe to audio from a specific user.\n\t *\n\t * @param userId - The Discord user ID to receive audio from\n\t * @returns A readable stream of PCM audio from that user\n\t *\n\t * @example\n\t * ```ts\n\t * const stream = receiver.subscribe('123456789');\n\t * stream.pipe(fileWriteStream);\n\t * ```\n\t */\n\tsubscribe(userId: string): UserAudioStream {\n\t\tconst existing = this.subscriptions.get(userId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst stream = new UserAudioStream(userId);\n\t\tthis.subscriptions.set(userId, stream);\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.subscriptions.delete(userId);\n\t\t});\n\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Unsubscribe from a user's audio.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.unsubscribe('123456789');\n\t * ```\n\t */\n\tunsubscribe(userId: string): void {\n\t\tconst stream = this.subscriptions.get(userId);\n\t\tif (stream) {\n\t\t\tstream.destroy();\n\t\t\tthis.subscriptions.delete(userId);\n\t\t}\n\t}\n\n\t/** @internal */\n\tmapSsrcToUser(ssrc: number, userId: string): void {\n\t\tlet state = this.ssrcMap.get(ssrc);\n\t\tif (!state) {\n\t\t\tstate = {\n\t\t\t\tuserId,\n\t\t\t\tdecoder: new OpusDecoder({ sampleRate: 48000, channels: 2 }),\n\t\t\t\tstream: new UserAudioStream(userId),\n\t\t\t};\n\t\t\tthis.ssrcMap.set(ssrc, state);\n\t\t} else {\n\t\t\tstate.userId = userId;\n\t\t}\n\t\tthis.userSsrcMap.set(userId, ssrc);\n\t\tthis.emit(\"userConnected\", userId, ssrc);\n\t}\n\n\t/** @internal */\n\tremoveUser(userId: string): void {\n\t\tconst ssrc = this.userSsrcMap.get(userId);\n\t\tif (ssrc !== undefined) {\n\t\t\tconst state = this.ssrcMap.get(ssrc);\n\t\t\tif (state) {\n\t\t\t\tstate.stream.destroy();\n\t\t\t\tthis.ssrcMap.delete(ssrc);\n\t\t\t}\n\t\t\tthis.userSsrcMap.delete(userId);\n\t\t}\n\t\tthis.subscriptions.get(userId)?.destroy();\n\t\tthis.subscriptions.delete(userId);\n\t\tthis.emit(\"userDisconnected\", userId);\n\t}\n\n\t/** @internal */\n\thandlePacket(rawPacket: Buffer, decryptedPayload: Buffer): void {\n\t\ttry {\n\t\t\tconst header = parseRtpHeader(rawPacket);\n\t\t\tconst state = this.ssrcMap.get(header.ssrc);\n\n\t\t\tif (!state?.userId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pcm = state.decoder.decode(decryptedPayload);\n\n\t\t\tconst subscription = this.subscriptions.get(state.userId);\n\t\t\tif (subscription && !subscription.destroyed) {\n\t\t\t\tsubscription.push(pcm);\n\t\t\t}\n\n\t\t\tthis.emit(\"audio\", state.userId, pcm, header);\n\t\t} catch {\n\t\t\t// Silently drop malformed packets\n\t\t}\n\t}\n\n\t/**\n\t * Destroy all streams and clean up.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.destroy();\n\t * ```\n\t */\n\tdestroy(): this {\n\t\tfor (const [, stream] of this.subscriptions) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.subscriptions.clear();\n\t\tthis.ssrcMap.clear();\n\t\tthis.userSsrcMap.clear();\n\t\treturn this;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport dgram from \"node:dgram\";\nimport WebSocket from \"ws\";\nimport {\n\tbuildRtpHeader,\n\tconfigureSocketForAudio,\n\tAudioThread as NativeAudioThread,\n\tAudioRingBuffer,\n} from \"@harmonia-audio/native\";\nimport { OpusEncoder } from \"@harmonia-audio/codec\";\nimport type {\n\tDiscordGatewayAdapter,\n\tDiscordGatewayAdapterCreator,\n\tVoiceServerUpdateData,\n\tVoiceStateUpdateData,\n} from \"./adapter.js\";\nimport {\n\tencryptOpusPacket,\n\tEncryptionMode,\n\tselectEncryptionMode,\n\tdecryptOpusPacket,\n} from \"./encryption.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\nimport { removeVoiceConnection, setVoiceConnection } from \"./store.js\";\nimport { VoiceConnectionState, type VoiceConnectionEvents } from \"./types.js\";\nimport type { AudioPlayer } from \"./player.js\";\nimport { AudioReceiver } from \"./receiver.js\";\n\nconst VOICE_GATEWAY_VERSION = 8;\nconst HEARTBEAT_MAX_MISSED = 3;\nconst IP_DISCOVERY_PACKET_SIZE = 74;\n\n/**\n * Options for creating a voice connection.\n *\n * @example\n * ```ts\n * const options: VoiceConnectionOptions = {\n * guildId: '123456789',\n * channelId: '987654321',\n * selfDeaf: false,\n * selfMute: false,\n * };\n * ```\n */\nexport interface VoiceConnectionOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\ninterface VoiceGatewayReady {\n\tssrc: number;\n\tip: string;\n\tport: number;\n\tmodes: string[];\n}\n\n/**\n * Manages a voice connection to a Discord voice channel.\n *\n * @example\n * ```ts\n * import { VoiceConnection } from '@harmonia/voice';\n *\n * const connection = new VoiceConnection({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n *\n * connection.on('ready', () => {\n * console.log('Connected to voice!');\n * });\n * ```\n */\nexport class VoiceConnection extends EventEmitter {\n\tprivate _state: VoiceConnectionState = VoiceConnectionState.Idle;\n\tprivate readonly guildId: string;\n\tprivate channelId: string;\n\tprivate readonly selfDeaf: boolean;\n\tprivate readonly selfMute: boolean;\n\tprivate adapter: DiscordGatewayAdapter | undefined;\n\n\tprivate sessionId: string | undefined;\n\tprivate voiceToken: string | undefined;\n\tprivate endpoint: string | undefined;\n\n\tprivate ws: WebSocket | undefined;\n\tprivate udpSocket: dgram.Socket | undefined;\n\tprivate ssrc = 0;\n\tprivate remoteIp = \"\";\n\tprivate remotePort = 0;\n\tprivate localIp = \"\";\n\tprivate localPort = 0;\n\tprivate secretKey: Buffer | undefined;\n\tprivate encryptionMode: EncryptionMode = EncryptionMode.XSalsa20Poly1305;\n\tprivate sequence = 0;\n\tprivate timestamp = 0;\n\tprivate nonceCounter = 0;\n\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n\tprivate heartbeatNonce = 0;\n\tprivate missedHeartbeats = 0;\n\tprivate lastHeartbeatAck = 0;\n\n\tprivate subscribedPlayer: AudioPlayer | undefined;\n\tprivate audioThread: NativeAudioThread | undefined;\n\tprivate ringBuffer: AudioRingBuffer | undefined;\n\n\tprivate readonly receiver: AudioReceiver;\n\n\tprivate voiceStateResolve: (() => void) | undefined;\n\tprivate voiceServerResolve: (() => void) | undefined;\n\n\tconstructor(options: VoiceConnectionOptions) {\n\t\tsuper();\n\t\tthis.guildId = options.guildId;\n\t\tthis.channelId = options.channelId;\n\t\tthis.selfDeaf = options.selfDeaf ?? false;\n\t\tthis.selfMute = options.selfMute ?? false;\n\t\tthis.receiver = new AudioReceiver(this);\n\n\t\tthis.adapter = options.adapterCreator({\n\t\t\tonVoiceStateUpdate: (data) => this.handleVoiceStateUpdate(data),\n\t\t\tonVoiceServerUpdate: (data) => this.handleVoiceServerUpdate(data),\n\t\t\tdestroy: () => this.destroy(),\n\t\t});\n\n\t\tsetVoiceConnection(this.guildId, this);\n\t\tthis.sendVoiceStateUpdate();\n\t}\n\n\t/**\n\t * Current connection state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (connection.state === VoiceConnectionState.Ready) { ... }\n\t * ```\n\t */\n\tget state(): VoiceConnectionState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Get the audio receiver for this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * const receiver = connection.getReceiver();\n\t * ```\n\t */\n\tgetReceiver(): AudioReceiver {\n\t\treturn this.receiver;\n\t}\n\n\t/**\n\t * Subscribe an audio player to this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.subscribe(player);\n\t * ```\n\t */\n\tsubscribe(player: AudioPlayer): void {\n\t\tthis.subscribedPlayer = player;\n\t}\n\n\t/**\n\t * Unsubscribe the current audio player.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.unsubscribe();\n\t * ```\n\t */\n\tunsubscribe(): void {\n\t\tthis.subscribedPlayer = undefined;\n\t}\n\n\t/**\n\t * Destroy the connection and clean up all resources.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tif (this._state === VoiceConnectionState.Destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Destroyed);\n\t\tthis.cleanup();\n\t\tremoveVoiceConnection(this.guildId);\n\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.sendPayload({\n\t\t\t\top: 4,\n\t\t\t\td: {\n\t\t\t\t\tguild_id: this.guildId,\n\t\t\t\t\tchannel_id: null,\n\t\t\t\t\tself_mute: false,\n\t\t\t\t\tself_deaf: false,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.adapter.destroy();\n\t\t\tthis.adapter = undefined;\n\t\t}\n\n\t\tthis.emit(\"destroyed\");\n\t}\n\n\t/**\n\t * Send an Opus packet through the voice connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.sendOpusPacket(opusBuffer);\n\t * ```\n\t */\n\tsendOpusPacket(opusPacket: Buffer): void {\n\t\tif (this._state !== VoiceConnectionState.Ready) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.secretKey || !this.udpSocket) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst header = buildRtpHeader(this.sequence, this.timestamp, this.ssrc, 0x78);\n\n\t\tconst encrypted = encryptOpusPacket(\n\t\t\theader,\n\t\t\topusPacket,\n\t\t\tthis.secretKey,\n\t\t\tthis.encryptionMode,\n\t\t\tthis.nonceCounter,\n\t\t);\n\n\t\tthis.udpSocket.send(encrypted, this.remotePort, this.remoteIp);\n\n\t\tthis.sequence = (this.sequence + 1) & 0xFFFF;\n\t\tthis.timestamp = (this.timestamp + 960) >>> 0;\n\t\tthis.nonceCounter = (this.nonceCounter + 1) >>> 0;\n\t}\n\n\tprivate sendVoiceStateUpdate(): void {\n\t\tthis.transitionTo(VoiceConnectionState.Signalling);\n\n\t\tthis.adapter?.sendPayload({\n\t\t\top: 4,\n\t\t\td: {\n\t\t\t\tguild_id: this.guildId,\n\t\t\t\tchannel_id: this.channelId,\n\t\t\t\tself_mute: this.selfMute,\n\t\t\t\tself_deaf: this.selfDeaf,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleVoiceStateUpdate(data: VoiceStateUpdateData): void {\n\t\tthis.sessionId = data.session_id;\n\t\tif (this.voiceStateResolve) {\n\t\t\tthis.voiceStateResolve();\n\t\t\tthis.voiceStateResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate handleVoiceServerUpdate(data: VoiceServerUpdateData): void {\n\t\tthis.voiceToken = data.token;\n\t\tthis.endpoint = data.endpoint ?? undefined;\n\t\tif (this.voiceServerResolve) {\n\t\t\tthis.voiceServerResolve();\n\t\t\tthis.voiceServerResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate tryConnect(): void {\n\t\tif (!this.sessionId || !this.voiceToken || !this.endpoint) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Connecting);\n\t\tthis.connectWebSocket();\n\t}\n\n\tprivate connectWebSocket(): void {\n\t\tconst wsUrl = `wss://${this.endpoint}/?v=${VOICE_GATEWAY_VERSION}`;\n\n\t\tthis.ws?.close();\n\t\tthis.ws = new WebSocket(wsUrl);\n\n\t\tthis.ws.on(\"open\", () => {\n\t\t\tthis.sendIdentify();\n\t\t});\n\n\t\tthis.ws.on(\"message\", (raw: WebSocket.Data) => {\n\t\t\tconst data = JSON.parse(raw.toString()) as {\n\t\t\t\top: number;\n\t\t\t\td: Record<string, unknown>;\n\t\t\t};\n\t\t\tthis.handleGatewayMessage(data.op, data.d);\n\t\t});\n\n\t\tthis.ws.on(\"close\", (code: number) => {\n\t\t\tthis.stopHeartbeat();\n\t\t\tif (this._state !== VoiceConnectionState.Destroyed) {\n\t\t\t\tif (code === 4014 || code === 4006) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Disconnected);\n\t\t\t\t\tthis.emit(\"disconnected\");\n\t\t\t\t} else if (this._state !== VoiceConnectionState.Disconnected) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Resuming);\n\t\t\t\t\tsetTimeout(() => this.connectWebSocket(), 1000);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.ws.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tprivate sendIdentify(): void {\n\t\tthis.wsSend(0, {\n\t\t\tserver_id: this.guildId,\n\t\t\tuser_id: \"\", // filled by adapter\n\t\t\tsession_id: this.sessionId,\n\t\t\ttoken: this.voiceToken,\n\t\t});\n\t}\n\n\tprivate handleGatewayMessage(op: number, d: Record<string, unknown>): void {\n\t\tswitch (op) {\n\t\t\tcase 2: // READY\n\t\t\t\tthis.handleReady(d as unknown as VoiceGatewayReady);\n\t\t\t\tbreak;\n\t\t\tcase 4: // SESSION_DESCRIPTION\n\t\t\t\tthis.handleSessionDescription(d);\n\t\t\t\tbreak;\n\t\t\tcase 5: // SPEAKING\n\t\t\t\tthis.handleSpeaking(d);\n\t\t\t\tbreak;\n\t\t\tcase 6: // HEARTBEAT_ACK\n\t\t\t\tthis.handleHeartbeatAck(d);\n\t\t\t\tbreak;\n\t\t\tcase 8: // HELLO\n\t\t\t\tthis.handleHello(d);\n\t\t\t\tbreak;\n\t\t\tcase 9: // RESUMED\n\t\t\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\t\t\tbreak;\n\t\t\tcase 12: // CLIENT_CONNECT\n\t\t\t\tthis.handleClientConnect(d);\n\t\t\t\tbreak;\n\t\t\tcase 13: // CLIENT_DISCONNECT\n\t\t\t\tthis.handleClientDisconnect(d);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleReady(data: VoiceGatewayReady): void {\n\t\tthis.ssrc = data.ssrc;\n\t\tthis.remoteIp = data.ip;\n\t\tthis.remotePort = data.port;\n\n\t\tthis.encryptionMode = selectEncryptionMode(data.modes);\n\t\tthis.connectUdp();\n\t}\n\n\tprivate connectUdp(): void {\n\t\tthis.udpSocket?.close();\n\t\tthis.udpSocket = dgram.createSocket(\"udp4\");\n\n\t\tthis.udpSocket.on(\"message\", (msg: Buffer) => {\n\t\t\tthis.handleUdpMessage(msg);\n\t\t});\n\n\t\tthis.udpSocket.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\n\t\tthis.udpSocket.bind(0, () => {\n\t\t\tconst address = this.udpSocket?.address();\n\t\t\tif (address) {\n\t\t\t\tthis.localPort = address.port;\n\n\t\t\t\t// Configure socket for low-latency audio\n\t\t\t\tconst fd = (this.udpSocket as unknown as { _handle: { fd: number } })?._handle?.fd;\n\t\t\t\tif (typeof fd === \"number\" && fd >= 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconfigureSocketForAudio(fd);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Non-critical, continue without socket tuning\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.performIpDiscovery();\n\t\t});\n\t}\n\n\tprivate performIpDiscovery(): void {\n\t\tconst discoveryPacket = Buffer.alloc(IP_DISCOVERY_PACKET_SIZE);\n\t\tdiscoveryPacket.writeUInt16BE(0x1, 0); // Type: request\n\t\tdiscoveryPacket.writeUInt16BE(70, 2); // Length\n\t\tdiscoveryPacket.writeUInt32BE(this.ssrc, 4);\n\n\t\tthis.udpSocket?.send(\n\t\t\tdiscoveryPacket,\n\t\t\tthis.remotePort,\n\t\t\tthis.remoteIp,\n\t\t);\n\t}\n\n\tprivate handleUdpMessage(msg: Buffer): void {\n\t\tif (msg.length === IP_DISCOVERY_PACKET_SIZE) {\n\t\t\tthis.handleIpDiscoveryResponse(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Incoming audio packet\n\t\tif (msg.length > 12 && this.secretKey) {\n\t\t\ttry {\n\t\t\t\tconst decrypted = decryptOpusPacket(msg, this.secretKey, this.encryptionMode);\n\t\t\t\tthis.receiver.handlePacket(msg, decrypted);\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed packets\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleIpDiscoveryResponse(response: Buffer): void {\n\t\t// Extract IP (null-terminated string starting at offset 8)\n\t\tconst ipEnd = response.indexOf(0, 8);\n\t\tthis.localIp = response.subarray(8, ipEnd > 8 ? ipEnd : 72).toString(\"utf8\").replace(/\\0/g, \"\");\n\t\tthis.localPort = response.readUInt16BE(72);\n\n\t\t// Send select protocol\n\t\tthis.wsSend(1, {\n\t\t\tprotocol: \"udp\",\n\t\t\tdata: {\n\t\t\t\taddress: this.localIp,\n\t\t\t\tport: this.localPort,\n\t\t\t\tmode: this.encryptionMode,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleSessionDescription(d: Record<string, unknown>): void {\n\t\tconst keyArray = d[\"secret_key\"] as number[];\n\t\tthis.secretKey = Buffer.from(keyArray);\n\t\tthis.encryptionMode = (d[\"mode\"] as string) as EncryptionMode;\n\n\t\tthis.sequence = 0;\n\t\tthis.timestamp = 0;\n\t\tthis.nonceCounter = 0;\n\n\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\tthis.emit(\"ready\");\n\n\t\t// Send speaking\n\t\tthis.setSpeaking(1);\n\t}\n\n\tprivate handleSpeaking(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst ssrc = d[\"ssrc\"] as number;\n\t\tthis.receiver.mapSsrcToUser(ssrc, userId);\n\t}\n\n\tprivate handleClientConnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst audioSsrc = d[\"audio_ssrc\"] as number;\n\t\tif (audioSsrc) {\n\t\t\tthis.receiver.mapSsrcToUser(audioSsrc, userId);\n\t\t}\n\t}\n\n\tprivate handleClientDisconnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tthis.receiver.removeUser(userId);\n\t}\n\n\tprivate handleHello(d: Record<string, unknown>): void {\n\t\tconst interval = d[\"heartbeat_interval\"] as number;\n\t\tthis.startHeartbeat(interval);\n\t}\n\n\tprivate handleHeartbeatAck(_d: Record<string, unknown>): void {\n\t\tthis.missedHeartbeats = 0;\n\t\tthis.lastHeartbeatAck = Date.now();\n\t}\n\n\tprivate startHeartbeat(intervalMs: number): void {\n\t\tthis.stopHeartbeat();\n\t\tthis.missedHeartbeats = 0;\n\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.missedHeartbeats >= HEARTBEAT_MAX_MISSED) {\n\t\t\t\tthis.ws?.close(4009);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.heartbeatNonce = Date.now();\n\t\t\tthis.wsSend(3, this.heartbeatNonce);\n\t\t\tthis.missedHeartbeats++;\n\t\t}, intervalMs);\n\t}\n\n\tprivate stopHeartbeat(): void {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Set the speaking flags.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.setSpeaking(1); // speaking\n\t * ```\n\t */\n\tsetSpeaking(flags: number): void {\n\t\tthis.wsSend(5, {\n\t\t\tspeaking: flags,\n\t\t\tdelay: 0,\n\t\t\tssrc: this.ssrc,\n\t\t});\n\t}\n\n\tprivate wsSend(op: number, d: unknown): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify({ op, d }));\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: VoiceConnectionState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.stopHeartbeat();\n\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\n\t\tif (this.ws) {\n\t\t\tthis.ws.removeAllListeners();\n\t\t\tthis.ws.close();\n\t\t\tthis.ws = undefined;\n\t\t}\n\n\t\tif (this.udpSocket) {\n\t\t\tthis.udpSocket.removeAllListeners();\n\t\t\tthis.udpSocket.close();\n\t\t\tthis.udpSocket = undefined;\n\t\t}\n\n\t\tthis.secretKey = undefined;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport { AudioPlayerState, type AudioPlayerEvents } from \"./types.js\";\nimport type { VoiceConnection } from \"./connection.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\n\n/** Represents a playable audio source. */\nexport interface PlayableResource {\n\tread(): Buffer | null;\n\treadonly ended: boolean;\n\tdestroy(): void;\n}\n\n/**\n * Options for creating an audio player.\n *\n * @example\n * ```ts\n * const player = new AudioPlayer({ noSubscriber: 'pause' });\n * ```\n */\nexport interface AudioPlayerOptions {\n\treadonly noSubscriber?: \"pause\" | \"stop\" | \"play\";\n}\n\n/**\n * Plays audio resources and dispatches packets to voice connections.\n *\n * @example\n * ```ts\n * import { AudioPlayer } from '@harmonia/voice';\n *\n * const player = new AudioPlayer();\n * player.play(resource);\n *\n * player.on('idle', () => {\n * console.log('Playback finished');\n * });\n * ```\n */\nexport class AudioPlayer extends EventEmitter {\n\tprivate _state: AudioPlayerState = AudioPlayerState.Idle;\n\tprivate resource: PlayableResource | undefined;\n\tprivate connections: Set<VoiceConnection> = new Set();\n\tprivate playbackTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate readonly noSubscriberBehavior: \"pause\" | \"stop\" | \"play\";\n\n\tconstructor(options: AudioPlayerOptions = {}) {\n\t\tsuper();\n\t\tthis.noSubscriberBehavior = options.noSubscriber ?? \"pause\";\n\t}\n\n\t/**\n\t * Current player state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (player.state === AudioPlayerState.Playing) { ... }\n\t * ```\n\t */\n\tget state(): AudioPlayerState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Start playing an audio resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.play(audioResource);\n\t * ```\n\t */\n\tplay(resource: PlayableResource): void {\n\t\tthis.stopInternal();\n\t\tthis.resource = resource;\n\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\tthis.startPlaybackLoop();\n\t}\n\n\t/**\n\t * Pause playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.pause();\n\t * ```\n\t */\n\tpause(): void {\n\t\tif (this._state === AudioPlayerState.Playing) {\n\t\t\tthis.transitionTo(AudioPlayerState.Paused);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.resume();\n\t * ```\n\t */\n\tresume(): void {\n\t\tif (\n\t\t\tthis._state === AudioPlayerState.Paused ||\n\t\t\tthis._state === AudioPlayerState.AutoPaused\n\t\t) {\n\t\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\t}\n\t}\n\n\t/**\n\t * Stop playback and release the resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.stop();\n\t * ```\n\t */\n\tstop(): void {\n\t\tthis.stopInternal();\n\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\tthis.emit(\"idle\");\n\t}\n\n\t/** @internal */\n\taddConnection(connection: VoiceConnection): void {\n\t\tthis.connections.add(connection);\n\t}\n\n\t/** @internal */\n\tremoveConnection(connection: VoiceConnection): void {\n\t\tthis.connections.delete(connection);\n\t}\n\n\tprivate startPlaybackLoop(): void {\n\t\tthis.playbackTimer = setInterval(() => {\n\t\t\tthis.processFrame();\n\t\t}, 20);\n\t}\n\n\tprivate processFrame(): void {\n\t\tif (this._state !== AudioPlayerState.Playing) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.resource) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.resource.ended) {\n\t\t\tthis.stopInternal();\n\t\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\t\tthis.emit(\"idle\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst packet = this.resource.read();\n\t\tif (!packet) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const connection of this.connections) {\n\t\t\tconnection.sendOpusPacket(packet);\n\t\t}\n\t}\n\n\tprivate stopInternal(): void {\n\t\tif (this.playbackTimer) {\n\t\t\tclearInterval(this.playbackTimer);\n\t\t\tthis.playbackTimer = undefined;\n\t\t}\n\t\tif (this.resource) {\n\t\t\tthis.resource.destroy();\n\t\t\tthis.resource = undefined;\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: AudioPlayerState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n}\n","import { VoiceConnection, type VoiceConnectionOptions } from \"./connection.js\";\nimport type { DiscordGatewayAdapterCreator } from \"./adapter.js\";\nimport { getVoiceConnection } from \"./store.js\";\n\n/**\n * Options for joining a voice channel.\n *\n * @example\n * ```ts\n * const connection = joinVoiceChannel({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport interface JoinVoiceChannelOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\n/**\n * Join a Discord voice channel and return a VoiceConnection.\n *\n * @example\n * ```ts\n * import { joinVoiceChannel } from '@harmonia/voice';\n *\n * const connection = joinVoiceChannel({\n * guildId: interaction.guildId,\n * channelId: member.voice.channelId,\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport function joinVoiceChannel(options: JoinVoiceChannelOptions): VoiceConnection {\n\tconst existing = getVoiceConnection(options.guildId);\n\tif (existing) {\n\t\texisting.destroy();\n\t}\n\n\treturn new VoiceConnection(options);\n}\n","import { Readable } from \"node:stream\";\nimport { OpusEncoder, OpusEncoderStream } from \"@harmonia-audio/codec\";\nimport type { PlayableResource } from \"./player.js\";\n\n/**\n * Options for creating an audio resource.\n *\n * @example\n * ```ts\n * const resource = createAudioResource('./song.pcm', {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport interface AudioResourceOptions {\n\treadonly inputType?: \"opus\" | \"pcm\" | \"raw\";\n\treadonly inlineVolume?: boolean;\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Audio resource that can be played by an AudioPlayer.\n *\n * @example\n * ```ts\n * const resource = createAudioResource(readableStream, { inputType: 'pcm' });\n * player.play(resource);\n * ```\n */\nexport class AudioResource implements PlayableResource {\n\tprivate readonly stream: Readable;\n\tprivate readonly packets: Buffer[] = [];\n\tprivate _ended = false;\n\tprivate draining = false;\n\n\tconstructor(stream: Readable) {\n\t\tthis.stream = stream;\n\n\t\tstream.on(\"data\", (chunk: Buffer) => {\n\t\t\tthis.packets.push(chunk);\n\t\t});\n\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\n\t\tstream.on(\"error\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\t}\n\n\t/**\n\t * Read the next Opus packet.\n\t *\n\t * @example\n\t * ```ts\n\t * const packet = resource.read();\n\t * ```\n\t */\n\tread(): Buffer | null {\n\t\treturn this.packets.shift() ?? null;\n\t}\n\n\t/** Whether the resource has finished producing packets. */\n\tget ended(): boolean {\n\t\treturn this._ended && this.packets.length === 0;\n\t}\n\n\t/**\n\t * Destroy the resource and release underlying streams.\n\t *\n\t * @example\n\t * ```ts\n\t * resource.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tthis.stream.destroy();\n\t\tthis.packets.length = 0;\n\t\tthis._ended = true;\n\t}\n}\n\n/**\n * Create an AudioResource from various input types.\n *\n * @example\n * ```ts\n * import { createAudioResource } from '@harmonia/voice';\n * import { createReadStream } from 'fs';\n *\n * const resource = createAudioResource(createReadStream('./audio.pcm'), {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport function createAudioResource(\n\tinput: Readable | string | Buffer,\n\toptions: AudioResourceOptions = {},\n): AudioResource {\n\tlet readable: Readable;\n\n\tif (typeof input === \"string\") {\n\t\tconst { createReadStream } = require(\"node:fs\") as typeof import(\"node:fs\");\n\t\treadable = createReadStream(input);\n\t} else if (Buffer.isBuffer(input)) {\n\t\treadable = Readable.from(input);\n\t} else {\n\t\treadable = input;\n\t}\n\n\tif (options.inputType === \"opus\") {\n\t\treturn new AudioResource(readable);\n\t}\n\n\t// PCM input: pipe through Opus encoder\n\tconst encoder = new OpusEncoderStream({\n\t\tsampleRate: 48000,\n\t\tchannels: 2,\n\t\tapplication: \"audio\",\n\t});\n\n\treadable.pipe(encoder);\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\treadable.destroy();\n\t\t\t\tencoder.destroy();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t}\n\n\treturn new AudioResource(encoder);\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harmonia-audio/voice",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Discord voice connection management for harmonia",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"ws": "^8.18.0",
|
|
27
|
+
"@harmonia-audio/codec": "0.1.0",
|
|
28
|
+
"@harmonia-audio/native": "0.1.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/ws": "^8.5.13",
|
|
32
|
+
"tsup": "^8.3.5",
|
|
33
|
+
"typescript": "^5.7.2",
|
|
34
|
+
"vitest": "^2.1.8",
|
|
35
|
+
"rimraf": "^6.0.1"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"clean": "rimraf dist"
|
|
42
|
+
}
|
|
43
|
+
}
|