Estoy tratando de hacer una aplicación de música, puedo iniciar bien el audio, pero cuando se trata de pausar, no funciona, este es el código:
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)); };
así que llamo a una API y obtengo el enlace de audio aquí para reproducir el audio:
setAudio(new Audio(response)); audio.play();
y en la parte superior de la función tengo esto para verificar si el audio no es nulo y si no es así pausa, así:
audio && audio.pause();
pero no funciona, está apilando el audio, e incluso si presiono otro audio, reprodujo el primero presionado
este es el código de reacción que activa el manejo de reproducción para cada audio disponible:
{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> ))}
El problema es probable aquí:
setAudio(new Audio(response)); audio.play();
La función setAudio
es asíncrona, por lo que no actualizará inmediatamente el valor de la variable de estado de audio
. Eso significa que cuando invoque inmediatamente audio.play()
, reproducirá el valor de audio anterior.
Si desea que el audio se reproduzca automáticamente una vez que se cargue, puede eliminar la invocación de audio.play()
en la devolución de llamada de búsqueda y luego agregar un useEffect
para encargarse de eso:
useEffect(() => { audio && audio.play(); }, [audio]);