1

I am new at react, so don't be too harsh. I'm building music player and I have one last thing left - I can't figure out how to play next song after current one ended.

Here is my code

  const [tracks, setTracks] = useState([])
  const [currentTrack, setCurrentTrack] = useState({})
  const [index, setIndex] = useState(0)
  const [isPlaying, setIsPlaying] = useState(false)
  const [songLength, setSongLength] = useState(0)
  const [songProgress, setSongProgress] = useState(0)


 useEffect(() => {
    let timeOut = null

    const onPlaying = () => {
      if (!audioRef.current.paused) {
        const { duration } = audioRef.current
        const { currentTime } = audioRef.current

        setSongProgress((currentTime / duration) * 100)
        setSongLength(duration)
      }
    }

    if (audioRef.current) {
      audioRef.current.pause()
    }

    if (track) {
      audioRef.current = new Audio(currentTrack?.track_file)
      timeOut = setInterval(onPlaying, 100)
      audioRef.current.play()
      audioRef.current.volume = volume / 100
      setIsPlaying(true)
    }

    return () => {
      if (timeOut) {
        clearInterval(timeOut)
      }
    }

  }, [track, currentTrack?.track_file])

That's part of code responsible for playing music in general.

I was trying to implement this function, but first I need to figure out how to understand that current track is finished. (This function the way it is works fine with the nextTrack button)

const nextTrack = () => {
    setCurrentTrack(tracks[index + 1])
}

Thank you in advance

  • Where is your react-player in code. Have you trried ''onEnded Callback props. Called when media finishes playing. Use this to check to current active tracks. If active track is the last item in array, set next active track to first item. https://www.npmjs.com/package/react-player – jones Jan 31 '23 at 12:05
  • I modified my code and added onEnded event listener, so now everything is working – Zarina Nugmanova Feb 05 '23 at 14:15

1 Answers1

0

Update, here is the code that works for me, I added eventListener for 'ended'

useEffect(() => {
    let timeOut = null

    const onEnded = () => {
      setCurrentTrack(tracks[index + 1])
      dispatch(getCurrentTrack(tracks[index + 1]))
    }

    const onPlaying = () => {
      if (!audioRef.current.paused) {
        const { duration } = audioRef.current
        const { currentTime } = audioRef.current

        setSongProgress((currentTime / duration) * 100)
        setSongLength(duration)
      }
    }

    if (audioRef.current) {
      audioRef.current.pause()
    }

    if (track) {
      audioRef.current = new Audio(currentTrack?.track_file)
      audioRef.current.addEventListener('ended', onEnded)

      timeOut = setInterval(onPlaying, 100)
      audioRef.current.play()
      audioRef.current.volume = volume / 100
      setIsPlaying(true)
    }

    return () => {
      if (timeOut) {
        clearInterval(timeOut)
      }
      if (audioRef.current) {
        audioRef.current.pause()
      }

      if (audioRef.current) {
        audioRef.current.removeEventListener('ended', onEnded)
      }
    }
  }, [track, currentTrack?.track_file, index, dispatch, tracks])