音乐

Web Audio 音乐可视化

用 Canvas 与 Web Audio API 实现圆形、柱状、波形、粒子四种频谱,并同步 LRC 歌词。

#web-audio #canvas #visualization #vue

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 取不同数据:

模式读取方法绘制思路
圆形 / 柱状 / 粒子getByteFrequencyData128 个频点映射为半径、柱高或粒子位移
波形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 合成