feat: create PlayerError
This commit is contained in:
parent
8e00bca2df
commit
59b1c60440
5 changed files with 106 additions and 49 deletions
|
@ -8,6 +8,7 @@ import { QueryResolver } from "./utils/QueryResolver";
|
|||
import YouTube from "youtube-sr";
|
||||
import { Util } from "./utils/Util";
|
||||
import Spotify from "spotify-url-info";
|
||||
import { PlayerError, ErrorStatusCode } from "./Structures/PlayerError";
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import { Client as SoundCloud } from "soundcloud-scraper";
|
||||
|
@ -128,7 +129,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
*/
|
||||
createQueue<T = unknown>(guild: GuildResolvable, queueInitOptions: PlayerOptions & { metadata?: T } = {}): Queue<T> {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD);
|
||||
if (this.queues.has(guild.id)) return this.queues.get(guild.id) as Queue<T>;
|
||||
|
||||
const _meta = queueInitOptions.metadata;
|
||||
|
@ -148,7 +149,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
*/
|
||||
getQueue<T = unknown>(guild: GuildResolvable) {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD);
|
||||
return this.queues.get(guild.id) as Queue<T>;
|
||||
}
|
||||
|
||||
|
@ -159,7 +160,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
*/
|
||||
deleteQueue<T = unknown>(guild: GuildResolvable) {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
if (!guild) throw new PlayerError("Unknown Guild", ErrorStatusCode.UNKNOWN_GUILD);
|
||||
const prev = this.getQueue<T>(guild);
|
||||
|
||||
try {
|
||||
|
@ -183,7 +184,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
*/
|
||||
async search(query: string | Track, options: SearchOptions) {
|
||||
if (query instanceof Track) return { playlist: null, tracks: [query] };
|
||||
if (!options) throw new Error("DiscordPlayer#search needs search options!");
|
||||
if (!options) throw new PlayerError("DiscordPlayer#search needs search options!", ErrorStatusCode.INVALID_ARG_TYPE);
|
||||
options.requestedBy = this.client.users.resolve(options.requestedBy);
|
||||
if (!("searchEngine" in options)) options.searchEngine = QueryType.AUTO;
|
||||
|
||||
|
@ -451,7 +452,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
use(extractorName: string, extractor: ExtractorModel | any, force = false): ExtractorModel {
|
||||
if (!extractorName) throw new Error("Cannot use unknown extractor!");
|
||||
if (!extractorName) throw new PlayerError("Cannot use unknown extractor!", ErrorStatusCode.UNKNOWN_EXTRACTOR);
|
||||
if (this.extractors.has(extractorName) && !force) return this.extractors.get(extractorName);
|
||||
if (extractor instanceof ExtractorModel) {
|
||||
this.extractors.set(extractorName, extractor);
|
||||
|
@ -459,7 +460,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
}
|
||||
|
||||
for (const method of ["validate", "getInfo"]) {
|
||||
if (typeof extractor[method] !== "function") throw new Error("Invalid extractor data!");
|
||||
if (typeof extractor[method] !== "function") throw new PlayerError("Invalid extractor data!", ErrorStatusCode.INVALID_EXTRACTOR);
|
||||
}
|
||||
|
||||
const model = new ExtractorModel(extractorName, extractor);
|
||||
|
@ -474,7 +475,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
* @returns {ExtractorModel}
|
||||
*/
|
||||
unuse(extractorName: string) {
|
||||
if (!this.extractors.has(extractorName)) throw new Error(`Cannot find extractor "${extractorName}"`);
|
||||
if (!this.extractors.has(extractorName)) throw new PlayerError(`Cannot find extractor "${extractorName}"`, ErrorStatusCode.UNKNOWN_EXTRACTOR);
|
||||
const prev = this.extractors.get(extractorName);
|
||||
this.extractors.delete(extractorName);
|
||||
return prev;
|
||||
|
|
48
src/Structures/PlayerError.ts
Normal file
48
src/Structures/PlayerError.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
export enum ErrorStatusCode {
|
||||
STREAM_ERROR = "StreamError",
|
||||
AUDIO_PLAYER_ERROR = "AudioPlayerError",
|
||||
PLAYER_ERROR = "PlayerError",
|
||||
NO_AUDIO_RESOURCE = "NoAudioResource",
|
||||
UNKNOWN_GUILD = "UnknownGuild",
|
||||
INVALID_ARG_TYPE = "InvalidArgType",
|
||||
UNKNOWN_EXTRACTOR = "UnknownExtractor",
|
||||
INVALID_EXTRACTOR = "InvalidExtractor",
|
||||
INVALID_CHANNEL_TYPE = "InvalidChannelType",
|
||||
INVALID_TRACK = "InvalidTrack",
|
||||
UNKNOWN_REPEAT_MODE = "UnknownRepeatMode",
|
||||
TRACK_NOT_FOUND = "TrackNotFound",
|
||||
NO_CONNECTION = "NoConnection",
|
||||
DESTROYED_QUEUE = "DestroyedQueue"
|
||||
}
|
||||
|
||||
export class PlayerError extends Error {
|
||||
message: string;
|
||||
statusCode: ErrorStatusCode;
|
||||
createdAt = new Date();
|
||||
|
||||
constructor(message: string, code: ErrorStatusCode = ErrorStatusCode.PLAYER_ERROR) {
|
||||
super();
|
||||
|
||||
this.message = `[${code}] ${message}`;
|
||||
this.statusCode = code;
|
||||
this.name = code;
|
||||
|
||||
Error.captureStackTrace(this);
|
||||
}
|
||||
|
||||
get createdTimestamp() {
|
||||
return this.createdAt.getTime();
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.statusCode;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return { stack: this.stack, code: this.statusCode, created: this.createdTimestamp };
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.stack;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import { AudioResource, StreamType } from "@discordjs/voice";
|
|||
import { Util } from "../utils/Util";
|
||||
import YouTube from "youtube-sr";
|
||||
import AudioFilters from "../utils/AudioFilters";
|
||||
import { PlayerError, ErrorStatusCode } from "./PlayerError";
|
||||
|
||||
class Queue<T = unknown> {
|
||||
public readonly guild: Guild;
|
||||
|
@ -113,7 +114,7 @@ class Queue<T = unknown> {
|
|||
* @type {Track}
|
||||
*/
|
||||
get current() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return this.connection.audioResource?.metadata ?? this.tracks[0];
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,7 @@ class Queue<T = unknown> {
|
|||
* @returns {Track}
|
||||
*/
|
||||
nowPlaying() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return this.current;
|
||||
}
|
||||
|
||||
|
@ -140,9 +141,10 @@ class Queue<T = unknown> {
|
|||
* @returns {Promise<Queue>}
|
||||
*/
|
||||
async connect(channel: GuildChannelResolvable) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
const _channel = this.guild.channels.resolve(channel) as StageChannel | VoiceChannel;
|
||||
if (!["GUILD_STAGE_VOICE", "GUILD_VOICE"].includes(_channel?.type)) throw new TypeError(`Channel type must be GUILD_VOICE or GUILD_STAGE_VOICE, got ${_channel?.type}!`);
|
||||
if (!["GUILD_STAGE_VOICE", "GUILD_VOICE"].includes(_channel?.type))
|
||||
throw new PlayerError(`Channel type must be GUILD_VOICE or GUILD_STAGE_VOICE, got ${_channel?.type}!`, ErrorStatusCode.INVALID_ARG_TYPE);
|
||||
const connection = await this.player.voiceUtils.connect(_channel, {
|
||||
deaf: this.options.autoSelfDeaf
|
||||
});
|
||||
|
@ -198,7 +200,7 @@ class Queue<T = unknown> {
|
|||
* @returns {void}
|
||||
*/
|
||||
destroy(disconnect = this.options.leaveOnStop) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (this.connection) this.connection.end();
|
||||
if (disconnect) this.connection?.disconnect();
|
||||
this.player.queues.delete(this.guild.id);
|
||||
|
@ -211,7 +213,7 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
skip() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection) return false;
|
||||
this._filtersUpdate = false;
|
||||
this.connection.end();
|
||||
|
@ -224,8 +226,8 @@ class Queue<T = unknown> {
|
|||
* @returns {void}
|
||||
*/
|
||||
addTrack(track: Track) {
|
||||
this.#watchDestroyed();
|
||||
if (!(track instanceof Track)) throw new Error("invalid track");
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!(track instanceof Track)) throw new PlayerError("invalid track", ErrorStatusCode.INVALID_TRACK);
|
||||
this.tracks.push(track);
|
||||
this.player.emit("trackAdd", this, track);
|
||||
}
|
||||
|
@ -235,8 +237,8 @@ class Queue<T = unknown> {
|
|||
* @param {Track[]} tracks Array of tracks to add
|
||||
*/
|
||||
addTracks(tracks: Track[]) {
|
||||
this.#watchDestroyed();
|
||||
if (!tracks.every((y) => y instanceof Track)) throw new Error("invalid track");
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!tracks.every((y) => y instanceof Track)) throw new PlayerError("invalid track", ErrorStatusCode.INVALID_TRACK);
|
||||
this.tracks.push(...tracks);
|
||||
this.player.emit("tracksAdd", this, tracks);
|
||||
}
|
||||
|
@ -247,7 +249,7 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
setPaused(paused?: boolean) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection) return false;
|
||||
return paused ? this.connection.pause(true) : this.connection.resume();
|
||||
}
|
||||
|
@ -258,7 +260,7 @@ class Queue<T = unknown> {
|
|||
* @returns {void}
|
||||
*/
|
||||
setBitrate(bitrate: number | "auto") {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection?.audioResource?.encoder) return;
|
||||
if (bitrate === "auto") bitrate = this.connection.channel?.bitrate ?? 64000;
|
||||
this.connection.audioResource.encoder.setBitrate(bitrate);
|
||||
|
@ -270,7 +272,7 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
setVolume(amount: number) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection) return false;
|
||||
this.#lastVolume = amount;
|
||||
this.options.initialVolume = amount;
|
||||
|
@ -282,8 +284,9 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
setRepeatMode(mode: QueueRepeatMode) {
|
||||
this.#watchDestroyed();
|
||||
if (![QueueRepeatMode.OFF, QueueRepeatMode.QUEUE, QueueRepeatMode.TRACK, QueueRepeatMode.AUTOPLAY].includes(mode)) throw new Error(`Unknown repeat mode "${mode}"!`);
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (![QueueRepeatMode.OFF, QueueRepeatMode.QUEUE, QueueRepeatMode.TRACK, QueueRepeatMode.AUTOPLAY].includes(mode))
|
||||
throw new PlayerError(`Unknown repeat mode "${mode}"!`, ErrorStatusCode.UNKNOWN_REPEAT_MODE);
|
||||
if (mode === this.repeatMode) return false;
|
||||
this.repeatMode = mode;
|
||||
return true;
|
||||
|
@ -294,7 +297,7 @@ class Queue<T = unknown> {
|
|||
* @type {number}
|
||||
*/
|
||||
get volume() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection) return 100;
|
||||
return this.connection.volume;
|
||||
}
|
||||
|
@ -326,7 +329,7 @@ class Queue<T = unknown> {
|
|||
* @type {number}
|
||||
*/
|
||||
get streamTime() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.connection) return 0;
|
||||
const playbackTime = this._streamTime + this.connection.streamTime;
|
||||
const NC = this._activeFilters.includes("nightcore") ? 1.25 : null;
|
||||
|
@ -337,7 +340,7 @@ class Queue<T = unknown> {
|
|||
}
|
||||
|
||||
set streamTime(time: number) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
this.seek(time);
|
||||
}
|
||||
|
||||
|
@ -346,7 +349,7 @@ class Queue<T = unknown> {
|
|||
* @returns {AudioFilters}
|
||||
*/
|
||||
getFiltersEnabled() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return AudioFilters.names.filter((x) => this._activeFilters.includes(x));
|
||||
}
|
||||
|
||||
|
@ -355,7 +358,7 @@ class Queue<T = unknown> {
|
|||
* @returns {AudioFilters}
|
||||
*/
|
||||
getFiltersDisabled() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return AudioFilters.names.filter((x) => !this._activeFilters.includes(x));
|
||||
}
|
||||
|
||||
|
@ -365,7 +368,7 @@ class Queue<T = unknown> {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async setFilters(filters?: QueueFilters) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!filters || !Object.keys(filters).length) {
|
||||
// reset filters
|
||||
const streamTime = this.streamTime;
|
||||
|
@ -404,7 +407,7 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
async seek(position: number) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.playing || !this.current) return false;
|
||||
if (position < 1) position = 0;
|
||||
if (position >= this.current.durationMS) return this.skip();
|
||||
|
@ -423,9 +426,9 @@ class Queue<T = unknown> {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async back() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
const prev = this.previousTracks[this.previousTracks.length - 2]; // because last item is the current track
|
||||
if (!prev) throw new Error("Could not find previous track");
|
||||
if (!prev) throw new PlayerError("Could not find previous track", ErrorStatusCode.TRACK_NOT_FOUND);
|
||||
|
||||
return await this.play(prev, { immediate: true });
|
||||
}
|
||||
|
@ -434,7 +437,7 @@ class Queue<T = unknown> {
|
|||
* Clear this queue
|
||||
*/
|
||||
clear() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
this.tracks = [];
|
||||
this.previousTracks = [];
|
||||
}
|
||||
|
@ -444,7 +447,7 @@ class Queue<T = unknown> {
|
|||
* @returns {void}
|
||||
*/
|
||||
stop() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return this.destroy();
|
||||
}
|
||||
|
||||
|
@ -453,7 +456,7 @@ class Queue<T = unknown> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
shuffle() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.tracks.length || this.tracks.length < 3) return false;
|
||||
const currentTrack = this.tracks.shift();
|
||||
|
||||
|
@ -473,7 +476,7 @@ class Queue<T = unknown> {
|
|||
* @returns {Track}
|
||||
*/
|
||||
remove(track: Track | Snowflake | number) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
let trackFound: Track = null;
|
||||
if (typeof track === "number") {
|
||||
trackFound = this.tracks[track];
|
||||
|
@ -496,9 +499,9 @@ class Queue<T = unknown> {
|
|||
* @returns {void}
|
||||
*/
|
||||
jump(track: Track | number): void {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
const foundTrack = this.remove(track);
|
||||
if (!foundTrack) throw new Error("Track not found");
|
||||
if (!foundTrack) throw new PlayerError("Track not found", ErrorStatusCode.TRACK_NOT_FOUND);
|
||||
this.tracks.splice(1, 0, foundTrack);
|
||||
|
||||
return void this.skip();
|
||||
|
@ -510,8 +513,8 @@ class Queue<T = unknown> {
|
|||
* @param {number} [index=0] The index where this track should be
|
||||
*/
|
||||
insert(track: Track, index = 0) {
|
||||
if (!track || !(track instanceof Track)) throw new TypeError("track must be the instance of Track");
|
||||
if (typeof index !== "number" || index < 0 || !Number.isFinite(index)) throw new Error(`Invalid index "${index}"`);
|
||||
if (!track || !(track instanceof Track)) throw new PlayerError("track must be the instance of Track", ErrorStatusCode.INVALID_TRACK);
|
||||
if (typeof index !== "number" || index < 0 || !Number.isFinite(index)) throw new PlayerError(`Invalid index "${index}"`, ErrorStatusCode.INVALID_ARG_TYPE);
|
||||
|
||||
this.tracks.splice(index, 0, track);
|
||||
|
||||
|
@ -530,7 +533,7 @@ class Queue<T = unknown> {
|
|||
* @returns {PlayerTimestamp}
|
||||
*/
|
||||
getPlayerTimestamp() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
const currentStreamTime = this.streamTime;
|
||||
const totalTime = this.current.durationMS;
|
||||
|
||||
|
@ -550,7 +553,7 @@ class Queue<T = unknown> {
|
|||
* @returns {string}
|
||||
*/
|
||||
createProgressBar(options: PlayerProgressbarOptions = { timecodes: true }) {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
const length = typeof options.length === "number" ? (options.length <= 0 || options.length === Infinity ? 15 : options.length) : 15;
|
||||
|
||||
const index = Math.round((this.streamTime / this.current.durationMS) * length);
|
||||
|
@ -581,7 +584,7 @@ class Queue<T = unknown> {
|
|||
* @type {Number}
|
||||
*/
|
||||
get totalTime(): number {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
|
||||
}
|
||||
|
||||
|
@ -593,7 +596,7 @@ class Queue<T = unknown> {
|
|||
*/
|
||||
async play(src?: Track, options: PlayOptions = {}): Promise<void> {
|
||||
if (!this.destroyed) this.#watchDestroyed();
|
||||
if (!this.connection || !this.connection.voiceConnection) throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
||||
if (!this.connection || !this.connection.voiceConnection) throw new PlayerError("Voice connection is not available, use <Queue>.connect()!", ErrorStatusCode.NO_CONNECTION);
|
||||
if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src);
|
||||
const track = options.filtersUpdate && !options.immediate ? src || this.current : src ?? this.tracks.shift();
|
||||
if (!track) return;
|
||||
|
@ -663,7 +666,7 @@ class Queue<T = unknown> {
|
|||
* @private
|
||||
*/
|
||||
private async _handleAutoplay(track: Track): Promise<void> {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!track || ![track.source, track.raw?.source].includes("youtube")) {
|
||||
if (this.options.leaveOnEnd) this.destroy();
|
||||
return void this.player.emit("queueEnd", this);
|
||||
|
@ -692,7 +695,7 @@ class Queue<T = unknown> {
|
|||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
yield* this.tracks;
|
||||
}
|
||||
|
||||
|
@ -701,7 +704,7 @@ class Queue<T = unknown> {
|
|||
* @returns {object}
|
||||
*/
|
||||
toJSON() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
return {
|
||||
id: this.id,
|
||||
guild: this.guild.id,
|
||||
|
@ -716,13 +719,16 @@ class Queue<T = unknown> {
|
|||
* @returns {string}
|
||||
*/
|
||||
toString() {
|
||||
this.#watchDestroyed();
|
||||
if (this.#watchDestroyed()) return;
|
||||
if (!this.tracks.length) return "No songs available to display!";
|
||||
return `**Upcoming Songs:**\n${this.tracks.map((m, i) => `${i + 1}. **${m.title}**`).join("\n")}`;
|
||||
}
|
||||
|
||||
#watchDestroyed() {
|
||||
if (this.#destroyed) throw new Error("Cannot use destroyed queue");
|
||||
if (this.#destroyed) {
|
||||
this.player.emit("error", this, new PlayerError("Cannot use destroyed queue", ErrorStatusCode.DESTROYED_QUEUE));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#getBufferingTimeout() {
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Duplex, Readable } from "stream";
|
|||
import { TypedEmitter as EventEmitter } from "tiny-typed-emitter";
|
||||
import Track from "../Structures/Track";
|
||||
import { Util } from "../utils/Util";
|
||||
import { PlayerError, ErrorStatusCode } from "../Structures/PlayerError";
|
||||
|
||||
export interface VoiceEvents {
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
@ -182,7 +183,7 @@ class StreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
* @returns {Promise<StreamDispatcher>}
|
||||
*/
|
||||
async playStream(resource: AudioResource<Track> = this.audioResource) {
|
||||
if (!resource) throw new Error("Audio resource is not available!");
|
||||
if (!resource) throw new PlayerError("Audio resource is not available!", ErrorStatusCode.NO_AUDIO_RESOURCE);
|
||||
if (!this.audioResource) this.audioResource = resource;
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
||||
this.audioPlayer.play(resource);
|
||||
|
|
|
@ -2,6 +2,7 @@ export { AudioFilters } from "./utils/AudioFilters";
|
|||
export { ExtractorModel } from "./Structures/ExtractorModel";
|
||||
export { Playlist } from "./Structures/Playlist";
|
||||
export { Player } from "./Player";
|
||||
export { PlayerError, ErrorStatusCode } from "./Structures/PlayerError";
|
||||
export { QueryResolver } from "./utils/QueryResolver";
|
||||
export { Queue } from "./Structures/Queue";
|
||||
export { Track } from "./Structures/Track";
|
||||
|
|
Loading…
Reference in a new issue