Music player directly into the Browswer!
Published: 2020-04-07 18:36:29

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.

```html
<audio src="" id="audio"></audio>
```

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

```html
<input type="file" name="files" id="files" multiple accept="audio/*" />
```

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](https://dev-to-uploads.s3.amazonaws.com/i/yqfsgcjcaluh9xdt059u.png)


```html
<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>
```


___
# 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**
```javascript
let addBtn = document.getElementById('addBtn');
let removeBtn = document.getElementById('removeBtn');
let musicFiles = document.getElementById('files');
```



Then, we add a listener to each of them, with the correct Handler.
```javascript
addBtn.addEventListener('click', () => musicFiles.click());
```

We also have an handler for “change” event. 

It means that when a user uploades some files, we will work with them.
```javascript
musicFiles.addEventListener('change', getFiles);
```

As soon as a user uploaded his files we create an array with these files, modifying this variable
```javascript
let songs;
```
With this function

```javascript
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');
}
```
Next step, we add the first song to audio element.

```javascript
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');
}
```

```javascript
function loadSong(song) {
  title.innerText = song.name;
  audio.src = URL.createObjectURL(song);
}
```

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.

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

  if (isPlaying) {
    pauseSong();
  } else {
    playSong();
  }
});
```

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.

```javascript
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();
  }
}
```

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.

```javascript
audio.addEventListener('ended', repeatSongs);
```

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.
```javascript
prevBtn.addEventListener('click', prevSong);
nextBtn.addEventListener('click', nextSong);
```
Here is a final result working!
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7dfthmtv3p76qtkjny6t.png)

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