构想

  1. 因为我的 QQ 是侧边隐藏的,aplayer 也是侧边隐藏的,两者时常会误触,虽说各放一边就能避免这个问题,但我还是想把它做的优雅一点,毕竟这个博客就是为了 Aplayer 做的(认真脸)。
  2. Aplayer 本身的 UI 做的很不错,但按钮太小,样式太简约,不够个性化。一开始的构想是想做一个可以随处拖动的小圆球,就像 iOS 的 AssistiveTouch 小方块一样。后来看到安知鱼大佬做的音乐胶囊,非常接近我的设计预想,虽然是固定的,但也解决了和 QQ 侧边隐藏冲突的问题,真的是非常好看。但是看完教程后发现它无法显示歌单,而且歌词特别小,所以只能放弃了。
  3. 我开始尝试着修改 Aplayer 的js源码,先是歌词的样式,修改了滚动速度和歌词大小,非常成功,达到了我预想的效果,就是你们现在看到的“桌面歌词”;然后尝试查找js源码里写好的一些方法,然而我几乎为0的 js 水平无法让我理解源码的结构,所以尝试失败了。
  4. 终于,我翻到了 Aplayer 的中文文档,发现了 Aplayer 其实提供了很多的 API 接口,还有很多 audio 的原生属性,顿时感觉之前好傻,一下子思路顺畅了许多——既然魔改 Aplayer 的原 UI 那么困难,那么为什么不自己写个界面,然后调用 API 的方法呢?于是就有了现在这个音乐控制器。
    说它是音乐控制器,其实很严谨,因为我只是给 Aplayer 加了个遥控器,而不是新做了一个播放器,所以功能基本上是和 aplayer 一样的。如果要增加其他功能,则要另写方法了。比如,在线搜索、歌曲收藏等。

效果

功能

音乐控制器是控制中心下的一个模块,所以通过控制中心按钮打开。目前已实现的功能如下:

歌曲信息显示:曲名、封面、歌手

暂停/播放

上一首/下一首

循环/随机播放

进度条显示/拖动控制

音量条显示/拖动控制

桌面歌词

歌单显示,支持切歌

导航栏mini音乐控制模块

切换其他歌单

预览

  1. 主界面

  2. 歌单界面

  3. 导航栏迷你音乐控制器、桌面歌词

代码

由于其他功能还没做好,建议 F12 大法直接扒。
下面列出代码可能不适用,谨慎参考!

console.pug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
div#console
//- 标头
div.console-head
span 控制中心
div.close-btn(onclick="ctrl.hideConsole()" href="javascript:void(0);")
i.fas.fa-circle-xmark

//- 音乐控制器
div.console-music-ctrl-item.item-show#console-music-item-main
div#console-music-cover
a#console-music-title 曲名
a#console-music-author 作者
div.console-progressbar-div
div#progress-low
a#progress-low-btn --:--
div#music-progressbar
div#p_bar_bg
div#p_bar
div#progress-high
a#progress-high-btn --:--
div#console-music-ctrl-btns
div#music-ctrl-first
a#music-ctrl-btn-first
i.fas.fa-shuffle
div#music-ctrl-left
a#music-ctrl-btn-left(onclick="ctrl.musicBackward()" title="上一曲" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i.fas.fa-backward
div#music-ctrl-center
a#music-ctrl-btn-center(onclick="ctrl.musicSwitch()" title="音乐开关" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i.fas.fa-play
div#music-ctrl-right
a#music-ctrl-btn-right(onclick="ctrl.musicForward()" title="下一曲" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i.fas.fa-forward
div#music-ctrl-end
a#music-ctrl-btn-end
i.fas.fa-indent
div.console-progressbar-div
div#volume-low
a#volume-low-btn
i.fas.fa-volume-off
div#music-volumebar
div#v_bar_bg
div#v_bar
div#volume-high
a#volume-high-btn
i.fas.fa-volume-high

div.console-music-ctrl-item#console-music-item-list
div.console-list-head
a.headline 当前歌单
a.music-list-title 网易云
div.console-list-body
ol#console-music-list
div.console-list-foot

//- 系统控制按钮
div.console-btn-group
div.console-btn-item#darkItem
a.switchButton#darkSwitchBtn(onclick="ctrl.switchDarkMode()" title="深色模式" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i#iconDarkMode.fas.fa-moon
div.console-btn-item#charItem
a.switchButton#charSwitchBtn(type="button" title="簡/繁" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i#iconCharMode.fas(style="font-size:1.5rem;") 繁
div.console-btn-item#ircItem
a.switchButton#ircSwitchBtn(onclick="ctrl.ircShowHide()" title="桌面歌词" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i#iconIrcMode.fas(style="font-size:1.5rem;") 词
div.console-btn-item#asideItem
a.switchButton#asideSwitchBtn(onclick="ctrl.hideAsideBtn()" title="单栏/双栏" href="javascript:void(0);" rel="external nofollow" data-pjax-state="external")
i#iconAside.fas.fa-arrows-alt-h

