server change
This commit is contained in:
@@ -17,6 +17,7 @@ import UploadPage from './Pages/UploadPage';
|
|||||||
import PreviewPage from './Pages/PreviewPage';
|
import PreviewPage from './Pages/PreviewPage';
|
||||||
import ProcessingPage from './Pages/ProcessingPage';
|
import ProcessingPage from './Pages/ProcessingPage';
|
||||||
import ResultsPage from './Pages/ResultsPage';
|
import ResultsPage from './Pages/ResultsPage';
|
||||||
|
import AudioVisualizer from './components/AudioVisualizer';
|
||||||
|
|
||||||
// Custom Link component for AppBar
|
// Custom Link component for AppBar
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
@@ -39,6 +40,7 @@ const App: React.FC = () => {
|
|||||||
<Route path="/processing" element={<ProcessingPage />} />
|
<Route path="/processing" element={<ProcessingPage />} />
|
||||||
<Route path="/results" element={<ResultsPage />} />
|
<Route path="/results" element={<ResultsPage />} />
|
||||||
<Route path="*" element={<Navigate to="/" replace />} />
|
<Route path="*" element={<Navigate to="/" replace />} />
|
||||||
|
<Route path='/audio' element={<AudioVisualizer/>}/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
</MediaProvider>
|
</MediaProvider>
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ function UploadPage() {
|
|||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
accept="audio/*,video/*"
|
accept="audio/*,video/*"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CloudUploadIcon color="primary" sx={{ fontSize: 64, mb: 2 }} />
|
<CloudUploadIcon color="primary" sx={{ fontSize: 64, mb: 2 }} />
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
{file ? file.name : 'Drop your file here or click to browse'}
|
{file ? file.name : 'Drop your file here or click to browse'}
|
||||||
@@ -135,6 +136,7 @@ function UploadPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
</Container>
|
</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