From a0d3859230814e13e346a7734908a49e73674b30 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 11 Jun 2021 15:02:42 +0545 Subject: [PATCH] voice events --- package.json | 1 + src/VoiceInterface/VoiceSubscription.ts | 30 +++++++++++++++++++++---- src/VoiceInterface/VoiceUtils.ts | 13 +++++------ src/utils/AudioFilters.ts | 2 +- src/utils/Constants.ts | 2 +- src/utils/PlayerError.ts | 2 +- src/utils/Util.ts | 2 +- 7 files changed, 37 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 3bad156..1a5d080 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "discord-ytdl-core": "^5.0.3", "soundcloud-scraper": "^5.0.0", "spotify-url-info": "^2.2.3", + "tiny-typed-emitter": "^2.0.3", "youtube-sr": "^4.1.4", "ytdl-core": "^4.8.2" }, diff --git a/src/VoiceInterface/VoiceSubscription.ts b/src/VoiceInterface/VoiceSubscription.ts index 4b9b394..5e5ff23 100644 --- a/src/VoiceInterface/VoiceSubscription.ts +++ b/src/VoiceInterface/VoiceSubscription.ts @@ -1,5 +1,7 @@ import { AudioPlayer, + AudioPlayerError, + AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, @@ -9,18 +11,26 @@ import { VoiceConnectionStatus } from "@discordjs/voice"; import { Duplex, Readable } from "stream"; +import { TypedEmitter as EventEmitter } from "tiny-typed-emitter"; -class VoiceSubscription { +export interface VoiceEvents { + error: (error: AudioPlayerError) => any; + debug: (message: string) => any; + start: () => any; + finish: () => any; +} + +class VoiceSubscription extends EventEmitter { public readonly voiceConnection: VoiceConnection; public readonly audioPlayer: AudioPlayer; public connectPromise?: Promise; constructor(connection: VoiceConnection) { + super(); + this.voiceConnection = connection; this.audioPlayer = createAudioPlayer(); - connection.subscribe(this.audioPlayer); - this.voiceConnection.on("stateChange", (_, newState) => { if (newState.status === VoiceConnectionStatus.Disconnected) { if (this.voiceConnection.reconnectAttempts < 5) { @@ -48,6 +58,18 @@ class VoiceSubscription { .finally(() => (this.connectPromise = undefined)); } }); + + this.audioPlayer.on("stateChange", (oldState, newState) => { + if (newState.status === AudioPlayerStatus.Idle && oldState.status !== AudioPlayerStatus.Idle) { + void this.emit("finish"); + } else if (newState.status === AudioPlayerStatus.Playing) { + void this.emit("start"); + } + }); + + this.audioPlayer.on("debug", (m) => void this.emit("debug", m)); + this.audioPlayer.on("error", (error) => void this.emit("error", error)); + this.voiceConnection.subscribe(this.audioPlayer); } /** @@ -56,7 +78,7 @@ class VoiceSubscription { * @param {({type?:StreamType;data?:any;inlineVolume?:boolean})} [ops] Options * @returns {AudioResource} */ - createStream(src: Readable | Duplex | string, ops?: { type?: StreamType, data?: any, inlineVolume?: boolean }) { + createStream(src: Readable | Duplex | string, ops?: { type?: StreamType; data?: any; inlineVolume?: boolean }) { return createAudioResource(src, { inputType: ops?.type ?? StreamType.Arbitrary, metadata: ops?.data, diff --git a/src/VoiceInterface/VoiceUtils.ts b/src/VoiceInterface/VoiceUtils.ts index a694c90..f69d87c 100644 --- a/src/VoiceInterface/VoiceUtils.ts +++ b/src/VoiceInterface/VoiceUtils.ts @@ -3,7 +3,6 @@ import { entersState, joinVoiceChannel, VoiceConnection, VoiceConnectionStatus } import { VoiceSubscription } from "./VoiceSubscription"; class VoiceUtils { - constructor() { throw new Error("Cannot instantiate static class!"); } @@ -17,9 +16,10 @@ class VoiceUtils { public static async connect( channel: VoiceChannel | StageChannel, options?: { - deaf?: boolean, - maxTime?: number - }): Promise { + deaf?: boolean; + maxTime?: number; + } + ): Promise { let conn = joinVoiceChannel({ guildId: channel.guild.id, channelId: channel.id, @@ -30,7 +30,7 @@ class VoiceUtils { try { conn = await entersState(conn, VoiceConnectionStatus.Ready, options?.maxTime ?? 20000); return new VoiceSubscription(conn); - } catch(err) { + } catch (err) { conn.destroy(); throw err; } @@ -43,7 +43,6 @@ class VoiceUtils { public static disconnect(connection: VoiceConnection) { connection.destroy(); } - } -export { VoiceUtils } \ No newline at end of file +export { VoiceUtils }; diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 3deda80..cb0ff5c 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -1 +1 @@ -export { } \ No newline at end of file +export {}; diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index 3deda80..cb0ff5c 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -1 +1 @@ -export { } \ No newline at end of file +export {}; diff --git a/src/utils/PlayerError.ts b/src/utils/PlayerError.ts index 3deda80..cb0ff5c 100644 --- a/src/utils/PlayerError.ts +++ b/src/utils/PlayerError.ts @@ -1 +1 @@ -export { } \ No newline at end of file +export {}; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 3deda80..cb0ff5c 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1 +1 @@ -export { } \ No newline at end of file +export {};