289 lines
6.4 KiB
Vue
289 lines
6.4 KiB
Vue
<template>
|
|
<APlayer
|
|
v-if="playList[0]"
|
|
ref="player"
|
|
:audio="playList"
|
|
:autoplay="store.playerAutoplay"
|
|
:theme="theme"
|
|
:autoSwitch="false"
|
|
:loop="store.playerLoop"
|
|
:order="store.playerOrder"
|
|
:volume="volume"
|
|
:showLrc="true"
|
|
:listFolded="listFolded"
|
|
:listMaxHeight="listMaxHeight"
|
|
:noticeSwitch="false"
|
|
@play="onPlay"
|
|
@pause="onPause"
|
|
@timeupdate="onTimeUp"
|
|
@error="loadMusicError"
|
|
/>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
|
import { getPlayerList } from "@/api";
|
|
import { mainStore } from "@/store";
|
|
import APlayer from "@worstone/vue-aplayer";
|
|
|
|
const store = mainStore();
|
|
|
|
// 获取播放器 DOM
|
|
const player = ref(null);
|
|
|
|
// 歌曲播放列表
|
|
const playList = ref([]);
|
|
|
|
// 歌曲播放项
|
|
const playIndex = ref(0);
|
|
|
|
// 配置项
|
|
const props = defineProps({
|
|
// 主题色
|
|
theme: {
|
|
type: String,
|
|
default: "#efefef",
|
|
},
|
|
// 默认音量
|
|
volume: {
|
|
type: Number,
|
|
default: 0.7,
|
|
validator: (value) => {
|
|
return value >= 0 && value <= 1;
|
|
},
|
|
},
|
|
// 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
|
|
songServer: {
|
|
type: String,
|
|
default: "netease", //'netease' | 'tencent'
|
|
},
|
|
// 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
|
songType: {
|
|
type: String,
|
|
default: "playlist",
|
|
},
|
|
// id
|
|
songId: {
|
|
type: String,
|
|
default: "7452421335",
|
|
},
|
|
// 列表是否默认折叠
|
|
listFolded: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
// 列表最大高度
|
|
listMaxHeight: {
|
|
type: Number,
|
|
default: 420,
|
|
},
|
|
});
|
|
|
|
const listHeight = computed(() => {
|
|
return props.listMaxHeight + "px";
|
|
});
|
|
|
|
// 初始化播放器
|
|
onMounted(() => {
|
|
nextTick(() => {
|
|
try {
|
|
getPlayerList(props.songServer, props.songType, props.songId).then((res) => {
|
|
console.log(res);
|
|
// 更改播放器加载状态
|
|
store.musicIsOk = true;
|
|
// 生成歌单
|
|
playList.value = res;
|
|
console.log("音乐加载完成");
|
|
console.log(playList.value);
|
|
console.log(playIndex.value, playList.value.length, props.volume);
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
store.musicIsOk = false;
|
|
ElMessage({
|
|
message: "播放器加载失败",
|
|
grouping: true,
|
|
icon: h(PlayWrong, {
|
|
theme: "filled",
|
|
fill: "#efefef",
|
|
}),
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// 播放
|
|
const onPlay = () => {
|
|
console.log("播放");
|
|
playIndex.value = player.value.aplayer.index;
|
|
// 播放状态
|
|
store.setPlayerState(player.value.audioRef.paused);
|
|
// 储存播放器信息
|
|
store.setPlayerData(playList.value[playIndex.value].name, playList.value[playIndex.value].artist);
|
|
ElMessage({
|
|
message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
|
grouping: true,
|
|
icon: h(MusicOne, {
|
|
theme: "filled",
|
|
fill: "#efefef",
|
|
}),
|
|
});
|
|
};
|
|
|
|
// 暂停
|
|
const onPause = () => {
|
|
store.setPlayerState(player.value.audioRef.paused);
|
|
};
|
|
|
|
// 音频时间更新事件
|
|
const onTimeUp = () => {
|
|
let lyrics = player.value.aplayer.lyrics[playIndex.value];
|
|
let lyricIndex = player.value.aplayer.lyricIndex;
|
|
if (!lyrics || !lyrics[lyricIndex]) {
|
|
return;
|
|
}
|
|
let lrc = lyrics[lyricIndex][1];
|
|
if (lrc === "Loading") {
|
|
lrc = "歌词加载中";
|
|
} else if (lrc === "Not available") {
|
|
lrc = "歌词加载失败";
|
|
}
|
|
store.setPlayerLrc(lrc);
|
|
};
|
|
|
|
// 切换播放暂停事件
|
|
const playToggle = () => {
|
|
player.value.toggle();
|
|
};
|
|
|
|
// 切换音量事件
|
|
const changeVolume = (value) => {
|
|
player.value.setVolume(value, false);
|
|
};
|
|
|
|
// 切换上下曲
|
|
const changeSong = (type) => {
|
|
type === 0 ? player.value.skipBack() : player.value.skipForward();
|
|
nextTick(() => {
|
|
player.value.play();
|
|
});
|
|
};
|
|
|
|
// 切换歌曲列表状态
|
|
const toggleList = () => {
|
|
player.value.toggleList();
|
|
};
|
|
|
|
// 加载音频错误
|
|
const loadMusicError = () => {
|
|
let notice = "";
|
|
if (playList.value.length > 1) {
|
|
notice = "播放歌曲出现错误,播放器将在 2s 后进行下一首";
|
|
} else {
|
|
notice = "播放歌曲出现错误";
|
|
}
|
|
ElMessage({
|
|
message: notice,
|
|
grouping: true,
|
|
icon: h(PlayWrong, {
|
|
theme: "filled",
|
|
fill: "#EFEFEF",
|
|
duration: 2000,
|
|
}),
|
|
});
|
|
console.error(
|
|
"播放歌曲: " + player.value.aplayer.audio[player.value.aplayer.index].name + " 出现错误",
|
|
);
|
|
};
|
|
|
|
// 暴露子组件方法
|
|
defineExpose({ playToggle, changeVolume, changeSong, toggleList });
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.aplayer {
|
|
width: 80%;
|
|
border-radius: 6px;
|
|
font-family: "HarmonyOS_Regular", sans-serif !important;
|
|
:deep(.aplayer-body) {
|
|
background-color: transparent;
|
|
.aplayer-pic {
|
|
display: none;
|
|
}
|
|
.aplayer-info {
|
|
margin-left: 0;
|
|
background-color: #ffffff40;
|
|
border-color: transparent !important;
|
|
.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: 7px 0 6px 6px;
|
|
height: 44px;
|
|
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;
|
|
height: v-bind(listHeight);
|
|
background-color: transparent;
|
|
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>
|