`THREE.AudioAnalyser` 音频分析

时间:2024-04-28 17:32:24
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webaudio - visualizer</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <link type="text/css" rel="stylesheet" href="main.css"> <!-- 顶点着色器 --> <script id="vertexShader" type="x-shader/x-vertex"> varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); } </script> <!-- 片段着色器 --> <script id="fragmentShader" type="x-shader/x-fragment"> uniform sampler2D tAudioData; varying vec2 vUv; void main() { vec3 backgroundColor = vec3(0.125, 0.125, 0.125); vec3 color = vec3(1.0, 1.0, 0.0); float f = texture2D(tAudioData, vec2(vUv.x, 0.0)).r; float i = step(vUv.y, f) * step(f - 0.0125, vUv.y); gl_FragColor = vec4(mix(backgroundColor, color, i), 1.0); } </script> </head> <body> <div id="overlay"> <button id="startButton">Play</button> </div> <div id="container"></div> <div id="info"> <a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> webaudio - visualizer<br/> music by <a href="http://www.newgrounds.com/audio/listen/376737" target="_blank" rel="noopener">skullbeatz</a> </div> <script type="importmap"> { "imports": { "three": "../build/three.module.js", "three/addons/": "./jsm/" } } </script> <script type="module"> // 导入所需的模块 import * as THREE from 'three'; // 定义全局变量 let scene, camera, renderer, analyser, uniforms; // 获取开始按钮并添加点击事件监听器 const startButton = document.getElementById('startButton'); startButton.addEventListener('click', init); // 初始化函数 function init() { const fftSize = 128; // FFT 大小 // 移除遮罩 const overlay = document.getElementById('overlay'); overlay.remove(); // 获取容器元素 const container = document.getElementById('container'); // 创建渲染器 renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); // 创建场景和相机 scene = new THREE.Scene(); camera = new THREE.Camera(); // 创建音频分析器 const listener = new THREE.AudioListener(); const audio = new THREE.Audio(listener); const file = './sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3'; // 检查是否在 iOS 设备上运行 if (/iPad|iPhone|iPod/g.test(navigator.userAgent)) { const loader = new THREE.AudioLoader(); loader.load(file, function (buffer) { audio.setBuffer(buffer); audio.play(); }); } else { const mediaElement = new Audio(file); mediaElement.play(); audio.setMediaElementSource(mediaElement); } // 创建音频分析器并设置数据纹理 analyser = new THREE.AudioAnalyser(audio, fftSize); const format = (renderer.capabilities.isWebGL2) ? THREE.RedFormat : THREE.LuminanceFormat; uniforms = { tAudioData: { value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format) } }; // 创建材质 const material = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader: document.getElementById('vertexShader').textContent, fragmentShader: document.getElementById('fragmentShader').textContent }); // 创建几何体和网格 const geometry = new THREE.PlaneGeometry(1, 1); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); // 监听窗口大小变化 window.addEventListener('resize', onWindowResize); // 开始动画循环 animate(); } // 窗口大小变化时更新渲染器尺寸 function onWindowResize() { renderer.setSize(window.innerWidth, window.innerHeight); } // 动画循环 function animate() { requestAnimationFrame(animate); render(); } // 渲染函数 function render() { // 更新频谱数据 analyser.getFrequencyData(); uniforms.tAudioData.value.needsUpdate = true; renderer.render(scene, camera); } </script> </body> </html>