AudioContext需用户手势触发才能启动,否则报DOMException;AnalyserNode须接入音频图并设fftSize为2的幂;Canvas绘图前清空画布,用freqData映射高度绘制频谱条。
直接 new AudioContext() 在多数现代浏览器里会报错,典型错误是 DOMException: The AudioContext was not allowed to start。这是因为浏览器要求音频上下文必须由用户手势(如 click、touchstart)触发才能启动,否则静音保护机制会阻止它初始化。
实操建议:
立即学习“前端免费学习笔记(深入)”;
new AudioContext(),改在按钮点击事件里调用<button onclick="initAudio()">开始可视化</button>
audioContext.resume()(尤其 Safari 和新版 Chrome),否则后续分析节点可能不工作AnalyserNode 是连接音频源与可视化逻辑的核心桥梁。它本身不处理或播放音频,只做 FFT 分析,输出频域或时域数组。关键点在于:它必须插入到音频图中,哪怕只是接在 destination 前面“路过”一下。
实操建议:
立即学习“前端免费学习笔记(深入)”;
audioContext.createAnalyser(),再设置 analyser.fftSize = 256(值必须是 2 的幂,常用 128–2048)analyser.getByteFrequencyData() 前,务必先准备好对应长度的 Uint8Array,例如:const freqData = new Uint8Array(analyser.frequencyBinCount)
source.connect(analyser); analyser.connect(audioContext.destination),否则数据不会流动可视化本身不依赖第三方库,原生 <canvas> + requestAnimationFrame 就够用。重点是把 freqData 数组映射成高度值,并逐列绘制。
实操建议:
立即学习“前端免费学习笔记(深入)”;
ctx.clearRect(0, 0, canvas.width, canvas.height)
freqData[i] 作为高度比例:height = (freqData[i] / 255) * canvas.height * 0.8
requestAnimationFrame 回调里反复调用 getByteFrequencyData() 之前没检查 analyser 是否已连接,否则返回全 0function draw() { analyser.getByteFrequencyData(freqData); ctx.fillStyle = '#4a55e5'; const barWidth = 3; for (let i = 0; i < freqData.length; i++) { const height = (freqData[i] / 255) * canvas.height * 0.8; ctx.fillRect(i * barWidth, canvas.height - height, barWidth, height); } requestAnimationFrame(draw);}
想让可视化响应环境声音(比如说话、拍手),得用 MediaStreamAudioSourceNode 接麦克风。但权限和兼容性比文件播放更敏感。
实操建议:
立即学习“前端免费学习笔记(深入)”;
navigator.mediaDevices.getUserMedia({ audio: true }) 获取流,且该 Promise 必须在用户手势后调用audioContext.createMediaStreamSource(stream) 创建源节点,不能直接用 stream 连接 analyser
getUserMedia 支持有限,部分机型需开启「录音」权限并在 HTTPS 下运行真正卡住人的往往不是算法,而是 AudioContext 的状态流转——suspended → running → closing,以及分析节点是否被正确插入音频图。漏掉一次 resume() 或连错一个节点,整条链就断了,但控制台未必报错。