diff --git a/.gitignore b/.gitignore index 2fd83a6..3f5a8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea +.git node_modules dist diff --git a/.npmignore b/.npmignore index 23d9d3b..6734cd8 100644 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1,8 @@ .idea +.git +.gitignore +.npmignore node_modules src -.gitignore -README.md tsconfig.json tsup.config.ts \ No newline at end of file diff --git a/README.md b/README.md index 6b77648..1eb0bc8 100644 --- a/README.md +++ b/README.md @@ -4,70 +4,82 @@ ![GitHub package.json version](https://img.shields.io/github/package-json/v/FrauJulian/discord-audio-stream) ![GitHub Repo stars](https://img.shields.io/github/stars/FrauJulian/discord-audio-stream?style=social) -# !ATTENTION! - -Usefully Links to write docs: - -ConnectionOptions: -- https://github.com/sidorares/node-mysql2/blob/master/typings/mysql/lib/Connection.d.ts#L82 - -# !ATTENTION! - -

This NPM package was created to make it easier to stream audio to Discord.

-

There is a security feature of discord that stops the stream of audio after some time. This problem can be solved by disconnecting the Discord channel every 1.5 hours for 2 seconds and then reconnecting the channel. (If you use this package!) I recommend using a database to store the data e.g. MySQL, SQLite, json file and other database types.

-

The package does not fix this error yet. However, it is currently being worked on!

- -**This module is designed to work with [discord.js](https://discord.js.org/) v14. This package doesn't support older +**This module is designed to work with [discord.js/voice](https://www.npmjs.com/package/@discordjs/voice) v0.18. This +package doesn't support older versions!** ## 👋 Support -Please create an [issue](https://github.com/FrauJulian/DiscordAudioStreamNPM/issues) on github or write [`fraujulian`](https://discord.com/users/860206216893693973) on discord! +Please create an [issue](https://github.com/FrauJulian/DiscordAudioStreamNPM/issues) on github or write [ +`fraujulian`](https://discord.com/users/860206216893693973) on discord! ## 📝 Usage ### Install package ```bash -npm i discord-audio-stream +npm install discord-audio-stream opusscript @discordjs/voice ffmpeg-static sodium-native ``` -### Code Snippet - Start +### Create Instance ```js -const AudioStream = require("discord-audio-stream"); - -AudioStream.startAudio({ - VoiceChannelID: 0, //Integer | voice channel id | e.g. interaction.member.voice.channel.id - GuildID: 0, //Integer | guild id | e.g. interaction.guild.id - VoiceAdapter: 0, //Integer | aoice adapter creator | e.g. interaction.guild.voiceAdapterCreator - Type: "", //String | choose the Audio Resource | File or Link - Resource: "", //String | audio stream link or file location | e.g. https://synradiode.stream.laut.fm/synradiode -}) +let audioManager = new AudioManager(); ``` -### Code Snippet - Stop +or (with parameters) ```js -const AudioStream = require("discord-audio-stream"); - -AudioStream.stopAudio({ - GuildID: 0, //Integer | guild id | e.g. interaction.guild.id -}) +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 + }); ``` -### Code Snippet - Set Max Listeners +### Properties of the AudioManager -```js -const AudioStream = require("discord-audio-stream"); +#### Properties -AudioStream.setMaxAudioListeners({ - GuildID: 0, //Integer | guild id | e.g. interaction.guild.id - MaxListeners: 0, //Integer | max Listeners | e.g. 30 -}) -``` +| 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. | +| `IsActive` | boolean | Variable to check if audio stream is active. | +| `IsAudioPlaying` | boolean | Variable to check if audio is playing. | +| `ConnectionData` | **VoiceConnectionDataModel** | Global variable for connection data. | +| `AudioData` | **AudioDataModel** | Global variable for audio data. | + +#### Methods + +| Callable with | Parameters | Return type | Description | +|--------------------------------|--------------------------------------------------------------------------------------------------------|-------------|--------------------------------------------------------------------| +| `OverrideOptions` | `connectionData` (type of **VoiceConnectionDataModel**), `audioData` (type of **VoiceAudioDataModel**) | void | Method to override global variables, connectionData and audioData. | +| `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. | +| `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) ## 📋 Credits: + ~ [**FrauJulian**](https://fraujulian.xyz/). ## 🤝 Enjoy the package? diff --git a/package.json b/package.json index 0c1f7ae..ad0a85e 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,6 @@ "@noble/ciphers": "^1.2.1", "ffmpeg-static": "^5.2.0", "libsodium-wrappers": "^0.7.15", - "mysql2": "^3.14.0", - "node-json-db": "^2.3.1", "opusscript": "^0.1.1", "sodium-native": "^5.0.0" } diff --git a/src/Core/Contants.ts b/src/Core/Contants.ts deleted file mode 100644 index cad2107..0000000 --- a/src/Core/Contants.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {JsonDatabaseServices} from "../InternalServices/DatabaseServices/JsonDatabaseServices"; -import {MySqlDatabaseServices} from "../InternalServices/DatabaseServices/MySqlDatabaseServices"; - -export class Constants { - public static DatabaseServices: JsonDatabaseServices | MySqlDatabaseServices | null = null; -} \ No newline at end of file diff --git a/src/DataAccess/Json/IJsonDao.ts b/src/DataAccess/Json/IJsonDao.ts deleted file mode 100644 index c448ef5..0000000 --- a/src/DataAccess/Json/IJsonDao.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IJsonDao { - -} \ No newline at end of file diff --git a/src/DataAccess/Json/JsonDao.ts b/src/DataAccess/Json/JsonDao.ts deleted file mode 100644 index a81472b..0000000 --- a/src/DataAccess/Json/JsonDao.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {IJsonDao} from "./IJsonDao"; -import {Config, JsonDB} from "node-json-db"; - -export class JsonDao implements IJsonDao { - private _jsonDatabaseContext: JsonDB; - - constructor(fileLocation: string) { - this._jsonDatabaseContext = new JsonDB(new Config(fileLocation, true, false, "/", true)); - } - -} \ No newline at end of file diff --git a/src/DataAccess/MySql/IMySqlDao.ts b/src/DataAccess/MySql/IMySqlDao.ts deleted file mode 100644 index 5e740bc..0000000 --- a/src/DataAccess/MySql/IMySqlDao.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IMySqlDao { - -} \ No newline at end of file diff --git a/src/DataAccess/MySql/MysqlDao.ts b/src/DataAccess/MySql/MysqlDao.ts deleted file mode 100644 index f659496..0000000 --- a/src/DataAccess/MySql/MysqlDao.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {IMySqlDao} from "./IMySqlDao"; -import mysql, {Connection, ConnectionOptions} from 'mysql2/promise'; -import {Connection as BaseConnection} from "mysql2/typings/mysql/lib/Connection"; - -export class MysqlDao implements IMySqlDao { - private _mysqlDatabaseContext!: Connection; - - constructor(mysqlAuthenticationData: ConnectionOptions) { - this.InitializeDatabaseContext(mysqlAuthenticationData).catch(error => { - throw new Error(error) - }); - } - - private async InitializeDatabaseContext(mysqlAuthenticationData: ConnectionOptions): Promise { - this._mysqlDatabaseContext = await mysql.createConnection(mysqlAuthenticationData); - } -} diff --git a/src/ExternalServices/AudioStreamManager/AudioStreamManager.ts b/src/ExternalServices/AudioStreamManager/AudioStreamManager.ts deleted file mode 100644 index 84f8304..0000000 --- a/src/ExternalServices/AudioStreamManager/AudioStreamManager.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {JsonDatabaseServices} from "../../InternalServices/DatabaseServices/JsonDatabaseServices"; -import {MySqlDatabaseServices} from "../../InternalServices/DatabaseServices/MySqlDatabaseServices"; -import {Constants} from "../../Core/Contants"; -import {ConnectionOptions} from "mysql2/promise"; - -export class AudioStreamManager { - constructor(databaseType: "Json" | "MySql", databaseOptions: ConnectionOptions | string) { - if (databaseType === "MySql" && - databaseOptions && - typeof databaseOptions === "object") { - Constants.DatabaseServices = new MySqlDatabaseServices(databaseOptions); - } else if (databaseType === "Json" && - databaseOptions && - typeof databaseOptions === "string") { - Constants.DatabaseServices = new JsonDatabaseServices(databaseOptions); - } else { - throw new Error("Failed validating database.") - } - } -} diff --git a/src/ExternalServices/ConnectionManager/ConnectionManager.ts b/src/ExternalServices/ConnectionManager/ConnectionManager.ts deleted file mode 100644 index 07d985a..0000000 --- a/src/ExternalServices/ConnectionManager/ConnectionManager.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {DiscordGatewayAdapterCreator, getVoiceConnection, joinVoiceChannel, VoiceConnection} from "@discordjs/voice"; -import {IConnectionManager} from "./IConnectionManager"; -import {Constants} from "../../Core/Contants"; - -class ConnectionManager implements IConnectionManager { - constructor() { - if (Constants.DatabaseServices === null) throw Error("Database services were not initialized."); - } - - CreateConnection(connectionData: { - VoiceChannelId: number; - GuildId: number; - VoiceAdapter: DiscordGatewayAdapterCreator; - }): VoiceConnection { - return joinVoiceChannel({ - channelId: connectionData.VoiceChannelId.toString(), - guildId: connectionData.GuildId.toString(), - adapterCreator: connectionData.VoiceAdapter - }) - } - - PlayAudioOnConnection(audioData: { - ResourceType: "Link" | "File"; - Resource: string; - }, guildId: bigint): VoiceConnection { - throw new Error("Method not implemented."); - } - - ConnectAndPlayAudio(connectionData: { VoiceChannelId: number; GuildId: number; VoiceAdapter: DiscordGatewayAdapterCreator; }, audioData: { - ResourceType: "Link" | "File"; - Resource: string; - }): VoiceConnection { - throw new Error("Method not implemented."); - } - - StopAudioOnConnection(guildId: bigint): VoiceConnection { - let voiceConnection = getVoiceConnection(guildId.toString()); - if (!voiceConnection) throw new Error("Voice connection were not found."); - - //TODO: MAKE STOP AUDIO WITHOUT DESTROYING CONNECTION - - return voiceConnection; - } - - DestroyConnection(guildId: bigint): void { - let voiceConnection = getVoiceConnection(guildId.toString()); - if (!voiceConnection) throw new Error("Voice connection were not found."); - - voiceConnection.destroy(); - } - - SetMaxListeners(maxListeners: number, guildId: bigint): VoiceConnection { - let voiceConnection = getVoiceConnection(guildId.toString()); - if (!voiceConnection) throw new Error("Voice connection were not found."); - - voiceConnection.setMaxListeners(maxListeners); - - return voiceConnection; - } - - SetVolume(volume: number, guildId: bigint): VoiceConnection { - if (volume < 0 || volume > 100) throw new Error("Volume must be between 0 and 100."); - - let voiceConnection = getVoiceConnection(guildId.toString()); - if (!voiceConnection) throw new Error("Voice connection were not found."); - - //TODO: MAKE VOLUME WORK - - return voiceConnection; - } -} \ No newline at end of file diff --git a/src/ExternalServices/ConnectionManager/IConnectionManager.ts b/src/ExternalServices/ConnectionManager/IConnectionManager.ts deleted file mode 100644 index e63d1e5..0000000 --- a/src/ExternalServices/ConnectionManager/IConnectionManager.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {DiscordGatewayAdapterCreator, getVoiceConnection, joinVoiceChannel, VoiceConnection} from "@discordjs/voice"; - -export interface IConnectionManager { - CreateConnection(connectionData: { - VoiceChannelId: number; - GuildId: number; - VoiceAdapter: DiscordGatewayAdapterCreator; - }): VoiceConnection; - - SetVolume(volume: number, guildId: bigint): VoiceConnection; - - SetMaxListeners(maxListeners: number, guildId: bigint): VoiceConnection; - - DestroyConnection(guildId: bigint): void; - - StopAudioOnConnection(guildId: bigint): VoiceConnection; - - ConnectAndPlayAudio(connectionData: { - VoiceChannelId: number; - GuildId: number; - VoiceAdapter: DiscordGatewayAdapterCreator; - }, audioData: { - ResourceType: "Link" | "File"; - Resource: string; - }): VoiceConnection; - - PlayAudioOnConnection(audioData: { - ResourceType: "Link" | "File"; - Resource: string; - }, guildId: bigint): VoiceConnection; -} \ No newline at end of file diff --git a/src/InternalServices/DatabaseServices/IDatabaseServices.ts b/src/InternalServices/DatabaseServices/IDatabaseServices.ts deleted file mode 100644 index 6d212cf..0000000 --- a/src/InternalServices/DatabaseServices/IDatabaseServices.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IDatabaseServices { - -} \ No newline at end of file diff --git a/src/InternalServices/DatabaseServices/JsonDatabaseServices.ts b/src/InternalServices/DatabaseServices/JsonDatabaseServices.ts deleted file mode 100644 index 0ee397a..0000000 --- a/src/InternalServices/DatabaseServices/JsonDatabaseServices.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {IDatabaseServices} from "./IDatabaseServices"; -import {JsonDao} from "../../DataAccess/Json/JsonDao"; - -export class JsonDatabaseServices implements IDatabaseServices { - private _databaseDao: JsonDao; - - constructor(databaseOptions : any) { - this._databaseDao = new JsonDao(databaseOptions); - } -} \ No newline at end of file diff --git a/src/InternalServices/DatabaseServices/MySqlDatabaseServices.ts b/src/InternalServices/DatabaseServices/MySqlDatabaseServices.ts deleted file mode 100644 index 0b857a6..0000000 --- a/src/InternalServices/DatabaseServices/MySqlDatabaseServices.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {IDatabaseServices} from "./IDatabaseServices"; -import {MysqlDao} from "../../DataAccess/MySql/MysqlDao"; -import {ConnectionOptions} from "mysql2/promise"; - -export class MySqlDatabaseServices implements IDatabaseServices { - private _databaseDao: MysqlDao; - - constructor(databaseOptions: ConnectionOptions) { - this._databaseDao = new MysqlDao(databaseOptions); - } -} \ No newline at end of file diff --git a/src/Methods/MaxListenerMethod.ts b/src/Methods/MaxListenerMethod.ts deleted file mode 100644 index d92937c..0000000 --- a/src/Methods/MaxListenerMethod.ts +++ /dev/null @@ -1,11 +0,0 @@ -const {getVoiceConnection} = require("@discordjs/voice"); - -import {maxListenerMethodOptions} from "../Utils/Options/MaxListenerMethodOptions"; - -export function setMaxAudioListeners({ - GuildID, - MaxListeners - }: maxListenerMethodOptions) { - let audioConnection = getVoiceConnection(GuildID); - audioConnection.setMaxListeners(MaxListeners); -} \ No newline at end of file diff --git a/src/Methods/StartMethod.ts b/src/Methods/StartMethod.ts deleted file mode 100644 index 3d0f3bd..0000000 --- a/src/Methods/StartMethod.ts +++ /dev/null @@ -1,48 +0,0 @@ -const { - joinVoiceChannel, createAudioPlayer, createAudioResource} = require("@discordjs/voice"); -const {join} = require("node:path"); - -import {startMethodOptions} from "../Utils/Options/StartMethodOptions"; - -export function startAudio({ - VoiceChannelID, - GuildID, - VoiceAdapter, - ResourceType, - Resource - }: startMethodOptions) { - let audioPlayer = createAudioPlayer(); - - function streamFile(file: string) { - let audioResource = createAudioResource(join(__dirname, file), {inlineVolume: true}); - audioPlayer.play(audioResource); - - joinVoiceChannel({ - channelId: VoiceChannelID, - guildId: GuildID, - adapterCreator: VoiceAdapter - }).subscribe(audioPlayer); - } - - function streamLink(link: string) { - let audioResource = createAudioResource(link); - audioPlayer.play(audioResource); - - joinVoiceChannel({ - channelId: VoiceChannelID, - guildId: GuildID, - adapterCreator: VoiceAdapter - }).subscribe(audioPlayer) - } - - switch (ResourceType) { - case "Link": - streamLink(Resource); - break; - case "File": - streamFile(Resource); - break; - default: - throw new TypeError("Invalid audio type"); - } -} \ No newline at end of file diff --git a/src/Methods/StopMethod.ts b/src/Methods/StopMethod.ts deleted file mode 100644 index 9e4cb5f..0000000 --- a/src/Methods/StopMethod.ts +++ /dev/null @@ -1,10 +0,0 @@ -const {getVoiceConnection} = require("@discordjs/voice"); - -import {stopMethodOptions} from "../Utils/Options/StopMethodOptions"; - -export function stopAudio({ - GuildID - }: stopMethodOptions) { - let audioConnection = getVoiceConnection(GuildID); - audioConnection.destroy(); -} \ No newline at end of file diff --git a/src/Models/VoiceAudioDataModel.d.ts b/src/Models/VoiceAudioDataModel.d.ts new file mode 100644 index 0000000..8f762c1 --- /dev/null +++ b/src/Models/VoiceAudioDataModel.d.ts @@ -0,0 +1,12 @@ +export interface 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; +} \ No newline at end of file diff --git a/src/Models/VoiceConnectionDataModel.d.ts b/src/Models/VoiceConnectionDataModel.d.ts new file mode 100644 index 0000000..4b3a614 --- /dev/null +++ b/src/Models/VoiceConnectionDataModel.d.ts @@ -0,0 +1,19 @@ +import {DiscordGatewayAdapterCreator} from "@discordjs/voice"; + +export interface VoiceConnectionDataModel { + /** + * The ID of the voice channel to connect to. + */ + VoiceChannelId: number; + + /** + * The Id of the guild (server) to connect to. + */ + GuildId: number; + + /** + * The adapter creator for the voice connection. + * Can be archived by the guild instance via the voiceAdapterCreator property. + */ + VoiceAdapter: DiscordGatewayAdapterCreator; +} diff --git a/src/Services/AudioManager/AudioManager.ts b/src/Services/AudioManager/AudioManager.ts new file mode 100644 index 0000000..d7821fe --- /dev/null +++ b/src/Services/AudioManager/AudioManager.ts @@ -0,0 +1,138 @@ +import { + AudioPlayer, + AudioResource, + createAudioPlayer, + createAudioResource, + joinVoiceChannel, + VoiceConnection +} from "@discordjs/voice"; +import {IAudioManager} from "./IAudioManager"; +import {VoiceConnectionDataModel} from "../../Models/VoiceConnectionDataModel"; +import {VoiceAudioDataModel} from "../../Models/VoiceAudioDataModel"; +import {join} from "node:path"; + +export class AudioManager implements IAudioManager { + public VoiceConnection: VoiceConnection | null = null; + public AudioPlayer: AudioPlayer | null = null; + public AudioResource: AudioResource | null = null; + + public IsActive: boolean = false; + public IsAudioPlaying: boolean = false; + + public ConnectionData: VoiceConnectionDataModel | null; + public AudioData: VoiceAudioDataModel | null; + + constructor(connectionData: VoiceConnectionDataModel | null = null, audioData: VoiceAudioDataModel | null = null) { + this.ConnectionData = connectionData; + this.AudioData = audioData; + } + + OverrideOptions(connectionData: VoiceConnectionDataModel | null = null, audioData: VoiceAudioDataModel | null = null): void { + this.ConnectionData = connectionData; + 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 + }); + + setTimeout((): void => { + this.RenewConnectionAndAudio(); + }, 5400000); + } + + 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 { + this.CheckIfNull(this.AudioPlayer); + this.AudioPlayer!.pause(); + } + + public ResumeAudio(): void { + this.CheckIfNull(this.AudioPlayer); + this.AudioPlayer!.unpause(); + } + + public CreateConnectionAndPlayAudio(): void { + this.CreateConnection(); + this.PlayAudioOnConnection(); + } + + public DestroyConnection(resetValidationParameters: boolean = true): void { + this.CheckIfNull(this.VoiceConnection); + this.VoiceConnection!.destroy(); + + if (resetValidationParameters) { + this.IsActive = false; + this.IsAudioPlaying = false; + } + } + + public SetMaxListeners(maxListeners: number): void { + this.CheckIfNull(this.VoiceConnection); + this.VoiceConnection!.setMaxListeners(maxListeners); + } + + public SetVolume(volumeInPercent: number): void { + if (volumeInPercent < 0 || volumeInPercent > 100) throw new Error("Volume must be between 0 and 100."); + this.AudioResource!.volume!.setVolume(volumeInPercent / 100); + } + + private RenewConnectionAndAudio(): void { + this.DestroyConnection(false); + if (this.IsActive) { + this.CreateConnection(true); + + if (this.IsAudioPlaying) { + this.PlayAudioOnConnection(); + } + } + } + + private CheckIfNull(value: T | null): boolean { + if (value === null) { + throw new Error(`${value} cannot be null in this case.`); + } + + return true; + } +} diff --git a/src/Services/AudioManager/IAudioManager.ts b/src/Services/AudioManager/IAudioManager.ts new file mode 100644 index 0000000..e9f990e --- /dev/null +++ b/src/Services/AudioManager/IAudioManager.ts @@ -0,0 +1,25 @@ +import {VoiceConnection} from "@discordjs/voice"; +import {VoiceAudioDataModel} from "../../Models/VoiceAudioDataModel"; +import {VoiceConnectionDataModel} from "../../Models/VoiceConnectionDataModel"; + +export interface IAudioManager { + OverrideOptions(connectionData?: VoiceConnectionDataModel | null, audioData?: VoiceAudioDataModel | null): void; + + CreateConnection(isRenew: boolean): void; + + PlayAudioOnConnection(): void; + + PauseAudio(): void; + + ResumeAudio(): void; + + StopAudioOnConnection(): void; + + CreateConnectionAndPlayAudio(): void; + + DestroyConnection(resetValidationParameters: boolean): void; + + SetVolume(volumeInPercent: number): void; + + SetMaxListeners(maxListeners: number): void; +} \ No newline at end of file diff --git a/src/Utils/Options/MaxListenerMethodOptions.ts b/src/Utils/Options/MaxListenerMethodOptions.ts deleted file mode 100644 index 74b0e26..0000000 --- a/src/Utils/Options/MaxListenerMethodOptions.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type maxListenerMethodOptions = { - GuildID: number; - MaxListeners: number; -}; \ No newline at end of file diff --git a/src/Utils/Options/StartMethodOptions.ts b/src/Utils/Options/StartMethodOptions.ts deleted file mode 100644 index 2af0cd6..0000000 --- a/src/Utils/Options/StartMethodOptions.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type startMethodOptions = { - VoiceChannelID: number; - GuildID: number; - VoiceAdapter: number; - ResourceType: "Link" | "File"; - Resource: string; -}; \ No newline at end of file diff --git a/src/Utils/Options/StopMethodOptions.ts b/src/Utils/Options/StopMethodOptions.ts deleted file mode 100644 index ae43eba..0000000 --- a/src/Utils/Options/StopMethodOptions.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type stopMethodOptions = { - GuildID: number; -}; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 58ea168..8c0e262 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,3 @@ -export { AudioStreamManager } from "./ExternalServices/AudioStreamManager/AudioStreamManager"; \ No newline at end of file +export {AudioManager} from "./Services/AudioManager/AudioManager"; +export type {VoiceConnectionDataModel} from "./Models/VoiceConnectionDataModel"; +export type {VoiceAudioDataModel} from "./Models/VoiceAudioDataModel"; \ No newline at end of file