修复播放器
This commit is contained in:
parent
e7beed15cd
commit
4ce5492139
@ -92,12 +92,10 @@
|
|||||||
:songServer="playerData.server"
|
:songServer="playerData.server"
|
||||||
:songType="playerData.type"
|
:songType="playerData.type"
|
||||||
:songId="playerData.id"
|
:songId="playerData.id"
|
||||||
|
:volume="volumeNum"
|
||||||
|
:shuffle="true"
|
||||||
ref="playerRef"
|
ref="playerRef"
|
||||||
/>
|
/>
|
||||||
<div class="error" v-if="!store.musicIsOk">
|
|
||||||
<play-wrong theme="outline" size="60" />
|
|
||||||
<span>音乐播放器加载失败</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
@ -105,7 +103,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, watch, onMounted } from "vue";
|
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||||
import {
|
import {
|
||||||
GoStart,
|
GoStart,
|
||||||
PlayOne,
|
PlayOne,
|
||||||
@ -115,7 +113,6 @@ import {
|
|||||||
VolumeMute,
|
VolumeMute,
|
||||||
VolumeSmall,
|
VolumeSmall,
|
||||||
VolumeNotice,
|
VolumeNotice,
|
||||||
PlayWrong,
|
|
||||||
} from "@icon-park/vue-next";
|
} from "@icon-park/vue-next";
|
||||||
import Player from "@/components/Player/index.vue";
|
import Player from "@/components/Player/index.vue";
|
||||||
import { mainStore } from "@/store";
|
import { mainStore } from "@/store";
|
||||||
@ -123,11 +120,7 @@ const store = mainStore();
|
|||||||
|
|
||||||
// 音量条数据
|
// 音量条数据
|
||||||
let volumeShow = ref(false);
|
let volumeShow = ref(false);
|
||||||
let volumeNum = ref(
|
let volumeNum = ref(store.musicVolume ? store.musicVolume : 0.7);
|
||||||
localStorage.getItem("aplayer-setting")
|
|
||||||
? JSON.parse(localStorage.getItem("aplayer-setting")).volume
|
|
||||||
: 0.7
|
|
||||||
);
|
|
||||||
|
|
||||||
// 播放列表数据
|
// 播放列表数据
|
||||||
let musicListShow = ref(false);
|
let musicListShow = ref(false);
|
||||||
@ -138,23 +131,21 @@ const playerData = reactive({
|
|||||||
type: import.meta.env.VITE_SONG_TYPE,
|
type: import.meta.env.VITE_SONG_TYPE,
|
||||||
id: import.meta.env.VITE_SONG_ID,
|
id: import.meta.env.VITE_SONG_ID,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 音乐播放暂停
|
// 音乐播放暂停
|
||||||
const changePlayState = () => {
|
const changePlayState = () => {
|
||||||
playerRef.value.playToggle();
|
playerRef.value.playToggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 音乐上下曲
|
// 音乐上下曲
|
||||||
const changeMusicIndex = (type) => {
|
const changeMusicIndex = (type) => {
|
||||||
if (type) {
|
playerRef.value.changeSong(type);
|
||||||
playerRef.value.changeSongPrev();
|
|
||||||
} else {
|
|
||||||
playerRef.value.changeSongNext();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 空格键事件
|
// 空格键事件
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
if (e.code == "Space" && store.musicIsOk) {
|
if (e.code == "Space") {
|
||||||
changePlayState();
|
changePlayState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -164,8 +155,8 @@ onMounted(() => {
|
|||||||
watch(
|
watch(
|
||||||
() => volumeNum.value,
|
() => volumeNum.value,
|
||||||
(value) => {
|
(value) => {
|
||||||
console.log(value);
|
store.musicVolume = value;
|
||||||
playerRef.value.changeVolume(value);
|
playerRef.value.changeVolume(store.musicVolume);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
@ -184,12 +175,10 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.5s;
|
-webkit-animation: fade 0.5s;
|
||||||
|
|
||||||
.btns {
|
.btns {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
background: #ffffff26;
|
background: #ffffff26;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -198,20 +187,17 @@ watch(
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ffffff4d;
|
background: #ffffff4d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.state {
|
.state {
|
||||||
.i-icon {
|
.i-icon {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@ -219,7 +205,6 @@ watch(
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.i-icon {
|
.i-icon {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
@ -229,17 +214,14 @@ watch(
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ffffff33;
|
background: #ffffff33;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -248,18 +230,15 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
// font-size: 1.1rem;
|
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.3s;
|
-webkit-animation: fade 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume {
|
.volume {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
@ -268,25 +247,20 @@ watch(
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.3s;
|
-webkit-animation: fade 0.3s;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(*) {
|
:deep(*) {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-slider__button) {
|
:deep(.el-slider__button) {
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-slider {
|
.el-slider {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
--el-slider-main-bg-color: #efefef;
|
--el-slider-main-bg-color: #efefef;
|
||||||
@ -296,7 +270,6 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.music-list {
|
.music-list {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -307,7 +280,6 @@ watch(
|
|||||||
background-color: #00000080;
|
background-color: #00000080;
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -320,7 +292,6 @@ watch(
|
|||||||
background-color: #ffffff66;
|
background-color: #ffffff66;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
@ -328,33 +299,22 @@ watch(
|
|||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
.i-icon {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 弹窗动画
|
// 弹窗动画
|
||||||
.fade-enter-active {
|
.fade-enter-active {
|
||||||
animation: fade 0.3s ease-in-out;
|
animation: fade 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
animation: fade 0.3s ease-in-out reverse;
|
animation: fade 0.3s ease-in-out reverse;
|
||||||
}
|
}
|
||||||
.zoom-enter-active {
|
.zoom-enter-active {
|
||||||
animation: zoom 0.4s ease-in-out;
|
animation: zoom 0.4s ease-in-out;
|
||||||
|
@ -92,10 +92,12 @@
|
|||||||
:songServer="playerData.server"
|
:songServer="playerData.server"
|
||||||
:songType="playerData.type"
|
:songType="playerData.type"
|
||||||
:songId="playerData.id"
|
:songId="playerData.id"
|
||||||
:volume="volumeNum"
|
|
||||||
:shuffle="true"
|
|
||||||
ref="playerRef"
|
ref="playerRef"
|
||||||
/>
|
/>
|
||||||
|
<div class="error" v-if="!store.musicIsOk">
|
||||||
|
<play-wrong theme="outline" size="60" />
|
||||||
|
<span>音乐播放器加载失败</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
@ -103,7 +105,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
import { ref, reactive, watch, onMounted } from "vue";
|
||||||
import {
|
import {
|
||||||
GoStart,
|
GoStart,
|
||||||
PlayOne,
|
PlayOne,
|
||||||
@ -113,14 +115,19 @@ import {
|
|||||||
VolumeMute,
|
VolumeMute,
|
||||||
VolumeSmall,
|
VolumeSmall,
|
||||||
VolumeNotice,
|
VolumeNotice,
|
||||||
|
PlayWrong,
|
||||||
} from "@icon-park/vue-next";
|
} from "@icon-park/vue-next";
|
||||||
import Player from "@/components/Player/Beta.vue";
|
import Player from "@/components/Player/index.vue";
|
||||||
import { mainStore } from "@/store";
|
import { mainStore } from "@/store";
|
||||||
const store = mainStore();
|
const store = mainStore();
|
||||||
|
|
||||||
// 音量条数据
|
// 音量条数据
|
||||||
let volumeShow = ref(false);
|
let volumeShow = ref(false);
|
||||||
let volumeNum = ref(store.musicVolume ? store.musicVolume : 0.7);
|
let volumeNum = ref(
|
||||||
|
localStorage.getItem("aplayer-setting")
|
||||||
|
? JSON.parse(localStorage.getItem("aplayer-setting")).volume
|
||||||
|
: 0.7
|
||||||
|
);
|
||||||
|
|
||||||
// 播放列表数据
|
// 播放列表数据
|
||||||
let musicListShow = ref(false);
|
let musicListShow = ref(false);
|
||||||
@ -131,21 +138,23 @@ const playerData = reactive({
|
|||||||
type: import.meta.env.VITE_SONG_TYPE,
|
type: import.meta.env.VITE_SONG_TYPE,
|
||||||
id: import.meta.env.VITE_SONG_ID,
|
id: import.meta.env.VITE_SONG_ID,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 音乐播放暂停
|
// 音乐播放暂停
|
||||||
const changePlayState = () => {
|
const changePlayState = () => {
|
||||||
playerRef.value.playToggle();
|
playerRef.value.playToggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 音乐上下曲
|
// 音乐上下曲
|
||||||
const changeMusicIndex = (type) => {
|
const changeMusicIndex = (type) => {
|
||||||
playerRef.value.changeSong(type);
|
if (type) {
|
||||||
|
playerRef.value.changeSongPrev();
|
||||||
|
} else {
|
||||||
|
playerRef.value.changeSongNext();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 空格键事件
|
// 空格键事件
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
if (e.code == "Space") {
|
if (e.code == "Space" && store.musicIsOk) {
|
||||||
changePlayState();
|
changePlayState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -155,8 +164,8 @@ onMounted(() => {
|
|||||||
watch(
|
watch(
|
||||||
() => volumeNum.value,
|
() => volumeNum.value,
|
||||||
(value) => {
|
(value) => {
|
||||||
store.musicVolume = value;
|
console.log(value);
|
||||||
playerRef.value.changeVolume(store.musicVolume);
|
playerRef.value.changeVolume(value);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
@ -175,10 +184,12 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.5s;
|
-webkit-animation: fade 0.5s;
|
||||||
|
|
||||||
.btns {
|
.btns {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
background: #ffffff26;
|
background: #ffffff26;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -187,17 +198,20 @@ watch(
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ffffff4d;
|
background: #ffffff4d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.state {
|
.state {
|
||||||
.i-icon {
|
.i-icon {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@ -205,6 +219,7 @@ watch(
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.i-icon {
|
.i-icon {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
@ -214,14 +229,17 @@ watch(
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ffffff33;
|
background: #ffffff33;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -230,15 +248,18 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
// font-size: 1.1rem;
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.3s;
|
-webkit-animation: fade 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume {
|
.volume {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
@ -247,20 +268,25 @@ watch(
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
animation: fade;
|
animation: fade;
|
||||||
-webkit-animation: fade 0.3s;
|
-webkit-animation: fade 0.3s;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(*) {
|
:deep(*) {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-slider__button) {
|
:deep(.el-slider__button) {
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-slider {
|
.el-slider {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
--el-slider-main-bg-color: #efefef;
|
--el-slider-main-bg-color: #efefef;
|
||||||
@ -270,6 +296,7 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.music-list {
|
.music-list {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -280,6 +307,7 @@ watch(
|
|||||||
background-color: #00000080;
|
background-color: #00000080;
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -292,6 +320,7 @@ watch(
|
|||||||
background-color: #ffffff66;
|
background-color: #ffffff66;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
@ -299,22 +328,33 @@ watch(
|
|||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
.i-icon {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 弹窗动画
|
// 弹窗动画
|
||||||
.fade-enter-active {
|
.fade-enter-active {
|
||||||
animation: fade 0.3s ease-in-out;
|
animation: fade 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
animation: fade 0.3s ease-in-out reverse;
|
animation: fade 0.3s ease-in-out reverse;
|
||||||
}
|
}
|
||||||
.zoom-enter-active {
|
.zoom-enter-active {
|
||||||
animation: zoom 0.4s ease-in-out;
|
animation: zoom 0.4s ease-in-out;
|
@ -1,306 +0,0 @@
|
|||||||
<template>
|
|
||||||
<aplayer
|
|
||||||
showLrc
|
|
||||||
ref="player"
|
|
||||||
v-if="playList[0]"
|
|
||||||
:music="playList[playIndex]"
|
|
||||||
:list="playList"
|
|
||||||
:autoplay="autoplay"
|
|
||||||
:theme="theme"
|
|
||||||
:repeat="repeat"
|
|
||||||
:shuffle="shuffle"
|
|
||||||
:listMaxHeight="listMaxHeight"
|
|
||||||
:listFolded="listFolded"
|
|
||||||
:volume="volume"
|
|
||||||
@play="onPlay"
|
|
||||||
@pause="onPause"
|
|
||||||
@timeupdate="onTimeUp"
|
|
||||||
@onSelectSong="onSelectSong"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
|
||||||
import aplayer from "vue3-aplayer";
|
|
||||||
import {
|
|
||||||
h,
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
nextTick,
|
|
||||||
onMounted,
|
|
||||||
onBeforeUnmount,
|
|
||||||
watch,
|
|
||||||
} from "vue";
|
|
||||||
import { getPlayerList } from "@/api";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 获取播放器 DOM
|
|
||||||
const player = ref(null);
|
|
||||||
|
|
||||||
// 歌曲播放列表
|
|
||||||
let playList = ref([]);
|
|
||||||
let playerLrc = ref("");
|
|
||||||
|
|
||||||
// 歌曲播放项
|
|
||||||
let playIndex = ref(0);
|
|
||||||
let playListCount = ref(0);
|
|
||||||
|
|
||||||
// 配置项
|
|
||||||
const props = defineProps({
|
|
||||||
// 音频自动播放
|
|
||||||
autoplay: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 主题色
|
|
||||||
theme: {
|
|
||||||
type: String,
|
|
||||||
default: "#efefef",
|
|
||||||
},
|
|
||||||
// 音频循环播放
|
|
||||||
repeat: {
|
|
||||||
type: String,
|
|
||||||
default: "list", //'list' | 'music' | 'none'
|
|
||||||
},
|
|
||||||
// 随机播放
|
|
||||||
shuffle: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 默认音量
|
|
||||||
volume: {
|
|
||||||
type: Number,
|
|
||||||
default: 0.7,
|
|
||||||
validator: (value) => {
|
|
||||||
return value >= 0 && value <= 1;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 歌曲服务器 ( netease-网易云, tencent-qq音乐, kugou-酷狗, xiami-小米音乐, baidu-百度音乐 )
|
|
||||||
songServer: {
|
|
||||||
type: String,
|
|
||||||
default: "netease", //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu'
|
|
||||||
},
|
|
||||||
// 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
|
||||||
songType: {
|
|
||||||
type: String,
|
|
||||||
default: "playlist",
|
|
||||||
},
|
|
||||||
// id
|
|
||||||
songId: {
|
|
||||||
type: String,
|
|
||||||
default: "7452421335",
|
|
||||||
},
|
|
||||||
// 列表是否默认折叠
|
|
||||||
listFolded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 列表最大高度
|
|
||||||
listMaxHeight: {
|
|
||||||
type: String,
|
|
||||||
default: "420px",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化播放器
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
getPlayerList(props.songServer, props.songType, props.songId)
|
|
||||||
.then((res) => {
|
|
||||||
// 生成歌单信息
|
|
||||||
playIndex.value = Math.floor(Math.random() * res.length);
|
|
||||||
playListCount.value = res.length;
|
|
||||||
// 更改播放器加载状态
|
|
||||||
store.musicIsOk = true;
|
|
||||||
console.log(
|
|
||||||
"音乐加载完成",
|
|
||||||
res,
|
|
||||||
playIndex.value,
|
|
||||||
playListCount.value,
|
|
||||||
props.volume
|
|
||||||
);
|
|
||||||
// 生成歌单
|
|
||||||
res.forEach((v) => {
|
|
||||||
playList.value.push({
|
|
||||||
title: v.name,
|
|
||||||
artist: v.artist,
|
|
||||||
src: v.url,
|
|
||||||
pic: v.pic,
|
|
||||||
lrc: v.lrc,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
store.musicIsOk = false;
|
|
||||||
ElMessage({
|
|
||||||
message: "播放器加载失败",
|
|
||||||
grouping: true,
|
|
||||||
icon: h(PlayWrong, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 播放暂停事件
|
|
||||||
const onPlay = () => {
|
|
||||||
console.log("播放");
|
|
||||||
// 播放状态
|
|
||||||
store.setPlayerState(player.value.audio.paused);
|
|
||||||
// 储存播放器信息
|
|
||||||
store.setPlayerData(
|
|
||||||
player.value.currentMusic.title,
|
|
||||||
player.value.currentMusic.artist
|
|
||||||
);
|
|
||||||
ElMessage({
|
|
||||||
message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
|
||||||
grouping: true,
|
|
||||||
icon: h(MusicOne, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const onPause = () => {
|
|
||||||
store.setPlayerState(player.value.audio.paused);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 音频时间更新事件
|
|
||||||
const onTimeUp = () => {
|
|
||||||
let playerRef = player.value.$.vnode.el;
|
|
||||||
if (playerRef) {
|
|
||||||
playerLrc.value = playerRef.getElementsByClassName(
|
|
||||||
"aplayer-lrc-current"
|
|
||||||
)[0].innerHTML;
|
|
||||||
store.setPlayerLrc(playerLrc.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换播放暂停事件
|
|
||||||
const playToggle = () => {
|
|
||||||
player.value.toggle();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换音量事件
|
|
||||||
const changeVolume = (value) => {
|
|
||||||
player.value.audio.volume = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSelectSong = (val) => {
|
|
||||||
console.log(val);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换上下曲
|
|
||||||
const changeSong = (type) => {
|
|
||||||
playIndex.value = player.value.playIndex;
|
|
||||||
playIndex.value += type ? 1 : -1;
|
|
||||||
// 判断是否处于最后/第一首
|
|
||||||
if (playIndex.value < 0) {
|
|
||||||
playIndex.value = playListCount.value - 1;
|
|
||||||
} else if (playIndex.value >= playListCount.value) {
|
|
||||||
playIndex.value = 0;
|
|
||||||
}
|
|
||||||
// console.log(playIndex.value, playList.value[playIndex.value]);
|
|
||||||
nextTick(() => {
|
|
||||||
player.value.play();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露子组件方法
|
|
||||||
defineExpose({ playToggle, changeVolume, changeSong });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
|
||||||
.aplayer {
|
|
||||||
width: 80%;
|
|
||||||
background: transparent;
|
|
||||||
border-radius: 6px;
|
|
||||||
:deep(.aplayer-body) {
|
|
||||||
.aplayer-pic {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.aplayer-info {
|
|
||||||
margin-left: 0;
|
|
||||||
background-color: #ffffff40;
|
|
||||||
border-color: transparent;
|
|
||||||
.aplayer-music {
|
|
||||||
flex-grow: initial;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
overflow: initial;
|
|
||||||
.aplayer-title {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
.aplayer-author {
|
|
||||||
color: #efefef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.aplayer-lrc {
|
|
||||||
text-align: left;
|
|
||||||
margin: 4px 0 6px 6px;
|
|
||||||
height: 100%;
|
|
||||||
mask: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
hsla(0, 0%, 100%, 0) 0,
|
|
||||||
hsla(0, 0%, 100%, 0.6) 10%,
|
|
||||||
#fff 15%,
|
|
||||||
#fff 85%,
|
|
||||||
hsla(0, 0%, 100%, 0.6) 90%,
|
|
||||||
hsla(0, 0%, 100%, 0)
|
|
||||||
);
|
|
||||||
-webkit-mask: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
hsla(0, 0%, 100%, 0) 0,
|
|
||||||
hsla(0, 0%, 100%, 0.6) 10%,
|
|
||||||
#fff 15%,
|
|
||||||
#fff 85%,
|
|
||||||
hsla(0, 0%, 100%, 0.6) 90%,
|
|
||||||
hsla(0, 0%, 100%, 0)
|
|
||||||
);
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: #efefef;
|
|
||||||
margin: 2px 0;
|
|
||||||
}
|
|
||||||
.aplayer-lrc-current {
|
|
||||||
font-size: 0.95rem;
|
|
||||||
margin-bottom: 4px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.aplayer-controller {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.aplayer-list) {
|
|
||||||
margin-top: 6px;
|
|
||||||
ol {
|
|
||||||
&::-webkit-scrollbar-track{
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
border-color: transparent;
|
|
||||||
&.aplayer-list-light {
|
|
||||||
background: #ffffff40;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
background: #ffffff26 !important;
|
|
||||||
border-radius: 6px !important;
|
|
||||||
}
|
|
||||||
.aplayer-list-index,
|
|
||||||
.aplayer-list-author {
|
|
||||||
color: #efefef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,11 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="playerRef"></div>
|
<aplayer
|
||||||
|
showLrc
|
||||||
|
ref="player"
|
||||||
|
v-if="playList[0]"
|
||||||
|
:music="playList[playIndex]"
|
||||||
|
:list="playList"
|
||||||
|
:autoplay="autoplay"
|
||||||
|
:theme="theme"
|
||||||
|
:repeat="repeat"
|
||||||
|
:shuffle="shuffle"
|
||||||
|
:listMaxHeight="listMaxHeight"
|
||||||
|
:listFolded="listFolded"
|
||||||
|
:volume="volume"
|
||||||
|
@play="onPlay"
|
||||||
|
@pause="onPause"
|
||||||
|
@timeupdate="onTimeUp"
|
||||||
|
@onSelectSong="onSelectSong"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
||||||
import APlayer from "APlayer";
|
import aplayer from "vue3-aplayer";
|
||||||
import "aplayer/dist/APlayer.min.css";
|
|
||||||
import {
|
import {
|
||||||
h,
|
h,
|
||||||
ref,
|
ref,
|
||||||
@ -17,51 +33,22 @@ import {
|
|||||||
} from "vue";
|
} from "vue";
|
||||||
import { getPlayerList } from "@/api";
|
import { getPlayerList } from "@/api";
|
||||||
import { mainStore } from "@/store";
|
import { mainStore } from "@/store";
|
||||||
|
|
||||||
const store = mainStore();
|
const store = mainStore();
|
||||||
|
|
||||||
const playerRef = ref();
|
// 获取播放器 DOM
|
||||||
const state = reactive({
|
const player = ref(null);
|
||||||
instance: null,
|
|
||||||
});
|
|
||||||
const playerData = reactive({
|
|
||||||
name: null,
|
|
||||||
artist: null,
|
|
||||||
lrc: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
// APlayer歌曲信息
|
// 歌曲播放列表
|
||||||
class Audio {
|
let playList = ref([]);
|
||||||
// 音频艺术家
|
let playerLrc = ref("");
|
||||||
// artist: String;
|
|
||||||
// 音频名称
|
|
||||||
// name: String;
|
|
||||||
// 音频链接
|
|
||||||
// url: String;
|
|
||||||
// 音频封面
|
|
||||||
// cover: String;
|
|
||||||
// 歌词
|
|
||||||
// lrc: String;
|
|
||||||
|
|
||||||
constructor(artist, name, url, cover, lrc) {
|
// 歌曲播放项
|
||||||
this.artist = artist;
|
let playIndex = ref(0);
|
||||||
this.name = name;
|
let playListCount = ref(0);
|
||||||
this.url = url;
|
|
||||||
this.cover = cover;
|
|
||||||
this.lrc = lrc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 配置项
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 开启吸底模式
|
|
||||||
fixed: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 开启迷你模式
|
|
||||||
mini: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 音频自动播放
|
// 音频自动播放
|
||||||
autoplay: {
|
autoplay: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -73,19 +60,14 @@ const props = defineProps({
|
|||||||
default: "#efefef",
|
default: "#efefef",
|
||||||
},
|
},
|
||||||
// 音频循环播放
|
// 音频循环播放
|
||||||
loop: {
|
repeat: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "all", //'all' | 'one' | 'none'
|
default: "list", //'list' | 'music' | 'none'
|
||||||
},
|
},
|
||||||
// 音频循环顺序
|
// 随机播放
|
||||||
order: {
|
shuffle: {
|
||||||
type: String,
|
type: Boolean,
|
||||||
default: "random", //'list' | 'random'
|
default: false,
|
||||||
},
|
|
||||||
// 预加载
|
|
||||||
preload: {
|
|
||||||
type: String,
|
|
||||||
default: "auto", //'auto' | 'metadata' | 'none'
|
|
||||||
},
|
},
|
||||||
// 默认音量
|
// 默认音量
|
||||||
volume: {
|
volume: {
|
||||||
@ -110,16 +92,6 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "7452421335",
|
default: "7452421335",
|
||||||
},
|
},
|
||||||
// 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
|
|
||||||
mutex: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
// 传递歌词方式
|
|
||||||
lrcType: {
|
|
||||||
type: Number,
|
|
||||||
default: 3,
|
|
||||||
},
|
|
||||||
// 列表是否默认折叠
|
// 列表是否默认折叠
|
||||||
listFolded: {
|
listFolded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -130,11 +102,6 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "420px",
|
default: "420px",
|
||||||
},
|
},
|
||||||
// 存储播放器设置的 localStorage key
|
|
||||||
storageName: {
|
|
||||||
type: String,
|
|
||||||
default: "aplayer-setting",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化播放器
|
// 初始化播放器
|
||||||
@ -142,67 +109,28 @@ onMounted(() => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
getPlayerList(props.songServer, props.songType, props.songId)
|
getPlayerList(props.songServer, props.songType, props.songId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// console.log(res);
|
// 生成歌单信息
|
||||||
|
playIndex.value = Math.floor(Math.random() * res.length);
|
||||||
|
playListCount.value = res.length;
|
||||||
// 更改播放器加载状态
|
// 更改播放器加载状态
|
||||||
store.musicIsOk = true;
|
store.musicIsOk = true;
|
||||||
console.log("音乐加载完成");
|
console.log(
|
||||||
let audioList = res.map(
|
"音乐加载完成",
|
||||||
(value) =>
|
res,
|
||||||
new Audio(value.artist, value.name, value.url, value.pic, value.lrc)
|
playIndex.value,
|
||||||
|
playListCount.value,
|
||||||
|
props.volume
|
||||||
);
|
);
|
||||||
state.instance = new APlayer({
|
// 生成歌单
|
||||||
container: playerRef.value,
|
res.forEach((v) => {
|
||||||
fixed: props.fixed,
|
playList.value.push({
|
||||||
mini: props.mini,
|
title: v.name,
|
||||||
autoplay: props.autoplay,
|
artist: v.artist,
|
||||||
theme: props.theme,
|
src: v.url,
|
||||||
loop: props.loop,
|
pic: v.pic,
|
||||||
order: props.order,
|
lrc: v.lrc,
|
||||||
preload: props.preload,
|
|
||||||
volume: props.volume,
|
|
||||||
mutex: props.mutex,
|
|
||||||
lrcType: props.lrcType,
|
|
||||||
listFolded: props.listFolded,
|
|
||||||
listMaxHeight: props.listMaxHeight,
|
|
||||||
storageName: props.storageName,
|
|
||||||
audio: audioList,
|
|
||||||
});
|
|
||||||
|
|
||||||
state.instance.on("play", () => {
|
|
||||||
// 播放状态
|
|
||||||
store.setPlayerState(state.instance.audio.paused);
|
|
||||||
// 储存播放器信息
|
|
||||||
store.setPlayerData(
|
|
||||||
playerRef.value.getElementsByClassName("aplayer-title")[0]
|
|
||||||
.innerHTML,
|
|
||||||
playerRef.value
|
|
||||||
.getElementsByClassName("aplayer-author")[0]
|
|
||||||
.innerHTML.split("-")[1]
|
|
||||||
.trim()
|
|
||||||
);
|
|
||||||
ElMessage({
|
|
||||||
message:
|
|
||||||
store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
|
||||||
grouping: true,
|
|
||||||
icon: h(MusicOne, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
state.instance.on("pause", () => {
|
|
||||||
// 播放状态
|
|
||||||
store.setPlayerState(state.instance.audio.paused);
|
|
||||||
});
|
|
||||||
|
|
||||||
state.instance.on("timeupdate", () => {
|
|
||||||
if (playerRef.value) {
|
|
||||||
playerData.lrc = playerRef.value.getElementsByClassName(
|
|
||||||
"aplayer-lrc-current"
|
|
||||||
)[0].innerHTML;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
store.musicIsOk = false;
|
store.musicIsOk = false;
|
||||||
@ -218,41 +146,72 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 销毁播放器
|
// 播放暂停事件
|
||||||
onBeforeUnmount(() => {
|
const onPlay = () => {
|
||||||
state.instance.destroy();
|
console.log("播放");
|
||||||
});
|
// 播放状态
|
||||||
|
store.setPlayerState(player.value.audio.paused);
|
||||||
|
// 储存播放器信息
|
||||||
|
store.setPlayerData(
|
||||||
|
player.value.currentMusic.title,
|
||||||
|
player.value.currentMusic.artist
|
||||||
|
);
|
||||||
|
ElMessage({
|
||||||
|
message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
||||||
|
grouping: true,
|
||||||
|
icon: h(MusicOne, {
|
||||||
|
theme: "filled",
|
||||||
|
fill: "#efefef",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onPause = () => {
|
||||||
|
store.setPlayerState(player.value.audio.paused);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 音频时间更新事件
|
||||||
|
const onTimeUp = () => {
|
||||||
|
let playerRef = player.value.$.vnode.el;
|
||||||
|
if (playerRef) {
|
||||||
|
playerLrc.value = playerRef.getElementsByClassName(
|
||||||
|
"aplayer-lrc-current"
|
||||||
|
)[0].innerHTML;
|
||||||
|
store.setPlayerLrc(playerLrc.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 切换播放暂停事件
|
// 切换播放暂停事件
|
||||||
const playToggle = () => {
|
const playToggle = () => {
|
||||||
state.instance.toggle();
|
player.value.toggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换音量事件
|
// 切换音量事件
|
||||||
const changeVolume = (value) => {
|
const changeVolume = (value) => {
|
||||||
state.instance.volume(value);
|
player.value.audio.volume = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelectSong = (val) => {
|
||||||
|
console.log(val);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换上下曲
|
// 切换上下曲
|
||||||
const changeSongPrev = () => {
|
const changeSong = (type) => {
|
||||||
state.instance.skipBack();
|
playIndex.value = player.value.playIndex;
|
||||||
};
|
playIndex.value += type ? 1 : -1;
|
||||||
const changeSongNext = () => {
|
// 判断是否处于最后/第一首
|
||||||
state.instance.skipForward();
|
if (playIndex.value < 0) {
|
||||||
|
playIndex.value = playListCount.value - 1;
|
||||||
|
} else if (playIndex.value >= playListCount.value) {
|
||||||
|
playIndex.value = 0;
|
||||||
|
}
|
||||||
|
// console.log(playIndex.value, playList.value[playIndex.value]);
|
||||||
|
nextTick(() => {
|
||||||
|
player.value.play();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暴露子组件方法
|
// 暴露子组件方法
|
||||||
defineExpose({ playToggle, changeVolume, changeSongPrev, changeSongNext });
|
defineExpose({ playToggle, changeVolume, changeSong });
|
||||||
|
|
||||||
// 监听歌词变化
|
|
||||||
watch(
|
|
||||||
() => playerData.lrc,
|
|
||||||
(value) => {
|
|
||||||
console.log(value);
|
|
||||||
// 储存至 pinia
|
|
||||||
store.setPlayerLrc(value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
@ -268,22 +227,47 @@ watch(
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
background-color: #ffffff40;
|
background-color: #ffffff40;
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
.aplayer-title {
|
.aplayer-music {
|
||||||
font-size: 16px;
|
flex-grow: initial;
|
||||||
}
|
margin-bottom: 2px;
|
||||||
.aplayer-author {
|
overflow: initial;
|
||||||
color: #efefef;
|
.aplayer-title {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
.aplayer-author {
|
||||||
|
color: #efefef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.aplayer-lrc {
|
.aplayer-lrc {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin: 4px 0 0 6px;
|
margin: 4px 0 6px 6px;
|
||||||
height: 38px;
|
height: 100%;
|
||||||
|
mask: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
hsla(0, 0%, 100%, 0) 0,
|
||||||
|
hsla(0, 0%, 100%, 0.6) 10%,
|
||||||
|
#fff 15%,
|
||||||
|
#fff 85%,
|
||||||
|
hsla(0, 0%, 100%, 0.6) 90%,
|
||||||
|
hsla(0, 0%, 100%, 0)
|
||||||
|
);
|
||||||
|
-webkit-mask: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
hsla(0, 0%, 100%, 0) 0,
|
||||||
|
hsla(0, 0%, 100%, 0.6) 10%,
|
||||||
|
#fff 15%,
|
||||||
|
#fff 85%,
|
||||||
|
hsla(0, 0%, 100%, 0.6) 90%,
|
||||||
|
hsla(0, 0%, 100%, 0)
|
||||||
|
);
|
||||||
&::before,
|
&::before,
|
||||||
&::after {
|
&::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
color: #efefef;
|
color: #efefef;
|
||||||
|
margin: 2px 0;
|
||||||
}
|
}
|
||||||
.aplayer-lrc-current {
|
.aplayer-lrc-current {
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
@ -298,6 +282,9 @@ watch(
|
|||||||
:deep(.aplayer-list) {
|
:deep(.aplayer-list) {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
ol {
|
ol {
|
||||||
|
&::-webkit-scrollbar-track{
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
li {
|
li {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
&.aplayer-list-light {
|
&.aplayer-list-light {
|
||||||
|
319
src/components/Player/old.vue
Normal file
319
src/components/Player/old.vue
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="playerRef"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
||||||
|
import APlayer from "APlayer";
|
||||||
|
import "aplayer/dist/APlayer.min.css";
|
||||||
|
import {
|
||||||
|
h,
|
||||||
|
ref,
|
||||||
|
reactive,
|
||||||
|
nextTick,
|
||||||
|
onMounted,
|
||||||
|
onBeforeUnmount,
|
||||||
|
watch,
|
||||||
|
} from "vue";
|
||||||
|
import { getPlayerList } from "@/api";
|
||||||
|
import { mainStore } from "@/store";
|
||||||
|
const store = mainStore();
|
||||||
|
|
||||||
|
const playerRef = ref();
|
||||||
|
const state = reactive({
|
||||||
|
instance: null,
|
||||||
|
});
|
||||||
|
const playerData = reactive({
|
||||||
|
name: null,
|
||||||
|
artist: null,
|
||||||
|
lrc: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
// APlayer歌曲信息
|
||||||
|
class Audio {
|
||||||
|
// 音频艺术家
|
||||||
|
// artist: String;
|
||||||
|
// 音频名称
|
||||||
|
// name: String;
|
||||||
|
// 音频链接
|
||||||
|
// url: String;
|
||||||
|
// 音频封面
|
||||||
|
// cover: String;
|
||||||
|
// 歌词
|
||||||
|
// lrc: String;
|
||||||
|
|
||||||
|
constructor(artist, name, url, cover, lrc) {
|
||||||
|
this.artist = artist;
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
this.cover = cover;
|
||||||
|
this.lrc = lrc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 开启吸底模式
|
||||||
|
fixed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 开启迷你模式
|
||||||
|
mini: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 音频自动播放
|
||||||
|
autoplay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 主题色
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
default: "#efefef",
|
||||||
|
},
|
||||||
|
// 音频循环播放
|
||||||
|
loop: {
|
||||||
|
type: String,
|
||||||
|
default: "all", //'all' | 'one' | 'none'
|
||||||
|
},
|
||||||
|
// 音频循环顺序
|
||||||
|
order: {
|
||||||
|
type: String,
|
||||||
|
default: "random", //'list' | 'random'
|
||||||
|
},
|
||||||
|
// 预加载
|
||||||
|
preload: {
|
||||||
|
type: String,
|
||||||
|
default: "auto", //'auto' | 'metadata' | 'none'
|
||||||
|
},
|
||||||
|
// 默认音量
|
||||||
|
volume: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.7,
|
||||||
|
validator: (value) => {
|
||||||
|
return value >= 0 && value <= 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 歌曲服务器 ( netease-网易云, tencent-qq音乐, kugou-酷狗, xiami-小米音乐, baidu-百度音乐 )
|
||||||
|
songServer: {
|
||||||
|
type: String,
|
||||||
|
default: "netease", //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu'
|
||||||
|
},
|
||||||
|
// 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
||||||
|
songType: {
|
||||||
|
type: String,
|
||||||
|
default: "playlist",
|
||||||
|
},
|
||||||
|
// id
|
||||||
|
songId: {
|
||||||
|
type: String,
|
||||||
|
default: "7452421335",
|
||||||
|
},
|
||||||
|
// 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
|
||||||
|
mutex: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 传递歌词方式
|
||||||
|
lrcType: {
|
||||||
|
type: Number,
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
// 列表是否默认折叠
|
||||||
|
listFolded: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 列表最大高度
|
||||||
|
listMaxHeight: {
|
||||||
|
type: String,
|
||||||
|
default: "420px",
|
||||||
|
},
|
||||||
|
// 存储播放器设置的 localStorage key
|
||||||
|
storageName: {
|
||||||
|
type: String,
|
||||||
|
default: "aplayer-setting",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化播放器
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
getPlayerList(props.songServer, props.songType, props.songId)
|
||||||
|
.then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// 更改播放器加载状态
|
||||||
|
store.musicIsOk = true;
|
||||||
|
console.log("音乐加载完成");
|
||||||
|
let audioList = res.map(
|
||||||
|
(value) =>
|
||||||
|
new Audio(value.artist, value.name, value.url, value.pic, value.lrc)
|
||||||
|
);
|
||||||
|
state.instance = new APlayer({
|
||||||
|
container: playerRef.value,
|
||||||
|
fixed: props.fixed,
|
||||||
|
mini: props.mini,
|
||||||
|
autoplay: props.autoplay,
|
||||||
|
theme: props.theme,
|
||||||
|
loop: props.loop,
|
||||||
|
order: props.order,
|
||||||
|
preload: props.preload,
|
||||||
|
volume: props.volume,
|
||||||
|
mutex: props.mutex,
|
||||||
|
lrcType: props.lrcType,
|
||||||
|
listFolded: props.listFolded,
|
||||||
|
listMaxHeight: props.listMaxHeight,
|
||||||
|
storageName: props.storageName,
|
||||||
|
audio: audioList,
|
||||||
|
});
|
||||||
|
|
||||||
|
state.instance.on("play", () => {
|
||||||
|
// 播放状态
|
||||||
|
store.setPlayerState(state.instance.audio.paused);
|
||||||
|
// 储存播放器信息
|
||||||
|
store.setPlayerData(
|
||||||
|
playerRef.value.getElementsByClassName("aplayer-title")[0]
|
||||||
|
.innerHTML,
|
||||||
|
playerRef.value
|
||||||
|
.getElementsByClassName("aplayer-author")[0]
|
||||||
|
.innerHTML.split("-")[1]
|
||||||
|
.trim()
|
||||||
|
);
|
||||||
|
ElMessage({
|
||||||
|
message:
|
||||||
|
store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
||||||
|
grouping: true,
|
||||||
|
icon: h(MusicOne, {
|
||||||
|
theme: "filled",
|
||||||
|
fill: "#efefef",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
state.instance.on("pause", () => {
|
||||||
|
// 播放状态
|
||||||
|
store.setPlayerState(state.instance.audio.paused);
|
||||||
|
});
|
||||||
|
|
||||||
|
state.instance.on("timeupdate", () => {
|
||||||
|
if (playerRef.value) {
|
||||||
|
playerData.lrc = playerRef.value.getElementsByClassName(
|
||||||
|
"aplayer-lrc-current"
|
||||||
|
)[0].innerHTML;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
store.musicIsOk = false;
|
||||||
|
ElMessage({
|
||||||
|
message: "播放器加载失败",
|
||||||
|
grouping: true,
|
||||||
|
icon: h(PlayWrong, {
|
||||||
|
theme: "filled",
|
||||||
|
fill: "#efefef",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 销毁播放器
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
state.instance.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 切换播放暂停事件
|
||||||
|
const playToggle = () => {
|
||||||
|
state.instance.toggle();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换音量事件
|
||||||
|
const changeVolume = (value) => {
|
||||||
|
state.instance.volume(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换上下曲
|
||||||
|
const changeSongPrev = () => {
|
||||||
|
state.instance.skipBack();
|
||||||
|
};
|
||||||
|
const changeSongNext = () => {
|
||||||
|
state.instance.skipForward();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露子组件方法
|
||||||
|
defineExpose({ playToggle, changeVolume, changeSongPrev, changeSongNext });
|
||||||
|
|
||||||
|
// 监听歌词变化
|
||||||
|
watch(
|
||||||
|
() => playerData.lrc,
|
||||||
|
(value) => {
|
||||||
|
console.log(value);
|
||||||
|
// 储存至 pinia
|
||||||
|
store.setPlayerLrc(value);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
.aplayer {
|
||||||
|
width: 80%;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 6px;
|
||||||
|
:deep(.aplayer-body) {
|
||||||
|
.aplayer-pic {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.aplayer-info {
|
||||||
|
margin-left: 0;
|
||||||
|
background-color: #ffffff40;
|
||||||
|
border-color: transparent;
|
||||||
|
.aplayer-title {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.aplayer-author {
|
||||||
|
color: #efefef;
|
||||||
|
}
|
||||||
|
.aplayer-lrc {
|
||||||
|
text-align: left;
|
||||||
|
margin: 4px 0 0 6px;
|
||||||
|
height: 38px;
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #efefef;
|
||||||
|
}
|
||||||
|
.aplayer-lrc-current {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
margin-bottom: 4px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.aplayer-controller {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.aplayer-list) {
|
||||||
|
margin-top: 6px;
|
||||||
|
ol {
|
||||||
|
li {
|
||||||
|
border-color: transparent;
|
||||||
|
&.aplayer-list-light {
|
||||||
|
background: #ffffff40;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: #ffffff26 !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
}
|
||||||
|
.aplayer-list-index,
|
||||||
|
.aplayer-list-author {
|
||||||
|
color: #efefef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onBeforeUnmount } from "vue";
|
import { ref, onMounted, onBeforeUnmount } from "vue";
|
||||||
import Music from "@/components/Music/test.vue";
|
import Music from "@/components/Music/index.vue";
|
||||||
import Hitokoto from "@/components/Hitokoto/index.vue";
|
import Hitokoto from "@/components/Hitokoto/index.vue";
|
||||||
import Weather from "@/components/Weather/index.vue";
|
import Weather from "@/components/Weather/index.vue";
|
||||||
import { getCurrentTime } from "@/utils/getTime";
|
import { getCurrentTime } from "@/utils/getTime";
|
||||||
|
Loading…
Reference in New Issue
Block a user