声音看得见:麦克风一开,频谱随音乐跳动
耳机里的歌、麦克风前的一句哼唱,都能变成跳动的柱状图和波形。这个工具用 Web Audio API 实时采样,把声音画成频谱视觉;主题换色、柱数调节、灵敏度缩放都实时生效,播放你的声音就能看到独一无二的「声波纹」。先看成品,再讲怎么用华为云 CodeArts 码道 WebUI 一段话把它做出来、部署上线。
这个工具做什么
它把「声音」变成一面实时跳动的可视化画布:
- 麦克风实时采样:
getUserMedia采集声音,AudioContext+AnalyserNode分析频域和时域。 - 频谱 + 波形双视图:上方频谱柱状图看频率能量,下方波形图看声压随时间起伏。
- 开始 / 暂停:点一下开麦,再点暂停并释放麦克风资源。
- 六种主题:一键切换配色,频谱颜色还能随时间流动。
- 柱数调节:64 / 96 / 128 等档位可调,密度随心换。
- 灵敏度调节:0.5–5.0 缩放显示幅度,安静环境也能拉出漂亮形态。
- 附加开关:镜像、峰值保持、平滑三个开关独立切换。
- 科技感界面:深色玻璃拟态、发光描边、高分屏适配、实时 FPS 显示,手机和电脑都能用。

码道开通(免费体验版)
开始之前,先免费开通码道体验版。不需要装任何软件,浏览器就能用:
https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz
开通后有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。
进入 AI 开发者空间
- 浏览器打开 https://devstation.developer.huaweicloud.com/aidevspace?utm_source=opcsfsq&utm_medium=wbwz
- 弹窗「请选择要进入的版本」→ 点击 体验版
- 首次使用会跳到华为云登录页,扫码登录一次,后续浏览器会话复用
- 弹窗「临时凭据自动配置」→ 点击 同意,沙箱自动创建
进入 AI 开发者空间主界面后,先等左侧菜单加载出来,再找到 CodeArts,点击它右侧的浏览器图标,打开码道 WebUI 对话窗口:

打开后码道 WebUI 会先和你打招呼,下方就是需求输入框:

小贴士:体验版沙箱 3 小时后自动重置,生成完记得把
index.html下载保存。
任务描述
在码道 WebUI 输入框粘贴以下需求,回车发送:
开发一个「音频频谱可视化」单文件网页应用:通过麦克风采集声音,用 Web Audio API 实时绘制频谱柱状图和波形图;支持单击开始/暂停、多种配色主题、频率柱数量调节、灵敏度调节,界面炫酷科技感,手机和电脑都能用,所有代码写在一个 index.html 里。完成后用部署功能部署成可访问的网页应用,生成一个公网可访问的分享链接,并告诉我访问地址。

这轮码道具体做了什么
不是复述通用 AI 能力,而是它在这次项目里的实际动作:
- 在
/workspace/audio-spectrum下创建单文件index.html,把音频链路、Canvas 绘制、主题和滑块交互全部写进一个文件,无第三方依赖。 - 探测空闲端口 3004 后启动
http.server并自检 HTTP 200,给出内部预览地址。 - 用 DevBridge 创建公网隧道并验证内容,最后给出 8 小时有效的公网分享链接。
代码亮点
以下是 index.html 里值得关注的设计思路和实现细节。
1. 一条标准音频链路:麦克风 → AnalyserNode → Canvas
toggle 首次点击时请求麦克风权限,建立 MediaStreamSource → AnalyserNode 链路。注意 source 只连到 analyser,不连到扬声器 destination,所以不会反馈啸叫:
mediaStream=await navigator.mediaDevices.getUserMedia({audio:{
echoCancellation:false,noiseSuppression:false,autoGainControl:false
}});
audioCtx=new (window.AudioContext||window.webkitAudioContext)();
source=audioCtx.createMediaStreamSource(mediaStream);
analyser=audioCtx.createAnalyser();
analyser.fftSize=2048;
analyser.smoothingTimeConstant=smooth?0.8:0;
source.connect(analyser);
freqData=new Uint8Array(analyser.frequencyBinCount);
timeData=new Uint8Array(analyser.fftSize);
关掉「平滑」时 smoothingTimeConstant 归零,频谱对声音变化更敏感、跳动更猛。
2. 主循环每帧取两份数据,再分别画频谱和波形
loop 用 getByteFrequencyData 拿频域能量、getByteTimeDomainData 拿时域波形,交给两个 Canvas 绘制,同时顺带统计 FPS:
function loop(){
if(!running)return;
rafId=requestAnimationFrame(loop);
analyser.getByteFrequencyData(freqData);
analyser.getByteTimeDomainData(timeData);
drawSpectrum();
drawWaveform();
const now=performance.now();
const dt=now-lastFrame;lastFrame=now;
if(dt>0){fpsAcc+=1000/dt;fpsCnt++;}
fpsTimer+=dt;
if(fpsTimer>=500){
document.getElementById('fps').textContent=Math.round(fpsAcc/fpsCnt)+' FPS';
fpsAcc=0;fpsCnt=0;fpsTimer=0;
}
}
3. 频率按对数风格分桶,低频不会挤在屏幕最左侧
人耳对低频更敏感,如果均匀分桶,笛声和鼓点会挤在一起。drawSpectrum 用 Math.pow(i/barCount, 1.6) 把频率区间偏向左半段,让低频分得更细:
for(let i=0;i<barCount;i++){
const lo=Math.floor(Math.pow(i/barCount,1.6)*usable);
const hi=Math.floor(Math.pow((i+1)/barCount,1.6)*usable);
let v=0;
for(let j=lo;j<hi&&j<bins;j++)v=Math.max(v,freqData[j]);
v=v/255*sensitivity;
if(v>1)v=1;
const h=v*maxH;
const x=gap+i*(bw+gap);
// 主题色 / 随时间的 hue 渐变着色
}
每个柱子里取该频段的最大值,再乘灵敏度并裁剪到 1,既稳定又不会爆表。
4. 灵敏度和主题都是「改了立即生效」的全局状态
柱数、灵敏度、镜像、峰值、平滑这些参数都存在顶层变量里,滑块和开关回调直接改值,下一帧 loop 自然用新参数重绘;主题切换则更新 themeIdx 后立即 applyTheme:
let barCount=64, sensitivity=1.6;
let mirror=true, peakHold=true, smooth=true;
const barCountEl=document.getElementById('barCount');
barCountEl.addEventListener('input',()=>{
barCount=+barCountEl.value;
barCountVal.textContent=barCount;
peaks=new Array(barCount).fill(0);
});
直接下载试玩
本次生成的项目就是单文件 index.html,没有第三方依赖,把文件保存到本地后双击用浏览器打开即可运行。源码同步到公开 Demo Park 仓库:
- Demo Park 仓库:https://atomgit.com/deli007/demo_park
- 本案例目录:https://atomgit.com/deli007/demo_park/tree/main/codearts-audio-spectrum-visualizer
总结
音频频谱可视化把「听」变成「看」,核心链路是 getUserMedia → AudioContext → AnalyserNode → Canvas。analyser 不连扬声器避免啸叫,loop 每秒六十帧取频域和时域数据,频谱用对数风格分桶照顾低频,滑块和主题都作为全局状态即时作用于下一帧。把工具再做深一点,可以支持「播放本地音乐文件分析」「导出当前帧为 PNG」,或接上 MIDI 键盘做实时灯效。
如果还没用过码道,可以免费开通体验版:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz
- 点赞
- 收藏
- 关注作者
评论(0)