Music player directly into the Browswer!

Francesco Ciulla - Apr 7 '20 - - Dev Community

Hello, The content of this article is all by https://twitter.com/aniribe

The idea is to implement a simple, but working, audio player, which takes some files in input and reproduces them directly in the browser!

All code is available at:
GitHub link: https://github.com/aniribe/Music-player

ID3 Parser Link: https://github.com/aadsm/JavaScript-ID3-Reader


HTML

We use an empty audio element in with a src attribute.

The user will upload his own files.

<audio src="" id="audio"></audio>
Enter fullscreen mode Exit fullscreen mode

In order to let user upload some files, we can use input with some attributes:

  • type = "file" in order upload some
  • multiple: to upload multiple files at once
  • accept= audio/* to allow only audio files
<input type="file" name="files" id="files" multiple accept="audio/*" />
Enter fullscreen mode Exit fullscreen mode

We will hide this input, to show our custom buttons. Here is an example of the add button, used to upload the files. It automatically switches to delete button once the files are added.

Alt Text

<button class="btn add active" id="addBtn">
  <i class="fas fa-plus"></i>
</button>
<button class="btn remove " id="removeBtn">
  <i class="fas fa-minus"></i>
</button>
Enter fullscreen mode Exit fullscreen mode

JAVASCRIPT

Here we will briefly exaplin the logic of our application

At the top, we take a reference of the div element, by their id, using document.getElementByid

let addBtn = document.getElementById('addBtn');
let removeBtn = document.getElementById('removeBtn');
let musicFiles = document.getElementById('files');
Enter fullscreen mode Exit fullscreen mode

Then, we add a listener to each of them, with the correct Handler.

addBtn.addEventListener('click', () => musicFiles.click());
Enter fullscreen mode Exit fullscreen mode

We also have an handler for “change” event.

It means that when a user uploades some files, we will work with them.

musicFiles.addEventListener('change', getFiles);
Enter fullscreen mode Exit fullscreen mode

As soon as a user uploaded his files we create an array with these files, modifying this variable

let songs;
Enter fullscreen mode Exit fullscreen mode

With this function

function getFiles() {
  //get audio files
  songs = musicFiles.files;

  //upload to audio element
  loadSong(songs[songIndex]);

  //set visualizer
  if (!audioCtx) {
    setVisualizer(audio);
  }

  //parse ID3 tags for play list
  parseTags();

  //add classes
  addBtn.classList.toggle('active');
  removeBtn.classList.toggle('active');
  playBtn.classList.add('ready');
}
Enter fullscreen mode Exit fullscreen mode

Next step, we add the first song to audio element.

function getFiles() {
  //get audio files
  songs = musicFiles.files;

  //upload to audio element
  loadSong(songs[songIndex]);

  //set visualizer
  if (!audioCtx) {
    setVisualizer(audio);
  }

  //parse ID3 tags for play list
  parseTags();

  //add classes
  addBtn.classList.toggle('active');
  removeBtn.classList.toggle('active');
  playBtn.classList.add('ready');
}
Enter fullscreen mode Exit fullscreen mode
function loadSong(song) {
  title.innerText = song.name;
  audio.src = URL.createObjectURL(song);
}
Enter fullscreen mode Exit fullscreen mode

URL.createObjectURL() - is a static method provided by the URL Web API. Returns a DOMString containing a unique blob URL, that is a URL with blob: as its scheme, followed by an opaque string uniquely identifying the object in the browser. So when we invoke the function on the variable blob, we get back a persistent reference string with a unique URL that temporarily references to the in-memory blob object that lives in the Blob URL Store.

Play button logic – in the handler for click event I check if a song is playing or not.

playBtn.addEventListener('click', () => {
  let isPlaying = playBtn.classList.contains('active');

  if (isPlaying) {
    pauseSong();
  } else {
    playSong();
  }
});
Enter fullscreen mode Exit fullscreen mode

Playsong() method - I used play() method from Audio API. The play() method starts playing the current audio or video. The other code in my playSong() function is for styling.

function playSong() {
  playBtn.classList.remove('fa-play');
  playBtn.classList.remove('ready');
  playBtn.classList.add('fa-pause');
  playBtn.classList.add('active');

  if (songs) {
    let activeSong = playList.querySelector('li i.active');

    if (activeSong) {
      activeSong.classList.remove('active');
    }

    playList.querySelector(`#li${songIndex} i`).classList.add('active');
    audio.play();
  }
}
Enter fullscreen mode Exit fullscreen mode

pauseSong() method – I used pause() method from Audio API.
The pause() method halts (pauses) the currently playing audio. The other code in my pauseSong () function is for styling.

Also we add eventListener for event “ended”.
Even “ended” returns whether the playback of the audio/video has ended or not.

audio.addEventListener('ended', repeatSongs);
Enter fullscreen mode Exit fullscreen mode

In this handler, we check if “loop” button or “random order” button is active, as further actions depend on this. If these buttons are not active, then the music player will stop working after the last song. If ‘loop’ button is active then the music player will play until somebody stops it. If “random order” is active (without “loop” button) then all songs will be played in random order and after the last song it will be stopped.

Finally, Next button and Prev button, have the ordinary logic.

prevBtn.addEventListener('click', prevSong);
nextBtn.addEventListener('click', nextSong);
Enter fullscreen mode Exit fullscreen mode

Here is a final result working!
Alt Text

For further explanations, you can check the GitHub Repository

GitHub link: https://github.com/aniribe/Music-player

ID3 Parser Link: https://github.com/aadsm/JavaScript-ID3-Reader

All contents by https://twitter.com/aniribe

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .