@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
JavaScript
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' }
}