Estoy creando un reproductor de audio en React y tengo el siguiente código. Se reproduce bien cuando hace clic en el botón de reproducción una vez, pero se niega a hacer una pausa cuando hace clic en pausa. Además, si vuelve a hacer clic en reproducir, en lugar de simplemente continuar con el audio, se crea un nuevo audio de la misma canción y se reproduce encima de la canción anterior. No estoy seguro de cómo arreglar esto.
const AudioPlayer = () => { let audio = new Audio(song) const [playing, setPlaying] = useState(false) const playHandler = () => { if(playing){ setPlaying(false) console.log(playing) } else{ setPlaying(true) } } const audioPause = () => { audio.pause() } const audioPlay = () => { audio.play() } useEffect (() => { (playing) ? audioPlay() : audioPause() }, [playing]) return( <div className="songPlaying"> <p> { (playing) ? "Now playing" : "Stopped Playing" } </p> <button type="submit" onClick={playHandler}> {(playing) ? "Pause" : "Play" } </button> </div> ) }En lugar de crear una variable de audio, puede crear un estado y actualizarlo en consecuencia.
Aquí está el código de muestra, esto debería funcionar en su caso:
... // let audio = new Audio(song) const [audio] = useState(new Audio(song)); ... En su caso, su código está creando un nuevo objeto cada vez, cuando presiona pause y play , por lo que esta es la razón por la que se superpone al audio en lugar de pause y reproducir.
Al crear un estado, sigue siendo el mismo objeto, por lo que cada vez que actualice el estado de reproducción y pausa, puede usar el mismo objeto de audio y realizar acciones en él, en lugar de crear uno nuevo.
Aquí está el código minificado tuyo:
const AudioPlayer = () => { const [audio] = useState(new Audio(song)); const [playing, setPlaying] = useState(false) const toggle = () => setPlaying(!playing); useEffect(() => { playing ? audio.play() : audio.pause(); }, [playing] ); return ( <div className="songPlaying"> <p> {(playing) ? "Now playing" : "Stopped Playing"} </p> <button type="submit" onClick={toggle}> {(playing) ? "Pause" : "Play"} </button> </div> ) }Lea esta respuesta para obtener más información.
import React, { useState } from "react"; // Play icon import voicemailplay from "../../assets/voicemail_play.png"; // Pause icon import voicemailpause from "../../assets/fax_call_icon.png"; // Global declaration audio array let audioArray = []; // Global declaration audio array index let audioIndex = ''; const VoicemailSider = (props) => { // Manage flag const [isPlaying, setIsPlaying] = useState(false); // Play audio const playAudio = (audioFilePath, index) => { if(audioIndex !== '' && audioArray[audioIndex]) { audioArray[audioIndex].pause(); } setIsPlaying( index ); audioArray = []; audioIndex = index; try{ if(index !== '' && event !== '') { audioArray[index] = new Audio(audioFilePath); audioArray[index].play(); } } catch(error) { console.log("Could not paly this audio - ", error); } } // Pause audio const pauseAudio = (index) => { setIsPlaying( false ); audioArray[index].pause(); } return ( <div> <List dataSource={voicemaillist} // Your data that comes from databse renderItem={(item,index) => ( <List.Item key={index}> <img src={isPlaying === index ? voicemailpause : voicemailplay } alt="voicemail_play" onClick={() => isPlaying !== index ? playAudio(item.audioFilePath, index) : pauseAudio(index) } id={"voicemail_play" + index} style={{width: 35 ,height: 35, margin: "0px 10px"}} /> </List.Item> )} </List> </div> ); }; export default VoicemailSider;