最近自己写博客,想找个现成的音乐播放器,由于用的vue3,逛了一圈下来,没有一个比较方便的实现方式,最后不得不再aplayer的基础上自己完善一下
Aplayer官网地址:https://aplayer.js.org/#/zh-Hans/
vue2有对应的组件版本vue-aplayer,但是vue3没有
css部分看看就行,不是很重要
<template>
<div id="aplayer"/>
</template>
<script>
import 'aplayer/dist/APlayer.min.css';
import APlayer from 'aplayer';
import {getMusicList} from "@/util/music";
import {loadingClose} from "@/util/loading";
export default {
name: "MusicPlayer",
data() {
return {
audio: [
{
//歌曲名,作者,歌曲链接,图片链接,歌词链接
name: "",
artist: "",
url: "",
cover: "",
lrc: ""
}
],
info: {
fixed: true, // 吸底模式
listFolded: true, // 折叠歌曲列表
autoplay: false, // 自动播放
preload: "auto", // 自动预加载歌曲
loop: "all", // 播放循环模式、all全部循环 one单曲循环 none只播放一次
order: "random", // 播放模式,list列表播放, random随机播放
volume: 1//默认音量
},
hover: true
};
},
mounted() {
// 初始化播放器
this.getAudioList();
},
methods: {
//这里我引入了jQuary来弥补无法调用aplayer的接口的问题(其实主要是他接口咋调用我没搞清楚)
//使用jQuary监听点击事件,动态添加隐藏动画
clickButton() {
window.$('.aplayer-icon').on('click', () => {
let aplayer = window.$('.aplayer-body');
if (this.hover) {
aplayer.removeClass('aplayer-hover');
this.hover = false;
} else {
aplayer.addClass('aplayer-hover');
this.hover = true;
}
})
},
createPlayer() {
// 创建一个音乐播放器实例,并挂载到DOM上,同时进行相关配置
// eslint-disable-next-line no-unused-vars
const aPlayer = new APlayer({
container: document.getElementById("aplayer"),
//使用js字符串格式加载歌词
lrcType: 1,
audio: this.audio, // 音乐信息
...this.info, // 其他配置信息
});
window.$('.aplayer-body').addClass('aplayer-hover');
this.clickButton();
loadingClose();
},
getAudioList() {
//这里主要是我需要从后端统一拉取博客设置,用的vuex
//轮询setting数据,当setting数据改变时,退出
let time = setInterval(() => {
const setting = this.$store.state.setting;
if (setting.isChanged) {
//从缓存中获取歌单ID,若相等则直接取用缓存中的歌单
let data = JSON.parse(sessionStorage.getItem("musicList"));
if (data !== null && data.uuid === setting.musicUuid) {
this.audio = data.audio;
this.createPlayer();
} else {
//实际上就这个函数有用,传入的酷狗音乐的歌单uuid
getMusicList(setting.musicUuid)
.then((list) => {
this.audio = list;
this.createPlayer();
});
}
clearInterval(time);
}
}, 1000);
}
}
,
}
;
</script>
<style lang="less">
#aplayer {
width: 320px; // 定个宽度
}
.aplayer-body, .aplayer-list {
color: var(--theme-skin-main);
}
.aplayer-hover {
left: -66px !important;
&:hover {
left: 0 !important;
}
}
.aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap {
.aplayer-bar {
height: 6px;
border-radius: 10px;
.aplayer-played {
height: inherit;
border-radius: inherit;
.aplayer-thumb {
height: 12px;
width: 12px;
right: 3px;
top: 1px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, .18);
transition: all .35s
}
}
.aplayer-loaded {
height: inherit;
border-radius: inherit;
}
}
}
</style>
原本是有一个配套的meta.js来弥补歌曲信息的问题,但实在没找到啥比较好的方法把他加进来
所以我个人分析了下酷狗音乐的接口,自己写了一个,有可能那天用着就用不了
这个接口的歌曲信息是有时效的,具体多长我也没测试过
import axios from "axios";
let audio = [];
//访问酷狗音乐接口,根据歌单UUID获取歌曲HASH
export async function getMusicList(uuid) {
let list = [];
await axios("/music/plist/list/" + uuid + "?json=true", {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"
})
.then((result) => {
list = result.data.list.list.info;
})
.catch((error) => {
console.log(error);
})
const mid = getMid();
let request = [];
for (const l of list) {
request.push(getAudioInfo(l['album_id'], l.hash, mid));
}
//多请求并发执行
await axios.all(request)
.then((result) => {
for (const resultElement of result) {
const r = resultElement.data.data;
const url = r['play_url'];
if (url.length !== 0) {
audio.push({
url, cover: r["img"], lrc: r["lyrics"],
name: r["song_name"], artist: r["author_name"],
});
}
}
})
.catch((error) => {
console.log(error);
})
//缓存歌单信息,加快二次加载速度
sessionStorage.setItem("musicList", JSON.stringify({
uuid, audio
}));
console.log(audio);
return audio;
}
//根据歌曲HASH和歌词ID获取具体歌曲信息
const getAudioInfo = (album_id, hash, mid) => {
return axios("/audio/yy/index.php" +
"?r=play/getdata" +
"&hash=" + hash +
"&mid=" + mid +
"&platid=4" +
"&album_id=" + album_id, {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"
})
}
//根据酷狗音乐规则伪造mid
const getMid = () => {
return Md5(n());
}
//随机数
const n = () => {
const e = () => (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
return e() + e() + "-" + e() + "-" + e() + "-" + e() + "-" + e() + e() + e()
}
//可能是标准的MD5,不确定
const Md5 = (e) => {
let t, r = 0, a = 8;
const s = (e, t, n, i, r, a) => {
return p(function (e, t) {
return e << t | e >>> 32 - t
}(p(p(t, e), p(i, a)), r), n)
}
const d = (e, t, n, i, r, a, o) => {
return s(t & n | ~t & i, e, t, r, a, o)
}
const f = (e, t, n, i, r, a, o) => {
return s(t & i | n & ~i, e, t, r, a, o)
}
const h = (e, t, n, i, r, a, o) => {
return s(t ^ n ^ i, e, t, r, a, o)
}
const g = (e, t, n, i, r, a, o) => {
return s(n ^ (t | ~i), e, t, r, a, o)
}
const p = (e, t) => {
const n = (65535 & e) + (65535 & t);
return (e >> 16) + (t >> 16) + (n >> 16) << 16 | 65535 & n
}
return e ? function (e) {
let t = r ? "0123456789ABCDEF" : "0123456789abcdef", n = "", i = 0;
for (; i < 4 * e.length; i++)
n += t.charAt(e[i >> 2] >> i % 4 * 8 + 4 & 15) + t.charAt(e[i >> 2] >> i % 4 * 8 & 15);
return n
}(function (e, t) {
e[t >> 5] |= 128 << t % 32;
e[14 + (t + 64 >>> 9 << 4)] = t;
let n = 1732584193, i = -271733879, r = -1732584194, a = 271733878;
for (let o = 0; o < e.length; o += 16) {
const s = n, c = i, l = r, u = a;
n = d(n, i, r, a, e[o], 7, -680876936)
a = d(a, n, i, r, e[o + 1], 12, -389564586)
r = d(r, a, n, i, e[o + 2], 17, 606105819)
i = d(i, r, a, n, e[o + 3], 22, -1044525330)
n = d(n, i, r, a, e[o + 4], 7, -176418897)
a = d(a, n, i, r, e[o + 5], 12, 1200080426)
r = d(r, a, n, i, e[o + 6], 17, -1473231341)
i = d(i, r, a, n, e[o + 7], 22, -45705983)
n = d(n, i, r, a, e[o + 8], 7, 1770035416)
a = d(a, n, i, r, e[o + 9], 12, -1958414417)
r = d(r, a, n, i, e[o + 10], 17, -42063)
i = d(i, r, a, n, e[o + 11], 22, -1990404162)
n = d(n, i, r, a, e[o + 12], 7, 1804603682)
a = d(a, n, i, r, e[o + 13], 12, -40341101)
r = d(r, a, n, i, e[o + 14], 17, -1502002290)
i = d(i, r, a, n, e[o + 15], 22, 1236535329)
n = f(n, i, r, a, e[o + 1], 5, -165796510)
a = f(a, n, i, r, e[o + 6], 9, -1069501632)
r = f(r, a, n, i, e[o + 11], 14, 643717713)
i = f(i, r, a, n, e[o], 20, -373897302)
n = f(n, i, r, a, e[o + 5], 5, -701558691)
a = f(a, n, i, r, e[o + 10], 9, 38016083)
r = f(r, a, n, i, e[o + 15], 14, -660478335)
i = f(i, r, a, n, e[o + 4], 20, -405537848)
n = f(n, i, r, a, e[o + 9], 5, 568446438)
a = f(a, n, i, r, e[o + 14], 9, -1019803690)
r = f(r, a, n, i, e[o + 3], 14, -187363961)
i = f(i, r, a, n, e[o + 8], 20, 1163531501)
n = f(n, i, r, a, e[o + 13], 5, -1444681467)
a = f(a, n, i, r, e[o + 2], 9, -51403784)
r = f(r, a, n, i, e[o + 7], 14, 1735328473)
i = f(i, r, a, n, e[o + 12], 20, -1926607734)
n = h(n, i, r, a, e[o + 5], 4, -378558)
a = h(a, n, i, r, e[o + 8], 11, -2022574463)
r = h(r, a, n, i, e[o + 11], 16, 1839030562)
i = h(i, r, a, n, e[o + 14], 23, -35309556)
n = h(n, i, r, a, e[o + 1], 4, -1530992060)
a = h(a, n, i, r, e[o + 4], 11, 1272893353)
r = h(r, a, n, i, e[o + 7], 16, -155497632)
i = h(i, r, a, n, e[o + 10], 23, -1094730640)
n = h(n, i, r, a, e[o + 13], 4, 681279174)
a = h(a, n, i, r, e[o], 11, -358537222)
r = h(r, a, n, i, e[o + 3], 16, -722521979)
i = h(i, r, a, n, e[o + 6], 23, 76029189)
n = h(n, i, r, a, e[o + 9], 4, -640364487)
a = h(a, n, i, r, e[o + 12], 11, -421815835)
r = h(r, a, n, i, e[o + 15], 16, 530742520)
i = h(i, r, a, n, e[o + 2], 23, -995338651)
n = g(n, i, r, a, e[o], 6, -198630844)
a = g(a, n, i, r, e[o + 7], 10, 1126891415)
r = g(r, a, n, i, e[o + 14], 15, -1416354905)
i = g(i, r, a, n, e[o + 5], 21, -57434055)
n = g(n, i, r, a, e[o + 12], 6, 1700485571)
a = g(a, n, i, r, e[o + 3], 10, -1894986606)
r = g(r, a, n, i, e[o + 10], 15, -1051523)
i = g(i, r, a, n, e[o + 1], 21, -2054922799)
n = g(n, i, r, a, e[o + 8], 6, 1873313359)
a = g(a, n, i, r, e[o + 15], 10, -30611744)
r = g(r, a, n, i, e[o + 6], 15, -1560198380)
i = g(i, r, a, n, e[o + 13], 21, 1309151649)
n = g(n, i, r, a, e[o + 4], 6, -145523070)
a = g(a, n, i, r, e[o + 11], 10, -1120210379)
r = g(r, a, n, i, e[o + 2], 15, 718787259)
i = g(i, r, a, n, e[o + 9], 21, -343485551)
n = p(n, s)
i = p(i, c)
r = p(r, l)
a = p(a, u)
}
return Array(n, i, r, a)
}(function (e) {
let t = Array(), n = (1 << a) - 1;
for (let i = 0; i < e.length * a; i += a)
t[i >> 5] |= (e.charCodeAt(i / a) & n) << i % 32;
return t
}(t = e), t.length * a)) : ""
}