Changed around line 1
+ const mp3Upload = document.getElementById('mp3-upload');
+ const generateBtn = document.getElementById('generate-btn');
+ const exportBtn = document.getElementById('export-btn');
+ const canvas = document.getElementById('flamegraph-canvas');
+ const ctx = canvas.getContext('2d');
+
+ let audioContext, analyser, source, dataArray;
+
+ mp3Upload.addEventListener('change', (e) => {
+ const file = e.target.files[0];
+ if (file) {
+ initAudio(file);
+ generateBtn.disabled = false;
+ }
+ });
+
+ generateBtn.addEventListener('click', () => {
+ drawFlamegraph();
+ exportBtn.disabled = false;
+ });
+
+ exportBtn.addEventListener('click', () => {
+ exportVideo();
+ });
+
+ function initAudio(file) {
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ const audio = new Audio(e.target.result);
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ analyser = audioContext.createAnalyser();
+ source = audioContext.createMediaElementSource(audio);
+ source.connect(analyser);
+ analyser.connect(audioContext.destination);
+ analyser.fftSize = 2048;
+ dataArray = new Uint8Array(analyser.frequencyBinCount);
+ audio.play();
+ };
+ reader.readAsDataURL(file);
+ }
+
+ function drawFlamegraph() {
+ const width = canvas.width;
+ const height = canvas.height;
+ const barWidth = (width / dataArray.length) * 2.5;
+ let x = 0;
+
+ function renderFrame() {
+ requestAnimationFrame(renderFrame);
+ analyser.getByteFrequencyData(dataArray);
+
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
+ ctx.fillRect(0, 0, width, height);
+
+ for (let i = 0; i < dataArray.length; i++) {
+ const barHeight = dataArray[i] / 2;
+ const hue = i / dataArray.length * 360;
+ ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
+ ctx.fillRect(x, height - barHeight, barWidth, barHeight);
+ x += barWidth + 1;
+ }
+ x = 0;
+ }
+ renderFrame();
+ }
+
+ function exportVideo() {
+ const stream = canvas.captureStream(30);
+ const recorder = new MediaRecorder(stream);
+ const chunks = [];
+
+ recorder.ondataavailable = (e) => chunks.push(e.data);
+ recorder.onstop = () => {
+ const blob = new Blob(chunks, { type: 'video/webm' });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = 'flamewave-video.webm';
+ a.click();
+ };
+
+ recorder.start();
+ setTimeout(() => recorder.stop(), 10000); // 10-second video
+ }