basic slash commands bot
This commit is contained in:
parent
5239e5f9cc
commit
b97e8e61fc
11 changed files with 239 additions and 106 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"printWidth": 120,
|
"printWidth": 200,
|
||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
|
|
231
example/index.ts
231
example/index.ts
|
@ -1,78 +1,199 @@
|
||||||
import { Client, Message } from "discord.js";
|
import { Client, GuildMember, Message, TextChannel } from "discord.js";
|
||||||
import { Player, Queue } from "../src/index";
|
import { Player, Queue, Track } from "../src/index";
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
|
// use this in prod.
|
||||||
|
// import { Player, Queue } from "discord-player";
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: ['GUILD_VOICE_STATES', 'GUILD_MESSAGES', 'GUILDS']
|
intents: ["GUILD_VOICE_STATES", "GUILD_MESSAGES", "GUILDS"]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
client.on("ready", () => {
|
||||||
|
console.log("Bot is online!");
|
||||||
|
client.user.setActivity({
|
||||||
|
name: "🎶 | Music Time",
|
||||||
|
type: "LISTENING"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
client.on("error", console.error);
|
||||||
|
client.on("warn", console.warn);
|
||||||
|
|
||||||
|
// instantiate the player
|
||||||
const player = new Player(client);
|
const player = new Player(client);
|
||||||
|
|
||||||
|
player.on("error", console.error);
|
||||||
|
|
||||||
player.on("trackStart", (queue, track) => {
|
player.on("trackStart", (queue, track) => {
|
||||||
const guildQueue = queue as Queue<Message>;
|
const guildQueue = queue as Queue<TextChannel>;
|
||||||
guildQueue.metadata.channel.send(`🎶 | Now playing: **${track.title}** in **${guildQueue.connection.channel.name}**!`);
|
guildQueue.metadata.send(`🎶 | Started playing: **${track.title}** in **${guildQueue.connection.channel.name}**!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("ready", () => console.log("Bot is online!"));
|
player.on("trackAdd", (queue, track) => {
|
||||||
|
const guildQueue = queue as Queue<TextChannel>;
|
||||||
|
guildQueue.metadata.send(`🎶 | Track **${track.title}** queued!`);
|
||||||
|
});
|
||||||
|
|
||||||
client.on("message", async message => {
|
client.on("message", async (message) => {
|
||||||
if (!client.application.owner) await client.application.fetch();
|
if (message.author.bot || !message.guild) return;
|
||||||
if (message.author.id !== client.application.owner.id) return;
|
if (!client.application?.owner) await client.application?.fetch();
|
||||||
|
|
||||||
if (message.content.startsWith("!np") && message.guild.me.voice.channelID) {
|
if (message.content === "!deploy" && message.author.id === client.application?.owner?.id) {
|
||||||
const conn = player.getQueue(message.guild.id);
|
await message.guild.commands.set([
|
||||||
if (!conn) return;
|
{
|
||||||
return void message.channel.send(`Now Playing: **${conn.current.title}** (Played **${Math.floor(conn.connection.streamTime / 1000)} seconds**)`);
|
name: "play",
|
||||||
|
description: "Plays a song from youtube",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "query",
|
||||||
|
type: "STRING",
|
||||||
|
description: "The song you want to play",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "volume",
|
||||||
|
description: "Sets music volume",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "amount",
|
||||||
|
type: "INTEGER",
|
||||||
|
description: "The volume amount to set (0-100)",
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "skip",
|
||||||
|
description: "Skip to the current song"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "queue",
|
||||||
|
description: "See the queue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pause",
|
||||||
|
description: "Pause the current song"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "resume",
|
||||||
|
description: "Resume the current song"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "stop",
|
||||||
|
description: "Stop the player"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "np",
|
||||||
|
description: "Now Playing"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await message.reply("Deployed!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("interaction", async (interaction) => {
|
||||||
|
if (!interaction.isCommand() || !interaction.guildID) return;
|
||||||
|
|
||||||
|
if (!(interaction.member instanceof GuildMember) || !interaction.member.voice.channel) {
|
||||||
|
return void interaction.reply({ content: "You are not in a voice channel!", ephemeral: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.content.startsWith("!pause") && message.guild.me.voice.channelID) {
|
if (interaction.guild.me.voice.channelID && interaction.member.voice.channelID !== interaction.guild.me.voice.channelID) {
|
||||||
const conn = player.getQueue(message.guild.id);
|
return void interaction.reply({ content: "You are not in my voice channel!", ephemeral: true });
|
||||||
if (!conn) return;
|
|
||||||
conn.setPaused(true);
|
|
||||||
return void message.channel.send("Paused!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.content.startsWith("!resume") && message.guild.me.voice.channelID) {
|
if (interaction.commandName === "play") {
|
||||||
const conn = player.getQueue(message.guild.id);
|
await interaction.defer();
|
||||||
if (!conn) return;
|
|
||||||
conn.setPaused(false);
|
|
||||||
return void message.channel.send("Resumed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.content.startsWith("!skip") && message.guild.me.voice.channelID) {
|
const query = interaction.options.get("query")!.value! as string;
|
||||||
const conn = player.getQueue(message.guild.id);
|
const searchResult = (await player.search(query, interaction.user).catch(() => [])) as Track[];
|
||||||
if (!conn) return;
|
if (!searchResult.length) return void interaction.followUp({ content: "No results were found!" });
|
||||||
conn.skip();
|
|
||||||
return void message.channel.send("Done!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.content.startsWith("!queue") && message.guild.me.voice.channelID) {
|
const queue = await player.createQueue(interaction.guild, {
|
||||||
const conn = player.getQueue(message.guild.id);
|
metadata: interaction.channel
|
||||||
if (!conn) return;
|
|
||||||
return void message.channel.send({ content: conn.toString(), split: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.content.startsWith("!vol") && message.guild.me.voice.channelID) {
|
|
||||||
const conn = player.getQueue(message.guild.id);
|
|
||||||
if (!conn) return;
|
|
||||||
conn.connection.setVolume(parseInt(message.content.slice(4).trim()));
|
|
||||||
return void message.channel.send("Volume changed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.content.startsWith("!p") && message.member.voice.channelID) {
|
|
||||||
const queue = player.createQueue<Message>(message.guild, {
|
|
||||||
metadata: message
|
|
||||||
});
|
});
|
||||||
const song = await player.search(message.content.slice(2).trim(), message.author).then(x => x[0]);
|
|
||||||
queue.addTrack(song);
|
|
||||||
|
|
||||||
if (!queue.connection) {
|
try {
|
||||||
queue.connect(message.member.voice.channel)
|
if (!queue.connection) await queue.connect(interaction.member.voice.channel);
|
||||||
.then(async q => {
|
} catch {
|
||||||
await q.play();
|
void player.deleteQueue(interaction.guildID);
|
||||||
});
|
return void interaction.followUp({ content: "Could not join your voice channel!" });
|
||||||
} else {
|
|
||||||
message.channel.send(`🎶 | Queued: **${song.title}**!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await interaction.followUp({ content: "⏱ | Loading your track..." });
|
||||||
|
await queue.play(searchResult[0]);
|
||||||
|
} else if (interaction.commandName === "volume") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
const vol = interaction.options.get("amount");
|
||||||
|
if (!vol) return void interaction.followUp({ content: `🎧 | Current volume is **${queue.volume}**%!` });
|
||||||
|
if ((vol.value as number) < 0 || (vol.value as number) > 100) return void interaction.followUp({ content: "❌ | Volume range must be 0-100" });
|
||||||
|
const success = queue.setVolume(vol.value as number);
|
||||||
|
return void interaction.followUp({
|
||||||
|
content: success ? `✅ | Volume set to **${vol.value}%**!` : "❌ | Something went wrong!"
|
||||||
|
});
|
||||||
|
} else if (interaction.commandName === "skip") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
const currentTrack = queue.current;
|
||||||
|
const success = queue.skip();
|
||||||
|
return void interaction.followUp({
|
||||||
|
content: success ? `✅ | Skipped **${currentTrack}**!` : "❌ | Something went wrong!"
|
||||||
|
});
|
||||||
|
} else if (interaction.commandName === "queue") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
const currentTrack = queue.current;
|
||||||
|
const tracks = queue.tracks
|
||||||
|
.slice(0, 10)
|
||||||
|
.map((m, i) => {
|
||||||
|
return `${i + 1}. **${m.title}**`;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
return void interaction.followUp({
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: "Server Queue",
|
||||||
|
description: `${tracks}${queue.tracks.length > tracks.length ? `...${queue.tracks.length - tracks.length} more tracks` : ""}`,
|
||||||
|
color: 0xff0000,
|
||||||
|
fields: [{ name: "Now Playing", value: `🎶 | **${currentTrack.title}**` }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} else if (interaction.commandName === "pause") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
const success = queue.setPaused(true);
|
||||||
|
return void interaction.followUp({ content: success ? "⏸ | Paused!" : "❌ | Something went wrong!" });
|
||||||
|
} else if (interaction.commandName === "resume") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
const success = queue.setPaused(false);
|
||||||
|
return void interaction.followUp({ content: success ? "▶ | Resumed!" : "❌ | Something went wrong!" });
|
||||||
|
} else if (interaction.commandName === "stop") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
queue.destroy();
|
||||||
|
return void interaction.followUp({ content: "🛑 | Stopped the player!" });
|
||||||
|
} else if (interaction.commandName === "np") {
|
||||||
|
await interaction.defer();
|
||||||
|
const queue = player.getQueue(interaction.guildID);
|
||||||
|
if (!queue || !queue.playing) return void interaction.followUp({ content: "❌ | No music is being played!" });
|
||||||
|
return void interaction.followUp({ content: `🎶 | Current song: **${queue.current.title}**!` });
|
||||||
|
} else {
|
||||||
|
interaction.reply({
|
||||||
|
content: "Unknown command!",
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "cd example && ts-node index.ts",
|
"test": "cd example && ts-node index.ts",
|
||||||
"build": "tsc",
|
"build": "rimraf lib && tsc",
|
||||||
"format": "prettier --write \"src/**/*.ts\"",
|
"format": "prettier --write \"src/**/*.ts\" \"example/**/*.ts\"",
|
||||||
"lint": "tslint -p tsconfig.json",
|
"lint": "tslint -p tsconfig.json",
|
||||||
"docs": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json",
|
"docs": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json",
|
||||||
"docs:test": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml"
|
"docs:test": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml"
|
||||||
|
@ -68,10 +68,11 @@
|
||||||
"@types/node": "^14.14.41",
|
"@types/node": "^14.14.41",
|
||||||
"@types/ws": "^7.4.1",
|
"@types/ws": "^7.4.1",
|
||||||
"discord-api-types": "^0.18.1",
|
"discord-api-types": "^0.18.1",
|
||||||
"discord.js": "^13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10",
|
"discord.js": "^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7",
|
||||||
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
||||||
"jsdoc-babel": "^0.5.0",
|
"jsdoc-babel": "^0.5.0",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.0.0",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
|
|
|
@ -31,6 +31,12 @@ class DiscordPlayer extends EventEmitter<PlayerEvents> {
|
||||||
return this.queues.get(guild) as Queue<T>;
|
return this.queues.get(guild) as Queue<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteQueue<T = unknown>(guild: Snowflake) {
|
||||||
|
const prev = this.getQueue<T>(guild);
|
||||||
|
this.queues.delete(guild);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search tracks
|
* Search tracks
|
||||||
* @param {string|Track} query The search query
|
* @param {string|Track} query The search query
|
||||||
|
|
|
@ -45,8 +45,7 @@ class Queue<T = unknown> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect(channel: StageChannel | VoiceChannel) {
|
async connect(channel: StageChannel | VoiceChannel) {
|
||||||
if (!["stage", "voice"].includes(channel?.type))
|
if (!["stage", "voice"].includes(channel?.type)) throw new TypeError(`Channel type must be voice or stage, got ${channel?.type}!`);
|
||||||
throw new TypeError(`Channel type must be voice or stage, got ${channel?.type}!`);
|
|
||||||
const connection = await this.player.voiceUtils.connect(channel);
|
const connection = await this.player.voiceUtils.connect(channel);
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
||||||
|
@ -69,6 +68,7 @@ class Queue<T = unknown> {
|
||||||
|
|
||||||
addTrack(track: Track) {
|
addTrack(track: Track) {
|
||||||
this.addTracks([track]);
|
this.addTracks([track]);
|
||||||
|
this.player.emit("trackAdd", this, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTracks(tracks: Track[]) {
|
addTracks(tracks: Track[]) {
|
||||||
|
@ -86,12 +86,21 @@ class Queue<T = unknown> {
|
||||||
this.connection.audioResource.encoder.setBitrate(bitrate);
|
this.connection.audioResource.encoder.setBitrate(bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setVolume(amount: number) {
|
||||||
|
if (!this.connection) return false;
|
||||||
|
return this.connection.setVolume(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
get volume() {
|
||||||
|
if (!this.connection) return 100;
|
||||||
|
return this.connection.volume;
|
||||||
|
}
|
||||||
|
|
||||||
async play(src?: Track, options: PlayOptions = {}) {
|
async play(src?: Track, options: PlayOptions = {}) {
|
||||||
if (!this.connection || !this.connection.voiceConnection)
|
if (!this.connection || !this.connection.voiceConnection) throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
||||||
throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src);
|
||||||
const track = options.filtersUpdate ? this.current : src ?? this.tracks.shift();
|
const track = options.filtersUpdate ? this.current : src ?? this.tracks.shift();
|
||||||
if (!track) return;
|
if (!track) return;
|
||||||
|
|
||||||
let stream;
|
let stream;
|
||||||
if (["youtube", "spotify"].includes(track.raw.source)) {
|
if (["youtube", "spotify"].includes(track.raw.source)) {
|
||||||
stream = ytdl(track.raw.source === "spotify" ? track.raw.engine : track.url, {
|
stream = ytdl(track.raw.source === "spotify" ? track.raw.engine : track.url, {
|
||||||
|
@ -102,18 +111,13 @@ class Queue<T = unknown> {
|
||||||
seek: options.seek
|
seek: options.seek
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
stream = ytdl.arbitraryStream(
|
stream = ytdl.arbitraryStream(track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : (track.raw.engine as string), {
|
||||||
track.raw.source === "soundcloud"
|
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
||||||
? await track.raw.engine.downloadProgressive()
|
opusEncoded: false,
|
||||||
: (track.raw.engine as string),
|
fmt: "s16le",
|
||||||
{
|
encoderArgs: options.encoderArgs ?? [],
|
||||||
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
seek: options.seek
|
||||||
opusEncoded: false,
|
});
|
||||||
fmt: "s16le",
|
|
||||||
encoderArgs: options.encoderArgs ?? [],
|
|
||||||
seek: options.seek
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource: AudioResource<Track> = this.connection.createStream(stream, {
|
const resource: AudioResource<Track> = this.connection.createStream(stream, {
|
||||||
|
@ -124,12 +128,12 @@ class Queue<T = unknown> {
|
||||||
const dispatcher = await this.connection.playStream(resource);
|
const dispatcher = await this.connection.playStream(resource);
|
||||||
dispatcher.setVolume(this.options.initialVolume);
|
dispatcher.setVolume(this.options.initialVolume);
|
||||||
|
|
||||||
dispatcher.on("start", () => {
|
dispatcher.once("start", () => {
|
||||||
this.playing = true;
|
this.playing = true;
|
||||||
if (!options.filtersUpdate) this.player.emit("trackStart", this, this.current);
|
if (!options.filtersUpdate) this.player.emit("trackStart", this, this.current);
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatcher.on("finish", () => {
|
dispatcher.once("finish", () => {
|
||||||
this.playing = false;
|
this.playing = false;
|
||||||
if (options.filtersUpdate) return;
|
if (options.filtersUpdate) return;
|
||||||
|
|
||||||
|
@ -138,9 +142,12 @@ class Queue<T = unknown> {
|
||||||
this.player.emit("queueEnd", this);
|
this.player.emit("queueEnd", this);
|
||||||
} else {
|
} else {
|
||||||
const nextTrack = this.tracks.shift();
|
const nextTrack = this.tracks.shift();
|
||||||
this.play(nextTrack);
|
this.play(nextTrack, { immediate: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dispatcher.on("error", (e) => this.player.emit("error", this, e));
|
||||||
|
dispatcher.on("debug", (msg) => this.player.emit("debug", this, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
*[Symbol.iterator]() {
|
*[Symbol.iterator]() {
|
||||||
|
|
|
@ -51,16 +51,11 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
||||||
}
|
}
|
||||||
} else if (newState.status === VoiceConnectionStatus.Destroyed) {
|
} else if (newState.status === VoiceConnectionStatus.Destroyed) {
|
||||||
this.end();
|
this.end();
|
||||||
} else if (
|
} else if (!this.connectPromise && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) {
|
||||||
!this.connectPromise &&
|
|
||||||
(newState.status === VoiceConnectionStatus.Connecting ||
|
|
||||||
newState.status === VoiceConnectionStatus.Signalling)
|
|
||||||
) {
|
|
||||||
this.connectPromise = entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000)
|
this.connectPromise = entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000)
|
||||||
.then(() => undefined)
|
.then(() => undefined)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)
|
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed) this.voiceConnection.destroy();
|
||||||
this.voiceConnection.destroy();
|
|
||||||
})
|
})
|
||||||
.finally(() => (this.connectPromise = undefined));
|
.finally(() => (this.connectPromise = undefined));
|
||||||
}
|
}
|
||||||
|
@ -140,8 +135,7 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
||||||
async playStream(resource: AudioResource<Track> = this.audioResource) {
|
async playStream(resource: AudioResource<Track> = this.audioResource) {
|
||||||
if (!resource) throw new PlayerError("Audio resource is not available!");
|
if (!resource) throw new PlayerError("Audio resource is not available!");
|
||||||
if (!this.audioResource) this.audioResource = resource;
|
if (!this.audioResource) this.audioResource = resource;
|
||||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready)
|
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
||||||
await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
|
||||||
this.audioPlayer.play(resource);
|
this.audioPlayer.play(resource);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -155,6 +149,12 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get volume() {
|
||||||
|
if (!this.audioResource || !this.audioResource.volume) return 100;
|
||||||
|
const currentVol = this.audioResource.volume.volume;
|
||||||
|
return Math.round(Math.pow(currentVol, 1 / 1.660964) * 200);
|
||||||
|
}
|
||||||
|
|
||||||
get streamTime() {
|
get streamTime() {
|
||||||
if (!this.audioResource) return 0;
|
if (!this.audioResource) return 0;
|
||||||
return this.audioResource.playbackDuration;
|
return this.audioResource.playbackDuration;
|
||||||
|
|
|
@ -119,7 +119,8 @@ export interface PlayerEvents {
|
||||||
botDisconnect: () => any;
|
botDisconnect: () => any;
|
||||||
channelEmpty: () => any;
|
channelEmpty: () => any;
|
||||||
connectionCreate: () => any;
|
connectionCreate: () => any;
|
||||||
error: () => any;
|
debug: (queue: Queue, message: string) => any;
|
||||||
|
error: (queue: Queue, error: Error) => any;
|
||||||
musicStop: () => any;
|
musicStop: () => any;
|
||||||
noResults: () => any;
|
noResults: () => any;
|
||||||
playlistAdd: () => any;
|
playlistAdd: () => any;
|
||||||
|
@ -130,7 +131,7 @@ export interface PlayerEvents {
|
||||||
searchCancel: () => any;
|
searchCancel: () => any;
|
||||||
searchInvalidResponse: () => any;
|
searchInvalidResponse: () => any;
|
||||||
searchResults: () => any;
|
searchResults: () => any;
|
||||||
trackAdd: () => any;
|
trackAdd: (queue: Queue, track: Track) => any;
|
||||||
trackStart: (queue: Queue, track: Track) => any;
|
trackStart: (queue: Queue, track: Track) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,4 +144,7 @@ export interface PlayOptions {
|
||||||
|
|
||||||
/** Time to seek to before playing */
|
/** Time to seek to before playing */
|
||||||
seek?: number;
|
seek?: number;
|
||||||
|
|
||||||
|
/** If it should start playing provided track immediately */
|
||||||
|
immediate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,15 +70,11 @@ const FilterList = {
|
||||||
},
|
},
|
||||||
|
|
||||||
get names() {
|
get names() {
|
||||||
return Object.keys(this).filter(
|
return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function");
|
||||||
(p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function"
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get length() {
|
get length() {
|
||||||
return Object.keys(this).filter(
|
return Object.keys(this).filter((p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function").length;
|
||||||
(p) => !["names", "length"].includes(p) && typeof this[p as FiltersName] !== "function"
|
|
||||||
).length;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
|
|
|
@ -6,11 +6,9 @@ import { validateURL as SoundcloudValidateURL } from "soundcloud-scraper";
|
||||||
|
|
||||||
// scary things below *sigh*
|
// scary things below *sigh*
|
||||||
const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/;
|
const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/;
|
||||||
const spotifyPlaylistRegex =
|
const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
||||||
/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
|
||||||
const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/;
|
const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/;
|
||||||
const vimeoRegex =
|
const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
||||||
/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
|
||||||
const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/;
|
const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/;
|
||||||
const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/;
|
const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/;
|
||||||
const attachmentRegex =
|
const attachmentRegex =
|
||||||
|
|
|
@ -1860,10 +1860,10 @@ discord.js-docgen@discordjs/docgen#ts-patch:
|
||||||
tsubaki "^1.3.2"
|
tsubaki "^1.3.2"
|
||||||
yargs "^14.0.0"
|
yargs "^14.0.0"
|
||||||
|
|
||||||
discord.js@^13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10:
|
discord.js@^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7:
|
||||||
version "13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10"
|
version "13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7"
|
||||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.f5f3f772865ee98bbb44df938e0e71f9f8865c10.tgz#0fe3389e4befffd429ba37fc669b9153e87f33e5"
|
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7.tgz#5baa6c758b970a1e6175d06373d4ab33eb6a4164"
|
||||||
integrity sha512-VuGJMzXStqeeHmB3DDEShGHXGey215573kkbFxQinzrFYt1UNnQZ5d1ZmB7Y0oY3JSivpv3Whc5M/YtH41NMXQ==
|
integrity sha512-nzbmF5MLSjpdr8DS7SpC9q291NQ8XkHlledM4lz+uFJ4YgnMmTpi6e0FgF7v2kpTJPqTsXDRY3rWBv6Dat+08A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@discordjs/collection" "^0.1.6"
|
"@discordjs/collection" "^0.1.6"
|
||||||
"@discordjs/form-data" "^3.0.1"
|
"@discordjs/form-data" "^3.0.1"
|
||||||
|
|
Loading…
Reference in a new issue