JavaScript Audio Player with Playlist

JavaScript Audio Player with Playlist
Code Snippet:HTML5 Audio Player with Playlist
Author: Sekedus
Published: January 11, 2024
Last Updated: January 22, 2024
Downloads: 27,462
License: MIT
Edit Code online: View on CodePen
Read More

This code snippet helps you to create a JavaScript audio player with a playlist. It comes with custom controls including volume progress, play/pause, next/previous, shuffles, and autoplay button. Likewise, users can expand and collapse the player and playlist.

The player is purely built with JavaScript without any dependency. However, it uses Font Awesome CSS for icons. If we talk about its customization, Sekedus provide us with an easy way to control the overall behavior of the player. You can pass the configuration object through HTML5 data-attribute “data-config”. On the other hand, the interface of the audio player can be customized with additional CSS.

How to Create JavaScript Audio Player with Playlist

1. First of all, create a div element with a class name “simple-audio-player” and define its id “simp” and data-config attribute with basic player’s settings. The HTML5 audio player will be rendered through JavaScript inside this div element.

The second part of the audio player is a playlist. So, create a div element with a class name “simp-playlist” and place an unordered list of your songs files. The complete HTML structure for the audio player with playlist is as follows:

<div class="simple-audio-player" id="simp" data-config='{"shide_top":false,"shide_btm":false,"auto_load":false}'>
  <div class="simp-playlist">
    <ul>
      <li><span class="simp-source" data-src="http://www.archive.org/download/CanonInD_261/CanoninD.mp3">Canon in D</span><span class="simp-desc">Johann Pachelbel</span></li>
      <li><span class="simp-source" data-src="https://www.script-tutorials.com/demos/363/data/05.mp3">Artist 5</span></li>
      <li><span class="simp-source" data-src="https://www.dropbox.com/s/6pays95q2a9jrsf/2020.01.02.mp3?dl=1" data-cover="https://i.postimg.cc/sDBycWS8/NMS-2019.jpg">Nightmare Side</span><span class="simp-desc">Set Stori</span></li>
      <li class="simp-active"><span class="simp-source" data-src="https://www.dropbox.com/s/k011ag91uktonbv/Angklung%20Preman%20Pensiun.mp3?dl=1">Angklung Preman Pensiun</span></li>
      <li><span class="simp-source" data-src="https://www.dropbox.com/s/prgte33m86n9ce7/Canon%20Rock%20%28JerryC%29%20-%20funtwo.mp3?dl=1">Canon Rock (JerryC)</span><span class="simp-desc">by Funtwo</span></li>
      <li><span class="simp-source" data-src="http://listento.ardanradio.com:1059/;">105.9 FM Ardan Radio</span><span class="simp-desc">Streaming Radio</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/78_jailhouse-rock_elvis-presley-jerry-leiber-mike-stoller_gbia0080595b/Jailhouse%20Rock%20-%20Elvis%20Presley%20-%20Jerry%20Leiber-restored.mp3">Jailhouse Rock</span><span class="simp-desc">Elvis Presley</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/J._Period_and_Michael_Jackson_-_Man_Or_The_Music-2010/17%20Smooth%20Criminal.mp3">Smooth Criminal</span><span class="simp-desc">Michael Jackson</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/OldPop_256/VillagePeople-Y.m.c.a.mp3">Y.M.C.A</span><span class="simp-desc">Village People</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/chuckberryjohnnyb.goode/Chuck%20Berry%20-%20Johnny%20B.%20Goode.mp3">Johnny B. Goode</span><span class="simp-desc">Chuck Berry</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/AnimalsTheHouseOfTheRisingSun_201811/Animals%20-%20The%20House%20Of%20The%20Rising%20Sun.mp3">House of the Rising Sun</span><span class="simp-desc">The Animals</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/DontStopMeNow_255/Queen-DontStopMeNow.mp3">Don't Stop Me Now</span><span class="simp-desc">Queen</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/NeverGonnaGiveYouUpOriginal/Never%20Gonna%20Give%20You%20Up%20Original.mp3">Never Gonna Give You Up</span><span class="simp-desc">Rick Astley</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/gunsnrosessweetchildomine_202003/Guns%20N%27%20Roses%20-%20Sweet%20Child%20%27O%20Mine.mp3">Sweet Child O' Mine</span><span class="simp-desc">Guns N' Roses</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/01.TheFinalCountdown/01.%20The%20Final%20Countdown.mp3">The Final Countdown</span><span class="simp-desc">Europe</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/1MyHeartWillGoOnLoveThemeFromTitanic/1%20-%20My%20Heart%20Will%20Go%20On%20%28Love%20Theme%20from%20_Titanic_%29.mp3">My Heart Will Go On</span><span class="simp-desc">Céline Dion</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/tntvillage_323140/John%20Lennon%20-%20Imagine/01%20Imagine.mp3">Imagine</span><span class="simp-desc">John Lennon</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/TheBeatles1970HeyJudeAppleRecords6e062.0434807HeyJude/The%20Beatles%20-%201970%20-%20Hey%20Jude%20%28Apple%20Records%3B%20%236e%20062.04348%29_07%20-%20Hey%20Jude.mp3">Hey Jude</span><span class="simp-desc">The Beatles</span></li>
      <li><span class="simp-source" data-src="https://archive.org/download/TakeMeHomeCountryRoad/JohnDenver-TakeMeHomeCountryRoad.mp3">Take Me Home, Country Roads</span><span class="simp-desc">John Denver</span></li>
    </ul>
  </div>
