2023-11-23 18:28:53 +08:00
|
|
|
<template>
|
2024-09-26 11:57:23 +08:00
|
|
|
<div
|
|
|
|
|
v-show="statusStore.showFullPlayer"
|
|
|
|
|
:style="{
|
2024-12-11 17:12:59 +08:00
|
|
|
'--main-color': statusStore.mainColor,
|
2024-09-26 11:57:23 +08:00
|
|
|
cursor: statusStore.playerMetaShow ? 'auto' : 'none',
|
|
|
|
|
}"
|
|
|
|
|
class="full-player"
|
|
|
|
|
@mouseleave="playerLeave"
|
|
|
|
|
>
|
|
|
|
|
<!-- 遮罩 -->
|
|
|
|
|
<Transition name="fade" mode="out-in">
|
|
|
|
|
<div
|
|
|
|
|
:key="musicStore.playSong?.id ?? 0"
|
|
|
|
|
:class="['overlay', settingStore.playerBackgroundType]"
|
|
|
|
|
>
|
|
|
|
|
<!-- 背景模糊 -->
|
|
|
|
|
<img
|
|
|
|
|
v-if="settingStore.playerBackgroundType === 'blur'"
|
|
|
|
|
:src="musicStore.songCover"
|
|
|
|
|
class="overlay-img"
|
|
|
|
|
alt="cover"
|
|
|
|
|
/>
|
|
|
|
|
<!-- 流体背景 -->
|
|
|
|
|
<PlayerBackground
|
|
|
|
|
v-else-if="settingStore.playerBackgroundType === 'animation'"
|
|
|
|
|
:album="musicStore.songCover"
|
|
|
|
|
:fps="60"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</Transition>
|
2024-10-05 11:13:25 +08:00
|
|
|
<!-- 独立歌词 -->
|
|
|
|
|
<Transition name="fade" mode="out-in">
|
|
|
|
|
<div
|
|
|
|
|
v-if="isShowComment && !statusStore.pureLyricMode"
|
|
|
|
|
:key="instantLyrics.content"
|
|
|
|
|
class="lrc-instant"
|
|
|
|
|
>
|
|
|
|
|
<span class="lrc">{{ instantLyrics.content }}</span>
|
|
|
|
|
<span v-if="instantLyrics.tran" class="lrc-tran">{{ instantLyrics.tran }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</Transition>
|
2024-09-26 11:57:23 +08:00
|
|
|
<!-- 菜单 -->
|
|
|
|
|
<PlayerMenu @mouseenter.stop="stopHide" @mouseleave.stop="playerMove" />
|
|
|
|
|
<!-- 主内容 -->
|
|
|
|
|
<Transition name="fade" mode="out-in">
|
|
|
|
|
<div
|
|
|
|
|
:key="playerContentKey"
|
|
|
|
|
:class="[
|
|
|
|
|
'player-content',
|
|
|
|
|
{
|
|
|
|
|
pure: statusStore.pureLyricMode,
|
|
|
|
|
'show-comment': isShowComment,
|
|
|
|
|
// 'no-lrc': !musicStore.isHasLrc,
|
|
|
|
|
},
|
|
|
|
|
]"
|
|
|
|
|
@mousemove="playerMove"
|
|
|
|
|
>
|
2023-11-23 18:28:53 +08:00
|
|
|
<div
|
2024-09-26 11:57:23 +08:00
|
|
|
v-if="
|
|
|
|
|
!(statusStore.pureLyricMode && musicStore.isHasLrc) ||
|
|
|
|
|
musicStore.playSong.type === 'radio'
|
|
|
|
|
"
|
|
|
|
|
class="content-left"
|
2023-11-23 18:28:53 +08:00
|
|
|
>
|
2024-09-26 11:57:23 +08:00
|
|
|
<!-- 封面 -->
|
|
|
|
|
<PlayerCover />
|
|
|
|
|
<!-- 数据 -->
|
2024-12-11 17:12:59 +08:00
|
|
|
<PlayerData :center="playerDataCenter" :theme="statusStore.mainColor" />
|
2023-11-23 18:28:53 +08:00
|
|
|
</div>
|
2024-09-26 11:57:23 +08:00
|
|
|
<Transition name="fade" mode="out-in">
|
|
|
|
|
<!-- 评论 -->
|
|
|
|
|
<PlayerComment v-if="isShowComment && !statusStore.pureLyricMode" />
|
|
|
|
|
<!-- 歌词 -->
|
|
|
|
|
<div v-else-if="musicStore.isHasLrc" class="content-right">
|
|
|
|
|
<!-- 数据 -->
|
2024-12-02 16:02:02 +08:00
|
|
|
<!-- <PlayerData
|
2024-09-26 11:57:23 +08:00
|
|
|
v-if="
|
|
|
|
|
(statusStore.pureLyricMode && musicStore.isHasLrc) ||
|
|
|
|
|
(settingStore.playerType === 'record' && musicStore.isHasLrc)
|
|
|
|
|
"
|
|
|
|
|
:center="statusStore.pureLyricMode"
|
|
|
|
|
:theme="mainColor"
|
2024-12-02 16:02:02 +08:00
|
|
|
/> -->
|
2023-12-14 15:10:23 +08:00
|
|
|
<!-- 歌词 -->
|
2024-09-26 11:57:23 +08:00
|
|
|
<MainAMLyric v-if="settingStore.useAMLyrics" />
|
|
|
|
|
<MainLyric v-else />
|
2023-11-23 18:28:53 +08:00
|
|
|
</div>
|
2024-09-26 11:57:23 +08:00
|
|
|
</Transition>
|
|
|
|
|
</div>
|
|
|
|
|
</Transition>
|
|
|
|
|
<!-- 控制中心 -->
|
|
|
|
|
<PlayerControl @mouseenter.stop="stopHide" @mouseleave.stop="playerMove" />
|
|
|
|
|
<!-- 音乐频谱 -->
|
|
|
|
|
<PlayerSpectrum
|
|
|
|
|
v-if="settingStore.showSpectrums"
|
2024-12-11 17:12:59 +08:00
|
|
|
:color="statusStore.mainColor ? `rgb(${statusStore.mainColor})` : 'rgb(239 239 239)'"
|
2024-09-26 11:57:23 +08:00
|
|
|
:show="!statusStore.playerMetaShow"
|
|
|
|
|
:height="60"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2023-11-23 18:28:53 +08:00
|
|
|
</template>
|
|
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { useStatusStore, useMusicStore, useSettingStore } from "@/stores";
|
|
|
|
|
import { isElectron } from "@/utils/helper";
|
|
|
|
|
import { throttle } from "lodash-es";
|
|
|
|
|
import player from "@/utils/player";
|
2023-11-23 18:28:53 +08:00
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
const musicStore = useMusicStore();
|
|
|
|
|
const statusStore = useStatusStore();
|
|
|
|
|
const settingStore = useSettingStore();
|
2023-11-23 18:28:53 +08:00
|
|
|
|
2024-12-02 16:02:02 +08:00
|
|
|
// 是否显示评论
|
|
|
|
|
const isShowComment = computed<boolean>(
|
|
|
|
|
() => !musicStore.playSong.path && statusStore.showPlayerComment,
|
|
|
|
|
);
|
|
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
// 主内容 key
|
|
|
|
|
const playerContentKey = computed(() => {
|
|
|
|
|
return `
|
|
|
|
|
${musicStore.playSong?.id ?? 0}-
|
|
|
|
|
${musicStore.isHasLrc}-
|
|
|
|
|
${statusStore.pureLyricMode}-
|
|
|
|
|
${isShowComment.value}`;
|
2023-12-04 18:04:03 +08:00
|
|
|
});
|
|
|
|
|
|
2024-12-02 16:02:02 +08:00
|
|
|
// 数据是否居中
|
|
|
|
|
const playerDataCenter = computed<boolean>(
|
|
|
|
|
() =>
|
|
|
|
|
!musicStore.isHasLrc ||
|
|
|
|
|
statusStore.pureLyricMode ||
|
|
|
|
|
settingStore.playerType === "record" ||
|
|
|
|
|
musicStore.playSong.type === "radio" ||
|
|
|
|
|
isShowComment.value,
|
|
|
|
|
);
|
2023-11-23 18:28:53 +08:00
|
|
|
|
2024-10-05 11:13:25 +08:00
|
|
|
// 当前实时歌词
|
|
|
|
|
const instantLyrics = computed(() => {
|
|
|
|
|
const isYrc = musicStore.songLyric.yrcData?.length && settingStore.showYrc;
|
|
|
|
|
const content = isYrc
|
|
|
|
|
? musicStore.songLyric.yrcData[statusStore.lyricIndex]
|
|
|
|
|
: musicStore.songLyric.lrcData[statusStore.lyricIndex];
|
2024-10-18 15:50:24 +08:00
|
|
|
return { content: content?.content, tran: settingStore.showTran && content?.tran };
|
2024-10-05 11:13:25 +08:00
|
|
|
});
|
|
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
// 隐藏播放元素
|
|
|
|
|
const {
|
|
|
|
|
isPending,
|
|
|
|
|
start: startShow,
|
|
|
|
|
stop: stopShow,
|
|
|
|
|
} = useTimeoutFn(() => {
|
|
|
|
|
statusStore.playerMetaShow = false;
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
|
|
// 鼠标移动
|
|
|
|
|
const playerMove = throttle(
|
|
|
|
|
() => {
|
|
|
|
|
statusStore.playerMetaShow = true;
|
|
|
|
|
if (!isPending.value) startShow();
|
|
|
|
|
},
|
|
|
|
|
300,
|
|
|
|
|
{ trailing: false },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 停用隐藏
|
|
|
|
|
const stopHide = () => {
|
|
|
|
|
stopShow();
|
|
|
|
|
statusStore.playerMetaShow = true;
|
2023-11-23 18:28:53 +08:00
|
|
|
};
|
|
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
// 鼠标离开
|
|
|
|
|
const playerLeave = () => {
|
|
|
|
|
statusStore.playerMetaShow = false;
|
|
|
|
|
stopShow();
|
2024-01-08 18:20:47 +08:00
|
|
|
};
|
|
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
onMounted(() => {
|
|
|
|
|
console.log("播放器开启");
|
|
|
|
|
statusStore.fullPlayerActive = true;
|
|
|
|
|
// 音乐频谱
|
|
|
|
|
if (settingStore.showSpectrums) player.initSpectrumData();
|
|
|
|
|
// 阻止息屏
|
|
|
|
|
if (isElectron && settingStore.preventSleep) {
|
|
|
|
|
window.electron.ipcRenderer.send("prevent-sleep", true);
|
2023-11-23 18:28:53 +08:00
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
});
|
2023-11-23 18:28:53 +08:00
|
|
|
|
2024-09-26 11:57:23 +08:00
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
console.log("离开播放器");
|
|
|
|
|
if (isElectron) window.electron.ipcRenderer.send("prevent-sleep", false);
|
2023-11-23 18:28:53 +08:00
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.full-player {
|
|
|
|
|
position: fixed;
|
2024-09-26 11:57:23 +08:00
|
|
|
top: 0;
|
2023-11-23 18:28:53 +08:00
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
2024-09-26 11:57:23 +08:00
|
|
|
flex-direction: column;
|
2023-11-23 18:28:53 +08:00
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
2024-09-26 11:57:23 +08:00
|
|
|
color: rgb(var(--main-color));
|
2023-11-23 18:28:53 +08:00
|
|
|
background-color: #00000060;
|
|
|
|
|
backdrop-filter: blur(80px);
|
|
|
|
|
overflow: hidden;
|
2024-09-26 11:57:23 +08:00
|
|
|
z-index: 1000;
|
2023-11-23 18:28:53 +08:00
|
|
|
.overlay {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
z-index: -1;
|
|
|
|
|
&::after {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
2024-09-26 11:57:23 +08:00
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
2023-11-23 18:28:53 +08:00
|
|
|
backdrop-filter: blur(20px);
|
|
|
|
|
}
|
|
|
|
|
&.blur {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
.overlay-img {
|
2024-09-26 11:57:23 +08:00
|
|
|
width: 100%;
|
|
|
|
|
height: auto;
|
|
|
|
|
transform: scale(1.5);
|
2023-11-23 18:28:53 +08:00
|
|
|
filter: blur(80px) contrast(1.2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-05 11:13:25 +08:00
|
|
|
.lrc-instant {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
height: 80px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
.lrc {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
}
|
|
|
|
|
.lrc-tran {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
.player-content {
|
2023-11-23 18:28:53 +08:00
|
|
|
display: flex;
|
2024-09-26 11:57:23 +08:00
|
|
|
flex-direction: row;
|
2023-11-23 18:28:53 +08:00
|
|
|
align-items: center;
|
2024-09-26 11:57:23 +08:00
|
|
|
width: 100%;
|
|
|
|
|
height: calc(100vh - 160px);
|
|
|
|
|
z-index: 0;
|
|
|
|
|
.content-left {
|
2023-11-23 18:28:53 +08:00
|
|
|
flex: 1;
|
2024-09-26 11:57:23 +08:00
|
|
|
min-width: 50%;
|
|
|
|
|
height: 100%;
|
2023-11-23 18:28:53 +08:00
|
|
|
display: flex;
|
2024-09-26 11:57:23 +08:00
|
|
|
flex-direction: column;
|
2023-11-23 18:28:53 +08:00
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
2024-09-26 11:57:23 +08:00
|
|
|
transition: width 0.3s;
|
2024-01-09 18:13:01 +08:00
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
.content-right {
|
|
|
|
|
flex: 1;
|
|
|
|
|
height: 100%;
|
|
|
|
|
max-width: 50%;
|
2023-12-14 15:10:23 +08:00
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2024-09-26 11:57:23 +08:00
|
|
|
.player-data {
|
|
|
|
|
margin-top: 0;
|
2023-12-14 15:10:23 +08:00
|
|
|
margin-bottom: 26px;
|
2023-12-07 15:27:15 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
&.pure {
|
|
|
|
|
.content-right {
|
|
|
|
|
align-items: center;
|
|
|
|
|
max-width: 100%;
|
2024-01-08 18:20:47 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
&.show-comment {
|
|
|
|
|
.content-left {
|
|
|
|
|
min-width: 40vw;
|
|
|
|
|
max-width: 50vh;
|
|
|
|
|
padding: 0 60px;
|
|
|
|
|
.player-cover,
|
|
|
|
|
.player-data {
|
|
|
|
|
width: 100%;
|
2024-01-08 18:20:47 +08:00
|
|
|
}
|
2024-09-26 11:57:23 +08:00
|
|
|
.player-cover {
|
|
|
|
|
&.record {
|
|
|
|
|
:deep(.cover-img) {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
min-width: auto;
|
|
|
|
|
}
|
|
|
|
|
:deep(.pointer) {
|
|
|
|
|
top: -13.5vh;
|
2024-01-08 18:20:47 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-23 18:28:53 +08:00
|
|
|
}
|
|
|
|
|
</style>
|