div.console-mask(onclick="ctrl.consoleBackBtn()" href="javascript:void(0);" rel="external nofollow")

自定义CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/* *********************控制中心音乐********************* */
/* 隐藏原来的Aplayer */
.aplayer-body {
display: none;
}

#console .console-music-ctrl-item {
margin: 1rem auto 0 auto;
width: 18rem;
height: 30rem;
border-radius: 1.8rem;
border: var(--style-border);
background: var(--card-bg);
position: fixed;
top: 3.5rem;
opacity: 0;
pointer-events: none;
transition: all 0.5s;
}

#console-music-item-main {
padding: 1.3rem;
}

#console-music-item-main.item-show,
#console-music-item-list.item-show,
#console-music-item-lrc.item-show,
#console-songsheet-item-list.item-show {
opacity: 1;
pointer-events: all;
transition: all 0.5s;
}

/* 封面 */
#console-music-cover {
width: 100%;
/* height: calc(100% - 12rem); */
border-radius: 0.5rem;
}

/* 曲名和作者 */
#console-music-title,
#console-music-author {
width: 100%;
display: flex;
white-space: nowrap;
overflow: hidden;
align-items: center;
}

#console-music-title {
height: 2.4rem;
padding-top: 0.5rem;
font-size: 1.3rem;
font-weight: bold;
color: var(--anzhiyu-reverse);
}

#console-music-author {
height: 1.6rem;
}

/* 组件外框 */
.console-progressbar-div {
width: 100%;
height: 2rem;
display: flex;
}

#console-music-ctrl-btns {
width: 100%;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
}

#music-ctrl-first, #music-ctrl-left, #music-ctrl-center, #music-ctrl-right, #music-ctrl-end{
width: 20%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}

#music-ctrl-btn-first, #music-ctrl-btn-left, #music-ctrl-btn-center, #music-ctrl-btn-right,#music-ctrl-btn-end {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}

/* 字色和字号 */
#music-ctrl-btn-first, #music-ctrl-btn-left, #music-ctrl-btn-right, #music-ctrl-btn-end {
font-size: 1.5rem;
}

.console-music-ctrl-item a {
color: var(--font-color); /*#99a9bf*/
}

#music-ctrl-btn-center {
color: var(--anzhiyu-reverse);
font-size: 2.4rem;
}

#music-ctrl-btn-first:hover, #music-ctrl-btn-left:hover, #music-ctrl-btn-right:hover, #music-ctrl-btn-end:hover {
color: var(--anzhiyu-reverse);
}

#progress-low-btn, #progress-high-btn {
font-size: 0.7rem;
color: rgba(136,136,136,0.5);
}

/* 进度条和音量条 */
#progress-low, #progress-high {
width: 2.5rem;
}

#music-progressbar {
width: 100%;
}

#volume-low, #volume-high {
width: 1.5rem;
}

#music-volumebar {
width: 100%;
}

#progress-low, #progress-high, #music-progressbar,
#volume-low, #volume-high, #music-volumebar {
display: flex;
align-items: center;
justify-content: center;
}

#p_bar_bg, #v_bar_bg {
width: calc(100% - 1rem);
height: 0.4rem;
border-radius: 0.3rem;
background-color: rgba(136, 136, 136, 0.5);
}

#p_bar, #v_bar {
width: 0;
height: 100%;
border-radius: 0.3rem;
background-color: var(--font-color);
transition: background-color 0.5s;
}

/* 控制中心文本不可选中 */
#console a, #console span {
user-select: none;
}

/* *********************歌单显示********************** */
.console-list-head {
width: 100%;
height: 4rem;
border-top-left-radius: 1.8rem; /*和外弧度保持一致*/
border-top-right-radius: 1.8rem; /*和外弧度保持一致*/
border-bottom: 1px solid var(--vercel-border-color);
background-color: var(--vercel-background);
display: flex;
align-items: center;
flex-flow: column;
transition: all 0.5s;
}

.console-list-foot {
width: 100%;
height: 1.8rem; /*和外弧度保持一致*/
border-bottom-left-radius: 1.8rem; /*和外弧度保持一致*/
border-bottom-right-radius: 1.8rem; /*和外弧度保持一致*/
border-top: 1px solid var(--vercel-border-color);
background-color: var(--vercel-background);
transition: all 0.5s;
}

.console-list-body {
width: 100%;
height: calc(100% - 5.8rem);
padding: 0;
}

#console-music-list, #console-songsheet-list {
width: 100%;
height: 100%;
margin: 0;
list-style: none; /*消除序号*/
padding-inline-start: 0;
overflow-y: auto;
}

#console-music-list li {
display: flex;
align-items: center;
cursor: pointer;
}

