Audio stream from CSV to Vue.js. Receiving data in the template is not bound and the current playback position of the next track is reset to zero

Viewed 18

I am trying to create Audio stream on Vue.

1 before DOM (rendering) get a list of tracks (url on google csv -> parsing -> output list of objects). Method getTracks()

2 select a track that is synchronized with the current time Datenow() and the range, i.e. Datenow() is in the range: [start: time_start, end: time_end] and get the time position from which the track playback starts position = Datenow() - time_start. Method setPlayerSource(). This track should be rendered in the DOM

3 each time play is pressed - there must be a constant synchronization of the current time with the track's playback range [start: time_start, end: time_end]

I get this data:

0: Object { time_start: "2022-09-15 00:00:00", time_end: "2022-09-15 00:32:12", duration: "0:32:12", cover: "https://pdcst.xyz/image/attachments/images/002/.png", episode: "something", file_link: "https://ysl.mp3", podcast: "something", podcast_link: "https://", pub_date: "August 10, 2022 18:01", publisher: "something"}

​​​ This is my code

<script>
import Papa from "papaparse";

const ggURL =
  "https://docs.google.com/spreadsheets/d/e/&output=csv";

export default {
  data() {
    return {
      player: new Audio(),
      currentTrackIndex: 0,
      tracks: [],
      muted: false,
      autoAdvance: true,
      isPlaying: false,
    };
  },
  methods: {
    getTracks() {
      try {
        Papa.parse(ggURL, {
          download: true,
          header: true,
          complete: (result) => {
            this.tracks.push(...result.data);
          },
        });
      } catch (error) {
        console.log(error);
      }
    },

    setPlayerSource() {
      let indexTrack = 0;
      let position;
      this.tracks.forEach(function (element, index) {
        let start = new Date(element?.time_start.split(" ").join("T"));
        let end = new Date(element?.time_end.split(" ").join("T"));
        let nowDate = new Date();

        if (nowDate > start && nowDate < end) {
          position = Math.floor((nowDate - start) * 0.001);
          indexTrack = index;
          console.log(position);

          // debug
          console.log(
            "position " + position / 60 + " min" + " - " + position + " sec"
          );
          console.log(nowDate);
          console.log(
            element?.time_start + " " + element?.time_end + " " + index
          );
        }
      });

      this.currentTrackIndex = indexTrack;
      this.player.currentTime = position;
      this.player.src = this.tracks[this.currentTrackIndex]?.file_link;

      // debug
      console.log(
        this.currentTrackIndex +
          " first" +
          ", position: " +
          this.player.currentTime / 60 +
          " min" +
          " - " +
          this.player.currentTime +
          " sec"
      );
    },

    playPause() {
      if (this.player.paused) {
        this.isPlaying = true;
        this.setPlayerSource();
        this.player.play();
      } else {
        this.isPlaying = false;
        this.setPlayerSource();
        this.player.pause();
      }
    },

    nextTrack() {
      if (this.currentTrackIndex < this.tracks.length - 1) {
        this.currentTrackIndex++;
        this.setPlayerSource();
        this.playPause();

        // debug
        console.log(this.currentTrackIndex + " next track");
      }
    },

    toggleMute() {
      this.player.muted = !this.player.muted;
      this.muted = this.player.muted;
    },
  },

  mounted() {
    this.getTracks();

    // debug
    console.log(this.tracks);
    // this.setPlayerSource();

    this.player.addEventListener("ended", () => {
      this.isPlaying = false;
      if (this.autoAdvance) {
        this.nextTrack();
      }
    });
    this.player.addEventListener("timeupdate", () => {
      console.log("currentTime " + this.player.currentTime);
    });
  },
};
</script>

And template

<template>
  <div class="wrapper">
    <div class="side">
      <div class="header">
        <img src="./assets/images/logo_light.svg" alt="" />
      </div>
    </div>

    <div class="content">
      <div class="item-player">
        <div class="btn__play">
          <button class="btn" @click="playPause">
            <img v-show="!isPlaying" src="./assets/images/play.svg" alt="" />
            <img v-show="isPlaying" src="./assets/images/pause.svg" alt="" />
          </button>
        </div>

        <div class="volume">
          <div class="volime__btn">
            <button @click="toggleMute">
              <img src="./assets/images/mute.svg" alt="" />
            </button>
          </div>

          <div class="volume__container">
            <div class="progress"></div>
          </div>

          <div class="volime__btn">
            <button>
              <img src="./assets/images/no-mute.svg" alt="" />
            </button>
          </div>
        </div>
      </div>

      <div class="item-description">
        <div class="description__cover">
          <img :src="tracks[currentTrackIndex]?.cover" alt="" />
        </div>
        <div class="description__text">
          <p class="description__text_name">
            {{ tracks[currentTrackIndex]?.podcast }}
          </p>
          <p class="description__text_about">
            {{ tracks[currentTrackIndex]?.episode }}
          </p>
          <p class="description__text_author">
            Подкаст {{ tracks[currentTrackIndex]?.publisher }}
          </p>
        </div>
      </div>

      <div class="item-nexttrack">
        <div class="item-nexttrack__text">ДАЛЬШЕ</div>
        <div class="next">
          <div class="next__left">
            <button>
              <img src="./assets/images/back-arrow.svg" alt="" />
            </button>
          </div>
          <div class="next__description">
            <p>
              <span>00:00</span> {{ tracks[currentTrackIndex + 1]?.podcast }}.
              {{ tracks[currentTrackIndex + 1]?.episode }}.
            </p>
            <p>Подкаст {{ tracks[currentTrackIndex + 1]?.publisher }}</p>
          </div>
          <div class="next__right">
            <button>
              <img src="./assets/images/next-arrow.svg" alt="" />
            </button>
          </div>
        </div>
      </div>
    </div>

    <div class="side"></div>
  </div>
</template>
0 Answers
Related