mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-10 10:11:46 +00:00
feat: Add equalizer plugin with presets (e.g. bass booster) (#2575)
This commit is contained in:
@ -95,6 +95,8 @@ Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸]
|
|||||||
- **Downloader**: downloads
|
- **Downloader**: downloads
|
||||||
MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
|
MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
|
||||||
|
|
||||||
|
- **Equalizer**: add filters to boost or cut specific range of frequencies (e.g. bass booster)
|
||||||
|
|
||||||
- **Exponential Volume**: Makes the volume
|
- **Exponential Volume**: Makes the volume
|
||||||
slider [exponential](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) so it's easier to
|
slider [exponential](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) so it's easier to
|
||||||
select lower volumes
|
select lower volumes
|
||||||
|
|||||||
@ -808,6 +808,18 @@
|
|||||||
"visualizer-type": "Visualizer Type"
|
"visualizer-type": "Visualizer Type"
|
||||||
},
|
},
|
||||||
"name": "Visualizer"
|
"name": "Visualizer"
|
||||||
|
},
|
||||||
|
"equalizer": {
|
||||||
|
"description": "Adds an equalizer to the player",
|
||||||
|
"name": "Equalizer",
|
||||||
|
"menu": {
|
||||||
|
"presets": {
|
||||||
|
"label": "Presets",
|
||||||
|
"list": {
|
||||||
|
"bass-booster": "Bass booster"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/plugins/equalizer/index.ts
Normal file
80
src/plugins/equalizer/index.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { createPlugin } from '@/utils';
|
||||||
|
import { t } from '@/i18n';
|
||||||
|
import { MenuContext } from '@/types/contexts';
|
||||||
|
import { MenuTemplate } from '@/menu';
|
||||||
|
import { defaultPresets, presetConfigs, Preset, FilterConfig } from './presets';
|
||||||
|
|
||||||
|
export type EqualizerPluginConfig = {
|
||||||
|
enabled: boolean;
|
||||||
|
filters: FilterConfig[];
|
||||||
|
presets: { [preset in Preset]: boolean };
|
||||||
|
};
|
||||||
|
|
||||||
|
let appliedFilters: BiquadFilterNode[] = [];
|
||||||
|
|
||||||
|
export default createPlugin({
|
||||||
|
name: () => t('plugins.equalizer.name'),
|
||||||
|
description: () => t('plugins.equalizer.description'),
|
||||||
|
restartNeeded: false,
|
||||||
|
config: {
|
||||||
|
enabled: false,
|
||||||
|
filters: [],
|
||||||
|
presets: { 'bass-booster': false },
|
||||||
|
} as EqualizerPluginConfig,
|
||||||
|
menu: async ({
|
||||||
|
getConfig,
|
||||||
|
setConfig,
|
||||||
|
}: MenuContext<EqualizerPluginConfig>): Promise<MenuTemplate> => {
|
||||||
|
const config = await getConfig();
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('plugins.equalizer.menu.presets.label'),
|
||||||
|
type: 'submenu',
|
||||||
|
submenu: defaultPresets.map((preset) => ({
|
||||||
|
label: t(`plugins.equalizer.menu.presets.list.${preset}`),
|
||||||
|
type: 'radio',
|
||||||
|
checked: config.presets[preset],
|
||||||
|
click() {
|
||||||
|
setConfig({
|
||||||
|
presets: { ...config.presets, [preset]: !config.presets[preset] },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
renderer: {
|
||||||
|
async start({ getConfig }) {
|
||||||
|
const config = await getConfig();
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
'ytmd:audio-can-play',
|
||||||
|
({ detail: { audioSource, audioContext } }) => {
|
||||||
|
const filtersToApply = config.filters.concat(
|
||||||
|
defaultPresets
|
||||||
|
.filter((preset) => config.presets[preset])
|
||||||
|
.map((preset) => presetConfigs[preset]),
|
||||||
|
);
|
||||||
|
filtersToApply.forEach((filter) => {
|
||||||
|
const biquadFilter = audioContext.createBiquadFilter();
|
||||||
|
biquadFilter.type = filter.type;
|
||||||
|
biquadFilter.frequency.value = filter.frequency; // filter frequency in Hz
|
||||||
|
biquadFilter.Q.value = filter.Q;
|
||||||
|
biquadFilter.gain.value = filter.gain; // filter gain in dB
|
||||||
|
|
||||||
|
audioSource.connect(biquadFilter);
|
||||||
|
biquadFilter.connect(audioContext.destination);
|
||||||
|
|
||||||
|
appliedFilters.push(biquadFilter);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ once: true, passive: true },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
stop() {
|
||||||
|
appliedFilters.forEach((filter) => filter.disconnect());
|
||||||
|
appliedFilters = [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
18
src/plugins/equalizer/presets.ts
Normal file
18
src/plugins/equalizer/presets.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export const defaultPresets = ['bass-booster'] as const;
|
||||||
|
export type Preset = (typeof defaultPresets)[number];
|
||||||
|
|
||||||
|
export type FilterConfig = {
|
||||||
|
type: BiquadFilterType;
|
||||||
|
frequency: number;
|
||||||
|
Q: number;
|
||||||
|
gain: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const presetConfigs: Record<Preset, FilterConfig> = {
|
||||||
|
'bass-booster': {
|
||||||
|
type: 'lowshelf',
|
||||||
|
frequency: 80,
|
||||||
|
Q: 100,
|
||||||
|
gain: 12.0,
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user