Changed around line 1
+ class AudioVisualizer {
+ constructor() {
+ this.audioContext = null;
+ this.source = null;
+ this.analyser = null;
+ this.isPlaying = false;
+ this.audioElement = new Audio();
+
+ this.canvas = document.getElementById('visualizer');
+ this.ctx = this.canvas.getContext('2d');
+
+ this.setupEventListeners();
+ this.resizeCanvas();
+ window.addEventListener('resize', () => this.resizeCanvas());
+ }
+
+ resizeCanvas() {
+ this.canvas.width = this.canvas.offsetWidth;
+ this.canvas.height = this.canvas.offsetHeight;
+ }
+
+ setupEventListeners() {
+ document.getElementById('audio-input').addEventListener('change', (e) => {
+ const file = e.target.files[0];
+ if (file) {
+ const url = URL.createObjectURL(file);
+ this.loadAudio(url);
+ }
+ });
+
+ document.getElementById('play-pause').addEventListener('click', () => {
+ this.togglePlayPause();
+ });
+
+ document.getElementById('viz-color').addEventListener('change', (e) => {
+ this.vizColor = e.target.value;
+ });
+
+ document.getElementById('viz-style').addEventListener('change', (e) => {
+ this.vizStyle = e.target.value;
+ });
+ }
+
+ async initAudio() {
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ this.analyser = this.audioContext.createAnalyser();
+ this.source = this.audioContext.createMediaElementSource(this.audioElement);
+ this.source.connect(this.analyser);
+ this.analyser.connect(this.audioContext.destination);
+ this.analyser.fftSize = 256;
+ }
+
+ loadAudio(url) {
+ this.audioElement.src = url;
+ if (!this.audioContext) {
+ this.initAudio();
+ }
+ }
+
+ togglePlayPause() {
+ if (this.audioContext.state === 'suspended') {
+ this.audioContext.resume();
+ }
+
+ if (this.isPlaying) {
+ this.audioElement.pause();
+ document.getElementById('play-pause').querySelector('.icon').textContent = '▶️';
+ } else {
+ this.audioElement.play();
+ document.getElementById('play-pause').querySelector('.icon').textContent = '⏸️';
+ this.startVisualization();
+ }
+ this.isPlaying = !this.isPlaying;
+ }
+
+ startVisualization() {
+ const bufferLength = this.analyser.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ const draw = () => {
+ if (!this.isPlaying) return;
+
+ requestAnimationFrame(draw);
+ this.analyser.getByteFrequencyData(dataArray);
+
+ this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
+
+ const barWidth = this.canvas.width / bufferLength * 2.5;
+ let x = 0;
+
+ for (let i = 0; i < bufferLength; i++) {
+ const barHeight = dataArray[i] * this.canvas.height / 256;
+
+ this.ctx.fillStyle = document.getElementById('viz-color').value;
+ this.ctx.fillRect(x, this.canvas.height - barHeight, barWidth, barHeight);
+
+ x += barWidth + 1;
+ }
+ };
+
+ draw();
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ new AudioVisualizer();
+ });