我创建了一个示例,该示例根据音频振幅更改 svg 圆形元素的半径和颜色。
这将在 WebKit 浏览器中工作,但没有别的。据我所知,Webkit 浏览器是唯一接近实现W3C Web 音频 API 规范的浏览器,但Mozilla 音频数据 API 文档似乎表明 Mozilla 已经放弃了该规范并且也将实现 Web 音频 API . 我很高兴地不知道 Internet Explorer 实施(或缺乏)规范的状态。
不幸的是,现在的答案是除了 Flash 之外没有很好的跨浏览器解决方案,但如果你走这条路,你就会被移动设备搞砸了。
这是完整的、有效的 JSBin 示例。
这是代码:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Drums</title>
</head>
<body>
<svg width="200" height="200">
<circle id="circle" r="10" cx="100" cy="100" />
</svg>
</body>
</html>
Javascript:
var context = new webkitAudioContext();
// Here's where most of the work happens
function processAudio(e) {
var buffer = e.inputBuffer.getChannelData(0);
var out = e.outputBuffer.getChannelData(0);
var amp = 0;
// Iterate through buffer to get the max amplitude for this frame
for (var i = 0; i < buffer.length; i++) {
var loud = Math.abs(buffer[i]);
if(loud > amp) {
amp = loud;
}
// write input samples to output unchanged
out[i] = buffer[i];
}
// set the svg circle's radius according to the audio's amplitude
circle.setAttribute('r',20 + (amp * 15));
// set the circle's color according to the audio's amplitude
var color = Math.round(amp * 255);
color = 'rgb(' + color + ',' + 0 + ',' + color + ')';
circle.setAttribute('fill',color);
}
window.addEventListener('load',function() {
var circle = document.getElementById('circle');
// Add an audio element
var audio = new Audio();
audio.src = 'http://www.mhat.com/phatdrumloops/audio/acm/mole_on_the_dole.wav';
audio.controls = true;
audio.preload = true;
document.body.appendChild(audio);
audio.addEventListener('canplaythrough',function() {
var node = context.createMediaElementSource(audio);
// create a node that will handle the animation, but won't alter the audio
// in any way
var processor = context.createJavaScriptNode(2048,1,1);
processor.onaudioprocess = processAudio;
// connect the audio element to the node responsible for the animation
node.connect(processor);
// connect the "animation" node to the output
processor.connect(context.destination);
// play the sound
audio.play();
});
});