@discordjs/voice 0.7.3 → 0.8.0-dev.1644106025.d8184f9
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/CHANGELOG.md +51 -0
- package/README.md +7 -7
- package/dist/index.d.ts +6 -6
- package/dist/index.js +7 -11
- package/dist/index.js.map +1 -7
- package/dist/index.mjs +8 -12
- package/dist/index.mjs.map +1 -7
- package/package.json +87 -91
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
# [0.8.0](https://github.com/discordjs/discord.js/compare/@discordjs/voice@0.7.5...@discordjs/voice@0.8.0) (2021-12-08)
|
|
6
|
+
|
|
7
|
+
## Refactor
|
|
8
|
+
|
|
9
|
+
- PresenceUpdate and demuxProbe (#7248) ([1745973](https://github.com/discordjs/discord.js/commit/174597302408f13c5bb685e2fb02ae2137cb481d))
|
|
10
|
+
|
|
11
|
+
## Testing
|
|
12
|
+
|
|
13
|
+
- **voice:** Fix tests ([62c74b8](https://github.com/discordjs/discord.js/commit/62c74b8333066465e5bd295b8b102b35a506751d))
|
|
14
|
+
- Fix voice secretbox tests ([4a2dbd6](https://github.com/discordjs/discord.js/commit/4a2dbd62382f904d596b34da0116d50e724b81c4))
|
|
15
|
+
- Fix voice tests ([b593bd3](https://github.com/discordjs/discord.js/commit/b593bd32a98282a92fa28f2fb0a8ef239866622c))
|
|
16
|
+
|
|
17
|
+
# [0.7.5](https://github.com/discordjs/voice/compare/v0.7.4...v0.7.5) (2021-11-12)
|
|
18
|
+
|
|
19
|
+
## Bug Fixes
|
|
20
|
+
|
|
21
|
+
- postbuild script ([644af95](https://github.com/discordjs/voice/commit/644af9579f02724c489514f482640b8413d2c305))
|
|
22
|
+
|
|
23
|
+
# [0.7.4](https://github.com/discordjs/voice/compare/v0.7.3...v0.7.4) (2021-11-12)
|
|
24
|
+
|
|
25
|
+
## Bug Fixes
|
|
26
|
+
|
|
27
|
+
- conditionally apply banner only to esm build ([8c4e8c4](https://github.com/discordjs/voice/commit/8c4e8c4ba5b9013a90de0238a7f2771e9113a62d))
|
|
28
|
+
|
|
29
|
+
# [0.7.3](https://github.com/discordjs/voice/compare/v0.7.2...v0.7.3) (2021-11-11)
|
|
30
|
+
|
|
31
|
+
## Bug Fixes
|
|
32
|
+
|
|
33
|
+
- **esm:** resolve esm imports ([#229](https://github.com/discordjs/voice/issues/229)) ([616f2bc](https://github.com/discordjs/voice/commit/616f2bcfde47e55ac7b09f4faaa07f15d78c11a5))
|
|
34
|
+
|
|
35
|
+
# [0.7.2](https://github.com/discordjs/voice/compare/v0.7.1...v0.7.2) (2021-10-30)
|
|
36
|
+
|
|
37
|
+
## Bug Fixes
|
|
38
|
+
|
|
39
|
+
- prism imports for ems ([0bfd6d5](https://github.com/discordjs/voice/commit/0bfd6d5247f89cfc125e7645e9fb7ebfed94bb2f))
|
|
40
|
+
|
|
41
|
+
# [0.7.1](https://github.com/discordjs/voice/compare/v0.7.0...v0.7.1) (2021-10-30)
|
|
42
|
+
|
|
43
|
+
## Bug Fixes
|
|
44
|
+
|
|
45
|
+
- prism imports for esm ([9222dbf](https://github.com/discordjs/voice/commit/9222dbfedd8bfaeb679133dfa41330ea75a03a70))
|
|
46
|
+
|
|
47
|
+
# [0.7.0](https://github.com/discordjs/voice/compare/v0.6.0...v0.7.0) (2021-10-30)
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- export some types so they render in docs ([#211](https://github.com/discordjs/voice/issues/211)) ([a6dad47](https://github.com/discordjs/voice/commit/a6dad4781fb479d22d7bff99888e42368d6d6411))
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
|
|
9
9
|
<a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/v/@discordjs/voice.svg?maxAge=3600" alt="npm version" /></a>
|
|
10
10
|
<a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/dt/@discordjs/voice.svg?maxAge=3600" alt="npm downloads" /></a>
|
|
11
|
-
<a href="https://github.com/discordjs/
|
|
11
|
+
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
|
|
12
12
|
<a href="https://codecov.io/gh/discordjs/voice"><img src="https://codecov.io/gh/discordjs/voice/branch/main/graph/badge.svg" alt="Code coverage" /></a>
|
|
13
13
|
<a href="https://www.patreon.com/discordjs"><img src="https://img.shields.io/badge/donate-patreon-F96854.svg" alt="Patreon" /></a>
|
|
14
14
|
</p>
|
|
@@ -20,16 +20,16 @@ An implementation of the Discord Voice API for Node.js, written in TypeScript.
|
|
|
20
20
|
|
|
21
21
|
**Features:**
|
|
22
22
|
|
|
23
|
-
- Send and receive
|
|
23
|
+
- Send and receive\* audio in Discord voice-based channels
|
|
24
24
|
- A strong focus on reliability and predictable behaviour
|
|
25
25
|
- Horizontal scalability and libraries other than [discord.js](https://discord.js.org/) are supported with custom adapters
|
|
26
26
|
- A robust audio processing system that can handle a wide range of audio sources
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
\*_Audio receive is not documented by Discord so stable support is not guaranteed_
|
|
29
29
|
|
|
30
30
|
## Installation
|
|
31
31
|
|
|
32
|
-
**Node.js 16.
|
|
32
|
+
**Node.js 16.9.0 or newer is required.**
|
|
33
33
|
|
|
34
34
|
```sh-session
|
|
35
35
|
npm install @discordjs/voice
|
|
@@ -65,16 +65,16 @@ try installing another.
|
|
|
65
65
|
|
|
66
66
|
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
|
|
67
67
|
- [Documentation](https://discord.js.org/#/docs/voice)
|
|
68
|
-
- [Examples](https://github.com/discordjs/
|
|
68
|
+
- [Examples](https://github.com/discordjs/discord.js/tree/main/packages/voice/examples)
|
|
69
69
|
- [discord.js Discord server](https://discord.gg/djs)
|
|
70
|
-
- [GitHub](https://github.com/discordjs/voice)
|
|
70
|
+
- [GitHub](https://github.com/discordjs/discord.js/tree/main/packages/voice)
|
|
71
71
|
- [npm](https://www.npmjs.com/package/@discordjs/voice)
|
|
72
72
|
|
|
73
73
|
## Contributing
|
|
74
74
|
|
|
75
75
|
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
|
|
76
76
|
[documentation](https://discord.js.org/#/docs/voice).
|
|
77
|
-
See [the contribution guide](https://github.com/discordjs/
|
|
77
|
+
See [the contribution guide](https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md) if you'd like to submit a PR.
|
|
78
78
|
|
|
79
79
|
## Help
|
|
80
80
|
|
package/dist/index.d.ts
CHANGED
|
@@ -552,17 +552,17 @@ interface DiscordGatewayAdapterLibraryMethods {
|
|
|
552
552
|
*
|
|
553
553
|
* @param data - The inner data of the VOICE_SERVER_UPDATE payload
|
|
554
554
|
*/
|
|
555
|
-
onVoiceServerUpdate(data: GatewayVoiceServerUpdateDispatchData)
|
|
555
|
+
onVoiceServerUpdate: (data: GatewayVoiceServerUpdateDispatchData) => void;
|
|
556
556
|
/**
|
|
557
557
|
* Call this when you receive a VOICE_STATE_UPDATE payload that is relevant to the adapter.
|
|
558
558
|
*
|
|
559
559
|
* @param data - The inner data of the VOICE_STATE_UPDATE payload
|
|
560
560
|
*/
|
|
561
|
-
onVoiceStateUpdate(data: GatewayVoiceStateUpdateDispatchData)
|
|
561
|
+
onVoiceStateUpdate: (data: GatewayVoiceStateUpdateDispatchData) => void;
|
|
562
562
|
/**
|
|
563
563
|
* Call this when the adapter can no longer be used (e.g. due to a disconnect from the main gateway)
|
|
564
564
|
*/
|
|
565
|
-
destroy()
|
|
565
|
+
destroy: () => void;
|
|
566
566
|
}
|
|
567
567
|
/**
|
|
568
568
|
* Methods that are provided by the implementer of a Discord gateway DiscordGatewayAdapter.
|
|
@@ -575,12 +575,12 @@ interface DiscordGatewayAdapterImplementerMethods {
|
|
|
575
575
|
*
|
|
576
576
|
* @returns `false` if the payload definitely failed to send - in this case, the voice connection disconnects
|
|
577
577
|
*/
|
|
578
|
-
sendPayload(payload: any)
|
|
578
|
+
sendPayload: (payload: any) => boolean;
|
|
579
579
|
/**
|
|
580
580
|
* This will be called by @discordjs/voice when the adapter can safely be destroyed as it will no
|
|
581
581
|
* longer be used.
|
|
582
582
|
*/
|
|
583
|
-
destroy()
|
|
583
|
+
destroy: () => void;
|
|
584
584
|
}
|
|
585
585
|
/**
|
|
586
586
|
* A function used to build adapters. It accepts a methods parameter that contains functions that
|
|
@@ -705,7 +705,7 @@ declare class VoiceWebSocket extends TypedEmitter<VoiceWebSocketEvents> {
|
|
|
705
705
|
* The time (milliseconds since UNIX epoch) that the last heartbeat was sent. This is set to 0 if a heartbeat
|
|
706
706
|
* hasn't been sent yet.
|
|
707
707
|
*/
|
|
708
|
-
private
|
|
708
|
+
private lastHeartbeatSend;
|
|
709
709
|
/**
|
|
710
710
|
* The number of consecutively missed heartbeats.
|
|
711
711
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import { createRequire as topLevelCreateRequire } from "module";
|
|
3
|
-
const require = topLevelCreateRequire(path.resolve("file://C:\Users\crawl\Source\voice\tsup.config.ts"));
|
|
4
|
-
|
|
5
|
-
var ze=Object.create;var M=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ze=Object.getPrototypeOf,Qe=Object.prototype.hasOwnProperty;var et=(i,e,t)=>e in i?M(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var re=i=>M(i,"__esModule",{value:!0});var tt=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),it=(i,e)=>{re(i);for(var t in e)M(i,t,{get:e[t],enumerable:!0})},st=(i,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Xe(e))!Qe.call(i,s)&&s!=="default"&&M(i,s,{get:()=>e[s],enumerable:!(t=Ye(e,s))||t.enumerable});return i},h=i=>st(re(M(i!=null?ze(Ze(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var r=(i,e,t)=>(et(i,typeof e!="symbol"?e+"":e,t),t);var Fe=tt((Li,Pt)=>{Pt.exports={name:"@discordjs/voice",version:"0.7.3",description:"Implementation of the Discord Voice API for Node.js",scripts:{pretest:"npm run build",test:"jest --pass-with-no-tests","test:ci":"jest --no-stack-trace --verbose --pass-with-no-tests",prebuild:"npm run lint",build:"tsup",lint:"eslint src --ext mjs,js,ts","lint:fix":"eslint src --ext mjs,js,ts --fix",format:"prettier --write **/*.{ts,js,json,yml,yaml}",prepare:"is-ci || husky install",docs:"typedoc --json docs/typedoc-out.json src/index.ts && node scripts/docs.mjs",prepublishOnly:"npm run lint && npm run test",release:"standard-version --preset angular"},main:"./dist/index.js",module:"./dist/index.mjs",typings:"./dist/index.d.ts",exports:{import:"./dist/index.mjs",require:"./dist/index.js"},directories:{lib:"src",test:"__tests__"},files:["dist"],author:"Amish Shah <amish@shah.gg>",license:"Apache-2.0",keywords:["discord","discord.js","audio","voice","streaming"],repository:{type:"git",url:"git+https://github.com/discordjs/voice.git"},bugs:{url:"https://github.com/discordjs/voice/issues"},homepage:"https://github.com/discordjs/voice",dependencies:{"@types/ws":"^8.2.0","discord-api-types":"^0.24.0","prism-media":"^1.3.2","tiny-typed-emitter":"^2.1.0",tslib:"^2.3.1",ws:"^8.2.3"},devDependencies:{"@babel/core":"^7.16.0","@babel/preset-env":"^7.16.0","@babel/preset-typescript":"^7.16.0","@commitlint/cli":"^13.2.1","@commitlint/config-angular":"^13.2.0","@discordjs/ts-docgen":"^0.3.2","@types/jest":"^27.0.2","@types/node":"^16.11.6","@typescript-eslint/eslint-plugin":"^5.2.0","@typescript-eslint/parser":"^5.2.0",eslint:"^8.1.0","eslint-config-marine":"^9.0.6","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^4.0.0",husky:"^7.0.4","is-ci":"^3.0.1",jest:"^27.3.1","jest-websocket-mock":"^2.2.1","lint-staged":"^11.2.6","mock-socket":"^9.0.6",prettier:"^2.4.1","standard-version":"^9.3.2",tsup:"^5.6.0",typedoc:"^0.22.7",typescript:"^4.4.4"},engines:{node:">=16.0.0",npm:">=7.0.0"},publishConfig:{access:"public"}}});it(exports,{AudioPlayer:()=>H,AudioPlayerError:()=>N,AudioPlayerStatus:()=>d,AudioReceiveStream:()=>J,AudioResource:()=>j,EndBehaviorType:()=>I,NoSubscriberBehavior:()=>x,PlayerSubscription:()=>W,SSRCMap:()=>L,SpeakingMap:()=>T,StreamType:()=>p,VoiceConnection:()=>K,VoiceConnectionDisconnectReason:()=>y,VoiceConnectionStatus:()=>c,VoiceReceiver:()=>q,createAudioPlayer:()=>De,createAudioResource:()=>je,createDefaultAudioReceiveStreamOptions:()=>ie,demuxProbe:()=>xt,entersState:()=>wt,generateDependencyReport:()=>Ct,getGroups:()=>ce,getVoiceConnection:()=>B,getVoiceConnections:()=>G,joinVoiceChannel:()=>gt,validateDiscordOpusHead:()=>qe});var ae=h(require("discord-api-types/v9"));function R(i){return{op:ae.GatewayOpcodes.VoiceStateUpdate,d:{guild_id:i.guildId,channel_id:i.channelId,self_deaf:i.selfDeaf,self_mute:i.selfMute}}}var U=new Map;U.set("default",new Map);function ot(i){let e=U.get(i);if(e)return e;let t=new Map;return U.set(i,t),t}function ce(){return U}function G(i="default"){return U.get(i)}function B(i,e="default"){return G(e)?.get(i)}function de(i){return G(i.joinConfig.group)?.delete(i.joinConfig.guildId)}function ue(i){return ot(i.joinConfig.group).set(i.joinConfig.guildId,i)}var nt=20,Y,V=-1,w=[];function pe(){if(V===-1)return;V+=nt;let i=w.filter(e=>e.checkPlayable());i.forEach(e=>e._stepDispatch()),le(i)}function le(i){let e=i.shift();if(!e){V!==-1&&(Y=setTimeout(()=>pe(),V-Date.now()));return}e._stepPrepare(),setImmediate(()=>le(i))}function rt(i){return w.includes(i)}function fe(i){return rt(i)||(w.push(i),w.length===1&&(V=Date.now(),setImmediate(()=>pe()))),i}function he(i){let e=w.indexOf(i);e!==-1&&(w.splice(e,1),w.length===0&&(V=-1,typeof Y!="undefined"&&clearTimeout(Y)))}var k=h(require("discord-api-types/voice/v4"));var me=h(require("node:dgram")),ge=h(require("node:net")),ye=h(require("tiny-typed-emitter")),at=5e3,ct=12,dt=2**32-1,X=class extends ye.TypedEmitter{constructor(e,t=!1){super();r(this,"socket");r(this,"remote");r(this,"keepAlives");r(this,"keepAliveCounter",0);r(this,"keepAliveBuffer");r(this,"keepAliveInterval");r(this,"ping");r(this,"debug");this.socket=(0,me.createSocket)("udp4"),this.socket.on("error",s=>this.emit("error",s)),this.socket.on("message",s=>this.onMessage(s)),this.socket.on("close",()=>this.emit("close")),this.remote=e,this.keepAlives=[],this.keepAliveBuffer=Buffer.alloc(8),this.keepAliveInterval=setInterval(()=>this.keepAlive(),at),setImmediate(()=>this.keepAlive()),this.debug=t?s=>this.emit("debug",s):null}onMessage(e){if(e.length===8){let t=e.readUInt32LE(0),s=this.keepAlives.findIndex(({value:n})=>n===t);if(s===-1)return;this.ping=Date.now()-this.keepAlives[s].timestamp,this.keepAlives.splice(0,s)}this.emit("message",e)}keepAlive(){if(this.keepAlives.length>=ct){this.debug?.("UDP socket has not received enough responses from Discord - closing socket"),this.destroy();return}this.keepAliveBuffer.writeUInt32LE(this.keepAliveCounter,0),this.send(this.keepAliveBuffer),this.keepAlives.push({value:this.keepAliveCounter,timestamp:Date.now()}),this.keepAliveCounter++,this.keepAliveCounter>dt&&(this.keepAliveCounter=0)}send(e){return this.socket.send(e,this.remote.port,this.remote.ip)}destroy(){try{this.socket.close()}catch{}clearInterval(this.keepAliveInterval)}performIPDiscovery(e){return new Promise((t,s)=>{let n=u=>{try{if(u.readUInt16BE(0)!==2)return;let a=ut(u);this.socket.off("message",n),t(a)}catch{}};this.socket.on("message",n),this.socket.once("close",()=>s(new Error("Cannot perform IP discovery - socket closed")));let o=Buffer.alloc(74);o.writeUInt16BE(1,0),o.writeUInt16BE(70,2),o.writeUInt32BE(e,4),this.send(o)})}};function ut(i){let e=Buffer.from(i),t=e.slice(8,e.indexOf(0,8)).toString("utf-8");if(!(0,ge.isIPv4)(t))throw new Error("Malformed IP address");let s=e.readUInt16BE(e.length-2);return{ip:t,port:s}}var Z=h(require("discord-api-types/voice/v4")),be=h(require("ws")),Se=h(require("tiny-typed-emitter")),Q=class extends Se.TypedEmitter{constructor(e,t){super();r(this,"heartbeatInterval");r(this,"lastHeartbeatAck");r(this,"lastHeatbeatSend");r(this,"missedHeartbeats",0);r(this,"ping");r(this,"debug");r(this,"ws");this.ws=new be.default(e),this.ws.onmessage=s=>this.onMessage(s),this.ws.onopen=s=>this.emit("open",s),this.ws.onerror=s=>this.emit("error",s instanceof Error?s:s.error),this.ws.onclose=s=>this.emit("close",s),this.lastHeartbeatAck=0,this.lastHeatbeatSend=0,this.debug=t?s=>this.emit("debug",s):null}destroy(){try{this.debug?.("destroyed"),this.setHeartbeatInterval(-1),this.ws.close(1e3)}catch(e){let t=e;this.emit("error",t)}}onMessage(e){if(typeof e.data!="string")return;this.debug?.(`<< ${e.data}`);let t;try{t=JSON.parse(e.data)}catch(s){let n=s;this.emit("error",n);return}t.op===Z.VoiceOpcodes.HeartbeatAck&&(this.lastHeartbeatAck=Date.now(),this.missedHeartbeats=0,this.ping=this.lastHeartbeatAck-this.lastHeatbeatSend),this.emit("packet",t)}sendPacket(e){try{let t=JSON.stringify(e);return this.debug?.(`>> ${t}`),this.ws.send(t)}catch(t){let s=t;this.emit("error",s)}}sendHeartbeat(){this.lastHeatbeatSend=Date.now(),this.missedHeartbeats++;let e=this.lastHeatbeatSend;return this.sendPacket({op:Z.VoiceOpcodes.Heartbeat,d:e})}setHeartbeatInterval(e){typeof this.heartbeatInterval!="undefined"&&clearInterval(this.heartbeatInterval),e>0&&(this.heartbeatInterval=setInterval(()=>{this.lastHeatbeatSend!==0&&this.missedHeartbeats>=3&&(this.ws.close(),this.setHeartbeatInterval(-1)),this.sendHeartbeat()},e))}};var ke={sodium:i=>({open:i.api.crypto_secretbox_open_easy,close:i.api.crypto_secretbox_easy,random:(e,t)=>(t||(t=Buffer.allocUnsafe(e)),i.api.randombytes_buf(t),t)}),"libsodium-wrappers":i=>({open:i.crypto_secretbox_open_easy,close:i.crypto_secretbox_easy,random:e=>i.randombytes_buf(e)}),tweetnacl:i=>({open:i.secretbox.open,close:i.secretbox,random:e=>i.randomBytes(e)})},ee=()=>{throw new Error(`Cannot play audio as no valid encryption package is installed.
|
|
1
|
+
var ze=Object.create;var A=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ze=Object.getPrototypeOf,Qe=Object.prototype.hasOwnProperty;var et=(i,e,t)=>e in i?A(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var ne=i=>A(i,"__esModule",{value:!0}),r=(i,e)=>A(i,"name",{value:e,configurable:!0});var tt=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),it=(i,e)=>{for(var t in e)A(i,t,{get:e[t],enumerable:!0})},re=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Xe(e))!Qe.call(i,s)&&(t||s!=="default")&&A(i,s,{get:()=>e[s],enumerable:!(o=Ye(e,s))||o.enumerable});return i},I=(i,e)=>re(ne(A(i!=null?ze(Ze(i)):{},"default",!e&&i&&i.__esModule?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i),ot=(i=>(e,t)=>i&&i.get(e)||(t=re(ne({}),e,1),i&&i.set(e,t),t))(typeof WeakMap!="undefined"?new WeakMap:0);var a=(i,e,t)=>(et(i,typeof e!="symbol"?e+"":e,t),t);var je=tt((qi,Pt)=>{Pt.exports={name:"@discordjs/voice",version:"0.8.0-dev",description:"Implementation of the Discord Voice API for node.js",scripts:{build:"tsup && node scripts/postbuild.mjs",test:"jest --pass-with-no-tests --collect-coverage",lint:"prettier --check . && eslint src __tests__ --ext mjs,js,ts",format:"prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",docs:"typedoc --json docs/typedoc-out.json src/index.ts && node scripts/docs.mjs",prepublishOnly:"yarn build && yarn lint && yarn test",changelog:"git cliff --prepend ./CHANGELOG.md -l -c ./cliff.toml -r ../../ --include-path 'packages/voice/*'"},main:"./dist/index.js",module:"./dist/index.mjs",typings:"./dist/index.d.ts",exports:{import:"./dist/index.mjs",require:"./dist/index.js"},directories:{lib:"src",test:"__tests__"},files:["dist"],contributors:["Crawl <icrawltogo@gmail.com>","Amish Shah <amishshah.2k@gmail.com>","SpaceEEC <spaceeec@yahoo.com>","Vlad Frangu <kingdgrizzle@gmail.com>","Antonio Roman <kyradiscord@gmail.com>"],license:"Apache-2.0",keywords:["discord","discord.js","audio","voice","streaming"],repository:{type:"git",url:"git+https://github.com/discordjs/discord.js.git"},bugs:{url:"https://github.com/discordjs/discord.js/issues"},homepage:"https://discord.js.org",dependencies:{"@types/ws":"^8.2.0","discord-api-types":"^0.26.1","prism-media":"^1.3.2","tiny-typed-emitter":"^2.1.0",tslib:"^2.3.1",ws:"^8.4.2"},devDependencies:{"@babel/core":"^7.17.0","@babel/preset-env":"^7.16.11","@babel/preset-typescript":"^7.16.0","@discordjs/ts-docgen":"^0.3.2","@types/jest":"^27.0.2","@types/node":"^16.11.7","@typescript-eslint/eslint-plugin":"^5.10.2","@typescript-eslint/parser":"^5.10.2",eslint:"^8.8.0","eslint-config-marine":"^9.3.2","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^4.0.0",jest:"^27.4.7","jest-websocket-mock":"^2.3.0","mock-socket":"^9.1.2",prettier:"^2.4.1",tsup:"^5.11.13",tweetnacl:"^1.0.3",typedoc:"^0.22.11",typescript:"^4.5.5"},engines:{node:">=16.9.0"},publishConfig:{access:"public"}}});var Dt={};it(Dt,{AudioPlayer:()=>N,AudioPlayerError:()=>w,AudioPlayerStatus:()=>Z,AudioReceiveStream:()=>B,AudioResource:()=>R,EndBehaviorType:()=>Ee,NoSubscriberBehavior:()=>X,PlayerSubscription:()=>x,SSRCMap:()=>M,SpeakingMap:()=>D,StreamType:()=>E,VoiceConnection:()=>W,VoiceConnectionDisconnectReason:()=>te,VoiceConnectionStatus:()=>L,VoiceReceiver:()=>U,createAudioPlayer:()=>Ve,createAudioResource:()=>Fe,createDefaultAudioReceiveStreamOptions:()=>Q,demuxProbe:()=>Vt,entersState:()=>xt,generateDependencyReport:()=>wt,getGroups:()=>ce,getVoiceConnection:()=>_,getVoiceConnections:()=>j,joinVoiceChannel:()=>yt,validateDiscordOpusHead:()=>qe});var ae=require("discord-api-types/v9");function P(i){return{op:ae.GatewayOpcodes.VoiceStateUpdate,d:{guild_id:i.guildId,channel_id:i.channelId,self_deaf:i.selfDeaf,self_mute:i.selfMute}}}r(P,"createJoinVoiceChannelPayload");var T=new Map;T.set("default",new Map);function st(i){let e=T.get(i);if(e)return e;let t=new Map;return T.set(i,t),t}r(st,"getOrCreateGroup");function ce(){return T}r(ce,"getGroups");function j(i="default"){return T.get(i)}r(j,"getVoiceConnections");function _(i,e="default"){return j(e)?.get(i)}r(_,"getVoiceConnection");function de(i){return j(i.joinConfig.group)?.delete(i.joinConfig.guildId)}r(de,"untrackVoiceConnection");function ue(i){return st(i.joinConfig.group).set(i.joinConfig.guildId,i)}r(ue,"trackVoiceConnection");var nt=20,K,v=-1,S=[];function pe(){if(v===-1)return;v+=nt;let i=S.filter(e=>e.checkPlayable());i.forEach(e=>e._stepDispatch()),le(i)}r(pe,"audioCycleStep");function le(i){let e=i.shift();if(!e){v!==-1&&(K=setTimeout(()=>pe(),v-Date.now()));return}e._stepPrepare(),setImmediate(()=>le(i))}r(le,"prepareNextAudioFrame");function rt(i){return S.includes(i)}r(rt,"hasAudioPlayer");function fe(i){return rt(i)||(S.push(i),S.length===1&&(v=Date.now(),setImmediate(()=>pe()))),i}r(fe,"addAudioPlayer");function he(i){let e=S.indexOf(i);e!==-1&&(S.splice(e,1),S.length===0&&(v=-1,typeof K!="undefined"&&clearTimeout(K)))}r(he,"deleteAudioPlayer");var h=require("discord-api-types/voice/v4");var me=require("dgram"),ge=require("net"),ye=require("tiny-typed-emitter");function at(i){let e=Buffer.from(i),t=e.slice(8,e.indexOf(0,8)).toString("utf-8");if(!(0,ge.isIPv4)(t))throw new Error("Malformed IP address");let o=e.readUInt16BE(e.length-2);return{ip:t,port:o}}r(at,"parseLocalPacket");var ct=5e3,dt=12,ut=2**32-1,G=class extends ye.TypedEmitter{constructor(e,t=!1){super();a(this,"socket");a(this,"remote");a(this,"keepAlives");a(this,"keepAliveCounter",0);a(this,"keepAliveBuffer");a(this,"keepAliveInterval");a(this,"ping");a(this,"debug");this.socket=(0,me.createSocket)("udp4"),this.socket.on("error",o=>this.emit("error",o)),this.socket.on("message",o=>this.onMessage(o)),this.socket.on("close",()=>this.emit("close")),this.remote=e,this.keepAlives=[],this.keepAliveBuffer=Buffer.alloc(8),this.keepAliveInterval=setInterval(()=>this.keepAlive(),ct),setImmediate(()=>this.keepAlive()),this.debug=t?o=>this.emit("debug",o):null}onMessage(e){if(e.length===8){let t=e.readUInt32LE(0),o=this.keepAlives.findIndex(({value:s})=>s===t);if(o===-1)return;this.ping=Date.now()-this.keepAlives[o].timestamp,this.keepAlives.splice(0,o)}this.emit("message",e)}keepAlive(){if(this.keepAlives.length>=dt){this.debug?.("UDP socket has not received enough responses from Discord - closing socket"),this.destroy();return}this.keepAliveBuffer.writeUInt32LE(this.keepAliveCounter,0),this.send(this.keepAliveBuffer),this.keepAlives.push({value:this.keepAliveCounter,timestamp:Date.now()}),this.keepAliveCounter++,this.keepAliveCounter>ut&&(this.keepAliveCounter=0)}send(e){return this.socket.send(e,this.remote.port,this.remote.ip)}destroy(){try{this.socket.close()}catch{}clearInterval(this.keepAliveInterval)}performIPDiscovery(e){return new Promise((t,o)=>{let s=r(c=>{try{if(c.readUInt16BE(0)!==2)return;let u=at(c);this.socket.off("message",s),t(u)}catch{}},"listener");this.socket.on("message",s),this.socket.once("close",()=>o(new Error("Cannot perform IP discovery - socket closed")));let n=Buffer.alloc(74);n.writeUInt16BE(1,0),n.writeUInt16BE(70,2),n.writeUInt32BE(e,4),this.send(n)})}};r(G,"VoiceUDPSocket");var z=require("discord-api-types/voice/v4"),be=I(require("ws")),Se=require("tiny-typed-emitter"),H=class extends Se.TypedEmitter{constructor(e,t){super();a(this,"heartbeatInterval");a(this,"lastHeartbeatAck");a(this,"lastHeartbeatSend");a(this,"missedHeartbeats",0);a(this,"ping");a(this,"debug");a(this,"ws");this.ws=new be.default(e),this.ws.onmessage=o=>this.onMessage(o),this.ws.onopen=o=>this.emit("open",o),this.ws.onerror=o=>this.emit("error",o instanceof Error?o:o.error),this.ws.onclose=o=>this.emit("close",o),this.lastHeartbeatAck=0,this.lastHeartbeatSend=0,this.debug=t?o=>this.emit("debug",o):null}destroy(){try{this.debug?.("destroyed"),this.setHeartbeatInterval(-1),this.ws.close(1e3)}catch(e){let t=e;this.emit("error",t)}}onMessage(e){if(typeof e.data!="string")return;this.debug?.(`<< ${e.data}`);let t;try{t=JSON.parse(e.data)}catch(o){let s=o;this.emit("error",s);return}t.op===z.VoiceOpcodes.HeartbeatAck&&(this.lastHeartbeatAck=Date.now(),this.missedHeartbeats=0,this.ping=this.lastHeartbeatAck-this.lastHeartbeatSend),this.emit("packet",t)}sendPacket(e){try{let t=JSON.stringify(e);return this.debug?.(`>> ${t}`),this.ws.send(t)}catch(t){let o=t;this.emit("error",o)}}sendHeartbeat(){this.lastHeartbeatSend=Date.now(),this.missedHeartbeats++;let e=this.lastHeartbeatSend;return this.sendPacket({op:z.VoiceOpcodes.Heartbeat,d:e})}setHeartbeatInterval(e){typeof this.heartbeatInterval!="undefined"&&clearInterval(this.heartbeatInterval),e>0&&(this.heartbeatInterval=setInterval(()=>{this.lastHeartbeatSend!==0&&this.missedHeartbeats>=3&&(this.ws.close(),this.setHeartbeatInterval(-1)),this.sendHeartbeat()},e))}};r(H,"VoiceWebSocket");var Ce={sodium:i=>({open:i.api.crypto_secretbox_open_easy,close:i.api.crypto_secretbox_easy,random:(e,t)=>(t||(t=Buffer.allocUnsafe(e)),i.api.randombytes_buf(t),t)}),"libsodium-wrappers":i=>({open:i.crypto_secretbox_open_easy,close:i.crypto_secretbox_easy,random:e=>i.randombytes_buf(e)}),tweetnacl:i=>({open:i.secretbox.open,close:i.secretbox,random:e=>i.randomBytes(e)})},Y=r(()=>{throw new Error(`Cannot play audio as no valid encryption package is installed.
|
|
6
2
|
- Install sodium, libsodium-wrappers, or tweetnacl.
|
|
7
3
|
- Use the generateDependencyReport() function for more information.
|
|
8
|
-
`)},
|
|
9
|
-
from ${
|
|
10
|
-
to ${
|
|
4
|
+
`)},"fallbackError"),y={open:Y,close:Y,random:Y};(async()=>{for(let i of Object.keys(Ce))try{let e=require(i);i==="libsodium-wrappers"&&e.ready&&await e.ready,Object.assign(y,Ce[i](e));break}catch{}})();var l=r(()=>{},"noop");var ke=require("tiny-typed-emitter"),lt=2,ft=48e3/100*lt,ht=2**32-1,mt=["xsalsa20_poly1305_lite","xsalsa20_poly1305_suffix","xsalsa20_poly1305"];var Ae=Buffer.alloc(24);function Pe(i){return JSON.stringify({...i,ws:Reflect.has(i,"ws"),udp:Reflect.has(i,"udp")})}r(Pe,"stringifyState");function gt(i){let e=i.find(t=>mt.includes(t));if(!e)throw new Error(`No compatible encryption modes. Available include: ${i.join(", ")}`);return e}r(gt,"chooseEncryptionMode");function ve(i){return Math.floor(Math.random()*2**i)}r(ve,"randomNBit");var J=class extends ke.TypedEmitter{constructor(e,t){super();a(this,"_state");a(this,"debug");this.onWsOpen=this.onWsOpen.bind(this),this.onChildError=this.onChildError.bind(this),this.onWsPacket=this.onWsPacket.bind(this),this.onWsClose=this.onWsClose.bind(this),this.onWsDebug=this.onWsDebug.bind(this),this.onUdpDebug=this.onUdpDebug.bind(this),this.onUdpClose=this.onUdpClose.bind(this),this.debug=t?o=>this.emit("debug",o):null,this._state={code:0,ws:this.createWebSocket(e.endpoint),connectionOptions:e}}destroy(){this.state={code:6}}get state(){return this._state}set state(e){let t=Reflect.get(this._state,"ws"),o=Reflect.get(e,"ws");t&&t!==o&&(t.off("debug",this.onWsDebug),t.on("error",l),t.off("error",this.onChildError),t.off("open",this.onWsOpen),t.off("packet",this.onWsPacket),t.off("close",this.onWsClose),t.destroy());let s=Reflect.get(this._state,"udp"),n=Reflect.get(e,"udp");s&&s!==n&&(s.on("error",l),s.off("error",this.onChildError),s.off("close",this.onUdpClose),s.off("debug",this.onUdpDebug),s.destroy());let c=this._state;this._state=e,this.emit("stateChange",c,e),this.debug?.(`state change:
|
|
5
|
+
from ${Pe(c)}
|
|
6
|
+
to ${Pe(e)}`)}createWebSocket(e){let t=new H(`wss://${e}?v=4`,Boolean(this.debug));return t.on("error",this.onChildError),t.once("open",this.onWsOpen),t.on("packet",this.onWsPacket),t.once("close",this.onWsClose),t.on("debug",this.onWsDebug),t}onChildError(e){this.emit("error",e)}onWsOpen(){if(this.state.code===0){let e={op:h.VoiceOpcodes.Identify,d:{server_id:this.state.connectionOptions.serverId,user_id:this.state.connectionOptions.userId,session_id:this.state.connectionOptions.sessionId,token:this.state.connectionOptions.token}};this.state.ws.sendPacket(e),this.state={...this.state,code:1}}else if(this.state.code===5){let e={op:h.VoiceOpcodes.Resume,d:{server_id:this.state.connectionOptions.serverId,session_id:this.state.connectionOptions.sessionId,token:this.state.connectionOptions.token}};this.state.ws.sendPacket(e)}}onWsClose({code:e}){(e===4015||e<4e3)&&this.state.code===4?this.state={...this.state,code:5,ws:this.createWebSocket(this.state.connectionOptions.endpoint)}:this.state.code!==6&&(this.destroy(),this.emit("close",e))}onUdpClose(){this.state.code===4&&(this.state={...this.state,code:5,ws:this.createWebSocket(this.state.connectionOptions.endpoint)})}onWsPacket(e){if(e.op===h.VoiceOpcodes.Hello&&this.state.code!==6)this.state.ws.setHeartbeatInterval(e.d.heartbeat_interval);else if(e.op===h.VoiceOpcodes.Ready&&this.state.code===1){let{ip:t,port:o,ssrc:s,modes:n}=e.d,c=new G({ip:t,port:o});c.on("error",this.onChildError),c.on("debug",this.onUdpDebug),c.once("close",this.onUdpClose),c.performIPDiscovery(s).then(u=>{this.state.code===2&&(this.state.ws.sendPacket({op:h.VoiceOpcodes.SelectProtocol,d:{protocol:"udp",data:{address:u.ip,port:u.port,mode:gt(n)}}}),this.state={...this.state,code:3})}).catch(u=>this.emit("error",u)),this.state={...this.state,code:2,udp:c,connectionData:{ssrc:s}}}else if(e.op===h.VoiceOpcodes.SessionDescription&&this.state.code===3){let{mode:t,secret_key:o}=e.d;this.state={...this.state,code:4,connectionData:{...this.state.connectionData,encryptionMode:t,secretKey:new Uint8Array(o),sequence:ve(16),timestamp:ve(32),nonce:0,nonceBuffer:Buffer.alloc(24),speaking:!1,packetsPlayed:0}}}else e.op===h.VoiceOpcodes.Resumed&&this.state.code===5&&(this.state={...this.state,code:4},this.state.connectionData.speaking=!1)}onWsDebug(e){this.debug?.(`[WS] ${e}`)}onUdpDebug(e){this.debug?.(`[UDP] ${e}`)}prepareAudioPacket(e){let t=this.state;if(t.code===4)return t.preparedPacket=this.createAudioPacket(e,t.connectionData),t.preparedPacket}dispatchAudio(){let e=this.state;return e.code!==4?!1:typeof e.preparedPacket!="undefined"?(this.playAudioPacket(e.preparedPacket),e.preparedPacket=void 0,!0):!1}playAudioPacket(e){let t=this.state;if(t.code!==4)return;let{connectionData:o}=t;o.packetsPlayed++,o.sequence++,o.timestamp+=ft,o.sequence>=2**16&&(o.sequence=0),o.timestamp>=2**32&&(o.timestamp=0),this.setSpeaking(!0),t.udp.send(e)}setSpeaking(e){let t=this.state;t.code===4&&t.connectionData.speaking!==e&&(t.connectionData.speaking=e,t.ws.sendPacket({op:h.VoiceOpcodes.Speaking,d:{speaking:e?1:0,delay:0,ssrc:t.connectionData.ssrc}}))}createAudioPacket(e,t){let o=Buffer.alloc(12);o[0]=128,o[1]=120;let{sequence:s,timestamp:n,ssrc:c}=t;return o.writeUIntBE(s,2,2),o.writeUIntBE(n,4,4),o.writeUIntBE(c,8,4),o.copy(Ae,0,0,12),Buffer.concat([o,...this.encryptOpusPacket(e,t)])}encryptOpusPacket(e,t){let{secretKey:o,encryptionMode:s}=t;if(s==="xsalsa20_poly1305_lite")return t.nonce++,t.nonce>ht&&(t.nonce=0),t.nonceBuffer.writeUInt32BE(t.nonce,0),[y.close(e,t.nonceBuffer,o),t.nonceBuffer.slice(0,4)];if(s==="xsalsa20_poly1305_suffix"){let n=y.random(24,t.nonceBuffer);return[y.close(e,n,o),n]}return[y.close(e,Ae,o)]}};r(J,"Networking");var Ie=require("tiny-typed-emitter");var $=require("discord-api-types/voice/v4");var De=require("stream");var w=class extends Error{constructor(e,t){super(e.message);a(this,"resource");this.resource=t,this.name=e.name,this.stack=e.stack}};r(w,"AudioPlayerError");var x=class{constructor(e,t){a(this,"connection");a(this,"player");this.connection=e,this.player=t}unsubscribe(){this.connection.onSubscriptionRemoved(this),this.player.unsubscribe(this)}};r(x,"PlayerSubscription");var we=require("tiny-typed-emitter"),V=Buffer.from([248,255,254]),X=(o=>(o.Pause="pause",o.Play="play",o.Stop="stop",o))(X||{}),Z=(n=>(n.Idle="idle",n.Buffering="buffering",n.Paused="paused",n.Playing="playing",n.AutoPaused="autopaused",n))(Z||{});function xe(i){return JSON.stringify({...i,resource:Reflect.has(i,"resource"),stepTimeout:Reflect.has(i,"stepTimeout")})}r(xe,"stringifyState");var N=class extends we.TypedEmitter{constructor(e={}){super();a(this,"_state");a(this,"subscribers",[]);a(this,"behaviors");a(this,"debug");this._state={status:"idle"},this.behaviors={noSubscriber:"pause",maxMissedFrames:5,...e.behaviors},this.debug=e.debug===!1?null:t=>this.emit("debug",t)}get playable(){return this.subscribers.filter(({connection:e})=>e.state.status==="ready").map(({connection:e})=>e)}subscribe(e){let t=this.subscribers.find(o=>o.connection===e);if(!t){let o=new x(e,this);return this.subscribers.push(o),setImmediate(()=>this.emit("subscribe",o)),o}return t}unsubscribe(e){let t=this.subscribers.indexOf(e),o=t!==-1;return o&&(this.subscribers.splice(t,1),e.connection.setSpeaking(!1),this.emit("unsubscribe",e)),o}get state(){return this._state}set state(e){let t=this._state,o=Reflect.get(e,"resource");t.status!=="idle"&&t.resource!==o&&(t.resource.playStream.on("error",l),t.resource.playStream.off("error",t.onStreamError),t.resource.audioPlayer=void 0,t.resource.playStream.destroy(),t.resource.playStream.read()),t.status==="buffering"&&(e.status!=="buffering"||e.resource!==t.resource)&&(t.resource.playStream.off("end",t.onFailureCallback),t.resource.playStream.off("close",t.onFailureCallback),t.resource.playStream.off("finish",t.onFailureCallback),t.resource.playStream.off("readable",t.onReadableCallback)),e.status==="idle"&&(this._signalStopSpeaking(),he(this)),o&&fe(this);let s=t.status!=="idle"&&e.status==="playing"&&t.resource!==e.resource;this._state=e,this.emit("stateChange",t,this._state),(t.status!==e.status||s)&&this.emit(e.status,t,this._state),this.debug?.(`state change:
|
|
11
7
|
from ${xe(t)}
|
|
12
|
-
to ${xe(e)}`)}play(e){if(e.ended)throw new Error("Cannot play a resource that has already ended.");if(e.audioPlayer){if(e.audioPlayer===this)return;throw new Error("Resource is already being played by another audio player.")}e.audioPlayer=this;let t=s=>{this.state.status!==d.Idle&&this.emit("error",new N(s,this.state.resource)),this.state.status!==d.Idle&&this.state.resource===e&&(this.state={status:d.Idle})};if(e.playStream.once("error",t),e.started)this.state={status:d.Playing,missedFrames:0,playbackDuration:0,resource:e,onStreamError:t};else{let s=()=>{this.state.status===d.Buffering&&this.state.resource===e&&(this.state={status:d.Playing,missedFrames:0,playbackDuration:0,resource:e,onStreamError:t})},n=()=>{this.state.status===d.Buffering&&this.state.resource===e&&(this.state={status:d.Idle})};e.playStream.once("readable",s),e.playStream.once("end",n),e.playStream.once("close",n),e.playStream.once("finish",n),this.state={status:d.Buffering,resource:e,onReadableCallback:s,onFailureCallback:n,onStreamError:t}}}pause(e=!0){return this.state.status!==d.Playing?!1:(this.state={...this.state,status:d.Paused,silencePacketsRemaining:e?5:0},!0)}unpause(){return this.state.status!==d.Paused?!1:(this.state={...this.state,status:d.Playing,missedFrames:0},!0)}stop(e=!1){return this.state.status===d.Idle?!1:(e||this.state.resource.silencePaddingFrames===0?this.state={status:d.Idle}:this.state.resource.silenceRemaining===-1&&(this.state.resource.silenceRemaining=this.state.resource.silencePaddingFrames),!0)}checkPlayable(){let e=this._state;return e.status===d.Idle||e.status===d.Buffering?!1:e.resource.readable?!0:(this.state={status:d.Idle},!1)}_stepDispatch(){let e=this._state;e.status===d.Idle||e.status===d.Buffering||this.playable.forEach(t=>t.dispatchAudio())}_stepPrepare(){let e=this._state;if(e.status===d.Idle||e.status===d.Buffering)return;let t=this.playable;if(e.status===d.AutoPaused&&t.length>0&&(this.state={...e,status:d.Playing,missedFrames:0}),e.status===d.Paused||e.status===d.AutoPaused){e.silencePacketsRemaining>0&&(e.silencePacketsRemaining--,this._preparePacket(O,t,e),e.silencePacketsRemaining===0&&this._signalStopSpeaking());return}if(t.length===0)if(this.behaviors.noSubscriber===x.Pause){this.state={...e,status:d.AutoPaused,silencePacketsRemaining:5};return}else this.behaviors.noSubscriber===x.Stop&&this.stop(!0);let s=e.resource.read();e.status===d.Playing&&(s?(this._preparePacket(s,t,e),e.missedFrames=0):(this._preparePacket(O,t,e),e.missedFrames++,e.missedFrames>=this.behaviors.maxMissedFrames&&this.stop()))}_signalStopSpeaking(){return this.subscribers.forEach(({connection:e})=>e.setSpeaking(!1))}_preparePacket(e,t,s){s.playbackDuration+=20,t.forEach(n=>n.prepareAudioPacket(e))}};function xe(i){return JSON.stringify({...i,resource:Reflect.has(i,"resource"),stepTimeout:Reflect.has(i,"stepTimeout")})}function De(i){return new H(i)}var I;(function(s){s[s.Manual=0]="Manual",s[s.AfterSilence=1]="AfterSilence",s[s.AfterInactivity=2]="AfterInactivity"})(I||(I={}));function ie(){return{end:{behavior:0}}}var J=class extends Ee.Readable{constructor({end:e,...t}){super({...t,objectMode:!0});r(this,"end");r(this,"endTimeout");this.end=e}push(e){return e&&(this.end.behavior===2||this.end.behavior===1&&(e.compare(O)!==0||typeof this.endTimeout=="undefined"))&&this.renewEndTimeout(this.end),super.push(e)}renewEndTimeout(e){this.endTimeout&&clearTimeout(this.endTimeout),this.endTimeout=setTimeout(()=>this.push(null),e.duration)}_read(){}};var Re=h(require("tiny-typed-emitter")),se=class extends Re.TypedEmitter{constructor(){super();r(this,"users");r(this,"speakingTimeouts");this.users=new Map,this.speakingTimeouts=new Map}onPacket(e){let t=this.speakingTimeouts.get(e);t?clearTimeout(t):(this.users.set(e,Date.now()),this.emit("start",e)),this.startTimeout(e)}startTimeout(e){this.speakingTimeouts.set(e,setTimeout(()=>{this.emit("end",e),this.speakingTimeouts.delete(e),this.users.delete(e)},se.DELAY))}},T=se;r(T,"DELAY",100);var Ve=h(require("tiny-typed-emitter")),L=class extends Ve.TypedEmitter{constructor(){super();r(this,"map");this.map=new Map}update(e){let t=this.map.get(e.audioSSRC),s={...this.map.get(e.audioSSRC),...e};this.map.set(e.audioSSRC,s),t||this.emit("create",s),this.emit("update",t,s)}get(e){if(typeof e=="number")return this.map.get(e);for(let t of this.map.values())if(t.userId===e)return t}delete(e){if(typeof e=="number"){let t=this.map.get(e);return t&&(this.map.delete(e),this.emit("delete",t)),t}for(let[t,s]of this.map.entries())if(s.userId===e)return this.map.delete(t),this.emit("delete",s),s}};var q=class{constructor(e){r(this,"voiceConnection");r(this,"ssrcMap");r(this,"subscriptions");r(this,"connectionData");r(this,"speaking");this.voiceConnection=e,this.ssrcMap=new L,this.speaking=new T,this.subscriptions=new Map,this.connectionData={},this.onWsPacket=this.onWsPacket.bind(this),this.onUdpMessage=this.onUdpMessage.bind(this)}onWsPacket(e){e.op===$.VoiceOpcodes.ClientDisconnect&&typeof e.d?.user_id=="string"?this.ssrcMap.delete(e.d.user_id):e.op===$.VoiceOpcodes.Speaking&&typeof e.d?.user_id=="string"&&typeof e.d?.ssrc=="number"?this.ssrcMap.update({userId:e.d.user_id,audioSSRC:e.d.ssrc}):e.op===$.VoiceOpcodes.ClientConnect&&typeof e.d?.user_id=="string"&&typeof e.d?.audio_ssrc=="number"&&this.ssrcMap.update({userId:e.d.user_id,audioSSRC:e.d.audio_ssrc,videoSSRC:e.d.video_ssrc===0?void 0:e.d.video_ssrc})}decrypt(e,t,s,n){let o;t==="xsalsa20_poly1305_lite"?(e.copy(s,0,e.length-4),o=e.length-4):t==="xsalsa20_poly1305_suffix"?(e.copy(s,0,e.length-24),o=e.length-24):e.copy(s,0,0,12);let u=C.open(e.slice(12,o),s,n);if(!!u)return Buffer.from(u)}parsePacket(e,t,s,n){let o=this.decrypt(e,t,s,n);if(!!o){if(o[0]===190&&o[1]===222&&o.length>4){let u=o.readUInt16BE(2),a=4;for(let D=0;D<u;D++){let E=o[a];a++,E!==0&&(a+=1+(E>>4))}let P=o.readUInt8(a);(P===0||P===2)&&a++,o=o.slice(a)}return o}}onUdpMessage(e){if(e.length<=8)return;let t=e.readUInt32BE(8),s=this.ssrcMap.get(t);if(!s)return;this.speaking.onPacket(s.userId);let n=this.subscriptions.get(s.userId);if(!!n&&this.connectionData.encryptionMode&&this.connectionData.nonceBuffer&&this.connectionData.secretKey){let o=this.parsePacket(e,this.connectionData.encryptionMode,this.connectionData.nonceBuffer,this.connectionData.secretKey);o?n.push(o):n.destroy(new Error("Failed to parse packet"))}}subscribe(e,t){let s=this.subscriptions.get(e);if(s)return s;let n=new J({...ie(),...t});return n.once("close",()=>this.subscriptions.delete(e)),this.subscriptions.set(e,n),n}};var c;(function(o){o.Signalling="signalling",o.Connecting="connecting",o.Ready="ready",o.Disconnected="disconnected",o.Destroyed="destroyed"})(c||(c={}));var y;(function(n){n[n.WebSocketClose=0]="WebSocketClose",n[n.AdapterUnavailable=1]="AdapterUnavailable",n[n.EndpointRemoved=2]="EndpointRemoved",n[n.Manual=3]="Manual"})(y||(y={}));var K=class extends Oe.TypedEmitter{constructor(e,{debug:t,adapterCreator:s}){super();r(this,"rejoinAttempts");r(this,"_state");r(this,"joinConfig");r(this,"packets");r(this,"receiver");r(this,"debug");this.debug=t?o=>this.emit("debug",o):null,this.rejoinAttempts=0,this.receiver=new q(this),this.onNetworkingClose=this.onNetworkingClose.bind(this),this.onNetworkingStateChange=this.onNetworkingStateChange.bind(this),this.onNetworkingError=this.onNetworkingError.bind(this),this.onNetworkingDebug=this.onNetworkingDebug.bind(this);let n=s({onVoiceServerUpdate:o=>this.addServerPacket(o),onVoiceStateUpdate:o=>this.addStatePacket(o),destroy:()=>this.destroy(!1)});this._state={status:c.Signalling,adapter:n},this.packets={server:void 0,state:void 0},this.joinConfig=e}get state(){return this._state}set state(e){let t=this._state,s=Reflect.get(t,"networking"),n=Reflect.get(e,"networking"),o=Reflect.get(t,"subscription"),u=Reflect.get(e,"subscription");if(s!==n&&(s&&(s.on("error",g),s.off("debug",this.onNetworkingDebug),s.off("error",this.onNetworkingError),s.off("close",this.onNetworkingClose),s.off("stateChange",this.onNetworkingStateChange),s.destroy()),n&&this.updateReceiveBindings(n.state,s?.state)),e.status===c.Ready)this.rejoinAttempts=0;else if(e.status===c.Destroyed)for(let a of this.receiver.subscriptions.values())a.destroyed||a.destroy();t.status!==c.Destroyed&&e.status===c.Destroyed&&t.adapter.destroy(),this._state=e,o&&o!==u&&o.unsubscribe(),this.emit("stateChange",t,e),t.status!==e.status&&this.emit(e.status,t,e)}addServerPacket(e){this.packets.server=e,e.endpoint?this.configureNetworking():this.state.status!==c.Destroyed&&(this.state={...this.state,status:c.Disconnected,reason:2})}addStatePacket(e){this.packets.state=e,typeof e.self_deaf!="undefined"&&(this.joinConfig.selfDeaf=e.self_deaf),typeof e.self_mute!="undefined"&&(this.joinConfig.selfMute=e.self_mute),e.channel_id&&(this.joinConfig.channelId=e.channel_id)}updateReceiveBindings(e,t){let s=Reflect.get(t??{},"ws"),n=Reflect.get(e,"ws"),o=Reflect.get(t??{},"udp"),u=Reflect.get(e,"udp");s!==n&&(s?.off("packet",this.receiver.onWsPacket),n?.on("packet",this.receiver.onWsPacket)),o!==u&&(o?.off("message",this.receiver.onUdpMessage),u?.on("message",this.receiver.onUdpMessage)),this.receiver.connectionData=Reflect.get(e,"connectionData")??{}}configureNetworking(){let{server:e,state:t}=this.packets;if(!e||!t||this.state.status===c.Destroyed||!e.endpoint)return;let s=new te({endpoint:e.endpoint,serverId:e.guild_id,token:e.token,sessionId:t.session_id,userId:t.user_id},Boolean(this.debug));s.once("close",this.onNetworkingClose),s.on("stateChange",this.onNetworkingStateChange),s.on("error",this.onNetworkingError),s.on("debug",this.onNetworkingDebug),this.state={...this.state,status:c.Connecting,networking:s}}onNetworkingClose(e){this.state.status!==c.Destroyed&&(e===4014?this.state={...this.state,status:c.Disconnected,reason:0,closeCode:e}:(this.state={...this.state,status:c.Signalling},this.rejoinAttempts++,this.state.adapter.sendPayload(R(this.joinConfig))||(this.state={...this.state,status:c.Disconnected,reason:1})))}onNetworkingStateChange(e,t){this.updateReceiveBindings(t,e),e.code!==t.code&&(this.state.status!==c.Connecting&&this.state.status!==c.Ready||(t.code===l.Ready?this.state={...this.state,status:c.Ready}:t.code!==l.Closed&&(this.state={...this.state,status:c.Connecting})))}onNetworkingError(e){this.emit("error",e)}onNetworkingDebug(e){this.debug?.(`[NW] ${e}`)}prepareAudioPacket(e){let t=this.state;if(t.status===c.Ready)return t.networking.prepareAudioPacket(e)}dispatchAudio(){let e=this.state;if(e.status===c.Ready)return e.networking.dispatchAudio()}playOpusPacket(e){let t=this.state;if(t.status===c.Ready)return t.networking.prepareAudioPacket(e),t.networking.dispatchAudio()}destroy(e=!0){if(this.state.status===c.Destroyed)throw new Error("Cannot destroy VoiceConnection - it has already been destroyed");B(this.joinConfig.guildId)===this&&de(this),e&&this.state.adapter.sendPayload(R({...this.joinConfig,channelId:null})),this.state={status:c.Destroyed}}disconnect(){return this.state.status===c.Destroyed||this.state.status===c.Signalling?!1:(this.joinConfig.channelId=null,this.state.adapter.sendPayload(R(this.joinConfig))?(this.state={adapter:this.state.adapter,reason:3,status:c.Disconnected},!0):(this.state={adapter:this.state.adapter,subscription:this.state.subscription,status:c.Disconnected,reason:1},!1))}rejoin(e){if(this.state.status===c.Destroyed)return!1;let t=this.state.status!==c.Ready;return t&&this.rejoinAttempts++,Object.assign(this.joinConfig,e),this.state.adapter.sendPayload(R(this.joinConfig))?(t&&(this.state={...this.state,status:c.Signalling}),!0):(this.state={adapter:this.state.adapter,subscription:this.state.subscription,status:c.Disconnected,reason:1},!1)}setSpeaking(e){return this.state.status!==c.Ready?!1:this.state.networking.setSpeaking(e)}subscribe(e){if(this.state.status===c.Destroyed)return;let t=e.subscribe(this);return this.state={...this.state,subscription:t},t}get ping(){return this.state.status===c.Ready&&this.state.networking.state.code===l.Ready?{ws:this.state.networking.state.ws.ping,udp:this.state.networking.state.udp.ping}:{ws:void 0,udp:void 0}}onSubscriptionRemoved(e){this.state.status!==c.Destroyed&&this.state.subscription===e&&(this.state={...this.state,subscription:void 0})}};function Ie(i,e){let t=R(i),s=B(i.guildId);if(s&&s.state.status!==c.Destroyed)return s.state.status===c.Disconnected?s.rejoin({channelId:i.channelId,selfDeaf:i.selfDeaf,selfMute:i.selfMute}):s.state.adapter.sendPayload(t)||(s.state={...s.state,status:c.Disconnected,reason:1}),s;let n=new K(i,e);return ue(n),n.state.status!==c.Destroyed&&(n.state.adapter.sendPayload(t)||(n.state={...n.state,status:c.Disconnected,reason:1})),n}function gt(i){let e={selfDeaf:!0,selfMute:!1,group:"default",...i};return Ie(e,{adapterCreator:i.adapterCreator,debug:i.debug})}var v=h(require("prism-media")),_e=["-analyzeduration","0","-loglevel","0","-f","s16le","-ar","48000","-ac","2"],Me=["-analyzeduration","0","-loglevel","0","-acodec","libopus","-f","opus","-ar","48000","-ac","2"],p;(function(o){o.Arbitrary="arbitrary",o.Raw="raw",o.OggOpus="ogg/opus",o.WebmOpus="webm/opus",o.Opus="opus"})(p||(p={}));var b;(function(a){a.FFmpegPCM="ffmpeg pcm",a.FFmpegOgg="ffmpeg ogg",a.OpusEncoder="opus encoder",a.OpusDecoder="opus decoder",a.OggOpusDemuxer="ogg/opus demuxer",a.WebmOpusDemuxer="webm/opus demuxer",a.InlineVolume="volume transformer"})(b||(b={}));var Ue=class{constructor(e){r(this,"edges",[]);r(this,"type");this.type=e}addEdge(e){this.edges.push({...e,from:this})}},Be=new Map;for(let i of Object.values(p))Be.set(i,new Ue(i));function m(i){let e=Be.get(i);if(!e)throw new Error(`Node type '${i}' does not exist!`);return e}m(p.Raw).addEdge({type:b.OpusEncoder,to:m(p.Opus),cost:1.5,transformer:()=>new v.default.opus.Encoder({rate:48e3,channels:2,frameSize:960})});m(p.Opus).addEdge({type:b.OpusDecoder,to:m(p.Raw),cost:1.5,transformer:()=>new v.default.opus.Decoder({rate:48e3,channels:2,frameSize:960})});m(p.OggOpus).addEdge({type:b.OggOpusDemuxer,to:m(p.Opus),cost:1,transformer:()=>new v.default.opus.OggDemuxer});m(p.WebmOpus).addEdge({type:b.WebmOpusDemuxer,to:m(p.Opus),cost:1,transformer:()=>new v.default.opus.WebmDemuxer});var oe={type:b.FFmpegPCM,to:m(p.Raw),cost:2,transformer:i=>new v.default.FFmpeg({args:typeof i=="string"?["-i",i,..._e]:_e})};m(p.Arbitrary).addEdge(oe);m(p.OggOpus).addEdge(oe);m(p.WebmOpus).addEdge(oe);m(p.Raw).addEdge({type:b.InlineVolume,to:m(p.Raw),cost:.5,transformer:()=>new v.default.VolumeTransformer({type:"s16le"})});function yt(){try{return v.default.FFmpeg.getInfo().output.includes("--enable-libopus")}catch{}return!1}if(yt()){let i={type:b.FFmpegOgg,to:m(p.OggOpus),cost:2,transformer:e=>new v.default.FFmpeg({args:typeof e=="string"?["-i",e,...Me]:Me})};m(p.Arbitrary).addEdge(i),m(p.OggOpus).addEdge(i),m(p.WebmOpus).addEdge(i)}function Ne(i,e,t=m(p.Opus),s=[],n=5){if(i===t&&e(s))return{cost:0};if(n===0)return{cost:1/0};let o;for(let u of i.edges){if(o&&u.cost>o.cost)continue;let a=Ne(u.to,e,t,[...s,u],n-1),P=u.cost+a.cost;(!o||P<o.cost)&&(o={cost:P,edge:u,next:a})}return o??{cost:1/0}}function bt(i){let e=[],t=i;for(;t?.edge;)e.push(t.edge),t=t.next;return e}function We(i,e){return bt(Ne(m(i),e))}var Te=h(require("node:stream"));var A=h(require("prism-media"));var j=class{constructor(e,t,s,n){r(this,"playStream");r(this,"edges");r(this,"metadata");r(this,"volume");r(this,"encoder");r(this,"audioPlayer");r(this,"playbackDuration",0);r(this,"started",!1);r(this,"silencePaddingFrames");r(this,"silenceRemaining",-1);this.edges=e,this.playStream=t.length>1?(0,Te.pipeline)(t,g):t[0],this.metadata=s,this.silencePaddingFrames=n;for(let o of t)o instanceof A.default.VolumeTransformer?this.volume=o:o instanceof A.default.opus.Encoder&&(this.encoder=o);this.playStream.once("readable",()=>this.started=!0)}get readable(){if(this.silenceRemaining===0)return!1;let e=this.playStream.readable;return e||(this.silenceRemaining===-1&&(this.silenceRemaining=this.silencePaddingFrames),this.silenceRemaining!==0)}get ended(){return this.playStream.readableEnded||this.playStream.destroyed||this.silenceRemaining===0}read(){if(this.silenceRemaining===0)return null;if(this.silenceRemaining>0)return this.silenceRemaining--,O;let e=this.playStream.read();return e&&(this.playbackDuration+=20),e}},St=i=>i.some(e=>e.type===b.InlineVolume),kt=()=>!0;function vt(i){return i instanceof A.default.opus.Encoder?{streamType:p.Opus,hasVolume:!1}:i instanceof A.default.opus.Decoder?{streamType:p.Raw,hasVolume:!1}:i instanceof A.default.VolumeTransformer?{streamType:p.Raw,hasVolume:!0}:i instanceof A.default.opus.OggDemuxer?{streamType:p.Opus,hasVolume:!1}:i instanceof A.default.opus.WebmDemuxer?{streamType:p.Opus,hasVolume:!1}:{streamType:p.Arbitrary,hasVolume:!1}}function je(i,e={}){let t=e.inputType,s=Boolean(e.inlineVolume);if(typeof i=="string")t=p.Arbitrary;else if(typeof t=="undefined"){let u=vt(i);t=u.streamType,s=s&&!u.hasVolume}let n=We(t,s?St:kt);if(n.length===0){if(typeof i=="string")throw new Error(`Invalid pipeline constructed for string resource '${i}'`);return new j([],[i],e.metadata??null,e.silencePaddingFrames??5)}let o=n.map(u=>u.transformer(i));return typeof i!="string"&&o.unshift(i),new j(n,o,e.metadata??null,e.silencePaddingFrames??5)}var F=h(require("node:path")),Ge=h(require("prism-media"));function Ct(){let i=[],e=t=>i.push(`- ${t}: ${At(t)}`);i.push("Core Dependencies"),e("@discordjs/voice"),e("prism-media"),i.push(""),i.push("Opus Libraries"),e("@discordjs/opus"),e("opusscript"),i.push(""),i.push("Encryption Libraries"),e("sodium"),e("libsodium-wrappers"),e("tweetnacl"),i.push(""),i.push("FFmpeg");try{let t=Ge.default.FFmpeg.getInfo();i.push(`- version: ${t.version}`),i.push(`- libopus: ${t.output.includes("--enable-libopus")?"yes":"no"}`)}catch{i.push("- not found")}return["-".repeat(50),...i,"-".repeat(50)].join(`
|
|
13
|
-
`)}
|
|
14
|
-
//# sourceMappingURL=index.js.map
|
|
8
|
+
to ${xe(e)}`)}play(e){if(e.ended)throw new Error("Cannot play a resource that has already ended.");if(e.audioPlayer){if(e.audioPlayer===this)return;throw new Error("Resource is already being played by another audio player.")}e.audioPlayer=this;let t=r(o=>{this.state.status!=="idle"&&this.emit("error",new w(o,this.state.resource)),this.state.status!=="idle"&&this.state.resource===e&&(this.state={status:"idle"})},"onStreamError");if(e.playStream.once("error",t),e.started)this.state={status:"playing",missedFrames:0,playbackDuration:0,resource:e,onStreamError:t};else{let o=r(()=>{this.state.status==="buffering"&&this.state.resource===e&&(this.state={status:"playing",missedFrames:0,playbackDuration:0,resource:e,onStreamError:t})},"onReadableCallback"),s=r(()=>{this.state.status==="buffering"&&this.state.resource===e&&(this.state={status:"idle"})},"onFailureCallback");e.playStream.once("readable",o),e.playStream.once("end",s),e.playStream.once("close",s),e.playStream.once("finish",s),this.state={status:"buffering",resource:e,onReadableCallback:o,onFailureCallback:s,onStreamError:t}}}pause(e=!0){return this.state.status!=="playing"?!1:(this.state={...this.state,status:"paused",silencePacketsRemaining:e?5:0},!0)}unpause(){return this.state.status!=="paused"?!1:(this.state={...this.state,status:"playing",missedFrames:0},!0)}stop(e=!1){return this.state.status==="idle"?!1:(e||this.state.resource.silencePaddingFrames===0?this.state={status:"idle"}:this.state.resource.silenceRemaining===-1&&(this.state.resource.silenceRemaining=this.state.resource.silencePaddingFrames),!0)}checkPlayable(){let e=this._state;return e.status==="idle"||e.status==="buffering"?!1:e.resource.readable?!0:(this.state={status:"idle"},!1)}_stepDispatch(){let e=this._state;e.status==="idle"||e.status==="buffering"||this.playable.forEach(t=>t.dispatchAudio())}_stepPrepare(){let e=this._state;if(e.status==="idle"||e.status==="buffering")return;let t=this.playable;if(e.status==="autopaused"&&t.length>0&&(this.state={...e,status:"playing",missedFrames:0}),e.status==="paused"||e.status==="autopaused"){e.silencePacketsRemaining>0&&(e.silencePacketsRemaining--,this._preparePacket(V,t,e),e.silencePacketsRemaining===0&&this._signalStopSpeaking());return}if(t.length===0)if(this.behaviors.noSubscriber==="pause"){this.state={...e,status:"autopaused",silencePacketsRemaining:5};return}else this.behaviors.noSubscriber==="stop"&&this.stop(!0);let o=e.resource.read();e.status==="playing"&&(o?(this._preparePacket(o,t,e),e.missedFrames=0):(this._preparePacket(V,t,e),e.missedFrames++,e.missedFrames>=this.behaviors.maxMissedFrames&&this.stop()))}_signalStopSpeaking(){return this.subscribers.forEach(({connection:e})=>e.setSpeaking(!1))}_preparePacket(e,t,o){o.playbackDuration+=20,t.forEach(s=>s.prepareAudioPacket(e))}};r(N,"AudioPlayer");function Ve(i){return new N(i)}r(Ve,"createAudioPlayer");var Ee=(o=>(o[o.Manual=0]="Manual",o[o.AfterSilence=1]="AfterSilence",o[o.AfterInactivity=2]="AfterInactivity",o))(Ee||{});function Q(){return{end:{behavior:0}}}r(Q,"createDefaultAudioReceiveStreamOptions");var B=class extends De.Readable{constructor({end:e,...t}){super({...t,objectMode:!0});a(this,"end");a(this,"endTimeout");this.end=e}push(e){return e&&(this.end.behavior===2||this.end.behavior===1&&(e.compare(V)!==0||typeof this.endTimeout=="undefined"))&&this.renewEndTimeout(this.end),super.push(e)}renewEndTimeout(e){this.endTimeout&&clearTimeout(this.endTimeout),this.endTimeout=setTimeout(()=>this.push(null),e.duration)}_read(){}};r(B,"AudioReceiveStream");var Re=require("tiny-typed-emitter"),ee=class extends Re.TypedEmitter{constructor(){super();a(this,"users");a(this,"speakingTimeouts");this.users=new Map,this.speakingTimeouts=new Map}onPacket(e){let t=this.speakingTimeouts.get(e);t?clearTimeout(t):(this.users.set(e,Date.now()),this.emit("start",e)),this.startTimeout(e)}startTimeout(e){this.speakingTimeouts.set(e,setTimeout(()=>{this.emit("end",e),this.speakingTimeouts.delete(e),this.users.delete(e)},ee.DELAY))}},D=ee;r(D,"SpeakingMap"),a(D,"DELAY",100);var Oe=require("tiny-typed-emitter"),M=class extends Oe.TypedEmitter{constructor(){super();a(this,"map");this.map=new Map}update(e){let t=this.map.get(e.audioSSRC),o={...this.map.get(e.audioSSRC),...e};this.map.set(e.audioSSRC,o),t||this.emit("create",o),this.emit("update",t,o)}get(e){if(typeof e=="number")return this.map.get(e);for(let t of this.map.values())if(t.userId===e)return t}delete(e){if(typeof e=="number"){let t=this.map.get(e);return t&&(this.map.delete(e),this.emit("delete",t)),t}for(let[t,o]of this.map.entries())if(o.userId===e)return this.map.delete(t),this.emit("delete",o),o}};r(M,"SSRCMap");var U=class{constructor(e){a(this,"voiceConnection");a(this,"ssrcMap");a(this,"subscriptions");a(this,"connectionData");a(this,"speaking");this.voiceConnection=e,this.ssrcMap=new M,this.speaking=new D,this.subscriptions=new Map,this.connectionData={},this.onWsPacket=this.onWsPacket.bind(this),this.onUdpMessage=this.onUdpMessage.bind(this)}onWsPacket(e){e.op===$.VoiceOpcodes.ClientDisconnect&&typeof e.d?.user_id=="string"?this.ssrcMap.delete(e.d.user_id):e.op===$.VoiceOpcodes.Speaking&&typeof e.d?.user_id=="string"&&typeof e.d?.ssrc=="number"?this.ssrcMap.update({userId:e.d.user_id,audioSSRC:e.d.ssrc}):e.op===$.VoiceOpcodes.ClientConnect&&typeof e.d?.user_id=="string"&&typeof e.d?.audio_ssrc=="number"&&this.ssrcMap.update({userId:e.d.user_id,audioSSRC:e.d.audio_ssrc,videoSSRC:e.d.video_ssrc===0?void 0:e.d.video_ssrc})}decrypt(e,t,o,s){let n;t==="xsalsa20_poly1305_lite"?(e.copy(o,0,e.length-4),n=e.length-4):t==="xsalsa20_poly1305_suffix"?(e.copy(o,0,e.length-24),n=e.length-24):e.copy(o,0,0,12);let c=y.open(e.slice(12,n),o,s);if(!!c)return Buffer.from(c)}parsePacket(e,t,o,s){let n=this.decrypt(e,t,o,s);if(!!n){if(n[0]===190&&n[1]===222&&n.length>4){let c=n.readUInt16BE(2),u=4;for(let C=0;C<c;C++){let k=n[u];u++,k!==0&&(u+=1+(k>>4))}let g=n.readUInt8(u);(g===0||g===2)&&u++,n=n.slice(u)}return n}}onUdpMessage(e){if(e.length<=8)return;let t=e.readUInt32BE(8),o=this.ssrcMap.get(t);if(!o)return;this.speaking.onPacket(o.userId);let s=this.subscriptions.get(o.userId);if(!!s&&this.connectionData.encryptionMode&&this.connectionData.nonceBuffer&&this.connectionData.secretKey){let n=this.parsePacket(e,this.connectionData.encryptionMode,this.connectionData.nonceBuffer,this.connectionData.secretKey);n?s.push(n):s.destroy(new Error("Failed to parse packet"))}}subscribe(e,t){let o=this.subscriptions.get(e);if(o)return o;let s=new B({...Q(),...t});return s.once("close",()=>this.subscriptions.delete(e)),this.subscriptions.set(e,s),s}};r(U,"VoiceReceiver");var L=(n=>(n.Signalling="signalling",n.Connecting="connecting",n.Ready="ready",n.Disconnected="disconnected",n.Destroyed="destroyed",n))(L||{}),te=(s=>(s[s.WebSocketClose=0]="WebSocketClose",s[s.AdapterUnavailable=1]="AdapterUnavailable",s[s.EndpointRemoved=2]="EndpointRemoved",s[s.Manual=3]="Manual",s))(te||{}),W=class extends Ie.TypedEmitter{constructor(e,{debug:t,adapterCreator:o}){super();a(this,"rejoinAttempts");a(this,"_state");a(this,"joinConfig");a(this,"packets");a(this,"receiver");a(this,"debug");this.debug=t?n=>this.emit("debug",n):null,this.rejoinAttempts=0,this.receiver=new U(this),this.onNetworkingClose=this.onNetworkingClose.bind(this),this.onNetworkingStateChange=this.onNetworkingStateChange.bind(this),this.onNetworkingError=this.onNetworkingError.bind(this),this.onNetworkingDebug=this.onNetworkingDebug.bind(this);let s=o({onVoiceServerUpdate:n=>this.addServerPacket(n),onVoiceStateUpdate:n=>this.addStatePacket(n),destroy:()=>this.destroy(!1)});this._state={status:"signalling",adapter:s},this.packets={server:void 0,state:void 0},this.joinConfig=e}get state(){return this._state}set state(e){let t=this._state,o=Reflect.get(t,"networking"),s=Reflect.get(e,"networking"),n=Reflect.get(t,"subscription"),c=Reflect.get(e,"subscription");if(o!==s&&(o&&(o.on("error",l),o.off("debug",this.onNetworkingDebug),o.off("error",this.onNetworkingError),o.off("close",this.onNetworkingClose),o.off("stateChange",this.onNetworkingStateChange),o.destroy()),s&&this.updateReceiveBindings(s.state,o?.state)),e.status==="ready")this.rejoinAttempts=0;else if(e.status==="destroyed")for(let u of this.receiver.subscriptions.values())u.destroyed||u.destroy();t.status!=="destroyed"&&e.status==="destroyed"&&t.adapter.destroy(),this._state=e,n&&n!==c&&n.unsubscribe(),this.emit("stateChange",t,e),t.status!==e.status&&this.emit(e.status,t,e)}addServerPacket(e){this.packets.server=e,e.endpoint?this.configureNetworking():this.state.status!=="destroyed"&&(this.state={...this.state,status:"disconnected",reason:2})}addStatePacket(e){this.packets.state=e,typeof e.self_deaf!="undefined"&&(this.joinConfig.selfDeaf=e.self_deaf),typeof e.self_mute!="undefined"&&(this.joinConfig.selfMute=e.self_mute),e.channel_id&&(this.joinConfig.channelId=e.channel_id)}updateReceiveBindings(e,t){let o=Reflect.get(t??{},"ws"),s=Reflect.get(e,"ws"),n=Reflect.get(t??{},"udp"),c=Reflect.get(e,"udp");o!==s&&(o?.off("packet",this.receiver.onWsPacket),s?.on("packet",this.receiver.onWsPacket)),n!==c&&(n?.off("message",this.receiver.onUdpMessage),c?.on("message",this.receiver.onUdpMessage)),this.receiver.connectionData=Reflect.get(e,"connectionData")??{}}configureNetworking(){let{server:e,state:t}=this.packets;if(!e||!t||this.state.status==="destroyed"||!e.endpoint)return;let o=new J({endpoint:e.endpoint,serverId:e.guild_id,token:e.token,sessionId:t.session_id,userId:t.user_id},Boolean(this.debug));o.once("close",this.onNetworkingClose),o.on("stateChange",this.onNetworkingStateChange),o.on("error",this.onNetworkingError),o.on("debug",this.onNetworkingDebug),this.state={...this.state,status:"connecting",networking:o}}onNetworkingClose(e){this.state.status!=="destroyed"&&(e===4014?this.state={...this.state,status:"disconnected",reason:0,closeCode:e}:(this.state={...this.state,status:"signalling"},this.rejoinAttempts++,this.state.adapter.sendPayload(P(this.joinConfig))||(this.state={...this.state,status:"disconnected",reason:1})))}onNetworkingStateChange(e,t){this.updateReceiveBindings(t,e),e.code!==t.code&&(this.state.status!=="connecting"&&this.state.status!=="ready"||(t.code===4?this.state={...this.state,status:"ready"}:t.code!==6&&(this.state={...this.state,status:"connecting"})))}onNetworkingError(e){this.emit("error",e)}onNetworkingDebug(e){this.debug?.(`[NW] ${e}`)}prepareAudioPacket(e){let t=this.state;if(t.status==="ready")return t.networking.prepareAudioPacket(e)}dispatchAudio(){let e=this.state;if(e.status==="ready")return e.networking.dispatchAudio()}playOpusPacket(e){let t=this.state;if(t.status==="ready")return t.networking.prepareAudioPacket(e),t.networking.dispatchAudio()}destroy(e=!0){if(this.state.status==="destroyed")throw new Error("Cannot destroy VoiceConnection - it has already been destroyed");_(this.joinConfig.guildId)===this&&de(this),e&&this.state.adapter.sendPayload(P({...this.joinConfig,channelId:null})),this.state={status:"destroyed"}}disconnect(){return this.state.status==="destroyed"||this.state.status==="signalling"?!1:(this.joinConfig.channelId=null,this.state.adapter.sendPayload(P(this.joinConfig))?(this.state={adapter:this.state.adapter,reason:3,status:"disconnected"},!0):(this.state={adapter:this.state.adapter,subscription:this.state.subscription,status:"disconnected",reason:1},!1))}rejoin(e){if(this.state.status==="destroyed")return!1;let t=this.state.status!=="ready";return t&&this.rejoinAttempts++,Object.assign(this.joinConfig,e),this.state.adapter.sendPayload(P(this.joinConfig))?(t&&(this.state={...this.state,status:"signalling"}),!0):(this.state={adapter:this.state.adapter,subscription:this.state.subscription,status:"disconnected",reason:1},!1)}setSpeaking(e){return this.state.status!=="ready"?!1:this.state.networking.setSpeaking(e)}subscribe(e){if(this.state.status==="destroyed")return;let t=e.subscribe(this);return this.state={...this.state,subscription:t},t}get ping(){return this.state.status==="ready"&&this.state.networking.state.code===4?{ws:this.state.networking.state.ws.ping,udp:this.state.networking.state.udp.ping}:{ws:void 0,udp:void 0}}onSubscriptionRemoved(e){this.state.status!=="destroyed"&&this.state.subscription===e&&(this.state={...this.state,subscription:void 0})}};r(W,"VoiceConnection");function Te(i,e){let t=P(i),o=_(i.guildId);if(o&&o.state.status!=="destroyed")return o.state.status==="disconnected"?o.rejoin({channelId:i.channelId,selfDeaf:i.selfDeaf,selfMute:i.selfMute}):o.state.adapter.sendPayload(t)||(o.state={...o.state,status:"disconnected",reason:1}),o;let s=new W(i,e);return ue(s),s.state.status!=="destroyed"&&(s.state.adapter.sendPayload(t)||(s.state={...s.state,status:"disconnected",reason:1})),s}r(Te,"createVoiceConnection");function yt(i){let e={selfDeaf:!0,selfMute:!1,group:"default",...i};return Te(e,{adapterCreator:i.adapterCreator,debug:i.debug})}r(yt,"joinVoiceChannel");var m=I(require("prism-media")),_e=["-analyzeduration","0","-loglevel","0","-f","s16le","-ar","48000","-ac","2"],Ne=["-analyzeduration","0","-loglevel","0","-acodec","libopus","-f","opus","-ar","48000","-ac","2"],E=(n=>(n.Arbitrary="arbitrary",n.Raw="raw",n.OggOpus="ogg/opus",n.WebmOpus="webm/opus",n.Opus="opus",n))(E||{});var ie=class{constructor(e){a(this,"edges",[]);a(this,"type");this.type=e}addEdge(e){this.edges.push({...e,from:this})}};r(ie,"Node");var Be=new Map;for(let i of Object.values(E))Be.set(i,new ie(i));function p(i){let e=Be.get(i);if(!e)throw new Error(`Node type '${i}' does not exist!`);return e}r(p,"getNode");p("raw").addEdge({type:"opus encoder",to:p("opus"),cost:1.5,transformer:()=>new m.default.opus.Encoder({rate:48e3,channels:2,frameSize:960})});p("opus").addEdge({type:"opus decoder",to:p("raw"),cost:1.5,transformer:()=>new m.default.opus.Decoder({rate:48e3,channels:2,frameSize:960})});p("ogg/opus").addEdge({type:"ogg/opus demuxer",to:p("opus"),cost:1,transformer:()=>new m.default.opus.OggDemuxer});p("webm/opus").addEdge({type:"webm/opus demuxer",to:p("opus"),cost:1,transformer:()=>new m.default.opus.WebmDemuxer});var oe={type:"ffmpeg pcm",to:p("raw"),cost:2,transformer:i=>new m.default.FFmpeg({args:typeof i=="string"?["-i",i,..._e]:_e})};p("arbitrary").addEdge(oe);p("ogg/opus").addEdge(oe);p("webm/opus").addEdge(oe);p("raw").addEdge({type:"volume transformer",to:p("raw"),cost:.5,transformer:()=>new m.default.VolumeTransformer({type:"s16le"})});function bt(){try{return m.default.FFmpeg.getInfo().output.includes("--enable-libopus")}catch{}return!1}r(bt,"canEnableFFmpegOptimizations");if(bt()){let i={type:"ffmpeg ogg",to:p("ogg/opus"),cost:2,transformer:e=>new m.default.FFmpeg({args:typeof e=="string"?["-i",e,...Ne]:Ne})};p("arbitrary").addEdge(i),p("ogg/opus").addEdge(i),p("webm/opus").addEdge(i)}function Me(i,e,t=p("opus"),o=[],s=5){if(i===t&&e(o))return{cost:0};if(s===0)return{cost:1/0};let n;for(let c of i.edges){if(n&&c.cost>n.cost)continue;let u=Me(c.to,e,t,[...o,c],s-1),g=c.cost+u.cost;(!n||g<n.cost)&&(n={cost:g,edge:c,next:u})}return n??{cost:1/0}}r(Me,"findPath");function St(i){let e=[],t=i;for(;t?.edge;)e.push(t.edge),t=t.next;return e}r(St,"constructPipeline");function Ue(i,e){return St(Me(p(i),e))}r(Ue,"findPipeline");var We=require("stream");var b=I(require("prism-media"));var R=class{constructor(e,t,o,s){a(this,"playStream");a(this,"edges");a(this,"metadata");a(this,"volume");a(this,"encoder");a(this,"audioPlayer");a(this,"playbackDuration",0);a(this,"started",!1);a(this,"silencePaddingFrames");a(this,"silenceRemaining",-1);this.edges=e,this.playStream=t.length>1?(0,We.pipeline)(t,l):t[0],this.metadata=o,this.silencePaddingFrames=s;for(let n of t)n instanceof b.default.VolumeTransformer?this.volume=n:n instanceof b.default.opus.Encoder&&(this.encoder=n);this.playStream.once("readable",()=>this.started=!0)}get readable(){if(this.silenceRemaining===0)return!1;let e=this.playStream.readable;return e||(this.silenceRemaining===-1&&(this.silenceRemaining=this.silencePaddingFrames),this.silenceRemaining!==0)}get ended(){return this.playStream.readableEnded||this.playStream.destroyed||this.silenceRemaining===0}read(){if(this.silenceRemaining===0)return null;if(this.silenceRemaining>0)return this.silenceRemaining--,V;let e=this.playStream.read();return e&&(this.playbackDuration+=20),e}};r(R,"AudioResource");var Ct=r(i=>i.some(e=>e.type==="volume transformer"),"VOLUME_CONSTRAINT"),kt=r(()=>!0,"NO_CONSTRAINT");function At(i){return i instanceof b.default.opus.Encoder?{streamType:"opus",hasVolume:!1}:i instanceof b.default.opus.Decoder?{streamType:"raw",hasVolume:!1}:i instanceof b.default.VolumeTransformer?{streamType:"raw",hasVolume:!0}:i instanceof b.default.opus.OggDemuxer?{streamType:"opus",hasVolume:!1}:i instanceof b.default.opus.WebmDemuxer?{streamType:"opus",hasVolume:!1}:{streamType:"arbitrary",hasVolume:!1}}r(At,"inferStreamType");function Fe(i,e={}){let t=e.inputType,o=Boolean(e.inlineVolume);if(typeof i=="string")t="arbitrary";else if(typeof t=="undefined"){let c=At(i);t=c.streamType,o=o&&!c.hasVolume}let s=Ue(t,o?Ct:kt);if(s.length===0){if(typeof i=="string")throw new Error(`Invalid pipeline constructed for string resource '${i}'`);return new R([],[i],e.metadata??null,e.silencePaddingFrames??5)}let n=s.map(c=>c.transformer(i));return typeof i!="string"&&n.unshift(i),new R(s,n,e.metadata??null,e.silencePaddingFrames??5)}r(Fe,"createAudioResource");var F=require("path"),Ge=I(require("prism-media"));function He(i,e,t){if(t===0)return;let o=(0,F.resolve)(i,"./package.json");try{let s=require(o);if(s.name!==e)throw new Error("package.json does not match");return s}catch{return He((0,F.resolve)(i,".."),e,t-1)}}r(He,"findPackageJSON");function vt(i){try{return(i==="@discordjs/voice"?je():He((0,F.dirname)(require.resolve(i)),i,3))?.version??"not found"}catch{return"not found"}}r(vt,"version");function wt(){let i=[],e=r(t=>i.push(`- ${t}: ${vt(t)}`),"addVersion");i.push("Core Dependencies"),e("@discordjs/voice"),e("prism-media"),i.push(""),i.push("Opus Libraries"),e("@discordjs/opus"),e("opusscript"),i.push(""),i.push("Encryption Libraries"),e("sodium"),e("libsodium-wrappers"),e("tweetnacl"),i.push(""),i.push("FFmpeg");try{let t=Ge.default.FFmpeg.getInfo();i.push(`- version: ${t.version}`),i.push(`- libopus: ${t.output.includes("--enable-libopus")?"yes":"no"}`)}catch{i.push("- not found")}return["-".repeat(50),...i,"-".repeat(50)].join(`
|
|
9
|
+
`)}r(wt,"generateDependencyReport");function Je(i){let e=new AbortController,t=setTimeout(()=>e.abort(),i);return e.signal.addEventListener("abort",()=>clearTimeout(t)),[e,e.signal]}r(Je,"abortAfter");var Le=require("events");async function xt(i,e,t){if(i.state.status!==e){let[o,s]=typeof t=="number"?Je(t):[void 0,t];try{await(0,Le.once)(i,e,{signal:s})}finally{o?.abort()}}return i}r(xt,"entersState");var $e=require("stream"),se=I(require("prism-media"));function qe(i){let e=i.readUInt8(9),t=i.readUInt32LE(12);return e===2&&t===48e3}r(qe,"validateDiscordOpusHead");function Vt(i,e=1024,t=qe){return new Promise((o,s)=>{if(i.readableObjectMode)return s(new Error("Cannot probe a readable stream in object mode"));if(i.readableEnded)return s(new Error("Cannot probe a stream that has ended"));let n=Buffer.alloc(0),c,u=r(f=>{i.off("data",q),i.off("close",O),i.off("end",O),i.pause(),c=f,i.readableEnded?o({stream:$e.Readable.from(n),type:f}):(n.length>0&&i.push(n),o({stream:i,type:f}))},"finish"),g=r(f=>Ke=>{t(Ke)&&u(f)},"foundHead"),C=new se.default.opus.WebmDemuxer;C.once("error",l),C.on("head",g("webm/opus"));let k=new se.default.opus.OggDemuxer;k.once("error",l),k.on("head",g("ogg/opus"));let O=r(()=>{c||u("arbitrary")},"onClose"),q=r(f=>{n=Buffer.concat([n,f]),C.write(f),k.write(f),n.length>=e&&(i.off("data",q),i.pause(),process.nextTick(O))},"onData");i.once("error",s),i.on("data",q),i.once("close",O),i.once("end",O)})}r(Vt,"demuxProbe");module.exports=ot(Dt);0&&(module.exports={AudioPlayer,AudioPlayerError,AudioPlayerStatus,AudioReceiveStream,AudioResource,EndBehaviorType,NoSubscriberBehavior,PlayerSubscription,SSRCMap,SpeakingMap,StreamType,VoiceConnection,VoiceConnectionDisconnectReason,VoiceConnectionStatus,VoiceReceiver,createAudioPlayer,createAudioResource,createDefaultAudioReceiveStreamOptions,demuxProbe,entersState,generateDependencyReport,getGroups,getVoiceConnection,getVoiceConnections,joinVoiceChannel,validateDiscordOpusHead});
|
|
10
|
+
//# sourceMappingURL=index.js.map
|