4

I'm having a bit of a trouble building an Audio frequency visualization. I am using HTML5 audio tag:

<audio id="music" src="https://cdn.glitch.com/02dcea11-9bd2-4462-ac38-eeb6a5ad9530%2F331_full_beautiful-minds_0171_preview.mp3?1522829295082" crossorigin="use-URL-credentials" controls="true"></audio>

(song is from www.premiumbeat.com)

used with AudioContext and Analyser as shown below:

const audio = document.getElementById('music');
audio.load();
audio.play();

const ctx = new AudioContext();
const audioSrc = ctx.createMediaElementSource(audio);
const analyser = ctx.createAnalyser();
audioSrc.connect(analyser);
analyser.connect(ctx.destination);

analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const frequencyData = new Uint8Array(bufferLength);
analyser.getByteFrequencyData(frequencyData);

setTimeout(() => {
   analyser.getByteFrequencyData(frequencyData);
   console.log(frequencyData);
}, 5000);

Output: Even though the song is playing when I call the getByteFrequencyData(), the output is 128 items long array full of zeros.

Expected behaviour: After 5 seconds console should output 128 items long array of current frequency data. (I do it this way because requestAnimationFrame would lag the window, however I tried it and the result is the same).

Any idea what I do wrong? (I'm using Firefox Quantum 59.0.2.)

Try it here: JSFiddle example

Thank you!

TomasB
  • 604
  • 5
  • 18
  • 1
    It's not full of zeros here `"0": 191, "1": 209, "2": 219, "3": 208, "4": 207, "5": 195, "6": 167, "7": 145, "8": 151,` – pokeybit Apr 29 '18 at 19:32
  • 1
    Oh, interesting! Mine is full of zeros - I'm using Firefox Quantum 59.0.2 – TomasB Apr 29 '18 at 19:34

1 Answers1

4

Following my experiments with the web audio api i modified your script to use getByteTimeDomainData instead of getByteFrequencyData.

https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteTimeDomainData

Using intervals instead of timeout for the demo.

const audio = document.getElementById('music');
audio.load();
audio.play();

const ctx = new AudioContext();
const audioSrc = ctx.createMediaElementSource(audio);
const analyser = ctx.createAnalyser();

audioSrc.connect(analyser);
analyser.connect(ctx.destination);

analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const frequencyData = new Uint8Array(bufferLength);

setInterval(() => {
   analyser.getByteFrequencyData(frequencyData);
   console.log(frequencyData);
}, 1000);
<audio id="music" src="https://cdn.glitch.com/02dcea11-9bd2-4462-ac38-eeb6a5ad9530%2F331_full_beautiful-minds_0171_preview.mp3?1522829295082" crossorigin="use-URL-credentials" controls="true"></audio>
NVRM
  • 11,480
  • 1
  • 88
  • 87
  • 1
    Wow, amazing, this actually worked! Thanks! Is there a reason Why do I need to mix getByteTimeDomainData in the beggining with the getByteFrequencyData in the interval? – TomasB Apr 29 '18 at 19:42
  • 1
    Well this is weird. After running your code here even my UNCHANGED project start working. – TomasB Apr 29 '18 at 19:54
  • 2
    On a usability note for future visitors finding this question, web audio can only play after page interaction, simply loading audio with autoplay or JS-based "blah.play()" will not do anything until the user has interacted with the page (unfortunately) e.g. by clicking a button or the like. – Mike 'Pomax' Kamermans Apr 07 '20 at 21:22