Add a button for random playback of tracks in the player

Issue

I want to add a small player to my site to listen to music. I found a beautiful example that I liked and want to change and finish it a little.

Specifically, I want to add a button here to randomly play tracks.

To start, I add this button to the html:

<button type="submit" id="btn-random">
   <i class="fas fa-random"></i>
</button>

Next, I add a check to the next track switching function, if the random button has an active class, then the tracks will play randomly:

else if (to == 'next') {
        stop();
        if (document.getElementById("btn-random").classList.contains("active")) {
          let songs = document.getElementById("sourceUrl").length - 1;
          let randomSong = Math.floor(Math.random() * songs) + 1;
        } else {
          currentSong = (++currentSong)%playlist.length;
        }
        playpause();
    }

Next, it remains to make sure that when you click on the random button, the active class turns on and off. To do this, I make a onclick function for this button and implement it:

<button type="submit" id="btn-random" onclick="random()">
   <i class="fas fa-random"></i>
</button>

//

var randomTrack = false;

function random() {
  if (randomTrack) {
        document.getElementById('btn-random').classList.add("active");
        randomTrack = false;
    }
    else {
        document.getElementById('btn-random').classList.remove("active");
        randomTrack = true;
    }
}

But in the end, when the random button has an active class and I try to switch the song, instead of a random track, the current track plays in a circle.

What could be the problem?

var song = new Audio;
var isStopped = true;
var currentSong = 0;
var playlist = [];
var playlistVisible = false;
var randomTrack = false;

function skip(to) {
    if (to == 'prev') {
        stop();
        currentSong = (--currentSong)%playlist.length;
        if (currentSong < 0) {
            currentSong += playlist.length;
        }
        playpause();
    }
    else if (to == 'next') {
        stop();
        if (document.getElementById("btn-random").classList.contains("active")) {
          let songs = document.getElementById("sourceUrl").length - 1;
              let randomSong = Math.floor(Math.random() * songs) + 1;
        } else {
          currentSong = (++currentSong)%playlist.length;
        }
        playpause();
    }
}

function playpause() {
  if (!song.paused) {
        song.pause();
        document.getElementById("glow").classList.add("disable-animation");
    }
  else if (playlist.length == 0){
    togglePlaylist();
  }
    else {
      if (isStopped) {
            song.src = playlist[currentSong];
        }
        song.play();
        songFile = playlist[currentSong].split("/");
        songName = document.getElementById("songName");
        songName.innerHTML = songFile[songFile.length - 1].split('.').slice(0, -1).join('.');
        document.getElementById("glow").classList.remove("disable-animation");
        isStopped = false;
    }
}

function random() {
  if (randomTrack) {
        document.getElementById('btn-random').classList.add("active");
        randomTrack = false;
    }
    else {
        document.getElementById('btn-random').classList.remove("active");
        randomTrack = true;
    }
}

function stop() {
    song.pause();
    document.getElementById("glow").classList.add("disable-animation");
    song.currentTime = 0;
    document.getElementById("seek").value = 0;
    isStopped = true;
    document.getElementById("songName").innerHTML = "playing track..";
}

function setPos(pos) {
    song.currentTime = pos;
}

function mute() {
    if (song.muted) {
        song.muted = false;
        document.getElementById('mute').className = "fa fa-volume-up";
    }
    else {
        song.muted = true;
        document.getElementById('mute').className = "fa fa-volume-off";
    }
}

function setVolume(volume) {
    song.volume = volume;
}

function togglePlaylist() {
    if (playlistVisible) {
        document.getElementById('playlist').className = "hide";
        document.getElementById('player').className = "";
        playlistVisible = false;
    }
    else {
        document.getElementById('player').className = "hide";
        document.getElementById('playlist').className = "";
        playlistVisible = true;
    }
}

function addList() {
    sourceUrl = document.getElementById('sourceUrl').value;
    sourceUrl.split(",").forEach((file) => {
        fileUrl = file.trim();
        if (fileUrl != "" && playlist.indexOf(fileUrl) == -1) {
            parent = document.getElementById('list');
            listItem = document.createElement('div');
            listItem.setAttribute('class','list-item');

            wrapper = document.createElement('div');
            wrapper.setAttribute('class','wrap-text');

            span = document.createElement('span');
      songFile = fileUrl.split("/");
            span.innerHTML = songFile[songFile.length - 1].split('.').slice(0, -1).join('.');

            wrapper.appendChild(span);
            listItem.appendChild(wrapper);

            btn = document.createElement('button');
            btn.setAttribute('onclick','removeList(this)');
            btn.innerHTML = '&times;';

            listItem.appendChild(btn);
            parent.appendChild(listItem);
            playlist.push(fileUrl);
        }
    });
  document.getElementById('sourceUrl').value = '';
}

function removeList(item) {
    index = playlist.indexOf(item.parentElement.firstChild.innerText);
    if (index != -1){
        playlist.splice(index,1);
        item.parentElement.remove();
    }
}

song.addEventListener('error', function(){
    stop();
    document.getElementById("songName").innerHTML = "error loading audio";
});

song.addEventListener('timeupdate', function() {
    curtime = parseInt(song.currentTime,10);
    document.getElementById('seek').max = song.duration;
    document.getElementById('seek').value = curtime;
});

song.addEventListener("ended", function() {
    song.pause();
    song.currentTime = 0;
    document.getElementById('seek').value = 0;
    if ((currentSong + 1) >= playlist.length) {
        currentSong = 0;    
    }
    else {
        currentSong++;
    }
    stop();
    song.src = playlist[currentSong];
    playpause();
});

var input = document.getElementById("sourceUrl");
input.addEventListener("keyup", function(event) {
    if (event.keyCode === 13) {
        event.preventDefault();
        addList();
    }
});


// This area of code is only for preview purposes only

document.getElementById('sourceUrl').value = ["https://www.bensound.com/bensound-music/bensound-summer.mp3",
"https://www.bensound.com/bensound-music/bensound-anewbeginning.mp3",
"https://www.bensound.com/bensound-music/bensound-littleidea.mp3",
"https://www.bensound.com/bensound-music/bensound-cute.mp3",
"https://www.bensound.com/bensound-music/bensound-memories.mp3"];
addList();
document.getElementById("glow").classList.remove("disable-animation");

// Code for preview ends here
* {
  box-sizing: border-box;
}
html {
  background: #000000;
}
html,
body,
.container {
  height: 100%;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  white-space: nowrap;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.container {
  display: flex;
  align-items: center;
  justify-content: center;
}
.glow {
  position: absolute;
  width: 300px;
  height: 300px;
  background: linear-gradient(0deg, #000000, #262626);
  border-radius: 50%;
}
.glow::before,
.glow::after {
  content: "";
  position: absolute;
  top: -2px;
  left: -2px;
  background: linear-gradient(
    45deg,
    #ebc6df,
    #ebc6c9,
    #e1c6eb,
    #c6c9eb,
    #c6e8eb,
    #e373fb,
    #f787e6,
    #cb87f7,
    #87a9f7,
    #87f7ee
  );
  background-size: 400%;
  max-width: calc(300px + 4px);
  max-height: calc(300px + 4px);
  width: calc(300px + 4px);
  height: calc(300px + 4px);
  z-index: -1;
  animation: animate 20s linear infinite;
  border-radius: 50%;
}
.disable-animation::before,
.disable-animation::after {
  animation-play-state: paused;
}
.glow::after {
  filter: blur(28px);
}
#player,
#playlist {
  width: 243px;
  height: 212px;
  text-align: center;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
#songName {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 30px;
}
.playlist-btn {
  width: 243px;
  margin-top: 30px;
  text-align: center;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}
.hide {
  display: none;
}
#list {
  height: 118px;
  max-height: 118px;
  margin-top: 16px;
  font-size: 12px;
  overflow-x: hidden;
  overflow-y: scroll;
  color: #fff;
  text-align: left;
  padding-left: 8px;
  border: 2px solid #262626;
  border-radius: 5px;
}
.list-item {
  line-height: 30px;
  height: 30px;
  margin-top: 4px;
}
.list-container button {
  width: 30px;
  padding: 0;
  float: right;
  margin-right: 4px;
}
.add-list {
  padding: 4px 6px;
}
.wrap-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 190px;
  display: inline-block;
}
#sourceUrl {
  background: none;
  padding: 8px;
  border: 2px solid #1f1f1f;
  border-radius: 47px;
  outline: none;
  color: white;
  height: 30px;
  width: 192px;
}
#sourceUrl:active,
#sourceUrl:focus {
  border: 2px solid #0088ff;
}
.text {
  color: #ffffff;
  display: block;
}
button {
  background: #000000;
  color: #ffffff;
  background: linear-gradient(0deg, #000000, #262626);
  font-size: 14px;
  border: none;
  outline: none;
  padding: 0px 15px;
  width: 55px;
  height: 30px;
  line-height: 30px;
  border-radius: 32px;
}
button:hover {
  box-shadow: 0 0 8px 0px #ffffff61;
}
button:active {
  box-shadow: inset 0 0 6px 0px #ffffff61;
}

#seek,
#volume {
  -webkit-appearance: none;
  border: 1px solid #000000;
  height: 5px;
  vertical-align: middle;
  border-radius: 20px;
  background-color: #232323;
  outline: none;
}
#seek::-webkit-slider-thumb,
#volume::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  border: 1px solid #000000;
  border-radius: 10px;
  background: #ffffff;
}
#seek {
  display: block;
  width: 230px;
}
.scrollbar::-webkit-scrollbar {
  max-width: 5px;
  max-height: 5px;
}
.scrollbar::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background: #333;
}
.scrollbar::-webkit-scrollbar-thumb:hover {
  box-shadow: inset 0 0 1px 1px #5c6670;
}

