vite-zmusic/src/views/common/SongCtrl.vue
2021-10-13 20:59:12 +08:00

220 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, onMounted, onUnmounted, watch } from "vue";
import { useStore } from "vuex";
import { NButton, NIcon, NSpace } from "naive-ui";
import PlayCircle from "@/assets/svgs/PlayCircle.svg";
import PlaySkipForward from "@/assets/svgs/PlaySkipForward.svg";
import PlaySkipBack from "@/assets/svgs/PlaySkipBack.svg";
import HeartOutline from "@/assets/svgs/HeartOutline.svg";
import TrashOutline from "@/assets/svgs/TrashOutline.svg";
import PauseCircle from "@/assets/svgs/PauseCircle.svg";
import { getSongUrl } from "@/network/song";
import pubsub from "pubsub-js";
const store = useStore();
const { settings } = store.state;
const audioEl = ref("");
const playing = ref(false);
let currentTime = 0;
let lastPause = Date.now()
onMounted(() => {
audioEl.value.addEventListener("play", onPlay);
audioEl.value.addEventListener("pause", onPause);
audioEl.value.addEventListener("ended", onEnd);
if (settings.songId) {
pubsub.publish("zp.play", {
id: settings.songId,
im: false,
});
// play(settings.songId, false)
}
});
onUnmounted(() => {
console.log("另外一个Unmounted");
// audioEl.value.removeEventListener("play", onPlay);
// audioEl.value.removeEventListener("pause", onPause);
// audioEl.value.removeEventListener("ended", onEnd);
});
const onPlay = () => {
console.log("onPlay");
};
const onPause = () => {
console.log("onPause");
};
const onEnd = () => {
playing.value = false;
currentTime = 0;
console.log("onEnd");
};
const play = async (id, im = true) => {
console.log(id);
await getSongUrl(id)
.then((res) => {
audioEl.value.src = res.data.data[0].url;
store.commit("saveSettings", {
songId: id,
});
if (im) {
audioEl.value.play();
playing.value = true;
}
})
.catch((err) => {
console.log("getSongUrl err", err);
});
};
const pause = () => {
audioEl.value.pause();
playing.value = false;
};
const resume = async () => {
if (audioEl.value.readyState) {
//如果暂停过了5分钟需要再次载入歌曲
// console.log(Date.now() - lastPause);
if((Date.now() - lastPause) > 1000 * 60 * 5){
console.log('暂停过了5分钟再次载入歌曲');
await play(settings.songId, false);
audioEl.value.currentTime = currentTime;
}
audioEl.value.play();
playing.value = true;
}
};
const setProgressScale = (scale) => {
if (audioEl.value.readyState) {
// console.log(progress);
audioEl.value.currentTime = currentTime =
scale * audioEl.value.duration;
}
};
const favorite = () => {
// console.log(audioEl.value.currentTime);
};
let interval;
watch(playing, (val, old) => {
if (val === true) {
interval = setInterval(() => {
// console.log(audioEl.value.currentTime);
currentTime = audioEl.value.currentTime;
pubsub.publish("zp.progress", {
progress: audioEl.value.currentTime,
total: audioEl.value.duration,
});
}, 200);
} else {
clearInterval(interval);
lastPause = Date.now();
}
});
//#region 处理消息订阅
const psToken = pubsub.subscribe("zp", (msg, data) => {
switch (msg) {
case "zp.play":
play(data.id, data.im);
break;
case "zp.setProgressScale":
setProgressScale(data.scale);
break;
}
});
//卸载组件
onUnmounted(() => {
pubsub.unsubscribe(psToken);
});
//#endregion
</script>
<template>
<!-- <div id="songsCtrl"> -->
<audio src="" ref="audioEl"></audio>
<n-space
id="songCtrl"
align="center"
:size="[6]"
style="padding-top: 2px"
>
<n-button circle @click="favorite">
<template #icon>
<n-icon>
<HeartOutline />
</n-icon>
</template>
</n-button>
<n-button circle>
<template #icon>
<n-icon>
<PlaySkipBack />
</n-icon>
</template>
</n-button>
<n-button
v-if="!playing"
text
class="start-play"
style="font-size: 56px"
type="primary"
@click="resume"
>
<!-- <template #icon> -->
<n-icon>
<PlayCircle />
</n-icon>
<!-- </template> -->
</n-button>
<n-button
v-if="playing"
text
class="start-play"
style="font-size: 56px"
type="primary"
@click="pause"
>
<!-- <template #icon> -->
<n-icon size="56">
<PauseCircle />
</n-icon>
<!-- </template> -->
</n-button>
<!-- <n-button circle color="#18a058"> -->
<n-button circle>
<template #icon>
<n-icon>
<PlaySkipForward />
</n-icon>
</template>
</n-button>
<n-button circle>
<template #icon>
<n-icon>
<TrashOutline />
</n-icon>
</template>
</n-button>
</n-space>
<!-- </div> -->
</template>
<script>
export default {};
</script>
<style lang="less" scoped>
#songCtrl {
display: flex;
align-items: center;
}
</style>