</div>    

In the above HTML, you just need to update the “data-src” and attribute in each li element.

2. After creating the HTML, now it’s time to style the audio player. So, copy the following CSS and include it in your project. You can change the CSS values if you want to customize the interface of the audio player.

@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');

*,*:before,*:after{outline:0;-webkit-box-sizing:border-box;box-sizing:border-box;}
input,button{outline:none;}
a,a:hover,a:visited{color:#ddd;text-decoration:none;}
.flex{display:-webkit-flex;display:flex;}
.flex-wrap{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;}
.flex-align{-webkit-align-items:center;align-items:center;}
.w-full{width:100%;}

/* HTML5 Audio Player with Playlist, source: https://www.codehim.com/vanilla-javascript/javascript-audio-player-with-playlist/ */
#simp button,#simp input,#simp img{border:0;}
#simp{max-width:600px;font-size:14px;font-family:"Segoe UI", Tahoma, sans-serif;text-align:initial;line-height:initial;background:#17212b;color:#ddd;margin:0 auto;border-radius:6px;overflow:hidden;}
#simp .simp-album{padding:20px 25px 5px;}
#simp .simp-album .simp-cover{margin-right:20px;}
#simp .simp-album .simp-cover img{max-width:80px;width:100%;margin:0;padding:0;display:block;}
#simp .simp-album .simp-title{font-size:120%;font-weight:bold;}
#simp .simp-album .simp-artist{font-size:90%;color:#6c7883;}
#simp .simp-controls{padding:15px;}
#simp .simp-controls button{font-size:130%;width:32px;height:32px;background:none;color:#ddd;padding:7px;cursor:pointer;border:0;border-radius:3px;}
#simp .simp-controls button[disabled]{color:#636469;cursor:initial;}
#simp .simp-controls button:not([disabled]):hover{background:#4082bc;color:#fff;}
#simp .simp-controls .simp-prev,#simp .simp-controls .simp-next{font-size:100%;}
#simp .simp-controls .simp-tracker,#simp .simp-controls .simp-volume{flex:1;margin-left:10px;position:relative;}
#simp .simp-controls .simp-buffer {position:absolute;top:50%;right:0;left:0;height:5px;margin-top:-2.5px;border-radius:100px;}
#simp .simp-controls .simp-loading .simp-buffer {-webkit-animation:audio-progress 1s linear infinite;animation:audio-progress 1s linear infinite;background-image: linear-gradient(-45deg, #000 25%, transparent 25%, transparent 50%, #000 50%, #000 75%, transparent 75%, transparent);background-repeat:repeat-x;background-size:25px 25px;color:transparent;}
#simp .simp-controls .simp-time,#simp .simp-controls .simp-others{margin-left:10px;}
#simp .simp-controls .simp-volume{max-width:110px;}
#simp .simp-controls .simp-volume .simp-mute{margin-right:5px;}
#simp .simp-controls .simp-others .simp-active{background:#242f3d;}
#simp .simp-controls .simp-others .simp-shide button{font-size:100%;padding:0;width:24px;height:14px;display:block;}
#simp .simp-controls input[type=range]{-webkit-appearance:none;background:transparent;height:19px;margin:0;width:100%;display:block;position:relative;z-index:2;}
#simp .simp-controls input[type=range]::-webkit-slider-runnable-track{background:rgba(183,197,205,.66);height:5px;border-radius:2.5px;transition:box-shadow .3s ease;position:relative;}
#simp .simp-controls input[type=range]::-moz-range-track{background:rgba(183,197,205,.66);height:5px;border-radius:2.5px;transition:box-shadow .3s ease;position:relative;}
#simp .simp-controls .simp-load .simp-progress::-webkit-slider-runnable-track{background:#2f3841;}
#simp .simp-controls .simp-load .simp-progress::-moz-range-track{background:#2f3841;}
#simp .simp-controls .simp-loading .simp-progress::-webkit-slider-runnable-track{background:rgba(255,255,255,.25);}
#simp .simp-controls .simp-loading .simp-progress::-moz-range-track{background:rgba(255,255,255,.25);}
#simp .simp-controls input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:#fff;height:13px;width:13px;margin-top:-4px;cursor:pointer;border-radius:50%;box-shadow:0 1px 1px rgba(0,0,0,.15), 0 0 0 1px rgba(47,52,61,.2);}
#simp .simp-controls input[type=range]::-moz-range-thumb{-webkit-appearance:none;background:#fff;height:13px;width:13px;cursor:pointer;border-radius:50%;box-shadow:0 1px 1px rgba(0,0,0,.15), 0 0 0 1px rgba(47,52,61,.2);}
#simp .simp-footer{padding:10px 10px 12px;font-size:90%;text-align:center;opacity:.7;}
#simp .simp-display{overflow:hidden;max-height:650px;transition:max-height .5s ease-in-out;}
#simp .simp-hide{max-height:0;}
/* playlist */
#simp ul{margin:5px 0 0;padding:0;list-style:none;max-height:245px;}
#simp ul li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;margin:0;padding:8px 20px;cursor:pointer;}
#simp ul li:last-child{padding-bottom:13px;}
#simp ul li:nth-child(odd){background:#0e1621;}
#simp ul li:hover{background:#242f3d;}
#simp ul li.simp-active{background:#4082bc;color:#fff;}
#simp ul li .simp-desc{font-size:90%;opacity:.5;margin-left:5px;}
/* playlist scrollbar */
#simp ul{overflow-y:auto;overflow-x:hidden;scrollbar-color:#73797f #2f3841;}
#simp ul::-webkit-scrollbar-track{background-color:#2f3841;}
#simp ul::-webkit-scrollbar{width:6px;background-color:#2f3841;}
#simp ul::-webkit-scrollbar-thumb{background-color:#73797f;}
/* progress animation */
@-webkit-keyframes audio-progress{to{background-position:25px 0;}}
@keyframes audio-progress{to{background-position:25px 0;}}
/* mobile */
@media screen and (max-width:480px) {
#simp .simp-controls .simp-volume,#simp .simp-controls .simp-others{display:none;}
#simp .simp-controls .simp-time{margin-right:10px;}
}
@media screen and (max-width:370px) {
#simp .simp-time .simp-slash,#simp .simp-time .end-time{display:none;}
}

3. In the final step you need to include the JavaScript code in your project in order to functionalize the audio player. So, copy the following audio player’s JavaScript code and paste it between the <script> tag and place it before closing the body tag. You can also create a separate JS file and include it in your project.

/*
Example: https://www.codehim.com/demo/javascript-audio-player-with-playlist/
*/
// Multiple events to a listener
function addEventListener_multi(element, eventNames, handler) {
  var events = eventNames.split(' ');
  events.forEach(e => element.addEventListener(e, handler, false));
}

// Random numbers in a specific range
function getRandom(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Position element inside element
function getRelativePos(elm) {
  var pPos = elm.parentNode.getBoundingClientRect(); // parent pos
  var cPos = elm.getBoundingClientRect(); // target pos
  var pos = {};

  pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop,
  pos.right  = cPos.right  - pPos.right,
  pos.bottom = cPos.bottom - pPos.bottom,
  pos.left   = cPos.left   - pPos.left;

  return pos;
}

function formatTime(val) {
  var h = 0, m = 0, s;
  val = parseInt(val, 10);
  if (val > 60 * 60) {
   h = parseInt(val / (60 * 60), 10);
   val -= h * 60 * 60;
  }
  if (val > 60) {
   m = parseInt(val / 60, 10);
   val -= m * 60;
  }
  s = val;
  val = (h > 0)? h + ':' : '';
  val += (m > 0)? ((m < 10 && h > 0)? '0' : '') + m + ':' : '0:';
  val += ((s < 10)? '0' : '') + s;
  return val;
}

function simp_initTime() {
  simp_controls.querySelector('.start-time').innerHTML = formatTime(simp_audio.currentTime); //calculate current value time
  if (!simp_isStream) {
    simp_controls.querySelector('.end-time').innerHTML = formatTime(simp_audio.duration); //calculate total value time
    simp_progress.value = simp_audio.currentTime / simp_audio.duration * 100; //progress bar
  }
  
  // ended of the audio
  if (simp_audio.currentTime == simp_audio.duration) {
    simp_controls.querySelector('.simp-plause').classList.remove('fa-pause');
    simp_controls.querySelector('.simp-plause').classList.add('fa-play');
    simp_audio.removeEventListener('timeupdate', simp_initTime);
    
    if (simp_isNext) { //auto load next audio
      var elem;
      simp_a_index++;
      if (simp_a_index == simp_a_url.length) { //repeat all audio
        simp_a_index = 0;
        elem = simp_a_url[0];
      } else {
        elem = simp_a_url[simp_a_index];  
      }
      simp_changeAudio(elem);
      simp_setAlbum(simp_a_index);
    } else {
      simp_isPlaying = false;
    }
  }
}

function simp_initAudio() {
  // if readyState more than 2, audio file has loaded
	simp_isLoaded = simp_audio.readyState == 4 ? true : false;
  simp_isStream = simp_audio.duration == 'Infinity' ? true : false;
  simp_controls.querySelector('.simp-plause').disabled = false;
  simp_progress.disabled = simp_isStream ? true : false;
  if (!simp_isStream) {
    simp_progress.parentNode.classList.remove('simp-load','simp-loading');
    simp_controls.querySelector('.end-time').innerHTML = formatTime(simp_audio.duration);
  }
  simp_audio.addEventListener('timeupdate', simp_initTime); //tracking load progress
  if (simp_isLoaded && simp_isPlaying) simp_audio.play();
  
  // progress bar click event
  addEventListener_multi(simp_progress, 'touchstart mousedown', function(e) {
    if (simp_isStream) {
      e.stopPropagation();
      return false;
    }
    if (simp_audio.readyState == 4) {
      simp_audio.removeEventListener('timeupdate', simp_initTime);
      simp_audio.pause();
    }
  });
  
  addEventListener_multi(simp_progress, 'touchend mouseup', function(e) {
    if (simp_isStream) {
      e.stopPropagation();
      return false;
    }
    if (simp_audio.readyState == 4) {
      simp_audio.currentTime = simp_progress.value * simp_audio.duration / 100;
      simp_audio.addEventListener('timeupdate', simp_initTime);
      if (simp_isPlaying) simp_audio.play();
    }
  });
}

function simp_loadAudio(elem) {
  simp_progress.parentNode.classList.add('simp-loading');
  simp_controls.querySelector('.simp-plause').disabled = true;
  simp_audio.querySelector('source').src = elem.dataset.src;
  simp_audio.load();
  
  simp_audio.volume = parseFloat(simp_v_num / 100); //based on valume input value
  simp_audio.addEventListener('canplaythrough', simp_initAudio); //play audio without stop for buffering
  
  // if audio fails to load, only IE/Edge 9.0 or above
  simp_audio.addEventListener('error', function() {
    alert('Please reload the page.');
  });
}

function simp_setAlbum(index) {
  simp_cover.innerHTML = simp_a_url[index].dataset.cover ? '<div style="background:url(' + simp_a_url[index].dataset.cover + ') no-repeat;background-size:cover;width:80px;height:80px;"></div>' : '<i class="fa fa-music fa-5x"></i>';
  simp_title.innerHTML = simp_source[index].querySelector('.simp-source').innerHTML;
  simp_artist.innerHTML = simp_source[index].querySelector('.simp-desc') ? simp_source[index].querySelector('.simp-desc').innerHTML : '';
}

function simp_changeAudio(elem) {
	simp_isLoaded = false;
  simp_controls.querySelector('.simp-prev').disabled = simp_a_index == 0 ? true : false;
  simp_controls.querySelector('.simp-plause').disabled = simp_auto_load ? true : false;
  simp_controls.querySelector('.simp-next').disabled = simp_a_index == simp_a_url.length-1 ? true : false;
  simp_progress.parentNode.classList.add('simp-load');
  simp_progress.disabled = true;
  simp_progress.value = 0;
  simp_controls.querySelector('.start-time').innerHTML = '00:00';
  simp_controls.querySelector('.end-time').innerHTML = '00:00';
  elem = simp_isRandom && simp_isNext ? simp_a_url[getRandom(0, simp_a_url.length-1)] : elem;
  
  // playlist, audio is running
  for (var i = 0; i < simp_a_url.length; i++) {
    simp_a_url[i].parentNode.classList.remove('simp-active');
    if (simp_a_url[i] == elem) {
      simp_a_index = i;
      simp_a_url[i].parentNode.classList.add('simp-active');
    }
  }
  
  // scrolling to element inside element
  var simp_active = getRelativePos(simp_source[simp_a_index]);
  simp_source[simp_a_index].parentNode.scrollTop = simp_active.top;
  
  if (simp_auto_load || simp_isPlaying) simp_loadAudio(elem);
  
  if (simp_isPlaying) {
    simp_controls.querySelector('.simp-plause').classList.remove('fa-play');
    simp_controls.querySelector('.simp-plause').classList.add('fa-pause');
  }
}

function simp_startScript() {
  ap_simp = document.querySelector('#simp');
  simp_audio = ap_simp.querySelector('#audio');
  simp_album = ap_simp.querySelector('.simp-album');
  simp_cover = simp_album.querySelector('.simp-cover');
  simp_title = simp_album.querySelector('.simp-title');
  simp_artist = simp_album.querySelector('.simp-artist');
  simp_controls = ap_simp.querySelector('.simp-controls');
  simp_progress = simp_controls.querySelector('.simp-progress');
  simp_volume = simp_controls.querySelector('.simp-volume');
  simp_v_slider = simp_volume.querySelector('.simp-v-slider');
  simp_v_num = simp_v_slider.value; //default volume
  simp_others = simp_controls.querySelector('.simp-others');
  simp_auto_load = simp_config.auto_load; //auto load audio file
  
  if (simp_config.shide_top) simp_album.parentNode.classList.toggle('simp-hide');
  if (simp_config.shide_btm) {
    simp_playlist.classList.add('simp-display');
    simp_playlist.classList.toggle('simp-hide');
  }
  
  if (simp_a_url.length <= 1) {
    simp_controls.querySelector('.simp-prev').style.display = 'none';
    simp_controls.querySelector('.simp-next').style.display = 'none';
    simp_others.querySelector('.simp-plext').style.display = 'none';
    simp_others.querySelector('.simp-random').style.display = 'none';
  }

  // Playlist listeners
  simp_source.forEach(function(item, index) {
    if (item.classList.contains('simp-active')) simp_a_index = index; //playlist contains '.simp-active'
    item.addEventListener('click', function() {
      simp_audio.removeEventListener('timeupdate', simp_initTime);
      simp_a_index = index;
      simp_changeAudio(this.querySelector('.simp-source'));
      simp_setAlbum(simp_a_index);
    });
  });
  
  // FIRST AUDIO LOAD =======
  simp_changeAudio(simp_a_url[simp_a_index]);
  simp_setAlbum(simp_a_index);
  // FIRST AUDIO LOAD =======
  
  // Controls listeners
  simp_controls.querySelector('.simp-plauseward').addEventListener('click', function(e) {
    var eles = e.target.classList;
    if (eles.contains('simp-plause')) {
      if (simp_audio.paused) {
        if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]);
        simp_audio.play();
        simp_isPlaying = true;
        eles.remove('fa-play');
        eles.add('fa-pause');
      } else {
        simp_audio.pause();
        simp_isPlaying = false;
        eles.remove('fa-pause');
        eles.add('fa-play');
      }
    } else {
      if (eles.contains('simp-prev') && simp_a_index != 0) {
        simp_a_index = simp_a_index-1;
        e.target.disabled = simp_a_index == 0 ? true : false;
      } else if (eles.contains('simp-next') && simp_a_index != simp_a_url.length-1) {
        simp_a_index = simp_a_index+1;
        e.target.disabled = simp_a_index == simp_a_url.length-1 ? true : false;
      }
      simp_audio.removeEventListener('timeupdate', simp_initTime);
      simp_changeAudio(simp_a_url[simp_a_index]);
      simp_setAlbum(simp_a_index);
    }
  });
  
  // Audio volume
  simp_volume.addEventListener('click', function(e) {
    var eles = e.target.classList;
    if (eles.contains('simp-mute')) {
      if (eles.contains('fa-volume-up')) {
        eles.remove('fa-volume-up');
        eles.add('fa-volume-off');
        simp_v_slider.value = 0;
      } else {
        eles.remove('fa-volume-off');
        eles.add('fa-volume-up');
        simp_v_slider.value = simp_v_num;
      }
    } else {
      simp_v_num = simp_v_slider.value;
      if (simp_v_num != 0) {
        simp_controls.querySelector('.simp-mute').classList.remove('fa-volume-off');
        simp_controls.querySelector('.simp-mute').classList.add('fa-volume-up');
      }
    }
    simp_audio.volume = parseFloat(simp_v_slider.value / 100);
  });
  
  // Others
  simp_others.addEventListener('click', function(e) {
    var eles = e.target.classList;
    if (eles.contains('simp-plext')) {
      simp_isNext = simp_isNext && !simp_isRandom ? false : true;
      if (!simp_isRandom) simp_isRanext = simp_isRanext ? false : true;
      eles.contains('simp-active') && !simp_isRandom ? eles.remove('simp-active') : eles.add('simp-active');
    } else if (eles.contains('simp-random')) {
      simp_isRandom = simp_isRandom ? false : true;
      if (simp_isNext && !simp_isRanext) {
        simp_isNext = false;
        simp_others.querySelector('.simp-plext').classList.remove('simp-active');
      } else {
        simp_isNext = true;
        simp_others.querySelector('.simp-plext').classList.add('simp-active');
      }
      eles.contains('simp-active') ? eles.remove('simp-active') : eles.add('simp-active');
    } else if (eles.contains('simp-shide-top')) {
      simp_album.parentNode.classList.toggle('simp-hide');
    } else if (eles.contains('simp-shide-bottom')) {
      simp_playlist.classList.add('simp-display');
      simp_playlist.classList.toggle('simp-hide');
    }
  });
}

