Updated types and dependencies #18

Merged
FrauJulian merged 6 commits from fraujulian into master 2025-10-10 16:12:13 +00:00
21 changed files with 15985 additions and 721 deletions
+3 -3
View File
@@ -15,10 +15,10 @@ jobs:
- name: Checkout Repository
uses: actions/checkout@v4
- name: use NodeJS v22.16.0
- name: use NodeJS v22.12.0
uses: actions/setup-node@v4
with:
node-version: '22.16.0'
node-version: '22.12.0'
registry-url: 'https://registry.npmjs.org'
always-auth: true
@@ -31,7 +31,7 @@ jobs:
run: npm install
- name: run Rollout Build
run: npm run rolloutBuild
run: npm run build
- name: Publish Library
run: npm publish
+1 -1
View File
@@ -20,4 +20,4 @@ jobs:
run: npm install
- name: run Rollout Build
run: npm run rolloutBuild
run: npm run build
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env sh
npm run format || exit 1
npm run lint:fix || exit 1
+13
View File
@@ -0,0 +1,13 @@
{
"printWidth": 140,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"trailingComma": "all",
"semi": true,
"arrowParens": "always",
"bracketSpacing": true,
"bracketSameLine": false,
"quoteProps": "as-needed",
"endOfLine": "crlf"
}
+46 -46
View File
@@ -15,19 +15,25 @@ Please create an [issue](https://github.com/FrauJulian/DiscordAudioStreamNPM/iss
## 📝 Usage
### Install package
### Install
> **Supported package managers:** npm, yarn, pnpm, bun
#### Recommended:
```bash
npm install discord-audio-stream
yarn add discord-audio-stream
pnpm add discord-audio-stream
bun add discord-audio-stream
npm install discord-audio-stream @snazzah/davey @discordjs/opus
yarn add discord-audio-stream @snazzah/davey @discordjs/opus
pnpm add discord-audio-stream @snazzah/davey @discordjs/opus
bun add discord-audio-stream @snazzah/davey @discordjs/opus
```
You need `@snazzah/davey` and one of the encryption libraries to run this package!
**Encryption Libraries (npm install):**
> You only need to install one of these libraries if your system does not support `aes-256-gcm` (verify by running
`require('node:crypto').getCiphers().includes('aes-256-gcm')`).
> `require('node:crypto').getCiphers().includes('aes-256-gcm')`).
- `sodium-native`
- `sodium`
@@ -54,15 +60,17 @@ let audioManager = new AudioManager();
or (with parameters)
```js
let audioManager = new AudioManager({
VoiceChannelId: 0, //voice channel id where to play music
GuildId: 0, //guild id
VoiceAdapter: 0 //guild VoiceAdapter
},
{
ResourceType: "", //resource type like link or file
Resource: "" //auto play link or file name
});
let audioManager = new AudioManager(
{
VoiceChannelId: 0, //voice channel id where to play music
GuildId: 0, //guild id
VoiceAdapter: 0, //guild VoiceAdapter
},
{
ResourceType: '', //resource type like link or file
Resource: '', //auto play link or file name
},
);
```
### Properties of the AudioManager
@@ -70,7 +78,7 @@ let audioManager = new AudioManager({
#### Properties
| Callable with | Type | Description |
|-------------------|------------------------------|-------------------------------------------------|
| ----------------- | ---------------------------- | ----------------------------------------------- |
| `VoiceConnection` | **VoiceConnection** | VoiceConnection instance from discord.js/voice. |
| `AudioPlayer` | **AudioPlayer** | AudioPlayer instance from discord.js/voice. |
| `AudioResource` | **AudioResource** | AudioResource instance from discord.js/voice. |
@@ -79,42 +87,34 @@ let audioManager = new AudioManager({
#### Methods
| Callable with | Parameters | Return type | Description |
|--------------------------------|---------------------------------------------------------|-------------|---------------------------------------------------------------|
| `OverrideVoiceConnectionData` | `connectionData` (type of **VoiceConnectionDataModel**) | void | Method to override global connectionData variable. |
| `OverrideVoiceAudioDataModel` | `audioData` (type of **VoiceAudioDataModel**) | void | Method to override global audioData variable. |
| `OverrideRenewInMs` | `renewInMs` (type of int, default value is 5400000) | void | Method to override global renewInMs variable. |
| `CreateConnection` | `isRenew` (type of boolean, default value is false) | void | Method to join the voice connection. |
| `PlayAudioOnConnection` | | void | Method to play audio on the existing voice connection. |
| `PauseAudio` | | void | Method to pause the audio. |
| `ResumeAudio` | | void | Method to resume the audio. |
| `StopAudioOnConnection` | | void | Method to stop the audio without destroying voice connection. |
| `CreateConnectionAndPlayAudio` | | void | Method to join the voice connection and play audio. |
| `DestroyConnection` | | void | Method to destroy the voice connection. |
| `Dispose` | | void | Dispose all data in object. |
| `SetVolume` | `volume` (type of number, 0 - 100 percent) | void | Method to set the audio volume. | Method to set the volume of the audio. |
| `SetMaxListeners` | `maxListeners` (type of number) | void | Method to set the max listeners of the audio stream. |
| Callable with | Parameters | Return type | Description | |
| ------------------------------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------- | -------------------------------------- |
| `OverrideVoiceConnectionData` | `connectionData` (type of **VoiceConnectionDataModel**) | void | Method to override global connectionData variable. | |
| `OverrideVoiceAudioDataModel` | `audioData` (type of **VoiceAudioDataModel**) | void | Method to override global audioData variable. | |
| `OverrideRenewInMs` | `renewInMs` (type of int, default value is 5400000) | void | Method to override global renewInMs variable. | |
| `CreateConnection` | `isRenew` (type of boolean, default value is false) | void | Method to join the voice connection. | |
| `PlayAudioOnConnection` | | void | Method to play audio on the existing voice connection. | |
| `PauseAudio` | | void | Method to pause the audio. | |
| `ResumeAudio` | | void | Method to resume the audio. | |
| `StopAudioOnConnection` | | void | Method to stop the audio without destroying voice connection. | |
| `CreateConnectionAndPlayAudio` | | void | Method to join the voice connection and play audio. | |
| `DestroyConnection` | | void | Method to destroy the voice connection. | |
| `Dispose` | | void | Dispose all data in object. | |
| `SetVolume` | `volume` (type of number, 0 - 100 percent) | void | Method to set the audio volume. | Method to set the volume of the audio. |
| `SetMaxListeners` | `maxListeners` (type of number) | void | Method to set the max listeners of the audio stream. | |
##### Types History
- [**VoiceConnection
** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/VoiceConnection.ts#L166)
- [**AudioPlayer
** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/audio/AudioPlayer.ts#L155)
- [**AudioResource
** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/audio/AudioResource.ts#L44)
- [**VoiceConnectionDataModel
**](https://github.com/FrauJulian/Discord-Audio-Stream/blob/main/src/Models/VoiceConnectionDataModel.d.ts#L3) (custom
type)
- [**VoiceAudioDataModel
**](https://github.com/FrauJulian/Discord-Audio-Stream/blob/main/src/Models/VoiceAudioDataModel.d.ts#L1) (custom type)
- [**VoiceConnection** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/VoiceConnection.ts#L166)
- [**AudioPlayer** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/audio/AudioPlayer.ts#L155)
- [**AudioResource** by discord.js/voice](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/audio/AudioResource.ts#L44)
- [**VoiceConnectionDataModel** by discord-audio-stream](https://github.com/FrauJulian/Discord-Audio-Stream/blob/main/src/Models/VoiceConnectionDataModel.d.ts#L3)
- [**VoiceAudioDataModel** by discord-audio-stream](https://github.com/FrauJulian/Discord-Audio-Stream/blob/main/src/Models/VoiceAudioDataModel.d.ts#L1)
## 📋 Credits:
## 📋 Contributors:
~ [**FrauJulian**](https://fraujulian.xyz/).
~ [**FrauJulian - Julian Lechner**](https://fraujulian.xyz/).
## 🤝 Enjoy the package?
Give it a star ⭐ on [github](https://github.com/FrauJulian/discord-audio-stream)!
### Greetings from Austria! ⛰️
+1269
View File
File diff suppressed because it is too large Load Diff
+101
View File
@@ -0,0 +1,101 @@
/** @type {import('eslint').Linter.FlatConfig[]} */
const config = [
// Globale Ignores (ersetzt .eslintignore)
{
ignores: ['dist/', 'node_modules/'],
},
// Haupt-Setup für TS/JS-Dateien
{
files: ['**/*.{ts,tsx,js,cjs,mjs}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module', // du schreibst TS mit ES-Imports; Laufzeit ist CJS nach Transpile
parser: require('@typescript-eslint/parser'),
parserOptions: {
// schnelles Profil: kein Type-Checker, nur Syntax-Linting
ecmaFeatures: {},
},
},
plugins: {
'@typescript-eslint': require('@typescript-eslint/eslint-plugin'),
import: require('eslint-plugin-import'),
promise: require('eslint-plugin-promise'),
'unused-imports': require('eslint-plugin-unused-imports'),
n: require('eslint-plugin-n'),
},
rules: {
/* Basis */
'no-debugger': 'warn',
/* TypeScript */
'@typescript-eslint/consistent-type-imports': ['warn', { prefer: 'type-imports' }],
'@typescript-eslint/no-unused-vars': 'off', // schneller über unused-imports
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-explicit-any': 'off', // pragmatisch für großen Bot
/* Imports */
'import/first': 'error',
'import/no-duplicates': 'error',
'import/newline-after-import': 'warn',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/*.config.{js,cjs,mjs,ts}',
'**/scripts/**',
'**/*.test.{ts,js}',
'**/Testing.{ts,js}',
'**/.eslintrc.{js,cjs}',
],
},
],
/* Node (wir kompilieren TS → CJS; ES-Syntax erlauben) */
'n/no-missing-import': 'off', // TypeScript-Resolver übernimmt
'n/no-unsupported-features/es-syntax': 'off',
/* Promises (Discord-/DB-/HTTP-Logik) */
'promise/catch-or-return': 'warn',
'promise/always-return': 'off',
/* bewusste „Fire-and-forget“-Promises mit `void` */
'no-void': ['warn', { allowAsStatement: true }],
},
settings: {
'import/resolver': {
typescript: {
alwaysTryTypes: true,
// nutzt automatisch deine tsconfig-Pfade
},
node: true,
},
},
},
// Reine JS/CJS-Skripte (Build/Hooks) dürfen require/exporte nutzen
{
files: ['**/*.{js,cjs}'],
languageOptions: {
sourceType: 'script',
},
rules: {
'n/global-require': 'off',
},
},
];
module.exports = config;
+25
View File
@@ -0,0 +1,25 @@
/** @type {import('eslint').Linter.FlatConfig[]} */
const base = require('./eslint.config.cjs');
const typeAwareLayer = {
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: require('@typescript-eslint/parser'),
parserOptions: {
project: ['./tsconfig.eslint.json'],
tsconfigRootDir: __dirname,
},
},
plugins: {
'@typescript-eslint': require('@typescript-eslint/eslint-plugin'),
},
rules: {
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-misused-promises': ['warn', { checksVoidReturn: false }],
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',
},
};
module.exports = [...base, typeAwareLayer];
+3928 -440
View File
File diff suppressed because it is too large Load Diff
+36 -12
View File
@@ -1,6 +1,6 @@
{
"name": "discord-audio-stream",
"version": "0.6.14",
"version": "0.6.17",
"license": "LGPL-2.1-only",
"description": "NodeJS library to make stream any audio on discord easier.",
"exports": {
@@ -25,11 +25,16 @@
"lib": "src"
},
"scripts": {
"updateDependencies": "npx npm-check-updates --upgrade && npm install && echo SUCCEED UPDATE",
"cleanSolution": "del-cli dist && echo SUCCEED CLEAN",
"updateVersion": "npm version patch --no-git-tag-version && echo SUCCEED UPDATE VERSION",
"buildPackage": "tsup && echo SUCCEED BUILD && npm run updateVersion",
"rolloutBuild": "npm run updateDependencies && npm run cleanSolution && tsup"
"lint": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs",
"lint:fix": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs --fix",
"lint:types": "eslint . --config eslint.config.typeaware.cjs --ext .ts,.tsx",
"format": "prettier --write .",
"format:check": "prettier --check .",
"update:dependencies": "npx npm-check-updates --upgrade && pnpm install && bun install && npm install && yarn install && echo PLEASE delete your node_modules directory and install again with your package manager.",
"update:version": "npm version patch --no-git-tag-version",
"clean:dist": "del-cli dist",
"build": "npm run clean:dist && npm run update:version && tsup",
"prepare": "husky"
},
"repository": "https://github.com/FrauJulian/Discord-Audio-Stream",
"bugs": "https://github.com/FrauJulian/Discord-Audio-Stream/issues",
@@ -37,23 +42,42 @@
"keywords": [
"discordjs",
"discord.js",
"discord",
"discordjs/voice",
"audio",
"voice",
"stream"
"voice"
],
"contributors": [
"FrauJulian - Lechner Julian <fraujulian@lechner.top>"
],
"lint-staged": {
"*.{ts,tsx,js,cjs,mjs}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
]
},
"dependencies": {
"@discordjs/voice": "^0.19.0"
"@discordjs/voice": "^0.19.0",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/parser": "^8.46.0"
},
"devDependencies": {
"@types/ejs": "^3.1.5",
"@types/node": "^24.6.2",
"@types/node": "^24.7.1",
"del-cli": "^7.0.0",
"eslint": "^9.37.0",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-n": "^17.23.1",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-unused-imports": "^4.2.0",
"husky": "^9.1.7",
"npm-check-updates": "^19.0.0",
"ts-jest": "^29.4.4",
"prettier": "^3.6.2",
"ts-jest": "^29.4.5",
"tsup": "^8.5.0",
"typescript": "^5.9.3"
},
copilot-pull-request-reviewer[bot] commented 2025-10-10 16:03:13 +00:00 (Migrated from github.com)
Review

TypeScript ESLint dependencies should be in devDependencies since they're development tools, not runtime dependencies required by package consumers.

    "@discordjs/voice": "^0.19.0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^8.46.0",
    "@typescript-eslint/parser": "^8.46.0",
TypeScript ESLint dependencies should be in devDependencies since they're development tools, not runtime dependencies required by package consumers. ```suggestion "@discordjs/voice": "^0.19.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.46.0", "@typescript-eslint/parser": "^8.46.0", ```
FrauJulian commented 2025-10-10 16:10:31 +00:00 (Migrated from github.com)
Review

nope best pratise is this:

nope best pratise is this:
+5870
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
ignoredBuiltDependencies:
- esbuild
- unrs-resolver
+159
View File
@@ -0,0 +1,159 @@
import type { AudioPlayer, AudioResource, VoiceConnection } from '@discordjs/voice';
import { createAudioPlayer, createAudioResource, joinVoiceChannel } from '@discordjs/voice';
import { join } from 'node:path';
import type { VoiceAudioDataModel, VoiceConnectionDataModel } from './index.d';
copilot-pull-request-reviewer[bot] commented 2025-10-10 16:03:13 +00:00 (Migrated from github.com)
Review

The import path './index.d' appears to be incorrect. TypeScript definition files typically use '.d.ts' extension, and this path doesn't match the file structure shown in the changes.

import type { VoiceAudioDataModel, VoiceConnectionDataModel } from './index.d.ts';
The import path './index.d' appears to be incorrect. TypeScript definition files typically use '.d.ts' extension, and this path doesn't match the file structure shown in the changes. ```suggestion import type { VoiceAudioDataModel, VoiceConnectionDataModel } from './index.d.ts'; ```
FrauJulian commented 2025-10-10 16:09:34 +00:00 (Migrated from github.com)
Review

doesnt make sense

doesnt make sense
export default class AudioManager {
public VoiceConnection?: VoiceConnection;
public AudioPlayer?: AudioPlayer;
public AudioResource?: AudioResource;
protected IsActive?: boolean;
protected IsAudioPlaying?: boolean;
protected ConnectionData?: VoiceConnectionDataModel;
protected AudioData?: VoiceAudioDataModel;
private TimeoutHandle?: NodeJS.Timeout;
private RenewInMs?: number;
constructor(connectionData?: VoiceConnectionDataModel, audioData?: VoiceAudioDataModel, renewInMs = 5400000) {
this.RenewInMs = renewInMs;
this.ConnectionData = connectionData;
this.AudioData = audioData;
}
public OverrideRenewInMs(renewInMs: number = 5400000): void {
this.RenewInMs = renewInMs;
}
public OverrideVoiceConnectionData(connectionData: VoiceConnectionDataModel): void {
this.ConnectionData = connectionData;
}
public OverrideVoiceAudioDataModel(audioData: VoiceAudioDataModel): void {
this.AudioData = audioData;
}
public CreateConnection(isRenew: boolean = false): void {
this.CheckIfNull(this.ConnectionData);
if (!isRenew) {
if (this.IsActive) {
this.DestroyConnection(false);
} else {
this.IsActive = true;
}
}
this.VoiceConnection = joinVoiceChannel({
channelId: this.ConnectionData!.VoiceChannelId.toString(),
guildId: this.ConnectionData!.GuildId.toString(),
adapterCreator: this.ConnectionData!.VoiceAdapter,
});
this.TimeoutHandle = setTimeout((): void => {
this.DestroyConnection(false);
if (this.IsActive) {
this.CreateConnection(true);
if (this.IsAudioPlaying) {
this.PlayAudioOnConnection();
}
}
}, this.RenewInMs);
}
public PlayAudioOnConnection(): void {
this.CheckIfNull(this.AudioData);
if (this.AudioData!.ResourceType === 'File') {
this.AudioResource = createAudioResource(join(__dirname, this.AudioData!.Resource), { inlineVolume: true });
} else if (this.AudioData!.ResourceType === 'Link') {
this.AudioResource = createAudioResource(this.AudioData!.Resource, { inlineVolume: true });
} else {
throw new Error('Invalid resource type.');
}
this.AudioPlayer = createAudioPlayer();
this.AudioPlayer.play(this.AudioResource);
this.VoiceConnection!.subscribe(this.AudioPlayer!);
this.IsAudioPlaying = true;
}
public StopAudioOnConnection(): void {
if (this.IsAudioPlaying) {
this.DestroyConnection(false);
this.CreateConnection();
} else {
throw new Error('Audio is not playing.');
}
}
public PauseAudio(): void {
if (this.IsAudioPlaying) {
this.AudioPlayer!.pause();
this.IsAudioPlaying = false;
} else {
throw new TypeError('Audio is not playing.');
}
}
public ResumeAudio(): void {
if (!this.IsAudioPlaying) {
this.AudioPlayer!.unpause();
this.IsAudioPlaying = true;
} else {
throw new TypeError('Audio is playing.');
}
}
public CreateConnectionAndPlayAudio(): void {
this.CreateConnection();
this.PlayAudioOnConnection();
}
public DestroyConnection(resetValidationParameters: boolean = true): void {
if (this.CheckIfNull(this.VoiceConnection)) return;
this.VoiceConnection!.destroy();
if (resetValidationParameters) {
this.IsActive = false;
this.IsAudioPlaying = false;
}
}
public SetMaxListeners(maxListeners: number): void {
if (this.CheckIfNull(this.VoiceConnection)) return;
this.VoiceConnection!.setMaxListeners(maxListeners);
}
public SetVolume(volumeInPercent: number): void {
if (volumeInPercent < 0 || volumeInPercent > 100) throw new Error('Volume must be between 0 and 100.');
if (this.CheckIfNull(this.VoiceConnection)) return;
this.AudioResource!.volume!.setVolume(volumeInPercent / 100);
}
public Dispose(): void {
this.VoiceConnection = undefined;
this.AudioPlayer = undefined;
this.AudioResource = undefined;
this.IsActive = undefined;
this.IsAudioPlaying = undefined;
this.ConnectionData = undefined;
this.AudioData = undefined;
this.TimeoutHandle = undefined;
this.RenewInMs = undefined;
}
private CheckIfNull<T>(value: T | null): boolean {
if (value === null) {
throw new Error(`${value} cannot be null in this case.`);
}
copilot-pull-request-reviewer[bot] commented 2025-10-10 16:03:13 +00:00 (Migrated from github.com)
Review

The error message will always display 'null' since value is null when the condition is true. The message should describe which parameter or property cannot be null.

The error message will always display 'null' since `value` is null when the condition is true. The message should describe which parameter or property cannot be null.
FrauJulian commented 2025-10-10 16:10:03 +00:00 (Migrated from github.com)
Review

nope? guess not

nope? guess not
return true;
}
}
-166
View File
@@ -1,166 +0,0 @@
import {
AudioPlayer,
AudioResource,
createAudioPlayer,
createAudioResource,
joinVoiceChannel,
VoiceConnection
} from "@discordjs/voice";
import {join} from "node:path";
import {VoiceAudioDataModel, VoiceConnectionDataModel} from "./typings";
export default class AudioManager {
public VoiceConnection?: VoiceConnection;
public AudioPlayer?: AudioPlayer;
public AudioResource?: AudioResource;
protected IsActive?: boolean;
protected IsAudioPlaying?: boolean;
protected ConnectionData?: VoiceConnectionDataModel;
protected AudioData?: VoiceAudioDataModel;
private TimeoutHandle?: NodeJS.Timeout;
private RenewInMs?: number;
constructor(connectionData?: VoiceConnectionDataModel, audioData?: VoiceAudioDataModel, renewInMs = 5400000) {
this.RenewInMs = renewInMs;
this.ConnectionData = connectionData;
this.AudioData = audioData;
}
public OverrideRenewInMs(renewInMs: number = 5400000): void {
this.RenewInMs = renewInMs;
}
public OverrideVoiceConnectionData(connectionData: VoiceConnectionDataModel): void {
this.ConnectionData = connectionData;
}
public OverrideVoiceAudioDataModel(audioData: VoiceAudioDataModel): void {
this.AudioData = audioData;
}
public CreateConnection(isRenew: boolean = false): void {
this.CheckIfNull(this.ConnectionData);
if (!isRenew) {
if (this.IsActive) {
this.DestroyConnection(false);
} else {
this.IsActive = true;
}
}
this.VoiceConnection = joinVoiceChannel({
channelId: this.ConnectionData!.VoiceChannelId.toString(),
guildId: this.ConnectionData!.GuildId.toString(),
adapterCreator: this.ConnectionData!.VoiceAdapter
});
this.TimeoutHandle = setTimeout((): void => {
this.DestroyConnection(false);
if (this.IsActive) {
this.CreateConnection(true);
if (this.IsAudioPlaying) {
this.PlayAudioOnConnection();
}
}
}, this.RenewInMs);
}
public PlayAudioOnConnection(): void {
this.CheckIfNull(this.AudioData);
if (this.AudioData!.ResourceType === "File") {
this.AudioResource = createAudioResource(join(__dirname, this.AudioData!.Resource), {inlineVolume: true});
} else if (this.AudioData!.ResourceType === "Link") {
this.AudioResource = createAudioResource(this.AudioData!.Resource, {inlineVolume: true});
} else {
throw new Error("Invalid resource type.");
}
this.AudioPlayer = createAudioPlayer();
this.AudioPlayer.play(this.AudioResource);
this.VoiceConnection!.subscribe(this.AudioPlayer!);
this.IsAudioPlaying = true;
}
public StopAudioOnConnection(): void {
if (this.IsAudioPlaying) {
this.DestroyConnection(false)
this.CreateConnection();
} else {
throw new Error("Audio is not playing.");
}
}
public PauseAudio(): void {
if (this.IsAudioPlaying) {
this.AudioPlayer!.pause();
this.IsAudioPlaying = false;
} else {
throw new TypeError("Audio is not playing.");
}
}
public ResumeAudio(): void {
if (!this.IsAudioPlaying) {
this.AudioPlayer!.unpause();
this.IsAudioPlaying = true;
} else {
throw new TypeError("Audio is playing.");
}
}
public CreateConnectionAndPlayAudio(): void {
this.CreateConnection();
this.PlayAudioOnConnection();
}
public DestroyConnection(resetValidationParameters: boolean = true): void {
if (this.CheckIfNull(this.VoiceConnection)) return;
this.VoiceConnection!.destroy();
if (resetValidationParameters) {
this.IsActive = false;
this.IsAudioPlaying = false;
}
}
public SetMaxListeners(maxListeners: number): void {
if (this.CheckIfNull(this.VoiceConnection)) return;
this.VoiceConnection!.setMaxListeners(maxListeners);
}
public SetVolume(volumeInPercent: number): void {
if (volumeInPercent < 0 || volumeInPercent > 100)
throw new Error("Volume must be between 0 and 100.");
if (this.CheckIfNull(this.VoiceConnection)) return;
this.AudioResource!.volume!.setVolume(volumeInPercent / 100);
}
public Dispose(): void {
this.VoiceConnection = undefined;
this.AudioPlayer = undefined;
this.AudioResource = undefined;
this.IsActive = undefined;
this.IsAudioPlaying = undefined;
this.ConnectionData = undefined;
this.AudioData = undefined;
this.TimeoutHandle = undefined;
this.RenewInMs = undefined;
}
private CheckIfNull<T>(value: T | null): boolean {
if (value === null) {
throw new Error(`${value} cannot be null in this case.`);
}
return true;
}
}
+32
View File
@@ -0,0 +1,32 @@
import type { DiscordGatewayAdapterCreator } from '@discordjs/voice';
export type VoiceConnectionDataModel = {
/**
* The ID of the voice channel to connect to.
*/
VoiceChannelId: string;
/**
* The Id of the guild (server) to connect to.
*/
GuildId: string;
/**
* The adapter creator for the voice connection.
* Can be archived by the guild instance via the voiceAdapterCreator property.
*/
VoiceAdapter: DiscordGatewayAdapterCreator;
};
export type VoiceAudioDataModel = {
/**
* The unique identifier for the audio resource.
*/
ResourceType: 'Link' | 'File';
/**
* The URL or file path of the audio resource.
* any is to be assumed to require(filepath)
*/
Resource: string | any;
};
+1 -2
View File
@@ -1,2 +1 @@
export {default as AudioManager} from './audioManager';
export type {VoiceConnectionDataModel, VoiceAudioDataModel} from './typings';
export { default as AudioManager } from './audio-manager';
-32
View File
@@ -1,32 +0,0 @@
import type {DiscordGatewayAdapterCreator} from "@discordjs/voice";
export type VoiceConnectionDataModel = {
/**
* The ID of the voice channel to connect to.
*/
VoiceChannelId: string;
/**
* The Id of the guild (server) to connect to.
*/
GuildId: string;
/**
* The adapter creator for the voice connection.
* Can be archived by the guild instance via the voiceAdapterCreator property.
*/
VoiceAdapter: DiscordGatewayAdapterCreator;
}
export type VoiceAudioDataModel = {
/**
* The unique identifier for the audio resource.
*/
ResourceType: "Link" | "File";
/**
* The URL or file path of the audio resource.
* any is to be assumed to require(filepath)
*/
Resource: string | any;
}
+4
View File
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts"]
}
+4 -12
View File
@@ -12,17 +12,9 @@
"isolatedModules": true,
"noEmit": true,
"outDir": "dist",
"types": [
"node"
],
"typeRoots": [
"node_modules/@types"
]
"types": ["node"],
"typeRoots": ["node_modules/@types"]
},
"include": [
"src"
],
"exclude": [
"node_modules"
]
"include": ["src"],
"exclude": ["node_modules"]
}
+7 -7
View File
@@ -1,10 +1,10 @@
import {defineConfig} from "tsup";
import { defineConfig } from 'tsup';
export default defineConfig({
format: ["cjs", "esm"],
entry: ["./src/index.ts"],
dts: true,
shims: true,
skipNodeModulesBundle: true,
clean: true,
format: ['cjs', 'esm'],
entry: ['./src/index.ts'],
dts: true,
shims: true,
skipNodeModulesBundle: true,
clean: true,
});
+4480
View File
File diff suppressed because it is too large Load Diff