.scrollbar::-webkit-scrollbar-track:hover {
  border: 1px solid #000000;
  border-radius: 20px;
  background-color: #232323;
}

@keyframes animate {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: 400% 0;
  }
  100% {
    background-position: 0 0;
  }
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet" type="text/css">
<div class="container">
  <div id="glow" class="glow disable-animation">
    <div id="player">
      <span class="text">iu player</span>
      <br>
      <span id="songName" class="text">playing track..</span>
      <br>
      <div class="playback_controls">
        <button onclick="skip('prev')">
          <i class="fa fa-fast-backward"></i>
        </button>
        <button onclick="playpause()">
          <i class="fa fa-play"></i><i class="fa fa-pause"></i>
        </button>
        <button onclick="stop()">
          <i class="fa fa-stop"></i>
        </button>
        <button onclick="skip('next')">
          <i class="fa fa-fast-forward"></i>
        </button>
      </div>
      <br>
      <div id="seekbar">
        <input type="range" oninput="setPos(this.value)" id="seek" value="0" max="">
      </div>
      <br>
      <div class="volume_controls">
        <button onclick="mute()">
          <i id="mute" class="fa fa-volume-up"></i>
        </button>
        <input type="range" id="volume" oninput="setVolume(this.value)" min="0" max="1" step="0.01" value="1">
      </div>
    </div>

    <div id="playlist" class="hide">
      <span class="text">iu playlist</span>
      <div class="list-container">

        <div id="list" class="scrollbar"></div>

        <div class="add-list">
          <input id="sourceUrl" type="text" placeholder="enter audio url" />
          <button onclick="addList()">+</button>
        </div>

      </div>
    </div>

    <div class="playlist-btn">
      <button id="btn-random" onclick="random()">
        <i class="fas fa-random"></i>
      </button>
      <button onclick="togglePlaylist()">
        <i id="playlist-btn" class="fa fa-list"></i>
      </button>
    </div>

  </div>
</div>

Solution

You are never reading your randomSong variable.

Just set currentSong to Math.floor(Math.random() * playlist.length) in that case:

if (
    document.getElementById("btn-random").classList.contains("active")
) {
    currentSong = Math.floor(Math.random() * playlist.length);
} else {
    currentSong = ++currentSong % playlist.length;
}
playpause();

Answered By – moonwave99

Answer Checked By – Mary Flores (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.