用Web Audio API实现麦克风实时频谱可视化需构建完整音频图:用户手势触发获取媒体流并创建MediaStreamSource,经AnalyserNode(fftSize=2048、smoothingTimeConstant=0.8)连接至destination,再用requestAnimationFrame持续读取getByteFrequencyData()数据,结合指数映射、对数分组、衰减逻辑和渐变色渲染Canvas条形图。

用 Web Audio API 对麦克风或媒体流做实时频谱可视化,关键在于构建一条通路:让音频流经过 AnalyserNode,再从中持续读取频率数据,最后用 Canvas 渲染成动态条形图。整个过程必须由用户手势触发,且节点连接不能断开,否则拿到的数据全是 0。
获取并接入媒体流音频源
先请求麦克风权限,再创建媒体流源节点:
- 调用
navigator.mediaDevices.getUserMedia({ audio: true })获取媒体流 - 用
audioContext.createMediaStreamSource(stream)创建源节点 - 注意:AudioContext 在 iOS Safari 等移动端必须等点击后才能 resume,否则静音且无法分析
配置 AnalyserNode 并正确接入音频图
AnalyserNode 不发声,只提供数据出口,必须嵌入信号链中:
- 创建后设
analyser.fftSize = 2048(值必须是 2 的幂,常用 1024–4096) - 设
analyser.smoothingTimeConstant = 0.8让跳变更柔和,避免频谱抖动 - 必须连接:源节点 → analyser → destination;只连 source → analyser 不够,analyser 还得连到输出,否则
getByteFrequencyData()返回全 0
用 requestAnimationFrame 实时读取并绘制频谱
高频绘制依赖稳定节奏和内存复用:
- 提前创建
Uint8Array缓冲区,长度为analyser.frequencyBinCount(即fftSize / 2) - 在
requestAnimationFrame循环里调用analyser.getByteFrequencyData(freqData) - 遍历
freqData,把每个值映射为柱高(如height = value * 1.5),用fillRect画竖条 - 避免每帧新建数组或清空整块 canvas,可只擦除频谱区域,或采用渐隐策略提升视觉流畅度
让频谱更符合听感的实用处理
原始线性频点分布与人耳感知不匹配,需简单调整:
- 低频段(前 1/3 索引)做指数映射,例如
Math.pow(value, 1.2),增强鼓点、贝斯表现 - 对高频密集区做对数分组,比如每 2–4 个 bin 合并为一个柱,避免右侧过于稀疏
- 加衰减逻辑:新高度 = 当前值 × 0.3 + 上一帧高度 × 0.7,模拟“余晖”效果
- 用渐变色区分频段——蓝→绿→红,对应低→中→高频,提升可读性

















