Home>
I am writing a sound visualizer in React using Web Audio API methods
In general, everything works fine except for requestAnimationFrame, this function goes into an endless loop that cannot be stopped by calling cancelAnimationFrame
I have already tried about 10 different options and still did not get the desired result
import React, {useEffect, useState} from 'react';
import "./equalizer.css"
//Work around the bug in chrome and safari
const AudioContext= window.AudioContext || window.webkitAudioContext
function Equalizer ({audio, playPauseSwitch}) {
useEffect (()= >
{
//Variables for the sound analyzer
let context, analyzer, audioNode, arrayVolums
function getAnalaizerAudio () {
//Check for an error while creating the audio object
if (audio!== undefined) {
//remove CORS policy
audio.crossOrigin= "anonymous"
//Create audio context
context= new AudioContext ();
//Create a function to get the frequency
analyser= context.createAnalyser ()
//Set the wave averaging
analyser.smoothingTimeConstant= 0.3;
//Set the number of blocks with a frequency -64
analyser.fftSize= 128;
//Create an audio node
audioNode= context.createMediaElementSource (audio);
//Connect it to the frequency analyzer
audioNode.connect (analyzer)
//sound output to speakers
analyser.connect (context.destination);
getVolumeEqualizer ()
}
}
//Control requestAnimationFrame for getVolumeEqualize
let animationFrameSwitch
//Function for frequency visualization
function getVolumeEqualizer () {
animationFrameSwitch= undefined
//Form a binary array and fill it with frequency data
arrayVolums= new Uint8Array (analyser.frequencyBinCount)
analyser.getByteFrequencyData (arrayVolums)
start ()
}
function start () {
if (playPauseSwitch=== true) {
animationFrameSwitch= window.requestAnimationFrame (getVolumeEqualizer)
}
}
function stop () {
if (playPauseSwitch=== false) {
window.cancelAnimationFrame (animationFrameSwitch)
return animationFrameSwitch= undefined
}
}
stop ()
getAnalaizerAudio ()
}, [audio])
return (
<
div >
<
div className= "equalizer__wraper" >
<
/div >
<
/div >
<
/div >
);
}
export default Equalizer;
You let animationFrameSwitch is initialized anew every time the component is redrawn. In other words, you are losing the link and therefore cannot be stopped. Use useRef ()
Sanya H2021-12-27 19:56:10Related questions
- javascript : Why do I get a jsx file instead of js after building a project with webpack using babel
- javascript : render {routes} in react
- javascript : React. Unloading ads for 10 pieces
- javascript : How to restart an existing React app?
- javascript : The simplest code on React.js does not work
- javascript : React. Send a get request to the server when pressing Enter
- javascript : Running webPack 5 in development mode does not see html page
- javascript : Problem with Route
- javascript : JS: wrap links found inside a string in an element
- javascript : How to optimize useSelector redux
In getAnalaizerAudio you call getVolumeEqualizer, and in it you call start, which schedules getVolumeEqualizer to be called again (window.requestAnimationFrame (getVolumeEqualizer)), which will call start again.
Вася Воронцов2021-12-27 18:49:56