Changes to sonicvisions.scroll.pub

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

Sonic Visions

+

Transform music into images and images into music.

+
+
+
+
+

Music to Image

+
+
+
+
+
+

Image to Music

+
+
+
+
+
+
+

Experience the harmony of sound and vision.

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://sonicvisions.scroll.pub
+ metaTags
+ editButton /edit.html
+ title Sonic Visions - Transform Music into Images and Images into Music
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "f0a20f05-daec-4fe3-88d0-ab7affb5f1ad",
+ "object": "chat.completion",
+ "created": 1736675012,
+ "model": "deepseek-chat",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "---domain---\nsonicvisions.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://sonicvisions.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Sonic Visions - Transform Music into Images and Images into Music\nstyle.css\nbody.html\nscript.js\n---body.html---\n
\n

Sonic Visions

\n

Transform music into images and images into music.

\n
\n\n
\n
\n

Music to Image

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

Image to Music

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

Experience the harmony of sound and vision.

\n
\n---style.css---\n:root {\n --primary-color: #1a1a1a;\n --secondary-color: #333;\n --accent-color: #ff6f61;\n --text-color: #f5f5f5;\n --font-family: 'Segoe UI', sans-serif;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: var(--font-family);\n color: var(--text-color);\n background-color: var(--primary-color);\n line-height: 1.6;\n padding: 20px;\n}\n\nheader {\n text-align: center;\n padding: 40px 0;\n}\n\nh1 {\n font-size: 2.5rem;\n color: var(--accent-color);\n}\n\nh2 {\n font-size: 2rem;\n margin-bottom: 20px;\n}\n\nmain {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 30px;\n margin-top: 40px;\n}\n\nsection {\n background: var(--secondary-color);\n padding: 20px;\n border-radius: 10px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\ninput[type=\"file\"] {\n width: 100%;\n margin-bottom: 20px;\n padding: 10px;\n border: 2px dashed var(--accent-color);\n border-radius: 5px;\n background: transparent;\n color: var(--text-color);\n}\n\ncanvas {\n width: 100%;\n height: 300px;\n background: var(--primary-color);\n border-radius: 5px;\n}\n\naudio {\n width: 100%;\n margin-top: 20px;\n}\n\nfooter {\n text-align: center;\n margin-top: 40px;\n padding: 20px;\n background: var(--secondary-color);\n border-radius: 10px;\n}\n\n@media (max-width: 768px) {\n h1 {\n font-size: 2rem;\n }\n\n h2 {\n font-size: 1.5rem;\n }\n}\n---script.js---\ndocument.getElementById('music-upload').addEventListener('change', function(event) {\n const file = event.target.files[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = function(e) {\n const audioContext = new (window.AudioContext || window.webkitAudioContext)();\n const audioData = e.target.result;\n\n audioContext.decodeAudioData(audioData, function(buffer) {\n visualizeAudio(buffer);\n });\n };\n reader.readAsArrayBuffer(file);\n }\n});\n\nfunction visualizeAudio(buffer) {\n const canvas = document.getElementById('music-canvas');\n const ctx = canvas.getContext('2d');\n const width = canvas.width;\n const height = canvas.height;\n\n const audioData = buffer.getChannelData(0);\n const step = Math.ceil(audioData.length / width);\n const amp = height / 2;\n\n ctx.clearRect(0, 0, width, height);\n ctx.beginPath();\n ctx.moveTo(0, amp);\n\n for (let i = 0; i < width; i++) {\n let min = 1.0;\n let max = -1.0;\n for (let j = 0; j < step; j++) {\n const datum = audioData[(i * step) + j];\n if (datum < min) min = datum;\n if (datum > max) max = datum;\n }\n ctx.lineTo(i, (1 + min) * amp);\n ctx.lineTo(i, (1 + max) * amp);\n }\n\n ctx.strokeStyle = '#ff6f61';\n ctx.lineWidth = 2;\n ctx.stroke();\n}\n\ndocument.getElementById('image-upload').addEventListener('change', function(event) {\n const file = event.target.files[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = function(e) {\n const img = new Image();\n img.src = e.target.result;\n img.onload = function() {\n const audio = imageToSound(img);\n const audioOutput = document.getElementById('audio-output');\n audioOutput.src = URL.createObjectURL(audio);\n };\n };\n reader.readAsDataURL(file);\n }\n});\n\nfunction imageToSound(img) {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n canvas.width = img.width;\n canvas.height = img.height;\n ctx.drawImage(img, 0, 0);\n\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n const data = imageData.data;\n\n const audioContext = new (window.AudioContext || window.webkitAudioContext)();\n const buffer = audioContext.createBuffer(1, data.length, audioContext.sampleRate);\n const output = buffer.getChannelData(0);\n\n for (let i = 0; i < data.length; i++) {\n output[i] = (data[i] - 128) / 128;\n }\n\n const source = audioContext.createBufferSource();\n source.buffer = buffer;\n source.connect(audioContext.destination);\n\n const blob = new Blob([bufferToWav(buffer)], { type: 'audio/wav' });\n return blob;\n}\n\nfunction bufferToWav(buffer) {\n const numOfChan = buffer.numberOfChannels;\n const length = buffer.length * numOfChan * 2 + 44;\n const bufferArray = new ArrayBuffer(length);\n const view = new DataView(bufferArray);\n\n writeString(view, 0, 'RIFF');\n view.setUint32(4, 36 + buffer.length * numOfChan * 2, true);\n writeString(view, 8, 'WAVE');\n writeString(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, numOfChan, true);\n view.setUint32(24, buffer.sampleRate, true);\n view.setUint32(28, buffer.sampleRate * 2 * numOfChan, true);\n view.setUint16(32, numOfChan * 2, true);\n view.setUint16(34, 16, true);\n writeString(view, 36, 'data');\n view.setUint32(40, buffer.length * numOfChan * 2, true);\n\n let offset = 44;\n for (let i = 0; i < buffer.length; i++) {\n for (let channel = 0; channel < numOfChan; channel++) {\n const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]));\n view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);\n offset += 2;\n }\n }\n\n return bufferArray;\n}\n\nfunction writeString(view, offset, string) {\n for (let i = 0; i < string.length; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n}\n---end---"
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 248,
+ "completion_tokens": 1853,
+ "total_tokens": 2101,
+ "prompt_cache_hit_tokens": 0,
+ "prompt_cache_miss_tokens": 248
+ },
+ "system_fingerprint": "fp_3a5770e1b4"
+ }
readme.scroll
Changed around line 1
+ # sonicvisions.scroll.pub
+
+ website generated by DeepSeek from prompt: 上传一个音乐,能转化成图片,上传一个图片能转换成音乐
script.js
Changed around line 1
+ document.getElementById('music-upload').addEventListener('change', function(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ const audioData = e.target.result;
+
+ audioContext.decodeAudioData(audioData, function(buffer) {
+ visualizeAudio(buffer);
+ });
+ };
+ reader.readAsArrayBuffer(file);
+ }
+ });
+
+ function visualizeAudio(buffer) {
+ const canvas = document.getElementById('music-canvas');
+ const ctx = canvas.getContext('2d');
+ const width = canvas.width;
+ const height = canvas.height;
+
+ const audioData = buffer.getChannelData(0);
+ const step = Math.ceil(audioData.length / width);
+ const amp = height / 2;
+
+ ctx.clearRect(0, 0, width, height);
+ ctx.beginPath();
+ ctx.moveTo(0, amp);
+
+ for (let i = 0; i < width; i++) {
+ let min = 1.0;
+ let max = -1.0;
+ for (let j = 0; j < step; j++) {
+ const datum = audioData[(i * step) + j];
+ if (datum < min) min = datum;
+ if (datum > max) max = datum;
+ }
+ ctx.lineTo(i, (1 + min) * amp);
+ ctx.lineTo(i, (1 + max) * amp);
+ }
+
+ ctx.strokeStyle = '#ff6f61';
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ }
+
+ document.getElementById('image-upload').addEventListener('change', function(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ const img = new Image();
+ img.src = e.target.result;
+ img.onload = function() {
+ const audio = imageToSound(img);
+ const audioOutput = document.getElementById('audio-output');
+ audioOutput.src = URL.createObjectURL(audio);
+ };
+ };
+ reader.readAsDataURL(file);
+ }
+ });
+
+ function imageToSound(img) {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ const data = imageData.data;
+
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ const buffer = audioContext.createBuffer(1, data.length, audioContext.sampleRate);
+ const output = buffer.getChannelData(0);
+
+ for (let i = 0; i < data.length; i++) {
+ output[i] = (data[i] - 128) / 128;
+ }
+
+ const source = audioContext.createBufferSource();
+ source.buffer = buffer;
+ source.connect(audioContext.destination);
+
+ const blob = new Blob([bufferToWav(buffer)], { type: 'audio/wav' });
+ return blob;
+ }
+
+ function bufferToWav(buffer) {
+ const numOfChan = buffer.numberOfChannels;
+ const length = buffer.length * numOfChan * 2 + 44;
+ const bufferArray = new ArrayBuffer(length);
+ const view = new DataView(bufferArray);
+
+ writeString(view, 0, 'RIFF');
+ view.setUint32(4, 36 + buffer.length * numOfChan * 2, true);
+ writeString(view, 8, 'WAVE');
+ writeString(view, 12, 'fmt ');
+ view.setUint32(16, 16, true);
+ view.setUint16(20, 1, true);
+ view.setUint16(22, numOfChan, true);
+ view.setUint32(24, buffer.sampleRate, true);
+ view.setUint32(28, buffer.sampleRate * 2 * numOfChan, true);
+ view.setUint16(32, numOfChan * 2, true);
+ view.setUint16(34, 16, true);
+ writeString(view, 36, 'data');
+ view.setUint32(40, buffer.length * numOfChan * 2, true);
+
+ let offset = 44;
+ for (let i = 0; i < buffer.length; i++) {
+ for (let channel = 0; channel < numOfChan; channel++) {
+ const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]));
+ view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);
+ offset += 2;
+ }
+ }
+
+ return bufferArray;
+ }
+
+ function writeString(view, offset, string) {
+ for (let i = 0; i < string.length; i++) {
+ view.setUint8(offset + i, string.charCodeAt(i));
+ }
+ }
style.css
Changed around line 1
+ :root {
+ --primary-color: #1a1a1a;
+ --secondary-color: #333;
+ --accent-color: #ff6f61;
+ --text-color: #f5f5f5;
+ --font-family: 'Segoe UI', sans-serif;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: var(--font-family);
+ color: var(--text-color);
+ background-color: var(--primary-color);
+ line-height: 1.6;
+ padding: 20px;
+ }
+
+ header {
+ text-align: center;
+ padding: 40px 0;
+ }
+
+ h1 {
+ font-size: 2.5rem;
+ color: var(--accent-color);
+ }
+
+ h2 {
+ font-size: 2rem;
+ margin-bottom: 20px;
+ }
+
+ main {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 30px;
+ margin-top: 40px;
+ }
+
+ section {
+ background: var(--secondary-color);
+ padding: 20px;
+ border-radius: 10px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ }
+
+ input[type="file"] {
+ width: 100%;
+ margin-bottom: 20px;
+ padding: 10px;
+ border: 2px dashed var(--accent-color);
+ border-radius: 5px;
+ background: transparent;
+ color: var(--text-color);
+ }
+
+ canvas {
+ width: 100%;
+ height: 300px;
+ background: var(--primary-color);
+ border-radius: 5px;
+ }
+
+ audio {
+ width: 100%;
+ margin-top: 20px;
+ }
+
+ footer {
+ text-align: center;
+ margin-top: 40px;
+ padding: 20px;
+ background: var(--secondary-color);
+ border-radius: 10px;
+ }
+
+ @media (max-width: 768px) {
+ h1 {
+ font-size: 2rem;
+ }
+
+ h2 {
+ font-size: 1.5rem;
+ }
+ }