#console-music-list li:hover {
background-color: var(--vercel-hover-bg);
}

/* 隐藏滚动条 */
#console-music-list::-webkit-scrollbar {display:none}

#console-music-list li:not(:first-child) div.list-music-info2 {
border-top: 1px solid var(--vercel-border-color);
}

div.list-music-info1 {
width: 2rem;
}

div.list-music-info2 {
width: calc(100% - 2.5rem);
white-space: nowrap;
overflow: hidden;
}

a.list-music-author {
color: rgb(136,136,136);
font-size: 0.8rem;
}

a.list-music-id {
text-align: center;
font-size: 0.8rem;
color: rgb(136,136,136);
display: block;
}

a.list-music-id.hide {
display: none;
}

a.list-music-state{
display: none;
text-align: center;
}

a.list-music-state.show{
display: block;
}

.console-list-head a.headline{
display: block;
height: 50%;
font-size: 1.1rem;
font-weight: bold;
padding-top: 0.5rem;
}

a#music-list-title, a#songsheet-title{
display: block;
height: 50%;
font-size: 0.9rem;
}

a#music-list-title {
cursor: pointer;
}

/* *********************歌单列表*********************** */
#console-songsheet-list li {
display: flex;
align-items: center;
cursor: pointer;
}

#console-songsheet-list li:last-child {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
height: 3rem;
}

/* 取消滚动条 */
#console-songsheet-list::-webkit-scrollbar {display:none}

#console-songsheet-list li:hover {
background-color: var(--vercel-hover-bg);
}

#console-songsheet-list li div.songsheet-info2 {
border-bottom: 1px solid var(--vercel-border-color);
}

.songsheet-info1 {
width: 2rem;
display: flex;
align-items: center;
justify-content: center;
}

.songsheet-info2 {
width: calc(100% - 2.5rem);
padding: 1rem 0;
white-space: nowrap;
overflow: hidden;
display: flex;
align-items: center;
}

.list-songsheet-cover {
height: 4rem;
width: 4rem;
border-radius: 0.5rem;
}

.list-songsheet-title {
margin-left: 1.5rem;
}

/* *************加载转圈************* */
#console-loading-icon {
width: 35px;
height: 35px;
position: fixed;
top: 50%;
opacity: 0;
transition: all 0.1s;
}

#console-loading-icon.show {
opacity: 1;
transition: all 0.1s;
}

#console-loading-icon i {
font-size: 1.8rem;
display: inline-block;
}

自定义JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
// pjax适配
function whenDOMReady() {
// pjax加载完成(切换页面)后需要执行的函数和代码
console.log("pjax开启");
musicState();
}

// 音乐状态检测(已添加事件监听器,修复点击aplayer后导航栏和控制中心不同步的问题)
function musicState() {
const music_state = document.querySelector("meting-js").aplayer.audio.paused;
if (music_state) {
document.querySelector("#music-Switch i").classList.remove("fa-pause");
document.querySelector("#music-Switch i").classList.add("fa-play");
document.querySelector("#console #music-ctrl-btn-center i").classList.remove("fa-pause");
document.querySelector("#console #music-ctrl-btn-center i").classList.add("fa-play");
} else {
document.querySelector("#music-Switch i").classList.remove("fa-play");
document.querySelector("#music-Switch i").classList.add("fa-pause");
document.querySelector("#console #music-ctrl-btn-center i").classList.remove("fa-play");
document.querySelector("#console #music-ctrl-btn-center i").classList.add("fa-pause");
}
}

function secToTime(s) {
if (isNaN(s)) s = 0;
var min = Math.floor(s / 60);
var sec = Math.floor(s % 60);
var t = min.toString().padStart(2, '0') + ":" + sec.toString().padStart(2, '0');
return t;
}

