From 7649cb7346d16b0a06126af11dc303dba9a28a56 Mon Sep 17 00:00:00 2001 From: ad044 Date: Sat, 24 Oct 2020 22:15:28 +0400 Subject: [PATCH] audio visualizer works properly, needs optimization --- .../AudioVisualizer/AudioVisualizer.tsx | 35 ++++-- .../AudioVisualizer/AudioVisualizerColumn.tsx | 112 ++++++++++++++++++ src/components/MediaScene/MediaPlayer.tsx | 5 +- src/react-app-env.d.ts | 9 +- src/store.ts | 13 +- 5 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 src/components/MediaScene/AudioVisualizer/AudioVisualizerColumn.tsx diff --git a/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx b/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx index 1787364..117397b 100644 --- a/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx +++ b/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx @@ -1,9 +1,12 @@ import React, { useMemo, useRef, useState } from "react"; import * as THREE from "three"; import { useFrame } from "react-three-fiber"; +import AudioVisualizerColumn from "./AudioVisualizerColumn"; +import { useAudioVisualizerStore } from "../../../store"; const AudioVisualizer = () => { - const analysedData = useMemo(() => { + const setFrequency = useAudioVisualizerStore((state) => state.setFrequency); + const analyser = useMemo(() => { const listener = new THREE.AudioListener(); const audio = new THREE.Audio(listener); @@ -11,19 +14,31 @@ const AudioVisualizer = () => { document.getElementById("media") as HTMLMediaElement ); - const analyser = new THREE.AudioAnalyser(audio, 32); - - return analyser.getFrequencyData()[0]; + return new THREE.AudioAnalyser(audio, 2048); }, []); - const t = useRef(); - useFrame(() => {}); + useFrame(() => { + if (!(document.getElementById("media") as HTMLMediaElement).paused) + setFrequency(analyser.getFrequencyData()); + }); + return ( <> - - - - + + + + + + + + + + + + + + + ); }; diff --git a/src/components/MediaScene/AudioVisualizer/AudioVisualizerColumn.tsx b/src/components/MediaScene/AudioVisualizer/AudioVisualizerColumn.tsx new file mode 100644 index 0000000..53915d9 --- /dev/null +++ b/src/components/MediaScene/AudioVisualizer/AudioVisualizerColumn.tsx @@ -0,0 +1,112 @@ +import React, { useEffect, useMemo, useRef, useState } from "react"; +import audioVisualizerOrangeOrb from "../../../static/sprite/audio_visual_orb_orange.png"; +import audioVisualizerYellowOrb from "../../../static/sprite/audio_visual_orb_yellow.png"; +import { useLoader } from "react-three-fiber"; +import * as THREE from "three"; +import { useAudioVisualizerStore, useBlueOrbStore } from "../../../store"; +import { useSpring, a } from "@react-spring/three"; +import level_y_values from "../../../resources/level_y_values.json"; + +type AudioVisualizerColumnProps = { + position: number[]; + idx: number; +}; + +const AudioVisualizerColumn = (props: AudioVisualizerColumnProps) => { + const orangeAudioVisualizerOrb = useLoader( + THREE.TextureLoader, + audioVisualizerOrangeOrb + ); + const yellowAudioVisualizerOrb = useLoader( + THREE.TextureLoader, + audioVisualizerYellowOrb + ); + + const [ + { fstOrbVisible, sndOrbVisible, thirdOrbVisible, fourthOrbVisible }, + set, + ] = useSpring(() => ({ + fstOrbVisible: false, + sndOrbVisible: false, + thirdOrbVisible: false, + fourthOrbVisible: false, + config: { duration: 800 }, + })); + + useEffect(() => { + useAudioVisualizerStore.subscribe(set, (state) => ({ + fstOrbVisible: state.frequency[props.idx * 32] >= 64, + sndOrbVisible: state.frequency[props.idx * 32] >= 128, + thirdOrbVisible: state.frequency[props.idx * 32] >= 192, + fourthOrbVisible: state.frequency[props.idx * 32] >= 255, + })); + }, [props.position, set]); + + return ( + + + + + + + + + + + + + + + + + + + + ); +}; + +export default AudioVisualizerColumn; diff --git a/src/components/MediaScene/MediaPlayer.tsx b/src/components/MediaScene/MediaPlayer.tsx index c9362f2..0c02abb 100644 --- a/src/components/MediaScene/MediaPlayer.tsx +++ b/src/components/MediaScene/MediaPlayer.tsx @@ -1,6 +1,5 @@ -import React, { useCallback, useRef, useState } from "react"; -import ReactPlayer from "react-player"; -import test from "../../static/movie/test.webm"; +import React, { useCallback, useRef } from "react"; +import test from "../../static/movie/LAIN01.XA[18].ogg"; import { useMediaStore } from "../../store"; const MediaPlayer = () => { diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 55adf9e..220aad7 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -4,8 +4,13 @@ declare module "*.webm" { export default src; } -declare module "threejs-slice-geometry" { - const src: any; +declare module "*.mp3" { + const src: string; + export default src; +} + +declare module "*.ogg" { + const src: string; export default src; } diff --git a/src/store.ts b/src/store.ts index 041f14a..ae5aaf5 100644 --- a/src/store.ts +++ b/src/store.ts @@ -124,6 +124,11 @@ type TextRendererState = { toggleGreenText: () => void; }; +type AudioVisualizerState = { + frequency: Uint8Array; + setFrequency: (to: Uint8Array) => void; +}; + export const useTextRendererStore = create((set) => ({ // yellow text yellowText: "Play", @@ -253,7 +258,8 @@ export const useMediaStore = create((set) => ({ set(() => ({ lastActiveLeftSideElement: to })), setLastActiveRightSideElement: (to) => set(() => ({ lastActiveRightSideElement: to })), - setMediaPercentageElapsed: (to) => set(() => ({ mediaPercentageElapsed: to })), + setMediaPercentageElapsed: (to) => + set(() => ({ mediaPercentageElapsed: to })), })); export const useMediaWordStore = create((set) => ({ @@ -324,3 +330,8 @@ export const useMediaWordStore = create((set) => ({ : state.wordPositionDataStructIdx + val, })), })); + +export const useAudioVisualizerStore = create((set) => ({ + frequency: new Uint8Array(), + setFrequency: (to) => set(() => ({ frequency: to })), +}));