mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-14 12:30:06 +02:00
Add visualizer configuration (#1443)
* add visualizer configuration * add visualizer presets * add butterchurn visualizer * wrap visualizers in error boundary
This commit is contained in:
@@ -8,7 +8,7 @@ import styles from './full-screen-player-queue.module.css';
|
||||
import { Lyrics } from '/@/renderer/features/lyrics/lyrics';
|
||||
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
||||
import { FullScreenSimilarSongs } from '/@/renderer/features/player/components/full-screen-similar-songs';
|
||||
import { usePlaybackSettings } from '/@/renderer/store';
|
||||
import { usePlaybackSettings, useSettingsStore } from '/@/renderer/store';
|
||||
import {
|
||||
useFullScreenPlayerStore,
|
||||
useFullScreenPlayerStoreActions,
|
||||
@@ -17,8 +17,14 @@ import { Button } from '/@/shared/components/button/button';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { ItemListKey, PlayerType } from '/@/shared/types/types';
|
||||
|
||||
const Visualizer = lazy(() =>
|
||||
import('/@/renderer/features/player/components/visualizer').then((module) => ({
|
||||
const AudioMotionAnalyzerVisualizer = lazy(() =>
|
||||
import('../../visualizer/components/audiomotionanalyzer/visualizer').then((module) => ({
|
||||
default: module.Visualizer,
|
||||
})),
|
||||
);
|
||||
|
||||
const ButterchurnVisualizer = lazy(() =>
|
||||
import('../../visualizer/components/butternchurn/visualizer').then((module) => ({
|
||||
default: module.Visualizer,
|
||||
})),
|
||||
);
|
||||
@@ -28,6 +34,7 @@ export const FullScreenPlayerQueue = () => {
|
||||
const { activeTab, opacity } = useFullScreenPlayerStore();
|
||||
const { setStore } = useFullScreenPlayerStoreActions();
|
||||
const { type, webAudio } = usePlaybackSettings();
|
||||
const visualizerType = useSettingsStore((store) => store.visualizer.type);
|
||||
|
||||
const headerItems = useMemo(() => {
|
||||
const items = [
|
||||
@@ -109,7 +116,11 @@ export const FullScreenPlayerQueue = () => {
|
||||
<Lyrics />
|
||||
) : activeTab === 'visualizer' && type === PlayerType.WEB && webAudio ? (
|
||||
<Suspense fallback={<></>}>
|
||||
<Visualizer />
|
||||
{visualizerType === 'butterchurn' ? (
|
||||
<ButterchurnVisualizer />
|
||||
) : (
|
||||
<AudioMotionAnalyzerVisualizer />
|
||||
)}
|
||||
</Suspense>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
.container {
|
||||
z-index: 50;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
|
||||
canvas {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import AudioMotionAnalyzer from 'audiomotion-analyzer';
|
||||
import { createRef, useEffect, useState } from 'react';
|
||||
|
||||
import styles from './visualizer.module.css';
|
||||
|
||||
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
||||
import { useSettingsStore } from '/@/renderer/store';
|
||||
|
||||
export const Visualizer = () => {
|
||||
const { webAudio } = useWebAudio();
|
||||
const canvasRef = createRef<HTMLDivElement>();
|
||||
const accent = useSettingsStore((store) => store.general.accent);
|
||||
const [motion, setMotion] = useState<AudioMotionAnalyzer>();
|
||||
|
||||
useEffect(() => {
|
||||
const { context, gains } = webAudio || {};
|
||||
if (gains && context && canvasRef.current && !motion) {
|
||||
const audioMotion = new AudioMotionAnalyzer(canvasRef.current, {
|
||||
ansiBands: true,
|
||||
audioCtx: context,
|
||||
connectSpeakers: false,
|
||||
gradient: 'prism',
|
||||
ledBars: true,
|
||||
mode: 8,
|
||||
overlay: true,
|
||||
showBgColor: false,
|
||||
showPeaks: false,
|
||||
showScaleX: false,
|
||||
showScaleY: false,
|
||||
smoothing: 0.8,
|
||||
});
|
||||
setMotion(audioMotion);
|
||||
for (const gain of gains) audioMotion.connectInput(gain);
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}, [accent, canvasRef, motion, webAudio]);
|
||||
|
||||
return <div className={styles.container} ref={canvasRef} />;
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import { openContextModal } from '@mantine/modals';
|
||||
|
||||
export const openVisualizerSettingsModal = () => {
|
||||
openContextModal({
|
||||
innerProps: {},
|
||||
modalKey: 'visualizerSettings',
|
||||
overlayProps: {
|
||||
blur: 0,
|
||||
opacity: 1,
|
||||
},
|
||||
size: 'xl',
|
||||
styles: {
|
||||
content: {
|
||||
height: '90%',
|
||||
maxWidth: '1400px',
|
||||
minHeight: '600px',
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
title: 'Visualizer Settings',
|
||||
transitionProps: {
|
||||
transition: 'pop',
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user