UNPKG

@terron/djs-music

Version:

New simple voice player with yt-dlp supporting, filters & events for discord.js v14.

180 lines (155 loc) 6.13 kB
module.exports.Filters = class Filters { /** * Generates a nightcore filter for audio processing. * @param {Object} options - Options for the nightcore filter. * @param {number} [options.strength=1.25] - Strength multiplier for the nightcore effect. * @returns {{ name: string, ffmpeg: string, strength: number }} - Nightcore filter object. */ static nightcore({ strength = 1.25 } = {}) { strength = Math.max(1, strength); const rate = 48000 * strength; const tempo = strength; return { name: 'nightcore', ffmpeg: `asetrate=${rate},aresample=48000,atempo=${tempo}`, strength }; } /** * Generates an audio crusher effect filter. * @param {Object} options - Options for the crusher filter. * @param {number} [options.levelIn=8] - Input level of the crusher effect. * @param {number} [options.levelOut=18] - Output level of the crusher effect. * @param {number} [options.bits=8] - Bit depth for the crusher effect. * @param {number} [options.aa=1] - Anti-aliasing parameter for the crusher effect (1 for enabled, 0 for disabled). * @returns {{ name: string, ffmpeg: string, levelIn: number, levelOut: number, bits: number, aa: number }} - Crusher filter object. */ static crusher({ levelIn = 8, levelOut = 18, bits = 8, aa = 1 } = {}) { levelIn = Math.max(0, levelIn); levelOut = Math.max(0, levelOut); bits = Math.max(1, bits); const ffmpegFilter = `acrusher=level_in=${levelIn}:level_out=${levelOut}:bits=${bits}:aa=${aa}`; return { name: 'crusher', ffmpeg: ffmpegFilter, levelIn, levelOut, bits, aa, }; } /** * Generates a bassboost filter for audio processing. * @param {Object} options - Options for the bassboost filter. * @param {number} [options.strength=10] - Strength of the bass boost effect. * @returns {{ name: string, ffmpeg: string, strength: number }} - Bassboost filter object. */ static bassboost({ strength = 10 } = {}) { strength = Math.max(0, strength); return { name: 'bassboost', ffmpeg: `bass=g=${strength},dynaudnorm=f=150:g=15`, strength }; } /** * Generates a reverb filter for audio processing. * @param {Object} options - Options for the reverb filter. * @param {number} [options.strength=50] - Strength of the reverb effect. * @returns {{ name: string, ffmpeg: string, strength: number }} - Reverb filter object. */ static reverb({ strength = 50 } = {}) { strength = Math.max(0, Math.min(100, strength)); return { name: 'reverb', ffmpeg: `aecho=0.8:0.9:${60 + strength}:${0.4}`, strength }; } /** * Generates a speed filter for audio processing. * @param {Object} options - Options for the speed filter. * @param {number} [options.strength=1] - Speed multiplier for the audio. * @returns {{ name: string, ffmpeg: string, strength: number }} - Speed filter object. */ static speed({ strength = 1 } = {}) { strength = Math.max(0, strength); return { name: 'speed', ffmpeg: `atempo=${strength}`, strength }; } /** * Registers a custom audio filter to the Filters class with configurable arguments. * @param {string} name - The name of the custom filter. * @param {string} ffmpegTemplate - The FFmpeg string template with placeholders for arguments (e.g., `{argName}`). * @param {Object} defaults - Default values for arguments. */ static registerAudioFilter(name, ffmpegTemplate, defaults = {}) { if (!name || typeof name !== 'string') { throw new Error('Filter name must be a valid string.'); } if (!ffmpegTemplate || typeof ffmpegTemplate !== 'string') { throw new Error('FFmpeg template must be a valid string.'); } this[name] = function (args = {}) { const config = { ...defaults, ...args }; const ffmpegString = Object.keys(config).reduce((acc, key) => { return acc.replace(new RegExp(`\\{${key}\\}`, 'g'), config[key]); }, ffmpegTemplate); return { name, ffmpeg: ffmpegString, ...config }; }; console.log(`Filter '${name}' successfully registered.`); } } module.exports.LoopStatuses = class LoopStatuses { /** * Represents the state when no looping is applied. * @static * @type {number} */ static get Nothing() { return 0; } /** * Represents the state when the current track is being looped. * @static * @type {number} */ static get Track() { return 1; } /** * Represents the state when the entire queue is being looped. * @static * @type {number} */ static get Queue() { return 2; } } module.exports.PlayerEvents = class PlayerEvents { /** * Event triggered when the bot joins a voice channel. * @type {string} */ static get VoiceJoin() { return 'voiceJoin' } /** * Event triggered when the bot leaves a voice channel. * @type {string} */ static get VoiceLeft() { return 'voiceLeft' } /** * Event triggered when there is an update in the voice channel (e.g., change in state). * @type {string} */ static get VoiceUpdate() { return 'voiceUpdate' } /** * Event triggered when a track is added to the playback queue. * @type {string} */ static get TrackAdd() { return 'trackAdd' } /** * Event triggered when a track starts playing. * @type {string} */ static get TrackStart() { return 'trackStart' } /** * Event triggered when the playback queue ends. * @type {string} */ static get QueueEnd() { return 'queueEnd' } /** * Event triggered when the loop status for the queue or track is updated. * @type {string} */ static get UpdateLoopStatus() { return 'updateLoopStatus' } /** * Event triggered when playback moves backward by a certain duration. * @type {string} */ static get Backward() { return 'trackBackward' } }