Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

audio play & pause in react

I’m trying to make a music app, I can start the audio fine, but when it comes to pausing it’s not working this is the code :

const handlePlay = (id) => {
    console.log(id);
    audio && audio.pause();
    fetch(`https://spotify23.p.rapidapi.com/tracks/?ids=${id}`, options)
      .then((response) => response.json())
      .then((response) => {
        console.log(response.tracks);
        return response.tracks[0].preview_url;
      })
      .then((response) => {
        setAudio(new Audio(response));
        audio.play();
      })
      .catch((err) => console.error(err));
  };

so I’m calling an API and getting the audio link here to play the audio :

setAudio(new Audio(response));
audio.play(); 

and at the top of the function I have this to check if audio is not null and if it is not so pause, like so:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

audio && audio.pause();

but it’s not working it’s stacking the audio together, and even if I press on another audio it played the first one pressed

this is the react code that triggers handle play for each audio available :

{tracks &&
            tracks.map((track) => (
              <div
                className="w-full h-1/12 p-4 hover:bg-gray-300 hover:bg-opacity-20 hover:text-emerald-500 cursor-pointer  transition duration-150 "
                key={track.data.id}
                onClick={() => handlePlay(track.data.id)}
              >
                <div className="flex items-center ">
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                    className="w-6 h-6 mr-2"
                  >
                    <path
                      fillRule="evenodd"
                      d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.348c1.295.712 1.295 2.573 0 3.285L7.28 19.991c-1.25.687-2.779-.217-2.779-1.643V5.653z"
                      clipRule="evenodd"
                    />
                  </svg>

                  <h1 className="text-xl ">{track.data.name}</h1>
                </div>
                <div className="text-sm font-thin">
                  by{" "}
                  {track.data.artists.items.map((artist) => (
                    <span key={artist.uri} className="">
                      {artist.profile.name}
                    </span>
                  ))}

>Solution :

The problem is likely here:

setAudio(new Audio(response));
audio.play(); 

The setAudio function is asynchronous, so it will not immediately update the value for the audio state variable. That means that when you immediately invoke audio.play(), it is going to play the previous audio value.

If you want the audio to play automatically once it is loaded, then you can remove the audio.play() invocation in the fetch callback, and then add a useEffect hook to take care of that:

useEffect(() => {
  audio && audio.play();
}, );
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading