Simple HTML Custom Audio Player (Step-By-Step Example)

Welcome to a quick tutorial and example on how to create an HTML custom audio player. Want to create your own custom player using HTML audio? Well, it’s quite a tricky situation.

There is no way to change the browser’s default HTML <audio> interface, but we can create our own custom audio player using Javascript:

  • Create a new audio object – var aud = new Audio("AUDIO.mp3");
  • To play and pause – aud.play(); aud.pause();
  • To set the volume – aud.volume = 0.0 TO 1.0;
  • Lastly, to skip to a specified time – aud.currentTime = SECONDS;

That covers the basic idea, but read on for an actual example!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Custom Player Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

  • No audio files are provided in the zip, please download your own.
  • Change new Audio("AUDIO.MP3") in aud-player.js to your own.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

CUSTOM AUDIO PLAYER

All right, let us now get into the step-by-step example of creating a custom audio player. Take note, there is no CSS involved here, only the pure mechanics.

 

STEP 1) THE HTML

aud-player.html
<!-- (A) CSS & JS -->
<!-- https://fonts.google.com/icons -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="aud-player.css"/>
<script defer src="aud-player.js"></script>
 
<div id="aWrap">
  <!-- (B) PLAY/PAUSE BUTTON -->
  <button id="aPlay" disabled><span id="aPlayIco" class="material-icons">
    play_arrow
  </span></button>
 
  <!-- (C) TIME -->
  <div id="aCron">
    <span id="aNow"></span> / <span id="aTime"></span>
  </div>
 
  <!-- (D) SEEK BAR -->
  <input id="aSeek" type="range" min="0" value="0" step="1" disabled/>

  <!-- (E) VOLUME SLIDE -->
  <span id="aVolIco" class="material-icons">volume_up</span>
  <input id="aVolume" type="range" min="0" max="1" value="1" step="0.1" disabled/>
</div>

There’s quite a bit of HTML, but it should be self-explanatory. There are only 4 sets of HTML controls here.

  • (B) <button id="aPlay"> The play/pause button.
  • (C) <span id="aNow"> is the current playtime of the track, <span id="aTime"> is the total time of the track.
  • (D) <input id="aSeek"> Time seek slider, the value is in seconds.
  • (E) <input id="aVolume"> Volume slider. As in the introduction, this is a value from 0.0 (muted) to 1.0 (full volume).

 

 

STEP 2) INITIALIZE AUDIO PLAYER

aud-player.js
window.addEventListener("load", () => {
  // (A) AUDIO OBJECT + HTML CONTROLS
  var audio = new Audio("sugar-palm-fairy.mp3"), // change to your own!
      aPlay = document.getElementById("aPlay"),
      aNow = document.getElementById("aNow"),
      aTime = document.getElementById("aTime"),
      aSeek = document.getElementById("aSeek"),
      aVolume = document.getElementById("aVolume");
});
  • Captain Obvious to the rescue. To prevent things from screwing up, we wait for the page to load DOMContentLoaded before initializing the Javascript.
  • Create the new Audio() and fetch all the HTML controls.

 

STEP 3) PLAY/PAUSE BUTTON

aud-player.js
// (B) PLAY & PAUSE
// (B1) CLICK TO PLAY/PAUSE
aPlay.onclick = () => {
  if (audio.paused) { audio.play(); }
  else { audio.pause(); }
});
 
// (B2) SET PLAY/PAUSE ICON
audio.onplay = () => { aPlayIco.innerHTML = "pause"; };
audio.onpause = () => { aPlayIco.innerHTML = "play_arrow"; };
  • (B1) Don’t think this needs any explanation… If the audio is paused, we click to play. If the audio is playing, we click to pause.
  • (B2) Automatically set the play/pause icon on the button.

 

 

STEP 4) TIME FORMAT

aud-player.js
// (C) TRACK PROGRESS
// (C1) SUPPORT FUNCTION - FORMAT HH:MM:SS
var timeString = (secs) => {
  // HOURS, MINUTES, SECONDS
  let ss = Math.floor(secs),
      hh = Math.floor(ss / 3600),
      mm = Math.floor((ss - (hh * 3600)) / 60);
  ss = ss - (hh * 3600) - (mm * 60);
 
  // RETURN FORMATTED TIME
  if (hh>0) { mm = mm<10 ? "0"+mm : mm; }
  ss = ss<10 ? "0"+ss : ss;
  return hh>0 ? `${hh}:${mm}:${ss}` : `${mm}:${ss}` ;
};

For the following step, we will be dealing with the track time and seek bar… But before that, there are no native Javascript functions to format the time into a nice hh:mm:ss format, so here is a simple one.

 

STEP 5) TRACK TIME

aud-player.js
// (C2) TRACK LOADING
audio.onloadstart = () => {
  aNow.innerHTML = "Loading";
  aTime.innerHTML = "";
};
 
// (C3) ON META LOADED
audio.onloadedmetadata = () => {
  // (C3-1) INIT SET TRACK TIME
  aNow.innerHTML = timeString(0);
  aTime.innerHTML = timeString(audio.duration);
 
  // (C3-2) SET SEEK BAR MAX TIME
  aSeek.max = Math.floor(audio.duration);
 
  // (C3-3) USER CHANGE SEEK BAR TIME
  var aSeeking = false; // user is now changing time
  aSeek.oninput = () => { aSeeking = true; }; // prevents clash with (c3-4)
  aSeek.onchange = () => {
    audio.currentTime = aSeek.value;
    if (!audio.paused) { audio.play(); }
    aSeeking = false;
  };
 
  // (C3-4) UPDATE SEEK BAR ON PLAYING
  audio.ontimeupdate = () => {
    if (!aSeeking) { aSeek.value = Math.floor(audio.currentTime); }
  };
};
  • (C2) Set a “now loading” message in the track time while the track is loading.
  • (C3) On metadata loaded (information on the track), a whole load of things needs to be done. Not going to explain line-by-line, but basically:
    • (C3-1) Set the HTML track time.
    • (C3-2) Also set the track time on the seek bar.
    • (C3-3 To C3-4) Update the track when the seek bar is being dragged. Take note of how we use the aSeeking flag here – We do not want the manual seek to clash with the auto-update as the track is playing.
    • (C3-4) Automatically update the HTML seek bar as the track plays.

 

 

STEP 6) VOLUME CONTROL

aud-player.js
// (D) VOLUME
aVolume.onchange = () => {
  audio.volume = aVolume.value;
  aVolIco.innerHTML = (aVolume.value==0 ? "volume_mute" : "volume_up");
};

Well… Just update the audio.volume as the user moves the slider.

 

STEP 7) ENABLE/DISABLE CONTROLS

aud-player.js
// (E) ENABLE/DISABLE CONTROLS
audio.oncanplaythrough = () => {
  aPlay.disabled = false;
  aVolume.disabled = false;
  aSeek.disabled = false;
});
audio.onwaiting = () => {
  aPlay.disabled = true;
  aVolume.disabled = true;
  aSeek.disabled = true;
});
  • canplaythrough When the browser has sufficient audio buffer to play through, we enable the controls.
  • waiting When there is an insufficient buffer, we disable the controls.

 

 

USEFUL BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

COMPATIBILITY CHECKS

This audio player is obviously not backward compatible with the ancient browsers. But it should work well across all “Grade A” modern browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “Simple HTML Custom Audio Player (Step-By-Step Example)”

Leave a Comment

Your email address will not be published.