var ctrl = {

// 显示中控台
showConsole: function () {
document.querySelector("#console-music-item-main").classList.add("item-show");
document.querySelector("#console").classList.add("show");
ctrl.initConsoleState();
},

// 隐藏中控台
hideConsole: function () {
var items = document.querySelectorAll(".item-show");
for(var i=0; i<items.length; i++) items[i].classList.remove("item-show");
document.querySelector("#console").classList.remove("show");
},

// 菜单返回
consoleBackBtn: function () {
var top_item = document.querySelector(".item-show");
switch (top_item.id) {
case 'console-music-item-mini': break;
case 'console-music-item-main': ctrl.hideConsole(); break;
case 'console-music-item-list':
top_item.classList.remove("item-show");
document.getElementById("console-music-item-main").classList.add("item-show");
break;
case 'console-songsheet-item-list':
top_item.classList.remove("item-show");
document.getElementById("console-music-item-list").classList.add("item-show");
break;
case 'console-music-item-lrc':
top_item.classList.remove("item-show");
document.getElementById("console-music-item-main").classList.add("item-show");
break;
default: console.log("异常情况");
}
},

// 桌面歌词
ircShowHide: function () {
const irc = document.querySelector(".aplayer > .aplayer-lrc-hide"); //这里防止与音乐页面的控制冲突
if (irc === null) {
document.querySelector(".aplayer > .aplayer-lrc").classList.add("aplayer-lrc-hide");
document.querySelector("#ircItem").classList.remove("on");
} else {
document.querySelector(".aplayer > .aplayer-lrc").classList.remove("aplayer-lrc-hide");
document.querySelector("#ircItem").classList.add("on");
}
},

// 导航栏音乐
musicSwitch: function () {
const music_state = document.querySelector("meting-js").aplayer.audio.paused;
if (music_state) {
document.querySelector("#music-Switch i").classList.remove("fa-play");
document.querySelector("#music-Switch i").classList.add("fa-pause");
document.querySelector("#music-ctrl-btn-center i").classList.remove("fa-play");
document.querySelector("#music-ctrl-btn-center i").classList.add("fa-pause");
} else {
document.querySelector("#music-Switch i").classList.remove("fa-pause");
document.querySelector("#music-Switch i").classList.add("fa-play");
document.querySelector("#music-ctrl-btn-center i").classList.remove("fa-pause");
document.querySelector("#music-ctrl-btn-center i").classList.add("fa-play");
}
document.querySelector("meting-js").aplayer.toggle();
},

musicForward: function () {
document.querySelector("meting-js").aplayer.skipForward();
ctrl.getMusicInfo();
},

musicBackward: function () {
document.querySelector("meting-js").aplayer.skipBack();
ctrl.getMusicInfo();
},

getMusicInfo: function () {
var music_id = document.querySelector("meting-js").aplayer.list.index; //当前曲目的id
var music_cover = document.querySelector("meting-js").aplayer.list.audios[music_id].cover;
var music_author = document.querySelector("meting-js").aplayer.list.audios[music_id].author;
var music_title = document.querySelector("meting-js").aplayer.list.audios[music_id].title;
document.getElementById("console-music-cover").innerHTML = "<img src='" + music_cover + "' style='width:100%;height:100%;border-radius:0.5rem;'>";// 歌曲信息
document.getElementById("console-music-title").innerHTML = music_title;
document.getElementById("console-music-author").innerHTML = music_author;
},

// 音乐进度更新
refreshProgress: function () {
var nowTime = document.querySelector("meting-js").aplayer.audio.currentTime;// 当前时间
if (isNaN(nowTime)) nowTime = 0;
var nowTimeString = secToTime(nowTime);
var allTime = document.querySelector("meting-js").aplayer.audio.duration;// 总时间
if (isNaN(allTime)) allTime = 0; //无歌曲时会返回NaN
var allTimeString = secToTime(allTime);
document.getElementById("progress-low-btn").innerHTML = nowTimeString;// 进度条时间
document.getElementById("progress-high-btn").innerHTML = allTimeString;
document.querySelector("#p_bar").style.width = document.querySelector("#p_bar_bg").offsetWidth * (nowTime / allTime) + "px";// 进度条进度
},

// 导入歌单
importMusicList: function() {
var audios = document.querySelector("meting-js").aplayer.list.audios;
var list_html;
for (var i = 0; i < audios.length; i++) {
list_html = document.getElementById("console-music-list").innerHTML;
document.getElementById("console-music-list").innerHTML = list_html + "<li class='music-list-item'><div class='list-music-info1'><a class='list-music-id' data-pjax-state=''>" + (i + 1) + "</a><a class='list-music-state' data-pjax-state=''><i class='iconfont icon-waveform'></i></a></div><div class='list-music-info2'><a class='list-music-title' data-pjax-state=''>" + audios[i].title + "</a><a class='list-music-author' data-pjax-state=''> - " + audios[i].author + "</a></div></li>";
// console.log("第" + (i + 1) + "首导入成功!");
}
},

// 歌单切换
changeMusicList: function(Music_id, Music_server) {
var ap = document.querySelector("meting-js").aplayer;
var music_list_url_str = "https://metingjs.gavin-chen.top/api?server=" + Music_server + "&type=playlist" + "&id=" + Music_id;
ap.list.clear();
fetch(music_list_url_str).then(response => response.json()).then(data => {
// 在这里使用返回的JSON数据
newSongsheetLen = data.length;
console.log(newSongsheetLen);
ap.list.add(data);
})
.catch(error => console.error(error));
},

//初始化console图标
initConsoleState: function () {
const irc = document.querySelector(".aplayer > .aplayer-lrc-hide");
const aplayer = document.querySelector(".aplayer > .aplayer-lrc");
irc === null && aplayer != null
? document.querySelector("#ircItem").classList.add("on")
: document.querySelector("#ircItem").classList.remove("on");
saveToLocal.get('aside-status') === 'hide'
? document.querySelector("#asideItem").classList.add("on")
: document.querySelector("#asideItem").classList.remove("on");
var console_musicBody = document.querySelector("#console .console-music-ctrl-item"); // 更新控制中心尺寸
var console_musicCover = document.getElementById("console-music-cover");
console_musicCover.style.height = console_musicCover.offsetWidth + "px";
console_musicBody.style.height = (console_musicCover.offsetWidth + 236) + "px"; //(12rem + 1.3rem + 1.3rem) * 16 = 233.6px
ctrl.getMusicInfo();
var nowVolume = document.querySelector("meting-js").aplayer.audio.volume;// 当前音量
document.querySelector("#v_bar").style.width = document.querySelector("#v_bar_bg").offsetWidth * nowVolume + "px";// 音量条进度
}

}

