当前播放开发中...

This commit is contained in:
zilong
2021-10-23 00:42:08 +08:00
parent 4ade4395d4
commit 8b42649ba1
7 changed files with 272 additions and 89 deletions

View File

@@ -1,10 +1,15 @@
<script setup>
import { ref, reactive, h, watch, toRaw } from "vue";
import {
RouterLink,
useRoute,
useRouter,
} from "vue-router";
ref,
reactive,
h,
watch,
toRaw,
onMounted,
onUnmounted,
nextTick,
} from "vue";
import { RouterLink, useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import {
NButton,
@@ -22,48 +27,110 @@ import {
useMessage,
} from "naive-ui";
import Play from "@/assets/svgs/Play_.svg";
import Add from "@/assets/svgs/Add.svg";
import Pause from "@/assets/svgs/Pause.svg";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import duration from "dayjs/plugin/duration";
import pubsub from "pubsub-js";
const store = useStore();
const playingList = ref([])
const router = useRouter();
dayjs.extend(duration);
const playingList = ref([]);
const wpTable = ref("");
const listHeight = ref(0);
const createColumns = ({ play ,singerInfo }) => {
onMounted(() => {
window.addEventListener("resize", onResize);
// console.log(wpTable.value.clientHeight);
listHeight.value = wpTable.value.clientHeight;
});
const onResize = () => {
if (wpTable.value) {
listHeight.value = wpTable.value.clientHeight - 40;
// console.log(wpTable.value.clientHeight)
}
};
const token = pubsub.subscribe("zp", (msg, data) => {
switch (msg) {
case "zp.togglePlaying":
nextTick(() => {
onResize();
});
break;
}
});
//卸载组件
onUnmounted(() => {
pubsub.unsubscribe(token);
});
const createColumns = ({ play, singerInfo }) => {
return [
{
title: "",
key: "index",
align: "right",
width: 20
width: 20,
render(row) {
if (row.id === store.state.settings.songId) {
const icon = h(store.state.settings.playing ? Play : Pause);
return h(
NButton,
{
text: true,
type: "primary",
circle: true,
size: "tiny",
},
{
default: () =>
h(
NIcon,
{
style: {
bottom: "-2px",
left: "-2px",
position: "absolute",
},
},
// [h(store.state.settings.playing ? Play : Pause,{},[])]
{ default: () => icon }
),
}
);
} else return "";
},
},
{
title: "音乐标题",
key: "name",
align: "left",
ellipsis: true,
render(row){
render(row) {
return h(
NButton,
{
style: {
marginRight: "6px",
},
text: true,
size: "small",
onClick: () => play(row.id),
NButton,
{
style: {
marginRight: "6px",
},
{
default: () => row.name,
}
);
}
text: true,
size: "small",
onClick: () => play(row.id),
},
{
default: () => row.name,
}
);
},
},
{
title: "歌手",
key: "artists",
ellipsis: true,
width: 120,
render(row) {
const ars = row.artists.map((ar, idx) => {
let r = h(
@@ -87,62 +154,81 @@ const createColumns = ({ play ,singerInfo }) => {
},
},
{
title: "播放时间",
key: "date",
title: "专辑",
key: "album.name",
width: 100,
render(row){
return h('span', [dayjs(row.date).format('YYYY-MM-DD')])
}
ellipsis: true,
},
{
title: "时长",
key: "duration",
width: 60,
render(row) {
return h("span", [
dayjs.duration(row.duration).format("mm:ss"),
]);
},
},
// {
// title: "播放时间",
// key: "date",
// width: 100,
// render(row) {
// return h("span", [
// dayjs(row.date).format("YYYY-MM-DD"),
// ]);
// },
// },
];
};
const columns = createColumns({
play(id){
pubsub.publish('zp.play', {id, im:true})
play(id) {
pubsub.publish("zp.play", { id, im: true });
},
singerInfo(id) {
// console.log("歌手页面");
router.push("/singer/" + id);
},
});
// watch(
// () => store.state.settings.playingList,
// (val, oldVal) => {
// playingList.value = toRaw(store.state.settings.playingList)
// },
// {
// immediate: true,
// deep: true,
// }
// );
watch(
() => store.state.settings.playingList,
(val, oldVal) => {
playingList.value = toRaw(store.state.settings.playingList);
},
{
immediate: true,
deep: true,
}
);
</script>
<template>
<n-layout>
<n-layout-header
style="padding: 6px 12px 0px 12px; font-size: 24px"
style="padding: 10px 12px 0px 12px; font-size: 24px"
>当前播放
</n-layout-header>
<n-layout has-sider>
<n-layout-content
style="padding: 6px 12px; font-size: 12px"
>
{{ playingList }}
<n-layout-content style="padding: 6px 12px; font-size: 12px">
{{ playingList.length }}
</n-layout-content>
<n-layout-sider width="100" style="padding: 0 12px 6px 12px">
<n-button size="tiny">清除列表</n-button>
</n-layout-sider>
</n-layout>
</n-layout>
<n-data-table
:bordered="false"
:single-line="true"
:columns="columns"
:data="playingList"
size="tiny"
/>
<div class="wp-table" ref="wpTable">
<n-data-table
:bordered="false"
:single-line="true"
:columns="columns"
:data="playingList"
size="small"
:max-height="listHeight"
/>
</div>
</template>
<script>
@@ -150,6 +236,17 @@ export default {};
</script>
<style lang="less" scoped>
.wp-table {
position: absolute;
bottom: 0px;
top: 76px;
overflow: hidden;
}
thead {
display: none;
}
.n-layout-header,
.n-layout-content,
.n-layout-side {

View File

@@ -33,7 +33,7 @@ onMounted(() => {
});
onUnmounted(() => {
console.log("另外一个Unmounted");
// console.log("另外一个Unmounted");
// audioEl.value.removeEventListener("play", onPlay);
// audioEl.value.removeEventListener("pause", onPause);
// audioEl.value.removeEventListener("ended", onEnd);
@@ -46,12 +46,46 @@ const onPause = () => {
console.log("onPause");
};
const onEnd = () => {
playing.value = false;
playNext(1)
// playing.value = false;
currentTime = 0;
console.log("onEnd");
console.log("下一首...");
};
const play = async (id, name, im = true) => {
const playNext = async (step) => {
let { songId, playingList, playMode , playing} = store.state.settings;
let idx = playingList.findIndex((item) => item.id == songId);
console.log(idx);
switch (playMode) {
case 0:
idx += step;
if (idx > playingList.length - 1) return;
if (idx < 0) return
break;
case 1:
idx += step;
if (idx > playingList.length - 1) idx = 0;
if (idx < 0) idx = playingList.length - 1;
break;
case 2:
break;
case 3:
break;
}
console.log(idx);
play(playingList[idx].id, playing)
};
const playPrev = async (id, im = true) => {};
const previous = async () => {
playNext(-1);
};
const forward = async () => {
playNext(1);
};
const play = async (id, im = true) => {
console.log(id);
await getSongUrl(id)
.then((res) => {
@@ -60,13 +94,16 @@ const play = async (id, name, im = true) => {
store.commit("saveSettings", {
songId: id,
});
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im})
// console.log(audioEl.value.duration);
pubsub.publish("zp.getSongInfo", {
id: store.state.settings.songId,
im,
});
if (im) {
audioEl.value.play();
playing.value = true;
}
}
})
.catch((err) => {
@@ -90,7 +127,10 @@ const resume = async () => {
}
audioEl.value.play();
playing.value = true;
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im: true})
pubsub.publish("zp.getSongInfo", {
id: store.state.settings.songId,
im: true,
});
}
};
@@ -108,9 +148,10 @@ const favorite = () => {
let interval;
watch(playing, (val, old) => {
store.state.settings.playing = val;
if (val === true) {
interval = setInterval(() => {
// console.log(audioEl.value.currentTime);
// console.log(audioEl.value.duration);
currentTime = audioEl.value.currentTime;
pubsub.publish("zp.progress", {
progress: audioEl.value.currentTime,
@@ -127,7 +168,7 @@ watch(playing, (val, old) => {
const psToken = pubsub.subscribe("zp", (msg, data) => {
switch (msg) {
case "zp.play":
play(data.id, data.name, data.im);
play(data.id, data.im);
break;
case "zp.setProgressScale":
setProgressScale(data.scale);
@@ -149,7 +190,7 @@ onUnmounted(() => {
id="songCtrl"
align="center"
:size="[6]"
style="padding-top: 2px;margin: 0 4px"
style="padding-top: 2px; margin: 0 4px"
>
<n-button circle @click="favorite">
<template #icon>
@@ -158,7 +199,7 @@ onUnmounted(() => {
</n-icon>
</template>
</n-button>
<n-button circle>
<n-button circle @click="previous">
<template #icon>
<n-icon>
<PlaySkipBack />
@@ -194,7 +235,7 @@ onUnmounted(() => {
<!-- </template> -->
</n-button>
<!-- <n-button circle color="#18a058"> -->
<n-button circle>
<n-button circle @click="forward">
<template #icon>
<n-icon>
<PlaySkipForward />

View File

@@ -21,7 +21,9 @@ const showInfo = ref(false);
const info = reactive({
name: "",
artists: "",
albumPicUrl: "",
album: {},
duration: 0,
mv: 0,
});
//#region 取得歌曲信息
@@ -31,12 +33,19 @@ const songInfo = (id, im) => {
showInfo.value = true;
info.name = res.data.songs[0].name;
info.artists = res.data.songs[0].ar;
info.albumPicUrl = res.data.songs[0].al.picUrl;
info.album = res.data.songs[0].al;
info.duration = res.data.songs[0].dt;
info.mv = res.data.songs[0].mv;
currTime.value = '00:00'
totalTime.value = zpTime(info.duration)
if(im){
store.commit('savePlayed', {...{
const p = {...{
id,
date: Date.now(),
}, ...toRaw(info)})
}, ...toRaw(info)}
store.commit('savePlayed', p)
store.commit('addToPlayingList', p)
console.log('savePlayed');
}
})
@@ -76,7 +85,7 @@ onUnmounted(() => {
<NAvatar
:size="40"
v-show="showInfo"
:src="info.albumPicUrl"
:src="info.album.picUrl"
></NAvatar>
<div class="song" v-show="showInfo">
<div class="w-song">

View File

@@ -1,5 +1,6 @@
<script setup>
import { ref } from "vue";
import { ref, watch, toRaw } from "vue";
import {useStore} from 'vuex';
import { NButton, NIcon, NSpace } from "naive-ui";
import PlaylistMusic from "@/assets/svgs/PlaylistMusic.svg";
import VolumeOffOutline from "@/assets/svgs/VolumeOffOutline.svg";
@@ -9,9 +10,27 @@ import Playlist from "@/assets/svgs/Playlist.svg";
import Random from "@/assets/svgs/Random.svg";
import pubsub from 'pubsub-js';
const store = useStore()
//播放模式0-3顺序循环单曲随机。
const playMode = ref(0)
let playMode = ref(0)
const chPlayMode = (mode) => {
store.commit('saveSettings', {
playMode: mode
})
}
watch(
() => store.state.settings.playMode,
(val, oldVal) => {
playMode.value = toRaw(store.state.settings.playMode);
},
{
immediate: true,
deep: true,
}
);
</script>
@@ -24,28 +43,28 @@ const playMode = ref(0)
:size="[6]"
style="padding-top: 2px; padding-right: 8px"
>
<n-button circle v-if="playMode==1">
<n-button circle v-if="playMode==1" @click="chPlayMode(2)">
<template #icon>
<n-icon>
<RepeatOutline />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==2">
<n-button circle v-if="playMode==2" @click="chPlayMode(3)">
<template #icon>
<n-icon>
<RepeatOne />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==0">
<n-button circle v-if="playMode==0" @click="chPlayMode(1)">
<template #icon>
<n-icon>
<Playlist />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==3">
<n-button circle v-if="playMode==3" @click="chPlayMode(0)">
<template #icon>
<n-icon>
<Random />