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>