// Start simple player
if (document.querySelector('#simp')) {
  var simp_auto_load, simp_audio, simp_album, simp_cover, simp_title, simp_artist, simp_controls, simp_progress, simp_volume, simp_v_slider, simp_v_num, simp_others;
  var ap_simp = document.querySelector('#simp');
  var simp_playlist = ap_simp.querySelector('.simp-playlist');
  var simp_source = simp_playlist.querySelectorAll('li');
  var simp_a_url = simp_playlist.querySelectorAll('[data-src]');
  var simp_a_index = 0;
  var simp_isPlaying = false;
  var simp_isNext = false; //auto play
  var simp_isRandom = false; //play random
  var simp_isRanext = false; //check if before random starts, simp_isNext value is true
  var simp_isStream = false; //radio streaming
  var simp_isLoaded = false; //audio file has loaded
  var simp_config = ap_simp.dataset.config ? JSON.parse(ap_simp.dataset.config) : {
    shide_top: false, //show/hide album
    shide_btm: false, //show/hide playlist
    auto_load: false //auto load audio file
  };
  
  var simp_elem = '';
  simp_elem += '<audio id="audio" preload><source src="" type="audio/mpeg"></audio>';
  simp_elem += '<div class="simp-display"><div class="simp-album w-full flex-wrap"><div class="simp-cover"><i class="fa fa-music fa-5x"></i></div><div class="simp-info"><div class="simp-title">Title</div><div class="simp-artist">Artist</div></div></div></div>';
  simp_elem += '<div class="simp-controls flex-wrap flex-align">';
  simp_elem += '<div class="simp-plauseward flex flex-align"><button type="button" class="simp-prev fa fa-backward" disabled></button><button type="button" class="simp-plause fa fa-play" disabled></button><button type="button" class="simp-next fa fa-forward" disabled></button></div>';
  simp_elem += '<div class="simp-tracker simp-load"><input class="simp-progress" type="range" min="0" max="100" value="0" disabled/><div class="simp-buffer"></div></div>';
  simp_elem += '<div class="simp-time flex flex-align"><span class="start-time">00:00</span><span class="simp-slash"> / </span><span class="end-time">00:00</span></div>';
  simp_elem += '<div class="simp-volume flex flex-align"><button type="button" class="simp-mute fa fa-volume-up"></button><input class="simp-v-slider" type="range" min="0" max="100" value="100"/></div>';
  simp_elem += '<div class="simp-others flex flex-align"><button type="button" class="simp-plext fa fa-play-circle" title="Auto Play"></button><button type="button" class="simp-random fa fa-random" title="Random"></button><div class="simp-shide"><button type="button" class="simp-shide-top fa fa-caret-up" title="Show/Hide Album"></button><button type="button" class="simp-shide-bottom fa fa-caret-down" title="Show/Hide Playlist"></button></div></div>';
  simp_elem += '</div>'; //simp-controls
  
  var simp_player = document.createElement('div');
  simp_player.classList.add('simp-player');
  simp_player.innerHTML = simp_elem;
  ap_simp.insertBefore(simp_player, simp_playlist);
  simp_startScript();
}

