import React, { useRef, useEffect, useState } from 'react'; import './App.css'; function App() { const audioContextRef = useRef(null); const analyserRef = useRef(null); const gainNodeRef = useRef(null); const bassFilterRef = useRef(null); const trebleFilterRef = useRef(null); const sourceRef = useRef(null); const canvasRef = useRef(null); const animationFrameIdRef = useRef(null); const [isPlaying, setIsPlaying] = useState(false); const [volume, setVolume] = useState(0.7); const [bass, setBass] = useState(0); const [treble, setTreble] = useState(0); useEffect(() => { // Initialize AudioContext and nodes audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)(); analyserRef.current = audioContextRef.current.createAnalyser(); gainNodeRef.current = audioContextRef.current.createGain(); bassFilterRef.current = audioContextRef.current.createBiquadFilter(); trebleFilterRef.current = audioContextRef.current.createBiquadFilter(); // Configure filters bassFilterRef.current.type = 'lowshelf'; bassFilterRef.current.frequency.value = 250; // Bass frequency trebleFilterRef.current.type = 'highshelf'; trebleFilterRef.current.frequency.value = 4000; // Treble frequency // Connect nodes: Source -> Bass -> Treble -> Gain -> Analyser -> Destination // Source will be connected when audio starts playing bassFilterRef.current.connect(trebleFilterRef.current); trebleFilterRef.current.connect(gainNodeRef.current); gainNodeRef.current.connect(analyserRef.current); analyserRef.current.connect(audioContextRef.current.destination); // Set initial volume gainNodeRef.current.gain.value = volume; // Clean up on unmount return () => { if (animationFrameIdRef.current) { cancelAnimationFrame(animationFrameIdRef.current); } if (audioContextRef.current) { audioContextRef.current.close(); } }; }, []); useEffect(() => { if (gainNodeRef.current) { gainNodeRef.current.gain.value = volume; } }, [volume]); useEffect(() => { if (bassFilterRef.current) { bassFilterRef.current.gain.value = bass; // Gain in dB } }, [bass]); useEffect(() => { if (trebleFilterRef.current) { trebleFilterRef.current.gain.value = treble; // Gain in dB } }, [treble]); const loadAndPlayAudio = async () => { if (sourceRef.current) { sourceRef.current.stop(); sourceRef.current.disconnect(); } // For demonstration, we'll use a dummy audio source. // In a real app, you'd fetch an actual audio file. const response = await fetch('https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'); const arrayBuffer = await response.arrayBuffer(); const audioBuffer = await audioContextRef.current.decodeAudioData(arrayBuffer); sourceRef.current = audioContextRef.current.createBufferSource(); sourceRef.current.buffer = audioBuffer; sourceRef.current.loop = true; sourceRef.current.connect(bassFilterRef.current); sourceRef.current.start(0); setIsPlaying(true); drawVisualizer(); }; const togglePlayPause = () => { if (audioContextRef.current.state === 'suspended') { audioContextRef.current.resume(); } else if (audioContextRef.current.state === 'running' && isPlaying) { audioContextRef.current.suspend(); } else if (audioContextRef.current.state === 'suspended' && !isPlaying) { audioContextRef.current.resume(); } if (!isPlaying && !sourceRef.current) { loadAndPlayAudio(); } else { setIsPlaying(!isPlaying); } }; const drawVisualizer = () => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); const WIDTH = canvas.width; const HEIGHT = canvas.height; analyserRef.current.fftSize = 256; const bufferLength = analyserRef.current.frequencyBinCount; const dataArray = new Uint8Array(bufferLength); const renderFrame = () => { animationFrameIdRef.current = requestAnimationFrame(renderFrame); analyserRef.current.getByteFrequencyData(dataArray); ctx.clearRect(0, 0, WIDTH, HEIGHT); ctx.fillStyle = 'rgb(0, 0, 0)'; ctx.fillRect(0, 0, WIDTH, HEIGHT); const barWidth = (WIDTH / bufferLength) * 2.5; let x = 0; for (let i = 0; i < bufferLength; i++) { const barHeight = dataArray[i] / 2; ctx.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)'; ctx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight); x += barWidth + 1; } }; renderFrame(); }; // Placeholder for Telegram Mini App SDK initialization useEffect(() => { if (window.Telegram && window.Telegram.WebApp) { window.Telegram.WebApp.ready(); window.Telegram.WebApp.expand(); console.log('Telegram Mini App initialized'); // Example: Set a button in Telegram // window.Telegram.WebApp.MainButton.setText('Play Audio').show(); // window.Telegram.WebApp.MainButton.onClick(() => togglePlayPause()); } }, []); return (

HCY Audio System Clone

setVolume(parseFloat(e.target.value))} />
setBass(parseFloat(e.target.value))} />
setTreble(parseFloat(e.target.value))} />
); } export default App;