问题
I know it's possible to animate an object with sound via Actionscript. I am really hoping it is also possible to animate an object with JavaScript since they are very similar.
Maybe it could be done with jQuery or HTML5. I am just hoping to find a way to do it outside of flash.
Does anyone know if this is possible in any of these formats? I have done lots of research and can't seem to find any forms or tutorials that say it is possible or not.
BASICALLY, I am trying to achieve this same effect that I coded in Actionscript but I want code it using another language so no flash views can also see.
Here is the flash example: http://beaubird.com/presentation.php
Here is an example of animating amplitude with actionscript: http://www.developphp.com/view.php?tid=22
回答1:
I've created an example that changes the radius and color of an svg circle element based on audio amplitude.
This will work in WebKit browsers, but nothing else. Webkit browsers are the only browsers that come even close to implementing the W3C Web Audio API Spec, as far as I know, but the Mozilla Audio Data API Documentation seems to indicate that Mozilla has abandoned that spec and will be implementing the Web Audio API too. I'm blissfully unaware of the state of Internet Explorer's implementation (or lack thereof) of the the spec.
Unfortunately, the answer right now is that there's no great cross-browser solution for this other than Flash, but if you go that route, you're screwed on mobile devices.
Here's the full, working JSBin example.
And here's the code:
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();
});
});
回答2:
Using a Javascript node to assess amplitude will work, but is less than ideal for performance reasons. I'd suggest using a RealtimeAnalyser on a requestAnimationFrame timer. You can start with the code from http://updates.html5rocks.com/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs, just use a smaller fftSize (128) and RMS the values.
回答3:
KievII library ( http://kievii.net ) is targeted for audio applications. Maybe you can find something useful there (for example, you can animate a Wavebox object or a series of ClickBar objects). Take a look at the examples there: http://kievII.net/examples.html
来源:https://stackoverflow.com/questions/13462206/animate-object-by-sound-amplitude