mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
add web visualizer (#314)
* add web visualizer * fallback to simple model * less samples, hopefully more efficient * Use audiomotion analyzer - Note: fixed to 4.1.1 because 4.2.0 uses esm which breaks in the current workflow... * revert publish changes * r2 * don't massively change package.json * lazy
This commit is contained in:
parent
fbac33ceba
commit
74aa88e082
9 changed files with 172 additions and 33 deletions
72
src/renderer/features/player/components/visualizer.tsx
Normal file
72
src/renderer/features/player/components/visualizer.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { createRef, useCallback, useEffect, useState } from 'react';
|
||||
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
||||
import AudioMotionAnalyzer from 'audiomotion-analyzer';
|
||||
import styled from 'styled-components';
|
||||
import { useSettingsStore } from '/@/renderer/store';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
margin: auto;
|
||||
max-width: 100%;
|
||||
|
||||
canvas {
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const Visualizer = () => {
|
||||
const { webAudio } = useWebAudio();
|
||||
const canvasRef = createRef<HTMLDivElement>();
|
||||
const accent = useSettingsStore((store) => store.general.accent);
|
||||
const [motion, setMotion] = useState<AudioMotionAnalyzer>();
|
||||
|
||||
const [length, setLength] = useState(500);
|
||||
|
||||
useEffect(() => {
|
||||
const { context, gain } = webAudio || {};
|
||||
if (gain && context && canvasRef.current && !motion) {
|
||||
const audioMotion = new AudioMotionAnalyzer(canvasRef.current, {
|
||||
ansiBands: true,
|
||||
audioCtx: context,
|
||||
connectSpeakers: false,
|
||||
gradient: 'prism',
|
||||
mode: 4,
|
||||
showPeaks: false,
|
||||
smoothing: 0.8,
|
||||
});
|
||||
setMotion(audioMotion);
|
||||
audioMotion.connectInput(gain);
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}, [accent, canvasRef, motion, webAudio]);
|
||||
|
||||
const resize = useCallback(() => {
|
||||
const body = document.querySelector('.full-screen-player-queue-container');
|
||||
const header = document.querySelector('.full-screen-player-queue-header');
|
||||
|
||||
if (body && header) {
|
||||
const width = body.clientWidth - 30;
|
||||
const height = body.clientHeight - header.clientHeight - 30;
|
||||
|
||||
setLength(Math.min(width, height));
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
resize();
|
||||
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', resize);
|
||||
};
|
||||
}, [resize]);
|
||||
|
||||
return (
|
||||
<StyledContainer
|
||||
ref={canvasRef}
|
||||
style={{ height: length, width: length }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue