@@ -17,6 +17,7 @@ import UploadPage from './Pages/UploadPage';
|
||||
import PreviewPage from './Pages/PreviewPage';
|
||||
import ProcessingPage from './Pages/ProcessingPage';
|
||||
import ResultsPage from './Pages/ResultsPage';
|
||||
import AudioVisualizer from './components/AudioVisualizer';
|
||||
|
||||
// Custom Link component for AppBar
|
||||
const App: React.FC = () => {
|
||||
@@ -39,6 +40,7 @@ const App: React.FC = () => {
|
||||
<Route path="/processing" element={<ProcessingPage />} />
|
||||
<Route path="/results" element={<ResultsPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
<Route path='/audio' element={<AudioVisualizer/>}/>
|
||||
</Routes>
|
||||
</Router>
|
||||
</MediaProvider>
|
||||
|
||||
@@ -108,6 +108,7 @@ function UploadPage() {
|
||||
onChange={handleFileChange}
|
||||
accept="audio/*,video/*"
|
||||
/>
|
||||
|
||||
<CloudUploadIcon color="primary" sx={{ fontSize: 64, mb: 2 }} />
|
||||
<Typography variant="h6" gutterBottom>
|
||||
{file ? file.name : 'Drop your file here or click to browse'}
|
||||
@@ -135,6 +136,7 @@ function UploadPage() {
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
import audioFile from "../assets/female-female-mixture.wav";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
const AudioVisualizer: React.FC = () => {
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const audioContextRef = useRef<AudioContext | null>(null);
|
||||
const sourceRef = useRef<MediaElementAudioSourceNode | null>(null);
|
||||
const analyserRef = useRef<AnalyserNode | null>(null);
|
||||
const [isPlaying, setIsPlaying] = useState<boolean>(false);
|
||||
const [audioSrc, setAudioSrc] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
setAudioSrc(audioFile);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!audioRef.current || !canvasRef.current) return;
|
||||
|
||||
if (!audioContextRef.current) {
|
||||
audioContextRef.current = new (window.AudioContext || window.AudioContext)();
|
||||
}
|
||||
const audioContext = audioContextRef.current;
|
||||
|
||||
if (!analyserRef.current) {
|
||||
analyserRef.current = audioContext.createAnalyser();
|
||||
analyserRef.current.fftSize = 256;
|
||||
}
|
||||
const analyser = analyserRef.current;
|
||||
|
||||
if (!sourceRef.current) {
|
||||
sourceRef.current = audioContext.createMediaElementSource(audioRef.current);
|
||||
sourceRef.current.connect(analyser);
|
||||
analyser.connect(audioContext.destination);
|
||||
}
|
||||
|
||||
const bufferLength = analyser.frequencyBinCount;
|
||||
const dataArray = new Uint8Array(bufferLength);
|
||||
const canvas = canvasRef.current;
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) return;
|
||||
|
||||
const draw = () => {
|
||||
if (!isPlaying) return;
|
||||
|
||||
analyser.getByteFrequencyData(dataArray);
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const barWidth = canvas.width / bufferLength; // Fit bars within canvas width
|
||||
const maxBarHeight = canvas.height * 0.9; // Scale bars relative to canvas height
|
||||
|
||||
let x = 0;
|
||||
for (let i = 0; i < bufferLength; i++) {
|
||||
const barHeight = (dataArray[i] / 255) * maxBarHeight; // Normalize height
|
||||
|
||||
ctx.fillStyle = `rgb(${barHeight + 100}, 50, 100)`;
|
||||
ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
|
||||
x += barWidth + 2; // Add spacing between bars
|
||||
}
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
};
|
||||
|
||||
if (isPlaying) {
|
||||
audioContext.resume();
|
||||
draw();
|
||||
}
|
||||
}, [isPlaying]);
|
||||
|
||||
const togglePlay = () => {
|
||||
const audio = audioRef.current;
|
||||
if (!audio) return;
|
||||
|
||||
if (audio.paused) {
|
||||
audio.play();
|
||||
setIsPlaying(true);
|
||||
} else {
|
||||
audio.pause();
|
||||
setIsPlaying(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
{audioSrc && <audio ref={audioRef} src={audioSrc} />}
|
||||
<canvas ref={canvasRef} width={window.innerWidth * 0.7} height={150} style={{ background: "#111", borderRadius: "10px" }} />
|
||||
<br />
|
||||
<button onClick={togglePlay}>{isPlaying ? "Pause" : "Play"}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AudioVisualizer;
|
||||
Reference in New Issue
Block a user