Changes to flamewave.scroll.pub

root
root
25 days ago
Initial commit
body.html
Changed around line 1
+
+

FlameWave

+

Transform your MP3s into stunning flamegraph videos

+
+
+
+
+
+ Upload MP3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Created with passion for audio visualization

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://flamewave.scroll.pub
+ metaTags
+ editButton /edit.html
+ title FlameWave - MP3 Flamegraph Generator
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "5a7c60a2-7920-4984-bf2f-9f706b1be249",
+ "object": "chat.completion",
+ "created": 1735321431,
+ "model": "deepseek-chat",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "---domain---\nflamewave.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://flamewave.scroll.pub\nmetaTags\neditButton /edit.html\ntitle FlameWave - MP3 Flamegraph Generator\nstyle.css\nbody.html\nscript.js\n---body.html---\n
\n

FlameWave

\n

Transform your MP3s into stunning flamegraph videos

\n
\n\n
\n
\n \n
\n \n
\n
\n\n
\n \n \n
\n
\n\n
\n

Created with passion for audio visualization

\n
\n---style.css---\n:root {\n --primary-color: #ff6b6b;\n --secondary-color: #4ecdc4;\n --bg-color: #1a1a1a;\n --text-color: #f0f0f0;\n --accent-color: #ffe66d;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Segoe UI', system-ui, sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\nheader {\n text-align: center;\n padding: 2rem;\n background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 0.5rem;\n text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);\n}\n\nmain {\n flex: 1;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n}\n\n.upload-section {\n margin-bottom: 2rem;\n}\n\n.upload-label {\n display: inline-block;\n padding: 1rem 2rem;\n background-color: var(--primary-color);\n color: white;\n border-radius: 25px;\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.upload-label:hover {\n transform: scale(1.05);\n}\n\n.upload-label input {\n display: none;\n}\n\n.visualizer-container {\n margin-top: 2rem;\n background-color: rgba(255, 255, 255, 0.1);\n border-radius: 15px;\n overflow: hidden;\n height: 400px;\n}\n\n#flamegraph-canvas {\n width: 100%;\n height: 100%;\n}\n\n.controls {\n display: flex;\n justify-content: center;\n gap: 1rem;\n margin-top: 2rem;\n}\n\nbutton {\n padding: 1rem 2rem;\n border: none;\n border-radius: 25px;\n background-color: var(--secondary-color);\n color: white;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\nbutton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\nbutton:not(:disabled):hover {\n background-color: var(--accent-color);\n transform: translateY(-2px);\n}\n\nfooter {\n text-align: center;\n padding: 1rem;\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n@media (max-width: 768px) {\n h1 {\n font-size: 2rem;\n }\n \n .visualizer-container {\n height: 300px;\n }\n \n button {\n padding: 0.8rem 1.5rem;\n }\n}\n---script.js---\nconst mp3Upload = document.getElementById('mp3-upload');\nconst generateBtn = document.getElementById('generate-btn');\nconst exportBtn = document.getElementById('export-btn');\nconst canvas = document.getElementById('flamegraph-canvas');\nconst ctx = canvas.getContext('2d');\n\nlet audioContext, analyser, source, dataArray;\n\nmp3Upload.addEventListener('change', (e) => {\n const file = e.target.files[0];\n if (file) {\n initAudio(file);\n generateBtn.disabled = false;\n }\n});\n\ngenerateBtn.addEventListener('click', () => {\n drawFlamegraph();\n exportBtn.disabled = false;\n});\n\nexportBtn.addEventListener('click', () => {\n exportVideo();\n});\n\nfunction initAudio(file) {\n const reader = new FileReader();\n reader.onload = (e) => {\n const audio = new Audio(e.target.result);\n audioContext = new (window.AudioContext || window.webkitAudioContext)();\n analyser = audioContext.createAnalyser();\n source = audioContext.createMediaElementSource(audio);\n source.connect(analyser);\n analyser.connect(audioContext.destination);\n analyser.fftSize = 2048;\n dataArray = new Uint8Array(analyser.frequencyBinCount);\n audio.play();\n };\n reader.readAsDataURL(file);\n}\n\nfunction drawFlamegraph() {\n const width = canvas.width;\n const height = canvas.height;\n const barWidth = (width / dataArray.length) * 2.5;\n let x = 0;\n\n function renderFrame() {\n requestAnimationFrame(renderFrame);\n analyser.getByteFrequencyData(dataArray);\n\n ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';\n ctx.fillRect(0, 0, width, height);\n\n for (let i = 0; i < dataArray.length; i++) {\n const barHeight = dataArray[i] / 2;\n const hue = i / dataArray.length * 360;\n ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;\n ctx.fillRect(x, height - barHeight, barWidth, barHeight);\n x += barWidth + 1;\n }\n x = 0;\n }\n renderFrame();\n}\n\nfunction exportVideo() {\n const stream = canvas.captureStream(30);\n const recorder = new MediaRecorder(stream);\n const chunks = [];\n\n recorder.ondataavailable = (e) => chunks.push(e.data);\n recorder.onstop = () => {\n const blob = new Blob(chunks, { type: 'video/webm' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'flamewave-video.webm';\n a.click();\n };\n\n recorder.start();\n setTimeout(() => recorder.stop(), 10000); // 10-second video\n}\n---end---"
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 262,
+ "completion_tokens": 1573,
+ "total_tokens": 1835,
+ "prompt_cache_hit_tokens": 0,
+ "prompt_cache_miss_tokens": 262
+ },
+ "system_fingerprint": "fp_f1afce2943"
+ }
readme.scroll
Changed around line 1
+ # flamewave.scroll.pub
+ Website generated by DeepSeek from prompt: a website allowing for mp3s to be imported and have a flamegraph generated for it. we want to be able to export as video
script.js
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
+ }
style.css
Changed around line 1
+ :root {
+ --primary-color: #ff6b6b;
+ --secondary-color: #4ecdc4;
+ --bg-color: #1a1a1a;
+ --text-color: #f0f0f0;
+ --accent-color: #ffe66d;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ background-color: var(--bg-color);
+ color: var(--text-color);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ header {
+ text-align: center;
+ padding: 2rem;
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
+ }
+
+ h1 {
+ font-size: 2.5rem;
+ margin-bottom: 0.5rem;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
+ }
+
+ main {
+ flex: 1;
+ padding: 2rem;
+ max-width: 1200px;
+ margin: 0 auto;
+ width: 100%;
+ }
+
+ .upload-section {
+ margin-bottom: 2rem;
+ }
+
+ .upload-label {
+ display: inline-block;
+ padding: 1rem 2rem;
+ background-color: var(--primary-color);
+ color: white;
+ border-radius: 25px;
+ cursor: pointer;
+ transition: transform 0.2s ease;
+ }
+
+ .upload-label:hover {
+ transform: scale(1.05);
+ }
+
+ .upload-label input {
+ display: none;
+ }
+
+ .visualizer-container {
+ margin-top: 2rem;
+ background-color: rgba(255, 255, 255, 0.1);
+ border-radius: 15px;
+ overflow: hidden;
+ height: 400px;
+ }
+
+ #flamegraph-canvas {
+ width: 100%;
+ height: 100%;
+ }
+
+ .controls {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ margin-top: 2rem;
+ }
+
+ button {
+ padding: 1rem 2rem;
+ border: none;
+ border-radius: 25px;
+ background-color: var(--secondary-color);
+ color: white;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+
+ button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ button:not(:disabled):hover {
+ background-color: var(--accent-color);
+ transform: translateY(-2px);
+ }
+
+ footer {
+ text-align: center;
+ padding: 1rem;
+ background-color: rgba(255, 255, 255, 0.05);
+ }
+
+ @media (max-width: 768px) {
+ h1 {
+ font-size: 2rem;
+ }
+
+ .visualizer-container {
+ height: 300px;
+ }
+
+ button {
+ padding: 0.8rem 1.5rem;
+ }
+ }