前言

在博客中嵌入音乐播放器可以让访客在阅读时享受音乐。本文将介绍如何利用 Butterfly 主题内置的 APlayer + MetingJS 支持,接入网易云音乐和QQ音乐的个人歌单,并通过自定义样式实现平台专属配色和优雅的卡片布局。


一、技术方案

使用 Butterfly 主题内置的 APlayer + MetingJS 支持(无需额外安装播放器包),配合 hexo-tag-aplayer 插件提供 {% meting %} 标签语法:

  • APlayer:HTML5 音乐播放器 UI
  • MetingJS:客户端 JS 库,从音乐平台 API 拉取歌单元数据并渲染为 APlayer 播放器
  • hexo-tag-aplayer:Hexo 标签插件,提供 {% meting %} 标签语法,解决 <meting-js> 被 Markdown 渲染器过滤的问题

支持的平台:网易云音乐(netease)、QQ音乐(tencent)、酷狗(kugou)等。


二、安装与配置

2.1 安装插件

1
npm install hexo-tag-aplayer --save

2.2 站点配置

_config.yml 中添加:

1
2
3
4
5
6
7
aplayer:
meting: true
asset_inject: false
cdn:
aplayer_css: https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css
aplayer_js: https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js
meting_js: https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js

asset_inject: false 表示不使用插件自带的资源注入,由 Butterfly 主题负责加载 APlayer/MetingJS 的 CSS 和 JS。

2.3 主题配置

_config.butterfly.yml 中启用 APlayer 注入:

1
2
3
aplayerInject:
enable: true
per_page: false

per_page: false 表示仅在 front-matter 包含 aplayer: true 的页面加载播放器资源。


三、页面结构

在音乐页面的 front-matter 中添加 aplayer: true,然后使用 {% meting %} 标签嵌入歌单:

1
2
3
4
5
---
title: 音乐
type: "music"
aplayer: true
---

3.1 Meting 标签语法

1
{% meting "歌单ID" "平台" "类型" "选项:值" ... %}

参数说明:

参数 说明
第1个 歌单/歌曲 ID 数字
第2个 平台 netease / tencent / kugou
第3个 类型 playlist / song / album
后续 可选项 theme:#颜色 listfolded listmaxheight:340px mutex:true preload:none

3.2 完整示例

1
2
3
4
5
6
7
<div class="music-playlist-item music-source-tencent">
<div class="music-card-header">
<span class="music-card-platform"><i class="fab fa-qq"></i> QQ音乐</span>
<h3 class="music-playlist-title">歌单名称</h3>
</div>
{% meting "123456" "tencent" "playlist" "theme:#11b458" "listfolded" "listmax-height:340px" "mutex:true" "preload:none" %}
</div>

关键选项

  • mutex:true:同时只允许一个播放器播放
  • preload:none:不预加载音频,避免页面加载时因 VIP 歌曲失败而自动跳转
  • listfolded:默认折叠歌曲列表

四、平台专属配色

通过为不同平台添加不同的 CSS 类,实现视觉区分:

4.1 HTML 结构

QQ音乐卡片使用 music-source-tencent,网易云卡片使用 music-source-netease

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- QQ音乐 - 绿色系 -->
<div class="music-playlist-item music-source-tencent">
<div class="music-card-header">
<span class="music-card-platform"><i class="fab fa-qq"></i> QQ音乐</span>
<h3 class="music-playlist-title">歌单名</h3>
</div>
{% meting "..." "tencent" "playlist" ... %}
</div>

<!-- 网易云 - 红色系 -->
<div class="music-playlist-item music-source-netease">
<div class="music-card-header">
<span class="music-card-platform"><i class="fas fa-cloud"></i> 网易云</span>
<h3 class="music-playlist-title">歌单名</h3>
</div>
{% meting "..." "netease" "playlist" ... %}
</div>

4.2 CSS 配色方案

QQ音乐(绿色系)

  • 背景:淡绿渐变 #e8f9ee → 白色
  • 顶部条:绿色渐变 #11b458#34d058
  • 平台徽章:绿色背景 + 深绿文字
  • 悬浮阴影:绿色调

网易云(红色系)

  • 背景:淡红渐变 #fdf0f0 → 白色
  • 顶部条:红色渐变 #c20c0c#e84040
  • 平台徽章:红色背景 + 深红文字
  • 悬浮阴影:红色调

暗色模式下,背景切换为对应的深色调,文字和徽章使用明亮的对应色。


五、播放错误处理

VIP 歌曲在未登录状态下无法播放,MetingJS 会自动跳到下一首。通过自定义 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
// source/js/music-player.js
(function () {
function showToast(msg) {
// 创建 toast 提示元素
}

function bindPlayers() {
document.querySelectorAll('.aplayer').forEach(function (el) {
if (el.aplayer && !el._errorBound) {
el._errorBound = true;
var ap = el.aplayer;
var userInitiated = false;

// 监听用户点击播放按钮或歌曲列表
el.addEventListener('pointerdown', function (e) {
if (
e.target.closest('.aplayer-icon-play') ||
e.target.closest('.aplayer-list li')
) {
userInitiated = true;
}
});

ap.on('error', function () {
if (userInitiated) {
showToast('播放失败,自动跳转下一首');
}
userInitiated = false;
});
}
});
}

// MetingJS 异步加载播放器,需监听 DOM 变化
var observer = new MutationObserver(bindPlayers);
observer.observe(document.body, { childList: true, subtree: true });
})();

_config.butterfly.yml 中注入该脚本:

1
2
3
inject:
bottom:
- <script src="/js/music-player.js"></script>

六、获取歌单 ID

网易云音乐

  1. 打开网页版网易云音乐,进入歌单页面
  2. URL 格式:https://music.163.com/#/playlist?id=123456
  3. 数字 123456 即为歌单 ID

QQ音乐

  1. 打开网页版 QQ音乐,进入歌单页面
  2. URL 格式:https://y.qq.com/n/yqq/playlist/123456.html
  3. 数字 123456 即为歌单 ID

注意:歌单需设为公开,否则无法获取数据。


七、常见问题

7.1 播放器不显示

  • 确认 front-matter 中有 aplayer: true
  • 确认 _config.butterfly.ymlaplayerInject.enable: true
  • 执行 npx hexo clean 清理缓存

7.2 歌曲播放失败

  • VIP 歌曲在未登录状态下无法播放,属于正常现象
  • MetingJS 会自动跳到下一首可播放的歌曲
  • 本方案通过自定义 JS 在用户主动播放失败时弹出 toast 提示

7.3 页面加载时自动跳转

  • {% meting %} 标签中添加 preload:none 选项
  • 这会阻止页面加载时预加载音频,避免初始化时的自动跳转

总结

通过 Butterfly 主题内置的 APlayer + MetingJS 支持,配合 hexo-tag-aplayer 插件,可以轻松实现:

  1. 多平台歌单接入:网易云、QQ音乐等平台的歌单/单曲/专辑
  2. 平台专属配色:QQ音乐绿色系、网易云红色系,视觉上一目了然
  3. 播放错误处理:VIP 歌曲播放失败时弹出 toast 提示并自动跳转
  4. 预加载控制preload:none 避免页面加载时的自动跳转问题

参考资料