// 主页/音乐列表/歌单列表 切换
var music_list_switch = document.getElementById("music-ctrl-btn-end");
var music_list_title = document.getElementById("music-list-title");
music_list_switch.addEventListener("click", function (e) {
document.getElementById("console-music-item-main").classList.remove("item-show");
document.getElementById("console-music-item-list").classList.add("item-show");
});
music_list_title.addEventListener("click", function (e) {
document.getElementById("console-music-item-list").classList.remove("item-show");
document.getElementById("console-songsheet-item-list").classList.add("item-show");
});

// 歌单列表监听器
var songsheet0 = document.getElementById("songsheet-X");
var songsheet1 = document.getElementById("songsheet-A");
var songsheet2 = document.getElementById("songsheet-B");
var songsheet3 = document.getElementById("songsheet-C");
songsheet0.addEventListener("click", function (e) {
document.getElementById("console-loading-icon").classList.add("show");
console.log("正在切换至默认专辑");
global_music_flag = 1;
ctrl.changeMusicList("8086610771","netease");
document.getElementById("music-list-title").innerHTML = "网易云";
});
songsheet1.addEventListener("click", function (e) {
document.getElementById("console-loading-icon").classList.add("show");
console.log("正在切换至纯音乐专辑");
global_music_flag = 1;
ctrl.changeMusicList("651630118","netease");
document.getElementById("music-list-title").innerHTML = "纯音乐";
});
songsheet2.addEventListener("click", function (e) {
document.getElementById("console-loading-icon").classList.add("show");
console.log("正在切换至古风专辑");
global_music_flag = 1;
ctrl.changeMusicList("5296755943","netease");
document.getElementById("music-list-title").innerHTML = "古风";
});
songsheet3.addEventListener("click", function (e) {
document.getElementById("console-loading-icon").classList.add("show");
console.log("正在切换至镜子Vlog专辑");
global_music_flag = 1;
ctrl.changeMusicList("4932756913","netease");
document.getElementById("music-list-title").innerHTML = "镜子Vlog";
});

// 音乐列表监听器
var console_music_list = document.getElementById("console-music-list");
var music_id = null;
console_music_list.addEventListener('click', function (e) {
var ap = document.querySelector("meting-js").aplayer
if (e.target && e.target.nodeName.toUpperCase() == "LI") {
music_id = parseInt(e.target.querySelector(".list-music-id").innerHTML);
ap.list.switch(music_id - 1);
ap.play();
ctrl.getMusicInfo();
} else if (e.target && e.target.nodeName.toUpperCase() == "DIV") {
music_id = parseInt(e.target.parentElement.querySelector(".list-music-id").innerHTML);
ap.list.switch(music_id - 1);
ap.play();
ctrl.getMusicInfo();
} else if (e.target && (e.target.nodeName.toUpperCase() == "A" || e.target.nodeName.toUpperCase() == "I")) {
music_id = parseInt(e.target.parentElement.parentElement.querySelector(".list-music-id").innerHTML);
ap.list.switch(music_id - 1);
ap.play();
ctrl.getMusicInfo();
} else alert("ERROR!")
}, false);

// 音量条监听器
var music_volumebar = document.getElementById("music-volumebar"); //扩大热区
var v_bar_bg = document.getElementById("v_bar_bg");
var v_bar = document.getElementById("v_bar");
var v_low = document.getElementById("volume-low-btn");
var v_high = document.getElementById("volume-high-btn");
var v_bar_bg_Len = v_bar_bg.offsetWidth; // 获取进度条总长Width

