I have been struggling for HOURS trying to beat this, but i can´t do it.
The problem down below have a BUTTON, which has a child of an FontAwesomeIcon component. i want the icon to change, is audio playing? then display the pause icon, if not.. you get the rest.
However, when i click the play button, it changes the icon as expected, and the audio plays. when i click it again, this is when the problem occurs. It will not pause the music, and it will certainly not change the icon back.
Can someone help me figure this out?
import React from 'react';
import { useState, useRef, useEffect } from 'react';
import wavesurfer from 'wavesurfer.js';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCirclePlay, faCirclePause } from "@fortawesome/free-solid-svg-icons";
const AudioVisualizer = (props) => {
const audioRef = useRef(null);
// const [playing, setPlay] = useState(null);
const [isClicked, setIsClicked] = useState(false)
const [volume, setVolume] = useState(0.5);
const [isBtnClicked, setBtnClicked] = useState(false)
const [icon, setIcon] = useState(faCirclePlay);
let audioTrack;
useEffect(()=>{
if (audioRef.current){
audioTrack = wavesurfer.create({
container: audioRef.current,
progressColor: "#13AEA2",
waveColor: "#eeee",
cursorColor: "OrangeRed",
preload: true,
backend: "MediaElement",
barWidth: 2,
barHeight: 1, // the height of the wave
fillParent: true,
hideScrollbar: true,
responsive: true,
});
audioTrack.load(props.audio);
// audioTrack.load(props.audio);
}
}, [])
const onVolumeChange = e => {
const { target } = e;
const newVolume = +target.value;
if (newVolume) {
console.log("new volume true,,, volume: " + volume)
setVolume(volume => newVolume);
audioTrack.current.setVolume(newVolume || 1);
}
};
const clicking = (e) => {
// Get a view of what the "click" registers:
console.log(e.currentTarget.tagName);
console.log(e.target);
// if plying == pause
if ( ! audioTrack.isPlaying() ) {
console.log("not playing.. Start playing");
audioTrack.play()
setIcon(icon => faCirclePause)
return
}
console.log("Is playing.. will pause")
audioTrack.play()
setIcon(faCirclePlay);
return
};
// FontAwesomeIcon => onClick change icon + pause/play audio.
return (
<>
<div className='audio' ref={audioRef}>
</div>
<div className='audioKnobs'>
<button className='playpausewrapper' onClick={clicking}>
<FontAwesomeIcon className='playButton' icon={icon} />
</button>
<input type="range" id="volume" name="volume" min="0.01" max="1" step=".025" onChange={onVolumeChange} defaultValue={volume}/>
</div>
</>
)
}
export default AudioVisualizer;
AudioVisualizer.js:75 Uncaught TypeError: Cannot read properties of undefined (reading 'isPlaying')
at clicking (AudioVisualizer.js:75:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
at react-dom.development.js:9288:1
Everything inside of a component is run every render. Components can rerender thousand of times.
You are declaring a variable every render:
let audioTrack;
But you are assigning the value only once
useEffect(()=>{
if (audioRef.current){
audioTrack = wavesurfer.create({
container: audioRef.current,
progressColor: "#13AEA2",
waveColor: "#eeee",
cursorColor: "OrangeRed",
preload: true,
backend: "MediaElement",
barWidth: 2,
barHeight: 1, // the height of the wave
fillParent: true,
hideScrollbar: true,
responsive: true,
});
audioTrack.load(props.audio);
// audioTrack.load(props.audio);
}
}, [])
You can't use normal variables like that.
You have to use ref
At the beginning of the component:
const audioTrackRef = useRef(undefined);
In the useEffect
audioTrackRef.current = wavesurfer.create({
container: audioRef.current,
progressColor: "#13AEA2",
waveColor: "#eeee",
cursorColor: "OrangeRed",
preload: true,
backend: "MediaElement",
barWidth: 2,
barHeight: 1, // the height of the wave
fillParent: true,
hideScrollbar: true,
responsive: true,
});
And in every other place
audioTrackRef.current
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.