feat(VoiceInterface): metadata

This commit is contained in:
Snowflake107 2021-06-11 17:35:43 +05:45
parent 5d5fd03997
commit 19039f8d9b
5 changed files with 36 additions and 12 deletions

View file

@ -1,11 +1,13 @@
import { Client, Collection, Guild, Snowflake } from "discord.js";
import { TypedEmitter as EventEmitter } from "tiny-typed-emitter";
import { Queue } from "./Structures/Queue";
import { VoiceUtils } from "./VoiceInterface/VoiceUtils";
import { PlayerOptions } from "./types/types";
class DiscordPlayer extends EventEmitter {
public readonly client: Client;
public readonly queues = new Collection<Snowflake, Queue>();
public readonly voiceUtils = new VoiceUtils();
constructor(client: Client) {
super();

View file

@ -9,7 +9,6 @@ class Playlist {
this.player = player;
this.tracks = tracks ?? [];
}
}
export { Playlist };

View file

@ -1,6 +1,5 @@
import { Guild, StageChannel, VoiceChannel } from "discord.js";
import { Player } from "../Player";
import { VoiceUtils } from "../VoiceInterface/VoiceUtils";
import { VoiceSubscription } from "../VoiceInterface/VoiceSubscription";
import Track from "./Track";
import { PlayerOptions } from "../types/types";
@ -36,10 +35,14 @@ class Queue {
);
}
get current() {
return this.voiceConnection.audioResource?.metadata ?? this.tracks[0];
}
async joinVoiceChannel(channel: StageChannel | VoiceChannel) {
if (!["stage", "voice"].includes(channel.type))
throw new TypeError(`Channel type must be voice or stage, got ${channel.type}!`);
const connection = await VoiceUtils.connect(channel);
const connection = await this.player.voiceUtils.connect(channel);
this.voiceConnection = connection;
return this;
@ -50,6 +53,10 @@ class Queue {
this.voiceConnection.disconnect();
this.player.queues.delete(this.guild.id);
}
play() {
throw new Error("Not implemented");
}
}
export { Queue };

View file

@ -12,6 +12,8 @@ import {
} from "@discordjs/voice";
import { Duplex, Readable } from "stream";
import { TypedEmitter as EventEmitter } from "tiny-typed-emitter";
import Track from "../Structures/Track";
import PlayerError from "../utils/PlayerError";
export interface VoiceEvents {
error: (error: AudioPlayerError) => any;
@ -24,6 +26,7 @@ class VoiceSubscription extends EventEmitter<VoiceEvents> {
public readonly voiceConnection: VoiceConnection;
public readonly audioPlayer: AudioPlayer;
public connectPromise?: Promise<void>;
public audioResource?: AudioResource<Track>;
constructor(connection: VoiceConnection) {
super();
@ -79,11 +82,13 @@ class VoiceSubscription extends EventEmitter<VoiceEvents> {
* @returns {AudioResource}
*/
createStream(src: Readable | Duplex | string, ops?: { type?: StreamType; data?: any; inlineVolume?: boolean }) {
return createAudioResource(src, {
this.audioResource = createAudioResource(src, {
inputType: ops?.type ?? StreamType.Arbitrary,
metadata: ops?.data,
inlineVolume: Boolean(ops?.inlineVolume)
});
return this.audioResource;
}
/**
@ -119,11 +124,18 @@ class VoiceSubscription extends EventEmitter<VoiceEvents> {
* Play stream
* @param {AudioResource} resource The audio resource to play
*/
playStream(resource: AudioResource) {
playStream(resource: AudioResource<Track> = this.audioResource) {
if (!resource) throw new PlayerError("Audio resource is not available!");
if (!this.audioResource && resource) this.audioResource = resource;
this.audioPlayer.play(resource);
return this;
}
get streamTime() {
if (!this.audioResource) return 0;
return this.audioResource.playbackDuration;
}
}
export { VoiceSubscription };

View file

@ -1,11 +1,9 @@
import { VoiceChannel, StageChannel } from "discord.js";
import { VoiceChannel, StageChannel, Collection, Snowflake } from "discord.js";
import { entersState, joinVoiceChannel, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice";
import { VoiceSubscription } from "./VoiceSubscription";
class VoiceUtils {
constructor() {
throw new Error("Cannot instantiate static class!");
}
public cache = new Collection<Snowflake, VoiceSubscription>();
/**
* Joins a voice channel
@ -13,7 +11,7 @@ class VoiceUtils {
* @param {({deaf?: boolean;maxTime?: number;})} [options] Join options
* @returns {Promise<VoiceSubscription>}
*/
public static async connect(
public async connect(
channel: VoiceChannel | StageChannel,
options?: {
deaf?: boolean;
@ -29,7 +27,9 @@ class VoiceUtils {
try {
conn = await entersState(conn, VoiceConnectionStatus.Ready, options?.maxTime ?? 20000);
return new VoiceSubscription(conn);
const sub = new VoiceSubscription(conn);
this.cache.set(channel.guild.id, sub);
return sub;
} catch (err) {
conn.destroy();
throw err;
@ -40,10 +40,14 @@ class VoiceUtils {
* Disconnects voice connection
* @param {VoiceConnection} connection The voice connection
*/
public static disconnect(connection: VoiceConnection | VoiceSubscription) {
public disconnect(connection: VoiceConnection | VoiceSubscription) {
if (connection instanceof VoiceSubscription) return connection.voiceConnection.destroy();
return connection.destroy();
}
public getConnection(guild: Snowflake) {
return this.cache.get(guild);
}
}
export { VoiceUtils };