// 按键按下
music_volumebar.addEventListener("mousedown", function (e) { //添加监听事件
v_bar_bg.style.height = "0.6rem";
v_bar.style.backgroundColor = "var(--anzhiyu-reverse)";
v_low.style.color = "var(--anzhiyu-reverse)";
v_high.style.color = "var(--anzhiyu-reverse)";
let x = e.pageX; // 获取按下时鼠标初始位置 // pageX是绝对位置 offsetX是相对位置
v_bar.style.width = (0 + e.offsetX) + "px"; // 按下时重新设置进度条
let v_bar_Len = v_bar.offsetWidth; // 获取进度条的初始Width
v_bar_bg_Len = v_bar_bg.offsetWidth;
let newVolume = e.offsetX / v_bar_bg_Len;
document.querySelector("meting-js").aplayer.volume(newVolume, true); // 更改音量
document.onmousemove = function (e) { // 拖动需要写到down里面
let diff = x - e.pageX; // 获取移动的距离
let v_bar_Len_New = v_bar_Len - diff; // 计算当前进度条的Width
if (v_bar_Len_New < 0) { // 当超出进度条范围,控制
v_bar_Len_New = 0;
} else if (v_bar_Len_New > v_bar_bg_Len) {
v_bar_Len_New = v_bar_bg_Len;
}
v_bar.style.width = v_bar_Len_New + "px"; // 更改进度条Width
newVolume = v_bar_Len_New / v_bar_bg_Len;
document.querySelector("meting-js").aplayer.volume(newVolume, true); // 更改音量
}
});

// 触摸按下
music_volumebar.addEventListener("touchstart", function (e) { //添加监听事件
v_bar_bg.style.height = "0.6rem";
v_bar.style.backgroundColor = "var(--anzhiyu-reverse)";
v_low.style.color = "var(--anzhiyu-reverse)";
v_high.style.color = "var(--anzhiyu-reverse)";
let x = e.targetTouches[0].pageX; // 获取按下时鼠标初始位置 // pageX是绝对位置 offsetX是相对位置
v_bar.style.width = (0 + e.targetTouches[0].offsetX) + "px"; // 按下时重新设置进度条
let v_bar_Len = v_bar.offsetWidth; // 获取进度条的初始Width
v_bar_bg_Len = v_bar_bg.offsetWidth;
let newVolume = e.targetTouches[0].offsetX / v_bar_bg_Len;
document.querySelector("meting-js").aplayer.volume(newVolume, true); // 更改音量
document.ontouchmove = function (e) { // 拖动需要写到down里面
let diff = x - e.targetTouches[0].pageX; // 获取移动的距离
let v_bar_Len_New = v_bar_Len - diff; // 计算当前进度条的Width
if (v_bar_Len_New < 0) { // 当超出进度条范围,控制
v_bar_Len_New = 0;
} else if (v_bar_Len_New > v_bar_bg_Len) {
v_bar_Len_New = v_bar_bg_Len;
}
v_bar.style.width = v_bar_Len_New + "px"; // 更改进度条Width
newVolume = v_bar_Len_New / v_bar_bg_Len;
document.querySelector("meting-js").aplayer.volume(newVolume, true); // 更改音量
}
});

// 进度条监听器
var music_progressbar = document.getElementById("music-progressbar"); //扩大热区
var p_bar_bg = document.getElementById("p_bar_bg");
var p_bar = document.getElementById("p_bar");
var p_low = document.getElementById("progress-low-btn");
var p_high = document.getElementById("progress-high-btn");
var p_bar_Len_New = 0;
var p_bar_bg_Len = p_bar_bg.offsetWidth; // 获取进度条总长Width
var ctrl_flag = 1;
var mousemove_flag = 1;

// 按键按下
music_progressbar.addEventListener("mousedown", function (e) { //添加监听事件
p_bar_bg.style.height = "0.6rem";
p_bar.style.backgroundColor = "var(--anzhiyu-reverse)";
p_low.style.color = "var(--anzhiyu-reverse)";
p_high.style.color = "var(--anzhiyu-reverse)";
ctrl_flag = 0;
global_music_flag = 1;
let x = e.pageX; // 获取按下时鼠标初始位置 // pageX是绝对位置 offsetX是相对位置
let p_bar_Len = p_bar.offsetWidth; // 获取进度条的初始Width
p_bar_bg_Len = p_bar_bg.offsetWidth; // 获取进度条总长Width,不知道为什么,第一次获取的值不对,这里还得再更新一次
document.onmousemove = function (e) { // 拖动需要写到down里面
let diff = x - e.pageX; // 获取移动的距离
mousemove_flag = 0;
p_bar_Len_New = p_bar_Len - diff; // 计算当前进度条的Width
if (p_bar_Len_New < 0) { // 当超出进度条范围,控制
p_bar_Len_New = 0;
} else if (p_bar_Len_New > p_bar_bg_Len) {
p_bar_Len_New = p_bar_bg_Len;
}
p_bar.style.width = p_bar_Len_New + "px"; // 更改进度条Width
let all_Time = document.querySelector("meting-js").aplayer.audio.duration;
let current_time = (p_bar_Len_New / p_bar_bg_Len) * all_Time;
document.getElementById("progress-low-btn").innerHTML = secToTime(current_time);
}
});

