Is there a way to repeat, shuffle and seek audio player

I am having trouble working with audio player which involves repeat of song, shuffle, player seek and also volume seek.

If anyone could would really appreciate it…

The code is here: Vue (forked) - StackBlitz

Hi @damonsta
I was able to complete the working of suffle functionality,
you need to do some changes in shuffle method and in the shuffle buttons

<template>
  <div>
    <img :src="current.image" alt="" class="artWork" />
    <h2>
      {{ current.title }} - <span>{{ current.artist }}</span>
    </h2>
  </div>
  <br />
  <div>
    <button @click="prev">Prev</button>
    <button @click="play" v-if="!isPlaying">Play</button>
    <button @click="pause" v-else>Pause</button>
    <button @click="next">Next</button>
    <button @click="shuffle" v-if="!isShuffle">Shuffle</button>
    <button @click="shuffle" v-else>Un Shuffle</button>
  </div>
  <br />
  <div>
    <button @click="repeat" v-if="isRepeat">Repeat</button>
    <button @click="repeat" v-else>Un Repeat</button>
  </div>
  <section class="playlist">
    <h3>The Playlist</h3>
    <button
      v-for="(song, index) in songs"
      :key="song.src"
      @click="switchSong(index)"
      :class="song.src == current.src ? 'song playing' : 'song'"
    >
      {{ song.title }} - {{ song.artist }}
    </button>
  </section>
  <br /><br />
  <div class="playbackBar">
    <span class="progressTime"
      >{{ formatTime(player.currentTime || 0) }}/{{
        formatTime(player.duration || 0)
      }}</span
    >

    <div class="progressBar">
      <div class="progressBarBg">
        <div
          @mousedown="seeking"
          @mouseup="seeking"
          :style="'width:' + progress + '%'"
          class="progress"
        ></div>
      </div>
    </div>
    <br />
    <!-- Volume SeekBar -->
    <div @click="volumeBar" class="progressBar">
      <div
        @click="volumeBar"
        ref="volBar"
        class="progressBarBg"
        v-if="!userSeeking"
      >
        <div
          @click="volumeBar"
          :style="'width:' + progressVolume + '%'"
          v-if="!userSeeking"
          class="progressVolume"
        ></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

function formatTime(time: number) {
  const m = 60;
  const s = 1;
  const mod_m = time % m;
  const mod_s = mod_m % s;
  const mm = ((time - mod_m) / m).toFixed(0).padStart(2, '0');
  const ss = ((mod_m - mod_s) / s).toFixed(0).padStart(2, '0');
  return `${mm}:${ss}`;
}

export default defineComponent({
  data() {
    return {
      index: 0,
      isPlaying: false,
      isRepeat: false,
      isShuffle: false,
      progress: 0,
      seeking: false,
      songs: [
        {
          title: 'Buga',
          artist: 'Kizz Daniel',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/05/Kizz-Daniel-Buga-ft.-Tekno.mp3',
          image: '/storage/images/buga.jpeg',
        },
        {
          title: 'Last Last',
          artist: 'Burna Boy',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/06/Harrysong-Meta.mp3',
          image: '/storage/images/last.jpeg',
        },
        {
          title: 'Once in a While',
          artist: 'OFB',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/03/Fireboy-DML-Playboy.mp3',
          image: '/storage/images/ofb.jpeg',
        },
        {
          title: 'Mean Mug',
          artist: '50 Cent (Feat. Soulja Boy)',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/04/Victony-Kolomental.mp3',
          image: '/storage/images/mean.jpeg',
        },
      ],
      defaultSongs: [
        {
          title: 'Buga',
          artist: 'Kizz Daniel',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/05/Kizz-Daniel-Buga-ft.-Tekno.mp3',
          image: '/storage/images/buga.jpeg',
        },
        {
          title: 'Last Last',
          artist: 'Burna Boy',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/06/Harrysong-Meta.mp3',
          image: '/storage/images/last.jpeg',
        },
        {
          title: 'Once in a While',
          artist: 'OFB',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/03/Fireboy-DML-Playboy.mp3',
          image: '/storage/images/ofb.jpeg',
        },
        {
          title: 'Mean Mug',
          artist: '50 Cent (Feat. Soulja Boy)',
          src: 'https://www.naijavibes.com/wp-content/uploads/2022/04/Victony-Kolomental.mp3',
          image: '/storage/images/mean.jpeg',
        },
      ],
      player: new Audio(),
    };
  },
  computed: {
    current() {
      return this.songs[this.index];
    },
  },
  mounted() {
    this.player.src = this.current.src;
    this.player.addEventListener('ended', this.onPlayerEnded);
    this.player.addEventListener('timeupdate', this.onPlayerTimeUpdate);
    this.player.addEventListener('seeking', this.onPlayerSeek);
  },
  destroyed() {
    this.player.removeEventListener('ended', this.onPlayerEnded);
    this.player.removeEventListener('timeupdate', this.onPlayerTimeUpdate);
  },
  methods: {
    formatTime,
    onPlayerEnded() {
      this.pause();
      this.next();
    },
    onPlayerSeek() {
      this.seeking = true;
    },
    onPlayerTimeUpdate() {
      this.progress = (this.player.currentTime / this.player.duration) * 100;
    },
    playNewSong() {
      this.player.src = this.current.src; // sync current.src to player.src
      this.play();
    },
    play() {
      if (!this.current) throw new Error('Play failed!');

      this.player
        .play()
        .then(() => {
          this.isPlaying = true;
        })
        .catch((error) => {
          this.isPlaying = false;
        });
    },
    pause() {
      this.player.pause();
      this.isPlaying = false;
    },
    next() {
      if (this.index == this.songs.length - 1) {
        this.index = 0;
      } else {
        this.index++;
      }
      this.playNewSong();
    },
    prev() {
      if (this.index == 0) {
        this.index = this.songs.length - 1;
      } else {
        this.index--;
      }
      this.playNewSong();
    },
    switchSong(index: number) {
      this.index = index;
      this.playNewSong();
    },
    shuffle() {
      this.player.shuffle = !this.player.shuffle;
      this.isShuffle = !this.isShuffle;
      if (this.player.shuffle == true) {
        this.shuffleArray(this.songs);
        this.current = this.songs[this.index];
        this.playNewSong();
      } else {
        this.songs = [];
        this.defaultSongs.forEach((song) => {
          this.songs.push(song);
        });
        this.playNewSong();
      }
    },
    shuffleArray(a) {
      var j, x, i;
      for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
      }
      return a;
    },
    repeat() {
      this.isRepeat = !this.isRepeat;
    },
  },
});
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.progressBar {
  width: 100%;
  height: 12px;
  display: inline-flex;
  cursor: pointer;
}

.progressBarBg {
  background-color: #404040;
  height: 4px;
  width: 100%;
  border-radius: 2px;
}

.progress {
  background-color: #a0a0a0;
  height: 4px;
  width: 0;
  border-radius: 2px;
}

.artWork {
  height: 100%;
  max-width: 57px;
  margin-right: 15px;
  float: left;
}
</style>

This is the src link for the code: Vue (forked) - StackBlitz
Hope this helps you.