2023-01-15 05:22:30 +00:00
|
|
|
<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>
|
2023-02-16 02:57:30 +00:00
|
|
|
|
2023-01-15 05:22:30 +00:00
|
|
|
<script setup>
|
2023-08-26 08:03:07 +00:00
|
|
|
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
|
|
|
import { getPlayerList } from "@/api";
|
|
|
|
import { mainStore } from "@/store";
|
|
|
|
import aplayer from "vue3-aplayer";
|
2023-01-15 05:22:30 +00:00
|
|
|
|
|
|
|
const store = mainStore();
|
|
|
|
|
|
|
|
// 获取播放器 DOM
|
|
|
|
const player = ref(null);
|
|
|
|
|
|
|
|
// 歌曲播放列表
|
2023-04-21 08:37:08 +00:00
|
|
|
const playList = ref([]);
|
2023-01-15 05:22:30 +00:00
|
|
|
|
|
|
|
// 歌曲播放项
|
2023-04-21 08:37:08 +00:00
|
|
|
const playIndex = ref(0);
|
|
|
|
const playListCount = ref(0);
|
2023-01-15 05:22:30 +00:00
|
|
|
|
|
|
|
// 配置项
|
|
|
|
const props = defineProps({
|
|
|
|
// 音频自动播放
|
|
|
|
autoplay: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
// 主题色
|
|
|
|
theme: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "#efefef",
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
// 音频循环播放
|
|
|
|
repeat: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "list", //'list' | 'music' | 'none'
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
// 随机播放
|
|
|
|
shuffle: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
// 默认音量
|
|
|
|
volume: {
|
|
|
|
type: Number,
|
|
|
|
default: 0.7,
|
|
|
|
validator: (value) => {
|
|
|
|
return value >= 0 && value <= 1;
|
|
|
|
},
|
|
|
|
},
|
2023-08-16 10:24:10 +00:00
|
|
|
// 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
|
2023-01-15 05:22:30 +00:00
|
|
|
songServer: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "netease", //'netease' | 'tencent'
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
// 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
|
|
|
songType: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "playlist",
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
// id
|
|
|
|
songId: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "7452421335",
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
// 列表是否默认折叠
|
|
|
|
listFolded: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
// 列表最大高度
|
|
|
|
listMaxHeight: {
|
|
|
|
type: String,
|
2023-08-26 08:03:07 +00:00
|
|
|
default: "420px",
|
2023-01-15 05:22:30 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
// 初始化播放器
|
|
|
|
onMounted(() => {
|
|
|
|
nextTick(() => {
|
2023-03-09 07:39:52 +00:00
|
|
|
try {
|
2023-08-23 05:38:17 +00:00
|
|
|
getPlayerList(props.songServer, props.songType, props.songId).then((res) => {
|
|
|
|
console.log(res);
|
|
|
|
// 生成歌单信息
|
|
|
|
playIndex.value = Math.floor(Math.random() * res.length);
|
|
|
|
playListCount.value = res.length;
|
|
|
|
// 更改播放器加载状态
|
|
|
|
store.musicIsOk = true;
|
|
|
|
// 生成歌单
|
|
|
|
res.forEach((v) => {
|
|
|
|
playList.value.push({
|
|
|
|
title: v.name || v.title,
|
|
|
|
artist: v.artist || v.author,
|
|
|
|
src: v.url || v.src,
|
|
|
|
pic: v.pic,
|
|
|
|
lrc: v.lrc,
|
2023-01-15 05:22:30 +00:00
|
|
|
});
|
2023-08-23 05:38:17 +00:00
|
|
|
});
|
|
|
|
console.log(
|
2023-08-26 08:03:07 +00:00
|
|
|
"音乐加载完成",
|
2023-08-23 05:38:17 +00:00
|
|
|
playList.value,
|
|
|
|
playIndex.value,
|
|
|
|
playListCount.value,
|
|
|
|
props.volume,
|
|
|
|
);
|
|
|
|
});
|
2023-03-09 07:39:52 +00:00
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
store.musicIsOk = false;
|
|
|
|
ElMessage({
|
2023-08-26 08:03:07 +00:00
|
|
|
message: "播放器加载失败",
|
2023-03-09 07:39:52 +00:00
|
|
|
grouping: true,
|
|
|
|
icon: h(PlayWrong, {
|
2023-08-26 08:03:07 +00:00
|
|
|
theme: "filled",
|
|
|
|
fill: "#efefef",
|
2023-03-09 07:39:52 +00:00
|
|
|
}),
|
2023-01-15 05:22:30 +00:00
|
|
|
});
|
2023-03-09 07:39:52 +00:00
|
|
|
}
|
2023-01-15 05:22:30 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-08-16 10:24:10 +00:00
|
|
|
// 播放
|
2023-01-15 05:22:30 +00:00
|
|
|
const onPlay = () => {
|
2023-08-26 08:03:07 +00:00
|
|
|
console.log("播放");
|
2023-01-15 05:22:30 +00:00
|
|
|
// 播放状态
|
|
|
|
store.setPlayerState(player.value.audio.paused);
|
|
|
|
// 储存播放器信息
|
2023-08-23 05:38:17 +00:00
|
|
|
store.setPlayerData(player.value.currentMusic.title, player.value.currentMusic.artist);
|
2023-01-15 05:22:30 +00:00
|
|
|
ElMessage({
|
2023-08-26 08:03:07 +00:00
|
|
|
message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
2023-01-15 05:22:30 +00:00
|
|
|
grouping: true,
|
|
|
|
icon: h(MusicOne, {
|
2023-08-26 08:03:07 +00:00
|
|
|
theme: "filled",
|
|
|
|
fill: "#efefef",
|
2023-01-15 05:22:30 +00:00
|
|
|
}),
|
|
|
|
});
|
|
|
|
};
|
2023-08-16 10:24:10 +00:00
|
|
|
|
|
|
|
// 暂停
|
2023-01-15 05:22:30 +00:00
|
|
|
const onPause = () => {
|
|
|
|
store.setPlayerState(player.value.audio.paused);
|
|
|
|
};
|
|
|
|
|
|
|
|
// 音频时间更新事件
|
|
|
|
const onTimeUp = () => {
|
|
|
|
let playerRef = player.value.$.vnode.el;
|
|
|
|
if (playerRef) {
|
2023-08-26 08:03:07 +00:00
|
|
|
const currentLrcElement = playerRef.querySelector(".aplayer-lrc-current");
|
2023-08-16 10:24:10 +00:00
|
|
|
const previousLrcElement = currentLrcElement?.previousElementSibling;
|
|
|
|
const lrcContent =
|
2023-08-26 08:03:07 +00:00
|
|
|
currentLrcElement?.innerHTML || previousLrcElement?.innerHTML || "这句没有歌词";
|
2023-08-16 10:24:10 +00:00
|
|
|
store.setPlayerLrc(lrcContent);
|
2023-01-15 05:22:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// 切换播放暂停事件
|
|
|
|
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>
|
2023-02-16 02:57:30 +00:00
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2023-01-15 05:22:30 +00:00
|
|
|
.aplayer {
|
|
|
|
width: 80%;
|
|
|
|
background: transparent;
|
|
|
|
border-radius: 6px;
|
2023-08-26 08:03:07 +00:00
|
|
|
font-family: "HarmonyOS_Regular", sans-serif !important;
|
2023-01-15 05:22:30 +00:00
|
|
|
:deep(.aplayer-body) {
|
|
|
|
.aplayer-pic {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.aplayer-info {
|
|
|
|
margin-left: 0;
|
|
|
|
background-color: #ffffff40;
|
2023-03-09 07:46:03 +00:00
|
|
|
border-color: transparent !important;
|
2023-01-15 05:22:30 +00:00
|
|
|
.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(
|
|
|
|
#fff 15%,
|
|
|
|
#fff 85%,
|
|
|
|
hsla(0deg, 0%, 100%, 0.6) 90%,
|
|
|
|
hsla(0deg, 0%, 100%, 0)
|
|
|
|
);
|
|
|
|
-webkit-mask: linear-gradient(
|
|
|
|
#fff 15%,
|
|
|
|
#fff 85%,
|
|
|
|
hsla(0deg, 0%, 100%, 0.6) 90%,
|
|
|
|
hsla(0deg, 0%, 100%, 0)
|
|
|
|
);
|
|
|
|
&::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 {
|
|
|
|
&::-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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-16 02:57:30 +00:00
|
|
|
</style>
|