// 触摸按下
music_progressbar.addEventListener("touchstart", function (e) { //添加监听事件
p_bar_bg.style.height = "0.6rem";
p_bar.style.backgroundColor = "var(--anzhiyu-reverse)";
p_low.style.color = "var(--anzhiyu-reverse)";
p_high.style.color = "var(--anzhiyu-reverse)";
ctrl_flag = 0;
global_music_flag = 1;
let x = e.targetTouches[0].pageX; // 获取按下时鼠标初始位置 // pageX是绝对位置 offsetX是相对位置
let p_bar_Len = p_bar.offsetWidth; // 获取进度条的初始Width
p_bar_bg_Len = p_bar_bg.offsetWidth; // 获取进度条总长Width,不知道为什么,第一次获取的值不对,这里还得再更新一次
document.ontouchmove = function (e) { // 拖动需要写到down里面
let diff = x - e.targetTouches[0].pageX; // 获取移动的距离
mousemove_flag = 0;
p_bar_Len_New = p_bar_Len - diff; // 计算当前进度条的Width
if (p_bar_Len_New < 0) { // 当超出进度条范围,控制
p_bar_Len_New = 0;
} else if (p_bar_Len_New > p_bar_bg_Len) {
p_bar_Len_New = p_bar_bg_Len;
}
p_bar.style.width = p_bar_Len_New + "px"; // 更改进度条Width
let all_Time = document.querySelector("meting-js").aplayer.audio.duration;
let current_time = (p_bar_Len_New / p_bar_bg_Len) * all_Time;
document.getElementById("progress-low-btn").innerHTML = secToTime(current_time);
}
});

// 按键抬起
document.onmouseup = function () { //当鼠标弹起的时候,不做任何操作
v_bar_bg.style.height = "0.4rem";
v_bar.style.backgroundColor = "var(--font-color)";
v_low.style.color = "var(--font-color)";
v_high.style.color = "var(--font-color)";
p_bar_bg.style.height = "0.4rem";
p_bar.style.backgroundColor = "var(--font-color)";
p_low.style.color = "var(--font-color)";
p_high.style.color = "var(--font-color)";
if (ctrl_flag == 0 && mousemove_flag == 0) {
let all_Time = document.querySelector("meting-js").aplayer.audio.duration;
let new_Time = (p_bar_Len_New / p_bar_bg_Len) * all_Time;
document.querySelector("meting-js").aplayer.seek(new_Time); //更改进度
}
global_music_flag = 0;
ctrl_flag = 1;
mousemove_flag = 1;
document.onmousemove = null;
};

// 触摸抬起
document.ontouchend = function () {
v_bar_bg.style.height = "0.4rem";
v_bar.style.backgroundColor = "var(--font-color)";
v_low.style.color = "var(--font-color)";
v_high.style.color = "var(--font-color)";
p_bar_bg.style.height = "0.4rem";
p_bar.style.backgroundColor = "var(--font-color)";
p_low.style.color = "var(--font-color)";
p_high.style.color = "var(--font-color)";
if (ctrl_flag == 0 && mousemove_flag == 0) {
let all_Time = document.querySelector("meting-js").aplayer.audio.duration;
let new_Time = (p_bar_Len_New / p_bar_bg_Len) * all_Time;
document.querySelector("meting-js").aplayer.seek(new_Time); //更改进度
}
global_music_flag = 0;
ctrl_flag = 1;
mousemove_flag = 1;
document.ontouchmove = null;
};

// runtime
var global_music_flag = 0;
var meting_load = 1;
var listener = 0;
var old_music_id = null;
var now_music_id = null;
var newSongsheetLen = 0;
var t_load;

