queue utils
This commit is contained in:
parent
1d88db1711
commit
2a6d9a74f4
10 changed files with 171 additions and 12 deletions
|
@ -92,7 +92,7 @@ client.on("message", async (message) => {
|
|||
}
|
||||
|
||||
const track = await client.player.search(args[0], {
|
||||
searchEngine: QueryType.YOUTUBE_SEARCH
|
||||
requestedBy: message.author
|
||||
}).then(x => x.tracks[1]);
|
||||
if (!track) return void message.reply("Track not found!");
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ client.on("message", async (message) => {
|
|||
}
|
||||
|
||||
const track = await client.player.search(args[0], {
|
||||
searchEngine: QueryType.YOUTUBE_SEARCH
|
||||
requestedBy: message.author
|
||||
}).then(x => x.tracks[1]);
|
||||
if (!track) return void message.reply("Track not found!");
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ The new update brings new features as well as better management of different thi
|
|||
```diff
|
||||
- player.play(message, query);
|
||||
+ const queue = player.createQueue(message.guild);
|
||||
+ const song = await player.search(query);
|
||||
+ const song = await player.search(query, {
|
||||
+ requestedBy: message.author
|
||||
});
|
||||
+
|
||||
+ try {
|
||||
+ await queue.connect(message.member.voice.channel);
|
||||
|
|
|
@ -254,7 +254,24 @@ client.on("interaction", async (interaction) => {
|
|||
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}**!` });
|
||||
const progress = queue.createProgressBar();
|
||||
const perc = queue.getPlayerTimestamp();
|
||||
|
||||
return void interaction.followUp({
|
||||
embeds: [
|
||||
{
|
||||
title: "Now Playing",
|
||||
description: `🎶 | **${queue.current.title}**! (\`${perc.progress}%\`)`,
|
||||
fields: [
|
||||
{
|
||||
name: "\u200b",
|
||||
value: progress
|
||||
}
|
||||
],
|
||||
color: 0xffffff
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (interaction.commandName === "loop") {
|
||||
await interaction.defer();
|
||||
const queue = player.getQueue(interaction.guildID);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@discordjs/opus": "^0.5.3",
|
||||
"discord-player": "^5.0.0-dev.3fd002187de27ed6dc3398fd8f4f5dfe309ba350",
|
||||
"discord-player": "^5.0.0-dev.1d88db17117d79a26967895675c17f117e52878d",
|
||||
"discord.js": "^13.0.0-dev.c850ae10270076c4b2e10b130dd8f88eed4ed201"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
||||
"@typescript-eslint/parser": "^4.28.0",
|
||||
"discord-api-types": "^0.18.1",
|
||||
"discord.js": "^13.0.0-dev.c850ae10270076c4b2e10b130dd8f88eed4ed201",
|
||||
"discord.js": "^13.0.0-dev.6d3d00b44577a70e840f0187d6894043677c5329",
|
||||
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
||||
"eslint": "^7.29.0",
|
||||
"jsdoc-babel": "^0.5.0",
|
||||
|
|
|
@ -188,6 +188,7 @@ class Player extends EventEmitter<PlayerEvents> {
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const [_, extractor] of this.extractors) {
|
||||
if (options.blockExtractor) break;
|
||||
if (!extractor.validate(query)) continue;
|
||||
const data = await extractor.handle(query);
|
||||
if (data && data.data.length) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Collection, Guild, StageChannel, VoiceChannel } from "discord.js";
|
|||
import { Player } from "../Player";
|
||||
import { StreamDispatcher } from "../VoiceInterface/BasicStreamDispatcher";
|
||||
import Track from "./Track";
|
||||
import { PlayerOptions, PlayOptions, QueueFilters, QueueRepeatMode } from "../types/types";
|
||||
import { PlayerOptions, PlayerProgressbarOptions, PlayOptions, QueueFilters, QueueRepeatMode } from "../types/types";
|
||||
import ytdl from "discord-ytdl-core";
|
||||
import { AudioResource, StreamType } from "@discordjs/voice";
|
||||
import { Util } from "../utils/Util";
|
||||
|
@ -300,6 +300,11 @@ class Queue<T = unknown> {
|
|||
return NC ? playbackTime * NC : VW ? playbackTime * VW : playbackTime;
|
||||
}
|
||||
|
||||
set streamTime(time: number) {
|
||||
this.#watchDestroyed();
|
||||
this.seek(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns enabled filters
|
||||
* @returns {AudioFilters}
|
||||
|
@ -398,6 +403,138 @@ class Queue<T = unknown> {
|
|||
this.previousTracks = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the player
|
||||
* @returns {void}
|
||||
*/
|
||||
stop() {
|
||||
return this.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffles this queue
|
||||
* @returns {boolean}
|
||||
*/
|
||||
shuffle() {
|
||||
if (!this.tracks.length || this.tracks.length < 3) return false;
|
||||
const currentTrack = this.tracks.shift();
|
||||
|
||||
for (let i = this.tracks.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
|
||||
}
|
||||
|
||||
this.tracks.unshift(currentTrack);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a track from the queue
|
||||
* @param {Track|number} track The track to remove
|
||||
* @returns {Track}
|
||||
*/
|
||||
remove(track: Track | number) {
|
||||
let trackFound: Track = null;
|
||||
if (typeof track === "number") {
|
||||
trackFound = this.tracks[track];
|
||||
if (trackFound) {
|
||||
this.tracks = this.tracks.filter((t) => t._trackID !== trackFound._trackID);
|
||||
}
|
||||
} else {
|
||||
trackFound = this.tracks.find((s) => s._trackID === track._trackID);
|
||||
if (trackFound) {
|
||||
this.tracks = this.tracks.filter((s) => s._trackID !== trackFound._trackID);
|
||||
}
|
||||
}
|
||||
|
||||
return trackFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Jumps to particular track
|
||||
* @param {Track|number} track The track
|
||||
* @returns {void}
|
||||
*/
|
||||
jump(track: Track | number): void {
|
||||
const foundTrack = this.remove(track);
|
||||
if (!foundTrack) throw new Error("Track not found");
|
||||
this.tracks.splice(1, 0, foundTrack);
|
||||
|
||||
return void this.skip();
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} PlayerTimestamp
|
||||
* @param {string} current The current progress
|
||||
* @param {string} end The total time
|
||||
* @param {number} progress Progress in %
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns player stream timestamp
|
||||
* @param {boolean} [queue=false] If it should generate timestamp for the queue
|
||||
* @returns {PlayerTimestamp}
|
||||
*/
|
||||
getPlayerTimestamp(queue = false) {
|
||||
const previousTracksTime = this.previousTracks.length > 0 ? this.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0;
|
||||
const currentStreamTime = queue ? previousTracksTime + this.streamTime : this.streamTime;
|
||||
const totalTracksTime = this.totalTime;
|
||||
const totalTime = queue ? previousTracksTime + totalTracksTime : this.current.durationMS;
|
||||
|
||||
const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime));
|
||||
const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime));
|
||||
|
||||
return {
|
||||
current: currentTimecode,
|
||||
end: endTimecode,
|
||||
progress: Math.round((currentStreamTime / totalTime) * 100)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates progress bar string
|
||||
* @param {PlayerProgressbarOptions} options The progress bar options
|
||||
* @returns {string}
|
||||
*/
|
||||
createProgressBar(options: PlayerProgressbarOptions = { timecodes: true, queue: false }) {
|
||||
const previousTracksTime = this.previousTracks.length > 0 ? this.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0;
|
||||
const currentStreamTime = options.queue ? previousTracksTime + this.streamTime : this.streamTime;
|
||||
const totalTracksTime = this.totalTime;
|
||||
const totalTime = options.queue ? previousTracksTime + totalTracksTime : this.current.durationMS;
|
||||
const length = typeof options.length === "number" ? (options.length <= 0 || options.length === Infinity ? 15 : options.length) : 15;
|
||||
|
||||
const index = Math.round((currentStreamTime / totalTime) * length);
|
||||
const indicator = typeof options.indicator === "string" && options.indicator.length > 0 ? options.indicator : "🔘";
|
||||
const line = typeof options.line === "string" && options.line.length > 0 ? options.line : "▬";
|
||||
|
||||
if (index >= 1 && index <= length) {
|
||||
const bar = line.repeat(length - 1).split("");
|
||||
bar.splice(index, 0, indicator);
|
||||
if (options.timecodes) {
|
||||
const timestamp = this.getPlayerTimestamp(options.queue);
|
||||
return `${timestamp.current} ┃ ${bar.join("")} ┃ ${timestamp.end}`;
|
||||
} else {
|
||||
return `${bar.join("")}`;
|
||||
}
|
||||
} else {
|
||||
if (options.timecodes) {
|
||||
const timestamp = this.getPlayerTimestamp(options.queue);
|
||||
return `${timestamp.current} ┃ ${indicator}${line.repeat(length - 1)} ┃ ${timestamp.end}`;
|
||||
} else {
|
||||
return `${indicator}${line.repeat(length - 1)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Total duration
|
||||
* @type {Number}
|
||||
*/
|
||||
get totalTime(): number {
|
||||
return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play stream in a voice/stage channel
|
||||
* @param {Track} [src] The track to play (if empty, uses first track from the queue)
|
||||
|
|
|
@ -337,11 +337,13 @@ export interface PlayOptions {
|
|||
/**
|
||||
* @typedef {object} SearchOptions
|
||||
* @property {UserResolvable} requestedBy The user who requested this search
|
||||
* @property {QueryType} searchEngine The query search engine
|
||||
* @property {QueryType} [searchEngine=QueryType.AUTO] The query search engine
|
||||
* @property {boolean} [blockExtractor=false] If it should block custom extractors
|
||||
*/
|
||||
export interface SearchOptions {
|
||||
requestedBy: UserResolvable;
|
||||
searchEngine?: QueryType;
|
||||
blockExtractor?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2003,10 +2003,10 @@ discord.js-docgen@discordjs/docgen#ts-patch:
|
|||
tsubaki "^1.3.2"
|
||||
yargs "^14.0.0"
|
||||
|
||||
discord.js@^13.0.0-dev.c850ae10270076c4b2e10b130dd8f88eed4ed201:
|
||||
version "13.0.0-dev.c850ae10270076c4b2e10b130dd8f88eed4ed201"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.c850ae10270076c4b2e10b130dd8f88eed4ed201.tgz#8790b4f48ed36106ea08d2dc3148ee51ef321497"
|
||||
integrity sha512-yp/s0AxcTNtvt9zcZv3kb0szLTFN2rqCoz4hclRE7C3umD7kgvcbF4O+k3RJ1ef6CAlrsZxvept/zYGqIn/dTA==
|
||||
discord.js@^13.0.0-dev.6d3d00b44577a70e840f0187d6894043677c5329:
|
||||
version "13.0.0-dev.6d3d00b44577a70e840f0187d6894043677c5329"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.6d3d00b44577a70e840f0187d6894043677c5329.tgz#7593fc7d86651f65c4e1f6a67802b7b72c532695"
|
||||
integrity sha512-K2jlMXX4cB8+/6CYh/QywULgUcMSJcR6CycEGnONeCskrejtArCUmiV8dKu20ABv3CeHWgTVN261BQWRTTelRg==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^0.1.6"
|
||||
"@discordjs/form-data" "^3.0.1"
|
||||
|
|
Loading…
Reference in a new issue