UNPKG

music-start-pro

Version:

Music Start Pro is a discord bot that can play YouTube music by slash command.

118 lines (106 loc) 4.33 kB
import { Options, EmbedBuilder } from 'discord.js'; import { Queue } from './queue'; import { CachedMusicInfo, MusicInfo } from './musicInfo'; import { EventEmitter } from 'node:events'; import ytdl from '@distube/ytdl-core'; export class Util { static randomHappy() { const emojis = ['(*´∀`)~♥', 'σ`∀´)σ', '(〃∀〃)', '(✪ω✪)', '(๑´ㅂ`๑)', '(◕ܫ◕)', '( • ̀ω•́ )', '(*゚∀゚*)', '(灬ºωº灬)']; return emojis[~~(Math.random() * emojis.length)]; } static randomCry() { const emojis = ['( ´•̥ו̥\`)', 'இдஇ', 'ヾ(;゚;Д;゚;)ノ゙', '(☍﹏⁰)', '( ´•̥̥̥ω•̥̥̥` )', '(;´༎ຶД༎ຶ`)', '(☍﹏⁰。)', '(´;ω;`)']; return emojis[~~(Math.random() * emojis.length)]; } // @param num: Integer static humanReadNum(num: number): string { try { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } catch (e) { throw (e); } } // @param `title` should not be empty string "" static createEmbedMessage(title: string, description: string, isErrorMessage?: boolean): Options { return { embeds: [new EmbedBuilder() .setTitle(title) .setColor((isErrorMessage === true) ? 0xf54242 : 0x33DFFF) .setDescription(description)] }; } static createMusicInfoMessage(info: MusicInfo): Options { let description = `From youtube: ${info.url}\n\n`; if (info.viewCount != -1) { description += `:eyes: ${Util.humanReadNum(info.viewCount)}`; } if (info.likes != -1) { if (info.likes != -1) { description += ' '; } description += `:heart: ${Util.humanReadNum(info.likes)}`; } description += ` :ear: ${Util.humanReadNum(info.playCounter)}`; return Util.createEmbedMessage(info?.title, description); } static sequentialEnqueueWithBatchListener(): EventEmitter { return new EventEmitter(); } static enQueueCached(list: CachedMusicInfo[], queue: Queue) { if (!Array.isArray(list) || list.length == 0) { return; } list.forEach((v) => { queue.add(MusicInfo.fromCache(v)); }); } static sequentialEnQueueWithBatch(list: string[], queue: Queue, listener?: EventEmitter, batch?: number) { if (!Array.isArray(list) || list.length == 0) { listener?.emit('error', 'The input array should not be empty.'); return; } const b = batch ?? 20; let done = 0; let success = 0; const total = list.length; const numBatches = Math.ceil(list.length / b); const batchList = Array.from(Array(numBatches).keys()); listener?.emit('progress', 0, total); batchList.reduce(async (p, j) => { await p.then(async () => { const task: Promise<ytdl.videoInfo>[] = []; for (let i = j * b; i < Math.min(b * (j + 1), total); i++) { done++; task.push(ytdl.getInfo(list[i])); } await Promise.allSettled(task).then(data => { data.filter(res => res.status === 'fulfilled').map(res => { const info = MusicInfo.fromDetails(res.value); if(info) { success++; queue.add(info); } }); listener?.emit('progress', done, total); }).catch(e => listener?.emit('error', e)); }); }, Promise.resolve()).then(() => { listener?.emit('done', total, total-success); }); } static progressBar(current: number, all: number, bar: number): string { let content = '['; const percent = all == 0 ? 0 : Math.min(1, current / all); for (let i = 0; i < Math.ceil(percent * bar); i++) { content += '='; } for (let i = 0; i < bar - Math.ceil(percent * bar); i++) { content += '.'; } content += (all == 0) ? ']' : `] ${current} / ${all}`; return content; } }