Files
youtube-music/plugins/visualizer/front.ts
JellyBrick 53f5bda382 feat: migration to TypeScript FINAL
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-09-04 02:27:53 +09:00

73 lines
2.2 KiB
TypeScript

import { Visualizer } from './visualizers/visualizer';
import vudio from './visualizers/vudio';
import wave from './visualizers/wave';
import type { ConfigType } from '../../config/dynamic';
import defaultConfig from '../../config/defaults';
export default (options: ConfigType<'visualizer'>) => {
const optionsWithDefaults = {
...defaultConfig.plugins.visualizer,
...options,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let visualizerType: { new(...args: any[]): Visualizer<unknown> } = vudio;
if (optionsWithDefaults.type === 'wave') visualizerType = wave;
document.addEventListener(
'audioCanPlay',
(e) => {
const video = document.querySelector('video') as (HTMLVideoElement & { captureStream(): MediaStream; });
const visualizerContainer = document.querySelector('#player') as HTMLElement;
let canvas = document.querySelector('#visualizer') as HTMLCanvasElement;
if (!canvas) {
canvas = document.createElement('canvas');
canvas.id = 'visualizer';
canvas.style.position = 'absolute';
canvas.style.background = 'black';
visualizerContainer.append(canvas);
}
const resizeCanvas = () => {
canvas.width = visualizerContainer.clientWidth;
canvas.height = visualizerContainer.clientHeight;
};
resizeCanvas();
const gainNode = e.detail.audioContext.createGain();
gainNode.gain.value = 1.25;
e.detail.audioSource.connect(gainNode);
const visualizer = new visualizerType(
e.detail.audioContext,
e.detail.audioSource,
visualizerContainer,
canvas,
gainNode,
video.captureStream(),
optionsWithDefaults,
);
const resizeVisualizer = (width: number, height: number) => {
resizeCanvas();
visualizer.resize(width, height);
};
resizeVisualizer(canvas.width, canvas.height);
const visualizerContainerObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
resizeVisualizer(entry.contentRect.width, entry.contentRect.height);
}
});
visualizerContainerObserver.observe(visualizerContainer);
visualizer.render();
},
{ passive: true },
);
};