I'm trying to use the HTML5 Web Audio API to create graphics like an equalizer, but the data is never cast to MediaElementSourc

I'm trying to use the HTML5 Web Audio API to create graphics like an equalizer, but for some reason, the data is never cast to MediaElementSource .

 $('.table').on('click', 'tr', function() { if ($(this) != $('.table tr:first-child')) { var src = $(this).children().first().attr('data-src'); var audio = new Audio(); audio.src = src; audio.controls = true; $('.file-playlist').append(audio); console.log(audio); audio.load(); audio.play(); context = new webkitAudioContext(); console.log(context); analyser = context.createAnalyser(); console.log(analyser); source = context.createMediaElementSource(audio); console.log(source); source.connect(analyser); console.log(source); analyser.connect(context.destination); console.log(analyser); rafCallback(); } }); 

In the above function, I created an audio element and used it as a source for the MediaElementSource context, however there is some problem that I cannot find, because in the console the activeSourceCount attribute in the AudioContext is always 0, which means that it never received an audio element which I gave it as a parameter.

EDIT:

I changed my code according to what idbehold said; however, now I have 2 errors, InvalidStateError: DOM Exception 11 in line source = context.createMediaElementSource(audio); and TypeError: Cannot read property 'frequencyBinCount' of undefined in the line var freqByteData = new Uint8Array(analyser.frequencyBinCount); In addition, MediaElementSource still has 0 activeSourceCounts.

 $(document).ready(function() { var context = new webkitAudioContext(); console.log(context); var audio; var source; $('.table').on('click', 'tr', function() { if ($(this) != $('.table tr:first-child')) { var src = $(this).children().first().attr('data-src'); if (audio) { audio.remove(); audio = new Audio(); audio.src = src; audio.controls = true; $('.file-playlist').append(audio); console.log(audio); audio.addEventListener("canplay", function(e) { analyser = context.createAnalyser(); console.log(analyser); source.disconnect(); source = context.createMediaElementSource(audio); console.log(source); source.connect(analyser); console.log(source); analyser.connect(context.destination); console.log(analyser); audio.load(); audio.play(); }, false); } else { audio = new Audio(); audio.src = src; audio.controls = true; $('.file-playlist').append(audio); console.log(audio); audio.addEventListener("canplay", function(e) { analyser = (analyser || context.createAnalyser()); console.log(analyser); source = context.createMediaElementSource(audio); console.log(source); source.connect(analyser); console.log(source); analyser.connect(context.destination); console.log(analyser); audio.load(); audio.play(); }, false); } } rafCallback(); }); }); 

EDIT 2:

in my rafCallback () function, I noticed that the data from Uint8Array was never processed, so I added getByteFrequencyData(analyser.frequencyBinCount); who fixed everything.

+4
source share
1 answer

You can create only one AudioContext for each window, and you must wait until the audio canplay event canplay before setting up the MediaElementSource . You should also disable MediaElementSource when you are finished using it.

Here is an example that I used to answer a similar question: http://jsbin.com/acolet/1/

+6
source

Source: https://habr.com/ru/post/1489364/


All Articles