// 设置重复执行函数,周期100ms
setInterval(() => {
if (document.querySelector("meting-js").aplayer != undefined) meting_load = 0;
if (meting_load == 0 && listener == 0) {
// 监测aplayer加载完开始注入音乐列表
ctrl.importMusicList();
// 音乐开始与暂停监听
var ap = document.querySelector("meting-js").aplayer;
ap.on('play', function () {
ctrl.getMusicInfo();
document.querySelector("#music-Switch i").classList.remove("fa-play");// 更新播放/暂停键
document.querySelector("#music-Switch i").classList.add("fa-pause");
document.querySelector("#music-ctrl-btn-center i").classList.remove("fa-play");
document.querySelector("#music-ctrl-btn-center i").classList.add("fa-pause");
old_music_id = now_music_id;// 更新列表标志
now_music_id = ap.list.index;
var ids = document.querySelectorAll("#console-music-list .list-music-id");
var states = document.querySelectorAll("#console-music-list .list-music-state");
for (var i = 0; i < ids.length; i++) {
if (parseInt(ids[i].innerHTML) == now_music_id + 1) {
if (old_music_id != null) {
ids[old_music_id].classList.remove("hide");
states[old_music_id].classList.remove("show");
ids[old_music_id].parentElement.parentElement.style.backgroundColor = "";
}
ids[now_music_id].classList.add("hide");
states[now_music_id].classList.add("show");
ids[now_music_id].parentElement.parentElement.style.backgroundColor = "var(--vercel-hover-bg)";
}
}
});
ap.on('pause', function () {
document.querySelector("#music-Switch i").classList.remove("fa-pause");
document.querySelector("#music-Switch i").classList.add("fa-play");
document.querySelector("#music-ctrl-btn-center i").classList.remove("fa-pause");
document.querySelector("#music-ctrl-btn-center i").classList.add("fa-play");
});
// 播放模式按钮监听(循环 / 随机)
var play_mode = document.getElementById("music-ctrl-btn-first");
var ap_play_mode = document.querySelector(".aplayer-icon.aplayer-icon-order");
var loop_str = '<path d="M0.622 18.334h19.54v7.55l11.052-9.412-11.052-9.413v7.549h-19.54v3.725z"></path>';
var random_str = '<path d="M22.667 4l7 6-7 6 7 6-7 6v-4h-3.653l-3.76-3.76 2.827-2.827 2.587 2.587h2v-8h-2l-12 12h-6v-4h4.347l12-12h3.653v-4zM2.667 8h6l3.76 3.76-2.827 2.827-2.587-2.587h-4.347v-4z"></path>';
play_mode.addEventListener("click", function (e) {
var ap_play_mode_str = document.querySelector(".aplayer-icon.aplayer-icon-order svg path").outerHTML;
if (ap_play_mode_str == loop_str) {
play_mode.querySelector("i").classList.remove("fa-repeat");
play_mode.querySelector("i").classList.add("fa-shuffle");
ap_play_mode.click();
} else if (ap_play_mode_str == random_str) {
play_mode.querySelector("i").classList.remove("fa-shuffle");
play_mode.querySelector("i").classList.add("fa-repeat");
ap_play_mode.click();
} else alert("程序错误,请刷新!");
});
ap_play_mode.addEventListener("click", function (e) {
var ap_play_mode_str = ap_play_mode.querySelector("svg path").outerHTML;
if (ap_play_mode_str == loop_str) {
play_mode.querySelector("i").classList.remove("fa-shuffle");
play_mode.querySelector("i").classList.add("fa-repeat");
console.log("进入顺序播放模式");
} else if (ap_play_mode_str == random_str) {
play_mode.querySelector("i").classList.remove("fa-repeat");
play_mode.querySelector("i").classList.add("fa-shuffle");
console.log("进入随机播放模式");
} else alert("程序错误,请刷新!");
});
// 歌单切换监听
ap.on("listclear", function(){
document.getElementById("console-music-list").innerHTML = "";
});
ap.on("listadd", function(){
var current_len = ap.list.audios.length;
t_load = setInterval(() => {
current_len = ap.list.audios.length;
if (current_len < newSongsheetLen) {
console.log("current_len: " + current_len);
} else {
console.log("开始导入")
ctrl.importMusicList();
global_music_flag = 1;
console.log("导入完毕")
clearInterval(t_load);
document.getElementById("console-loading-icon").classList.remove("show");
ctrl.consoleBackBtn();
}
}, 50);
});
listener = 1;
};
//音乐进度更新
if (meting_load == 0 && global_music_flag == 0) ctrl.refreshProgress();
}, 100);

whenDOMReady(); // 打开网站先执行一次
document.addEventListener("pjax:complete", whenDOMReady); // pjax加载完成(切换页面)后再执行一次

其它

参考文档:Aplayer官方文档
原生audio文档

控制中心

控制中心部分可以查看Hexo+Butterfly博客搭建记录(3)

mPlayer2

  1. 原吸底 Aplayer 若想隐藏可自行添加 CSS
  2. 原来坐下角 APlayer 的位置我放了一个 mPlayer2,是dodododooo大佬做的,不仅UI精美,而且功能特别强大,支持 QQ 音乐、网易云、酷狗三大平台在线搜索歌曲,还有收藏功能。
    教程超级简单,直接看他的仓库吧。
    仓库地址
    效果如下:

幻音坊

叶椰子大佬做的,模仿 QQ 音乐界面风格,颜值拉满!!!直接吹爆好吧!!!!!!!!!!!!!!!!!(原谅我这颜控 >_< )

本来打算直接在原音乐页面上改的,但我不是一图流风格,得慢慢调才行。突然看到Heo大佬也复刻了一个,而且还是独立的域名,顿时又感觉自己太傻了(脑子真的瓦特了>_<)。于是乎,直接 fork 了 Heo 的 github 仓库,托管到 vercel,到 cloudflare 给它配个二级域名,一套下来两三分钟搞定!

叶椰子教程地址
Heo仓库地址
效果如下:

更新

新增歌单列表

  1. 增加了歌单列表,支持歌单切换。
  2. 页面切换添加过渡效果。
  3. 效果图: