Web Audio 音乐可视化
用 Canvas 与 Web Audio API 实现圆形、柱状、波形、粒子四种频谱,并同步 LRC 歌词。
Web Audio 音乐可视化
浏览器里的音乐播放器不只是 <audio> 控件。通过 Web Audio API 把音频流接入 AnalyserNode,再用 Canvas 读取频谱数据,就能做出随节拍律动的可视化。下方 demo 支持四种频谱样式、LRC 歌词滚动与歌单切换。
核心链路
整个 demo 可以拆成三条并行管线:音频图负责把 <audio> 接入 Web Audio;Canvas 动画每帧读取分析器数据并绘制;歌词根据 currentTime 滚动高亮。
1. 音频图:从元素到 AnalyserNode
<audio> 本身只负责解码和播放。第一次点击播放时,才创建 AudioContext 并把元素挂到音频图上:
<audio> → MediaElementSource → AnalyserNode → destination(扬声器)
↓
每帧读取频谱 / 波形数据
AnalyserNode 是可视化的数据来源。fftSize 设为 256(128 个频点),smoothingTimeConstant 控制相邻帧的平滑程度——数值越大,柱状跳动越「黏」,越小则越灵敏。
audioCtx = new AudioContext()
source = audioCtx.createMediaElementSource(audio)
analyser = audioCtx.createAnalyser()
analyser.fftSize = 256
source.connect(analyser)
analyser.connect(audioCtx.destination)
浏览器要求 用户手势 后才能 resume() 音频上下文,所以 demo 必须点播放才能启动;暂停时取消 requestAnimationFrame,Canvas 回到 idle 态。
2. Canvas 绘制:同一数据源,四种画法
绘制循环在 requestAnimationFrame 里跑。根据当前模式,从 AnalyserNode 取不同数据:
| 模式 | 读取方法 | 绘制思路 |
|---|---|---|
| 圆形 / 柱状 / 粒子 | getByteFrequencyData | 128 个频点映射为半径、柱高或粒子位移 |
| 波形 | getByteTimeDomainData | 时域采样连成曲线,并做帧间平滑 |
频谱类模式用频率能量驱动视觉;波形模式看的是振幅随时间的变化。切歌或切模式时会清空帧间缓存,避免上一首的能量「残留」。
每首歌还配了一套主题色(主色、辅色、光晕),切歌时同步更新 Canvas 渐变和 UI 变量。
3. 歌词同步
LRC 文本先解析成 { time, text }[],播放过程中根据 audio.currentTime 二分查找当前行,用 transform: translateY(...) 把高亮行滚到视口中央。timeupdate 事件触发频繁,滚动逻辑做了 500ms 节流;点击某行歌词则 seek 到对应时间。
在线体验
下方为完整交互 demo(需点击播放后启动 AudioContext)。也可 全屏预览 打开独立页面。
小结
Web Audio 可视化并不复杂:把 <audio> 接入 AnalyserNode,再在 Canvas 里每帧读数据、画图形。难点在于体验细节——播放前后的 idle 动画、切歌时的状态重置、波形与频谱不同的平滑策略,以及歌词与进度的双向联动。
四种频谱样式共用同一套分析器,只是映射方式不同;这也是前端可视化里常见的模式:数据层稳定,表现层可插拔。如果你要做自己的播放器可视化,可以从一个 AnalyserNode + 一种绘制函数开始,再逐步加模式和主题。
想走另一条 Web Audio 路线——用振荡器合成声音而非分析播放——可以看 网页钢琴与 Web Audio 合成。