Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get FFT from audio tag in HTML5

Tags:

html

audio

fft

I want to get the FFT data from an <audio> tag, but it doesn't work without any syntax error. Looking at the Web Audio API document, I write a sample code, here is my code:

<audio id="aud" controls="controls" src="test.mp3"></audio>

<script type="text/javascript">
var audioElement = document.getElementById("aud");
var audioContext = new webkitAudioContext();
var streamingAudioSource = audioContext.createMediaElementSource(audioElement);
var jsProcessor = audioContext.createJavaScriptNode(4096,1,1);
jsProcessor.onaudioprocess = process;
var analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;

//streaming:AudioSource->jsProcessor->analyser->destination
streamingAudioSource.connect(jsProcessor);
jsProcessor.connect(analyser);
analyser.connect(audioContext.destination);
//autoplay
audioElement.play();
function process(event){
    var freqByteData = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(freqByteData);
    document.getElementById("info").innerHTML=freqByteData[1];//show data in div
}
</script>

My Chrome version is 20.0.1096.1 dev-m and I think it works well. Through process(), I'm trying to write down freqByteData, but it shows 0, and all of them are always 0. It must have something wrong of my code, and I want to know how to get frequency data from an audio tag.

like image 638
echoloyuk Avatar asked Apr 13 '12 03:04

echoloyuk


1 Answers

It seems that createMediaSourceElement breaks if it's called before window.onload. There is a bug report about this issue: http://code.google.com/p/chromium/issues/detail?id=112368

There are currently two workarounds:

Wait the window load event before executing the whole javascript

window.addEventListener('load', function(){
  // your code
}, false);

or

Create the MediaElementSource in a setTimeout with 0 delay

setTimeout(function (){
  var streamingAudioSource = audioContext.createMediaElementSource(audioElement);
  var jsProcessor = audioContext.createJavaScriptNode(4096,1,1);
  // The rest of the code
}, 0);
like image 114
idFlood Avatar answered Sep 24 '22 15:09

idFlood