404 lines
12 KiB
Vue
404 lines
12 KiB
Vue
<template>
|
|
<div class="player">
|
|
<div class="player__cover">
|
|
<q-skeleton v-if="loaderPlay" height="100%" />
|
|
<img v-else :src="currentPlay.art" alt="player" />
|
|
</div>
|
|
<div class="player__content">
|
|
<div class="player__top">
|
|
<q-skeleton
|
|
v-if="loaderPlay"
|
|
type="circle"
|
|
class="player__btn m--skeleton"
|
|
/>
|
|
<template v-else>
|
|
<button
|
|
v-if="currentPlay.isPlay"
|
|
@click="handlerPause"
|
|
class="button player__btn m--pause"
|
|
></button>
|
|
<button
|
|
v-else
|
|
@click="handlerPlay"
|
|
class="button player__btn m--play"
|
|
></button>
|
|
</template>
|
|
<div class="player__executor">
|
|
<q-skeleton v-if="loaderPlay" class="player__executor m--skeleton" />
|
|
<template v-else>
|
|
{{ currentPlay.title || '—' }}
|
|
</template>
|
|
<span>
|
|
<q-skeleton v-if="loaderPlay" />
|
|
<template v-else>
|
|
{{ currentPlay.artist || '—' }}
|
|
</template>
|
|
</span>
|
|
</div>
|
|
<template v-if="user?.id">
|
|
<q-skeleton v-if="loaderPlay" class="player__favorites m--skeleton" />
|
|
<div
|
|
v-else
|
|
class="player__favorites"
|
|
:class="[isFavorites && 'm--active']"
|
|
@click="handlerFavorites"
|
|
></div>
|
|
</template>
|
|
<div class="player__tools">
|
|
<q-skeleton v-if="loaderPlay" class="player__tools m--skeleton" />
|
|
<FormKit
|
|
v-else
|
|
v-model="isUserMusic"
|
|
type="toggle"
|
|
label="Включить мою музыку"
|
|
:disabled="!user?.id || userSongList.length === 0"
|
|
/>
|
|
<q-skeleton v-if="loaderPlay" class="player__tools m--skeleton" />
|
|
<div v-else class="player__volume">
|
|
<span @click="changeVolume('set')" />
|
|
<input type="range" v-model="songVolume" @change="changeVolume" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="player__bottom">
|
|
<div
|
|
class="player__time"
|
|
:class="!loaderPlay && !isUserMusic && 'm--ether'"
|
|
>
|
|
<q-skeleton v-if="loaderPlay" />
|
|
<template v-else-if="isUserMusic">
|
|
{{ getTime(playerInfo.currentTime) }} /
|
|
{{ getTime(playerInfo.duration) }}
|
|
</template>
|
|
<template v-else> Эфир </template>
|
|
</div>
|
|
<div class="player__progress">
|
|
<q-skeleton v-if="loaderPlay" height="5px" />
|
|
<input
|
|
v-else
|
|
:disabled="!isUserMusic"
|
|
type="range"
|
|
v-model="playerInfo.progress"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { app, audio as Player } from '@/services';
|
|
|
|
export default {
|
|
name: 'player',
|
|
components: {},
|
|
data() {
|
|
return {
|
|
isFavorites: false,
|
|
isPlayRadio: false,
|
|
connection: null,
|
|
isUserMusic: !this.$store.state.currentPlay.live,
|
|
songVolume: this.$store.state.currentPlay.volume,
|
|
playerInfo: {
|
|
progress: 0,
|
|
currentTime: 0,
|
|
duration: 0,
|
|
},
|
|
};
|
|
},
|
|
computed: {
|
|
user() {
|
|
return this.$store.state.user;
|
|
},
|
|
currentPlay() {
|
|
return this.$store.state.currentPlay;
|
|
},
|
|
player() {
|
|
return this.$store.state.player;
|
|
},
|
|
userSongList() {
|
|
return this.$store.state.userFavorite?.songs || [];
|
|
},
|
|
loaderPlay() {
|
|
return this.$store.state.currentPlay.isLoader;
|
|
},
|
|
},
|
|
watch: {
|
|
currentPlay: {
|
|
immediate: false,
|
|
handler(to, from) {
|
|
if (this.isUserMusic === this.currentPlay.live) {
|
|
this.isUserMusic = !this.currentPlay.live;
|
|
}
|
|
if (this.user?.id && to.id !== from.id) {
|
|
this.checkSongIsFavorite();
|
|
}
|
|
if (!this.currentPlay.live && to.id !== from.id) {
|
|
this.getAudio(this.currentPlay.azura_id);
|
|
}
|
|
},
|
|
},
|
|
userSongList: {
|
|
immediate: false,
|
|
handler(to, from) {
|
|
if (this.user?.id && to.length !== from.length) {
|
|
this.checkSongIsFavorite();
|
|
}
|
|
},
|
|
},
|
|
isUserMusic: {
|
|
immediate: false,
|
|
handler() {
|
|
if (this.isUserMusic === this.currentPlay.live) {
|
|
this.changeLive();
|
|
}
|
|
},
|
|
},
|
|
},
|
|
created() {
|
|
this.connectionPlayer();
|
|
},
|
|
mounted() {
|
|
console.log(this.currentPlay);
|
|
this.$store.dispatch('initPlayer');
|
|
if (this.user?.id) {
|
|
this.checkSongIsFavorite();
|
|
this.getSongList();
|
|
}
|
|
this.playerInfo.progress = this.currentPlay.live ? 100 : 0;
|
|
if (!this.currentPlay.live && this.userSongList?.length > 0) {
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.userSongList[this.currentPlay.currentIndex || 0],
|
|
live: false,
|
|
});
|
|
this.getAudio(
|
|
this.userSongList[this.currentPlay.currentIndex || 0]?.azura_id,
|
|
);
|
|
if (this.player.target) {
|
|
this.player.target.addEventListener('timeupdate', this.updateProgress);
|
|
}
|
|
}
|
|
if (!this.user?.id) {
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
live: true,
|
|
isLoader: true,
|
|
currentIndex: null,
|
|
});
|
|
}
|
|
},
|
|
methods: {
|
|
connectionPlayer() {
|
|
if (this.connection) {
|
|
this.connection.removePlay();
|
|
}
|
|
this.connection = new Player();
|
|
this.connection.init();
|
|
this.connection.onHandler(this.getPlaying);
|
|
},
|
|
checkSongIsFavorite() {
|
|
app
|
|
.getCheckFavoriteSong(this.currentPlay.azura_id || this.currentPlay.id)
|
|
.then((res) => {
|
|
this.isFavorites = res.is_favorite;
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
},
|
|
removeFavorites(song) {
|
|
app
|
|
.removeFavorites(song)
|
|
.then(() => {
|
|
this.getSongList();
|
|
})
|
|
.catch((err) => {
|
|
this.showLoader = false;
|
|
console.error(err);
|
|
});
|
|
},
|
|
getPlaying(e) {
|
|
const jsonData = JSON.parse(e.data);
|
|
if (jsonData?.pub?.data) {
|
|
const data = jsonData?.pub?.data;
|
|
if (this.currentPlay.live) {
|
|
if (data.np.station.listen_url !== this.player.target.src) {
|
|
console.log(
|
|
'data.np.station.listen_url',
|
|
data.np.station.listen_url,
|
|
);
|
|
this.$store.dispatch('changePlayer', data.np.station.listen_url);
|
|
const params = {
|
|
...this.currentPlay,
|
|
...data.np.now_playing.song,
|
|
azura_id: data.np.now_playing.song.id,
|
|
isLoader: false,
|
|
live: true,
|
|
currentIndex: null,
|
|
};
|
|
delete params.unique_id;
|
|
this.$store.dispatch('setCurrentPlay', params);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
updateProgress(e) {
|
|
this.playerInfo = {
|
|
...this.playerInfo,
|
|
progress:
|
|
(this.player.target.currentTime / this.player.target.duration) * 100,
|
|
currentTime: this.player.target.currentTime,
|
|
};
|
|
if (this.player.target.currentTime === this.player.target.duration) {
|
|
let currentIndex = this.currentPlay.currentIndex + 1;
|
|
if (
|
|
!this.userSongList[currentIndex]?.azura_id ||
|
|
currentIndex === null
|
|
) {
|
|
currentIndex = 0;
|
|
}
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
...this.userSongList[currentIndex],
|
|
currentIndex,
|
|
});
|
|
}
|
|
},
|
|
handlerPlay() {
|
|
console.log(this.currentPlay);
|
|
console.log(this.player);
|
|
this.$store.dispatch('handlerPlayer', { play: true });
|
|
},
|
|
handlerPause() {
|
|
this.$store.dispatch('handlerPlayer', { pause: true });
|
|
},
|
|
getSongList() {
|
|
app
|
|
.getFavoriteList()
|
|
.then((res) => {
|
|
this.$store.dispatch('setUserFavorite', { songs: res });
|
|
console.log('res.length', res.length);
|
|
if (res.length === 0) {
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
live: true,
|
|
isLoader: true,
|
|
});
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
},
|
|
handlerFavorites() {
|
|
if (this.user?.id) {
|
|
const params = {
|
|
...this.currentPlay,
|
|
azura_id: Number(this.currentPlay.id)
|
|
? this.currentPlay.azura_id
|
|
: this.currentPlay.id,
|
|
};
|
|
if (!this.isFavorites) {
|
|
delete params.id;
|
|
app
|
|
.createFavoriteForUser(params)
|
|
.then(() => {
|
|
this.isFavorites = !this.isFavorites;
|
|
this.getSongList();
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
} else {
|
|
console.log(params);
|
|
app
|
|
.removeFavorites(params)
|
|
.then(() => {
|
|
this.getSongList();
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
}
|
|
} else {
|
|
this.$emit('shopAuthentication', true);
|
|
}
|
|
},
|
|
changeVolume(type) {
|
|
let volume = this.songVolume;
|
|
if (type === 'set') {
|
|
volume = this.songVolume === 0 ? 0.9 : 0.01;
|
|
this.songVolume = this.songVolume === 0 ? 100 : 0;
|
|
} else {
|
|
volume = this.songVolume / 100;
|
|
}
|
|
if (volume === 0) volume = 0.01;
|
|
this.$store.dispatch('handlerPlayer', { volume });
|
|
},
|
|
getAudio(id) {
|
|
app
|
|
.getAudio(id)
|
|
.then((res) => {
|
|
const blob = new Blob([res], { type: 'application/audio' });
|
|
const audioUrl = URL.createObjectURL(blob);
|
|
this.$store.dispatch('changePlayer', audioUrl);
|
|
this.player.target.addEventListener(
|
|
'timeupdate',
|
|
this.updateProgress,
|
|
);
|
|
|
|
blob.arrayBuffer().then((buffer) => {
|
|
var audioContext = new (window.AudioContext ||
|
|
window.webkitAudioContext)();
|
|
audioContext.decodeAudioData(buffer, (decodedData) => {
|
|
this.playerInfo.duration = decodedData.duration;
|
|
});
|
|
});
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
isLoader: false,
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
isLoader: false,
|
|
});
|
|
console.debug(err);
|
|
});
|
|
},
|
|
changeLive() {
|
|
if (this.currentPlay.live) {
|
|
console.log('избранное');
|
|
this.playerInfo.progress = 0;
|
|
const params = {
|
|
...this.userSongList[this.currentPlay.currentIndex || 0],
|
|
live: false,
|
|
isLoader: true,
|
|
};
|
|
if (!this.currentPlay.currentIndex) params.currentIndex = 0;
|
|
this.$store.dispatch('setCurrentPlay', params);
|
|
} else {
|
|
this.playerInfo.progress = 100;
|
|
this.$store.dispatch('setCurrentPlay', {
|
|
...this.currentPlay,
|
|
live: true,
|
|
isLoader: true,
|
|
});
|
|
console.log('поток');
|
|
}
|
|
},
|
|
getTime(value) {
|
|
let minutes = Math.floor(value / 60);
|
|
let seconds = Math.round(value % 60);
|
|
|
|
let paddedMinutes = minutes < 10 ? '0' + minutes : minutes;
|
|
let paddedSeconds = seconds < 10 ? '0' + seconds : seconds;
|
|
if (!paddedMinutes) paddedMinutes = '00';
|
|
if (!paddedSeconds) paddedSeconds = '00';
|
|
return `${paddedMinutes}:${paddedSeconds}`;
|
|
},
|
|
},
|
|
};
|
|
</script>
|