That’s all! hopefully, you have successfully integrated this audio player into your website project. If you have any questions or facing any issues, feel free to comment below.

42 thoughts on “JavaScript Audio Player with Playlist”

  1. Without ANY doubt the easiest and yet beautiful HTML/JS/Css media player out there (And I’ve tried many!).
    Thanks a million for this!
    Best

    Sony

    Reply
  2. It’s a beatifully interface and codes.
    But one question how can i let it always auto play the next song after loading the page.

    Reply
    • Hi Peter!
      Thanks for your feedback! you can enable autoplay next song by passing the true value in its config options.

      <div class="simple-audio-player" id="simp" data-config='{"shide_top":false,"shide_btm":false,"auto_load":true}'>
      .
      .
      .
      .
      .
      
      </div>
      
      Reply
    • Hi Anhlevan!
      You’re welcome. Please make sure Font Awesome CSS loaded on your webpage. Check console errors by pressing ctr+Shift+i to open chrome dev tools and check console tab. Alternatively, you can load the Font Awesome CSS by adding the following CDN link into the head tag of your webpage.

      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha512-SfTiTlX6kk+qitfevl/7LibUOeJWlt9rbyDn92a1DqWOw9vWG2MFoays0sgObmWazO5BQPiFucnnEAjpAB+/Sw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
      

      It’s 4.7 version, you can browse other versions below:
      https://cdnjs.com/libraries/font-awesome/

      Reply
      • Many thanks for your detailed instructions.
        Please help me with the code that makes the playing line go to the top of the play list, thanks. If you can visit “https://musicanhlevan.blogspot.com/p/nhac-mp3-nuoc-ngoai.html” and give your opinion

  3. A good and elegant tutorial.May I ask a question?How to play the song automatically when I click the song in the list at the first time without pressing the play button.

    Reply
  4. I have just installed this code of yours in my blog. Getting very good response. But one problem is coming that since I installed it, the fonts of my blog are becoming invisible. The address of my blog is as follows: bhojpurimp3.blogspot.com
    how to fix it

    Reply
    • Hi Akhliesh!

      The links color used in the player’s CSS globally effected the blog’s links, that’s why your anchor text became invisible. To solve this, just add the player’s id before the “a” selector. Find the following line:

      a,a:hover,a:visited{color:#ddd;text-decoration:none;}
      

      and replace with the following:

      #simp,
      #simp a:hover,
      #simp a:visited{color:#ddd;text-decoration:none;}
      
      Reply
  5. Thank you very much. You gave very good response. Now it is working fine. One more thing is that above you have given option to play next song but it is not working for me. Also, on randomizing, the same song comes many times. Whereas I want him to play one song after another. I want to lengthen the player so that the list of all the songs in it is shown together. That means full player view. Play option is visible in mobile but random option is not visible.

    Reply
  6. Hi Asif,
    thank you so much. i’m trying to implement it on my website and I have a question relative to auto_play configuration.
    You mentioned to set up “auto_load”:true in the data_config section. When doing that, it doesn’t work properly on my website. It stays not activated. Did I miss something ?

    Reply
    • Hi Vincent!

      You’re welcome, please make sure you are not adding any invalid character instead of quotations. Press ctr+shift+i to open Chrome Dev Tools and check the console errors. You can detect the error if something went wrong with your configurations.

      Hopefully, it will help you to figure out the error.

      Reply
  7. Thanks a lot for your answer.
    Looking at the console I got this error message : Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received.
    Have you any idea about what it is ?

    Reply
  8. Hi

    Thanks so much for this, excellent player with playlist, I’ve been looking for years for something this good.

    One question, is it possible to configure the player to play a track when clicked rather than having to hit the play button?

    Reply
  9. This is great! Exactly what I was looking for! The only thing I can’t figure out, is how to get the Album Cover to show. When I use data-cover= the div is just a black background.

    Reply
  10. Hi Asif,

    thank you for this player !
    Just one question : i don’t find how to replace the logo with a real image over.
    I suppose i have to modify the html code but…

    Thanks you very much for your help,
    Dominique

    Reply
  11. Thank you very much for your great work. It’s the first player witch is running with my small coding-knowledge.
    One question.
    “auto_load”:true is not working for me, but “shide_top”:true is working – any idea?

    Reply
  12. Hi Asif, thank you for this very good media player, i use at home for my mp3s. It is really easy o install and its working fine. I have only one problem: there is no display of the cover, when i use spaces in the data-cover URL, also no display when i substitute them with %20. Do you have a hint for me? Best regards from Germany
    Uwe

    Reply
  13. Hi thank a lots for his beautiful player! I want to change the logo at the top(quarter note) to put my album image instead, how can i do this? i don’t find…Thank you

    Reply
  14. This is a brilliant little player you’ve made.
    Now unfortunately I’m not particularly technical, so I was just wondering if you could please let me know how to pass a number of parameters to the player?
    To tell the player:
    @ to start at track N when it loads (and maybe 0 if it’s not to start playing)
    @ when it finishes a track to automatically go onto the next track
    @ to set its volume at N
    @ any other parameters which would be easy to set and which you think might be useful.
    I would be most grateful for any help you can give me and I will, of course, buy you at least a coffee!
    Cheers,
    Philip

    Reply
  15. Is it possible to play the song automatically when I click the song in the list at the first time without pressing the play button? And thanks for this wonderful player!!

    Reply
  16. Hi, I really love your audio player, very easy to use and customize, thank you very much!

    I wish there was a way to change the cover image and replace it with a thumbnail of the song instead of the fa icon is there a way to do that that I didn’t figure out?

    Thank you again, great work.

    Reply
  17. I’ve been troubleshooting an issue where the player wouldn’t advance to the next track. I found that .currentTime could in some cases (on some devices) get higher than .duration.
    I changed this:

    if (simp_audio.currentTime == simp_audio.duration) {

    to this:

    if (simp_audio.currentTime >= simp_audio.duration) {

    And now it works without a hitch.

    Reply
  18. The links color used in the player’s CSS globally effected the blog’s links,
    i replaced the hover line in style as per your advice,my problem solved
    thanks a lot.
    kindly make a change to start the player as page loads.
    kindly provide a coding to upgrade the player
    Tarlok Singh

    Reply
    • Hi Tarlok,

      You can update the config option to automatically load the selected audio on page loads. Here is the example:

      <div class="simple-audio-player" id="simp" data-config='{"shide_top":false,"shide_btm":false,"auto_load":true}'>
      .
      .
      .
      .
      .
      
      </div>
      
      Reply
  19. Thanks so much for providing the code. I was able to set up my own version of iTunes on my local network using your template. Your code example was by far the best fit for my needs and your walk-through was intuitive. I included my edit of your code as my website for your page. I added you as one of the main contributors to the project.

    Reply
  20. Hi, Asif! Really enjoy your player, thank you for sharing!

    I’ve two issues/questions.
    1)Is it possible to add preload metadata function?
    2)Is it possible to have audio playback active on mobile lock screen? Atm it’s turning off when screen gets locked.

    Best wishes!

    Reply
    • Hey there! Thanks a bunch for your message and I’m thrilled you’re enjoying the player!

      So, you’ve got a couple of things on your mind, right?

      Adding a preload metadata function sounds like a cool idea! Let me check into that and see how we can make it work.

      Ah, the mobile lock screen issue with audio playback – totally get why that could be a bit of a hassle. I’ll dive into it and see if there’s a way to keep that music going even when your screen takes a nap.

      Reply
  21. Hi, this player is amazing but I’m not able to customize it as I’d need:
    I’m unable to set the auto_load function as default, setting “auto_load”:true or simp_audio.currentTime >= simp_audio.duration does not work.

    Another cool thing would be play a song automatically when clicked in the list

    Great player anyway
    Greetings from Italy

    Reply
    • Hi Alessandro,

      Thank you for your feedback! We’re pleased to inform you that the updated version of the player will indeed include the autoplay feature when a song is clicked in the playlist. We appreciate your patience and hope this enhancement further elevates your experience with the player.

      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...