Music player

DEMO

Order

ComaStudio

MusicPlayer.jsx

const MusicPlayer = () => {
  const [currTrack, setCurrTrack] = useState(0);
  const { play, stop, sound, pause } = useSound(
    tracks[currTrack].soundSrc);
  const [isPlaying, setIsPlaying] = useState(false);
  const [pos, setPos] = useState(0);

  // regularly update the progress bar
  useEffect(() => {
    if (isPlaying) {
      const intervalId = setInterval(() => {
        if (sound?.seek() >= sound?.duration() - 0.5) {
          sound?.seek(0);
        } else setPos(sound?.seek());
      }, 1);
      return () => clearInterval(intervalId);
    }
  }, [isPlaying, sound]);

  // seek a position on thre track based on click
  const seek = (newVal) => {
    sound?.seek((newVal / 100) * sound?.duration());
    if (!isPlaying) {
      setIsPlaying(true);
    }
  };

  const changeTrack = (diff) => {
    // no more tracks to go to
    if (currTrack + diff < 0 || currTrack + diff >= tracks.length) {
      // restart the current track
      sound?.seek(0);
      return;
    }
    setCurrTrack(currTrack + diff);
  };

  useEffect(() => {
    if (isPlaying) {
      play();
    } else {
      pause();
    }
  }, [play, pause, isPlaying]);

  // stop sound when leaving the page
  useEffect(() => {
    return () => {
      stop();
    };
  }, [stop]);

  return (
    <PlayerWrapper>
      <CoverArt src={tracks[currTrack].imgSrc} />
      <SongTitle>{tracks[currTrack].title}</SongTitle>
      <SongArtist>{tracks[currTrack].artist}</SongArtist>
      <ProgressSlider 
        value={(pos / sound?.duration()) * 100} 
        seek={seek} />
      <TrackControls>
        <PrevTrackBtn onClick={() => changeTrack(-1)}/>
        <PlayBtn>
          {isPlaying ? (
            <BsPauseCircleFill onClick={() => {setIsPlaying(false);}}/>
          ) : (
            <BsPlayCircleFill onClick={() => {setIsPlaying(true);}}/>
          )}
        </PlayBtn>
        <NextTrackBtn onClick={() => changeTrack(1)}/>
      </TrackControls>
    </PlayerWrapper>
  );
};

const tracks = [
  {
    title: "Order",
    artist: "ComaStudio",
    imgSrc: orderCoverArt,
    soundSrc: orderSong,
  },
  {
    title: "Abstract Design",
    artist: "ComaStudio",
    imgSrc: adCoverArt,
    soundSrc: adSong,
  },
  {
    title: "Lucid",
    artist: "Nomyn",
    imgSrc: lucidCoverArt,
    soundSrc: lucidSong,
  },
];

Note: Code snippets do not include styling details unless they are the focus of the exercise.

Copyright © 2022 Explore React