diff --git a/package.json b/package.json index ea057e6..8622c77 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "discord-ytdl-core": "^5.0.2", - "youtube-sr": "^4.0.3" + "youtube-sr": "^4.0.3", + "ytdl-core": "^4.5.0" }, "devDependencies": { "@discordjs/opus": "^0.5.0", diff --git a/src/AudioFilters.ts b/src/AudioFilters.ts new file mode 100644 index 0000000..047fa4f --- /dev/null +++ b/src/AudioFilters.ts @@ -0,0 +1,47 @@ +export default { + bassboost: "bass=g=20", + "8D": "apulsator=hz=0.09", + vaporwave: "aresample=48000,asetrate=48000*0.8", + nightcore: "aresample=48000,asetrate=48000*1.25", + phaser: "aphaser=in_gain=0.4", + tremolo: "tremolo", + vibrato: "vibrato=f=6.5", + reverse: "areverse", + treble: "treble=g=5", + normalizer: "dynaudnorm=g=101", + surrounding: "surround", + pulsator: "apulsator=hz=1", + subboost: "asubboost", + karaoke: "stereotools=mlev=0.03", + flanger: "flanger", + gate: "agate", + haas: "haas", + mcompand: "mcompand", + mono: "pan=mono|c0=.5*c0+.5*c1", + mstlr: "stereotools=mode=ms>lr", + mstrr: "stereotools=mode=ms>rr", + compressor: "compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6", + expander: "compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3", + softlimiter: "compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8", + chorus: "chorus=0.7:0.9:55:0.4:0.25:2", + chorus2d: "chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3", + chorus3d: "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3", + fadein: "afade=t=in:ss=0:d=10", + + *[Symbol.iterator](): IterableIterator<{ name: string, value: string }> { + for (const [k, v] of Object.entries(this)) { + + // @ts-ignore + yield { name: k, value: v }; + } + }, + get names() { + return Object.keys(this); + }, + get length() { + return Object.keys(this).length; + }, + toString() { + return `"${Object.values(this).join(",")}"` + } +}; \ No newline at end of file diff --git a/src/Player.ts b/src/Player.ts new file mode 100644 index 0000000..e7f202a --- /dev/null +++ b/src/Player.ts @@ -0,0 +1,30 @@ +import { EventEmitter } from "events"; +import { Client } from "discord.js"; +import { PlayerOptions } from "./types/Player"; +import Util from "./Util"; + +export default class Player extends EventEmitter { + public client!: Client; + public options: PlayerOptions; + + constructor(client: Client, options?: PlayerOptions) { + super(); + + /** + * The discord client that instantiated this player + */ + Object.defineProperty(this, "client", { + value: client, + enumerable: false + }); + + /** + * The player options + */ + this.options = Object.assign({}, Util.DefaultPlayerOptions, options ?? {}); + + // check FFmpeg + void Util.alertFFmpeg(); + } + +} \ No newline at end of file diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts new file mode 100644 index 0000000..88020a9 --- /dev/null +++ b/src/Structures/Queue.ts @@ -0,0 +1,13 @@ +import Player from "../Player"; + +export default class Queue { + public player!: Player; + + constructor(player: Player) { + + /** + * The player that instantiated this Queue + */ + Object.defineProperty(this, "player", { value: player, enumerable: false }); + } +} \ No newline at end of file diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 515cb98..287e3c1 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1 +1,38 @@ -export default class Track {} \ No newline at end of file +import Player from "../Player"; +import { User } from "discord.js"; + +export default class Track { + public player!: Player; + public title!: string; + public description!: string; + public author!: string; + public url!: string; + public thumbnail!: string; + public duration!: string; + public views!: number; + public requestedBy!: User; + public fromPlaylist!: boolean; + + constructor(player: Player, data: any) { + + /** + * The player that instantiated this Track + */ + Object.defineProperty(this, "player", { value: player, enumerable: false }); + + void this._patch(data); + } + + private _patch(data: any) { + this.title = data.title ?? ""; + this.description = data.description ?? ""; + this.author = data.author ?? ""; + this.url = data.url ?? ""; + this.thumbnail = typeof data.thumbnail === "object" ? data.thumbnail.url : data.thumbnail; + this.duration = data.duration ?? ""; + this.views = data.views ?? 0; + this.requestedBy = data.requestedBy; + this.fromPlaylist = Boolean(data.fromPlaylist); + } + +} \ No newline at end of file diff --git a/src/Util.ts b/src/Util.ts new file mode 100644 index 0000000..4c118e6 --- /dev/null +++ b/src/Util.ts @@ -0,0 +1,38 @@ +import { PlayerOptions } from "./types/Player"; +import { FFmpeg } from "prism-media"; + +export default class Util { + + constructor() { + throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); + } + + static get DefaultPlayerOptions() { + return { + leaveOnEnd: true, + leaveOnStop: true, + leaveOnEmpty: true, + leaveOnEmptyCooldown: 0, + autoSelfDeaf: true, + enableLive: false, + ytdlDownloadOptions: {} + } as PlayerOptions; + } + + static checkFFmpeg(force?: boolean) { + try { + FFmpeg.getInfo(Boolean(force)); + + return true; + } catch { + return false; + } + } + + static alertFFmpeg() { + const hasFFmpeg = Util.checkFFmpeg(); + + if (!hasFFmpeg) console.warn("[Discord Player] FFmpeg/Avconv not found! Install via \"npm install ffmpeg-static\" or download from https://ffmpeg.org/download.html"); + } + +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4cde362..a323cbc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ -import { version } from "../package.json" - -export { - version -} \ No newline at end of file +export * as AudioFilters from "./AudioFilters"; +export * as Player from "./Player"; +export * as Util from "./Util"; +export * as Track from "./Structures/Track"; +export * as Queue from "./Structures/Queue"; +export * from "./types/Player"; +export { version } from "../package.json"; \ No newline at end of file diff --git a/src/types/Player.ts b/src/types/Player.ts new file mode 100644 index 0000000..cb91fba --- /dev/null +++ b/src/types/Player.ts @@ -0,0 +1,12 @@ +import { downloadOptions } from "ytdl-core"; + +export interface PlayerOptions { + leaveOnEnd?: boolean; + leaveOnEndCooldown?: number; + leaveOnStop?: boolean; + leaveOnEmpty?: boolean; + leaveOnEmptyCooldown?: number; + autoSelfDeaf?: boolean; + enableLive?: boolean; + ytdlDownloadOptions?: downloadOptions; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b293134..a224a27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -281,6 +281,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +m3u8stream@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.3.tgz#c4624e92b4240eb356d040c4a5e155586cf58108" + integrity sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng== + dependencies: + miniget "^4.0.0" + sax "^1.2.4" + make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -300,6 +308,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.47.0" +miniget@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.0.tgz#0004e95536b192d95a7d09f4435d67b9285481d0" + integrity sha512-IzTOaNgBw/qEpzkPTE7X2cUVXQfSKbG8w52Emi93zb+Zya2ZFrbmavpixzebuDJD9Ku4ecbaFlC7Y1cEESzQtQ== + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -416,6 +429,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +sax@^1.1.3, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -535,3 +553,12 @@ youtube-sr@^4.0.3: dependencies: node-fetch "^2.6.1" simple-youtube-api "^5.2.1" + +ytdl-core@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/ytdl-core/-/ytdl-core-4.5.0.tgz#f07733387c548e5c3a5614c93ef55bde666eeaf4" + integrity sha512-e8r6skrakWNixsVlNPBMoRM1HrdW1swE97If9nenDUjF65uogYk4DvxIuqlmqRfBWKe+6aIZwqedNxUU9XLYJA== + dependencies: + m3u8stream "^0.8.3" + miniget "^4.0.0" + sax "^1.1.3"