这篇文章记录 hexo-generator-music-wall 的开发和使用过程:把网易云歌单渲染成可拖拽的 3D 音乐卡片墙,加入播放控制、桌面歌词、收藏、历史、音频可视化和跨页面悬浮播放器,并尽量把主题兼容逻辑留在插件内部。文中给出可直接使用的安装命令、Hexo 配置和常见问题说明。
Hexo 网易云音乐墙插件:从歌单配置到跨页播放
我一直想给博客加一个不太像传统列表播放器的音乐页面:进入页面后先看到一整面散落的歌曲卡片,可以拖拽、滚轮移动,选中歌曲后卡片会自动来到中间,播放控制和歌词也能跟着歌曲状态变化。
最后把这套功能整理成了一个独立的 Hexo 插件:hexo-generator-music-wall。它不要求修改主题模板,安装后会生成固定的音乐页面,并在其他页面提供一个可收起的悬浮播放器。
- 在线示例:https://hansiy.net/music/
- GitHub 仓库:imHansiy/hexo-generator-music-wall

这个插件实现了什么
当前版本主要包含这些功能:
- 把网易云音乐歌单渲染成可拖拽的 3D 卡片墙。
- 支持播放、暂停、上一首、下一首、进度拖动和音量控制。
- 支持顺序播放、单曲循环、随机播放和单次播放。
- 提供收藏、最近播放、歌词和多种音频可视化效果。
- 点击卡片可以打开大卡片,显示封面、歌曲信息和动态歌词。
- 离开音乐页后显示悬浮播放器,收起时是带圆形进度的封面,悬浮后展开控制器。
- 通过插件自己的站内导航保持同一个音频实例,普通页面切换时音乐不会中断。
- 样式限制在插件容器中,尽量避免覆盖 Hexo 主题已有组件。
页面刷新后会默认选中歌单第一首,但不会自动播放。这样既能让首屏有明确焦点,也不会触发浏览器的自动播放限制。底部控制器和歌词会等到用户第一次点击播放后再出现。
安装插件
进入 Hexo 博客目录,安装 GitHub 仓库版本:
npm install github:imHansiy/hexo-generator-music-wall |
如果后续已经发布到 npm,也可以直接使用包名:
npm install hexo-generator-music-wall |
插件要求 Hexo 6 或更高版本,不需要在主题目录中复制页面模板。
配置网易云歌单
在 Hexo 根目录的 _config.yml 中加入:
music_wall: |
其中:
path:生成页面的路径,默认访问/music/。playlist_id:网易云音乐歌单 ID。fallback:歌单接口不可用时是否显示占位卡片,避免页面完全空白。quality:渲染质量,默认是high;只有显式设置为fast、lite、low或performance时才启用轻量模式。
也可以填写完整歌单链接:
music_wall: |
完成配置后重新生成:
hexo clean |
然后打开:
http://127.0.0.1:4000/music/ |
配置 API 回退节点
网易云官方没有面向普通网页开放完整的歌单播放接口,所以插件在浏览器端使用社区 Meting API 读取歌单和音频地址。为了降低单个节点失效带来的影响,可以配置多个节点:
music_wall: |
歌单请求失败时会按顺序切换节点。播放单曲时,插件也会根据网易云资源 ID 尝试重建备用音频地址。
需要注意,公开节点并不由本插件或网易云音乐运营,随时可能出现跨域限制、限流或音频地址失效。正式部署时,最好把自己可控的 Meting 服务放在数组第一项。
添加到博客导航
插件只负责生成页面,不会强制修改主题菜单。大部分主题可以在自己的导航配置中加入:
menu: |
如果不想在顶部增加菜单,也可以从首页组件、文章链接或悬浮播放器进入音乐墙。这样主题原本的导航结构不会被插件接管。
跨页面播放是怎么实现的
普通的 Hexo 页面切换本质上是一次完整导航。浏览器会销毁旧页面里的 <audio>,因此仅靠 localStorage 只能记住歌曲和进度,无法让声音真正连续。
插件在 auto 模式下只接管和音乐相关、或者已经存在播放状态的同源链接:
当前页面 |
配置项如下:
music_wall: |
三种模式的区别:
auto:默认模式,只在需要保持播放时接管站内导航。plugin:所有同源站内链接都由插件处理,适合没有 PJAX 的简单主题。native:完全交给主题自己的导航系统处理。
浏览器地址栏直接输入新 URL、手动刷新或打开新标签页时,页面运行环境仍然会被销毁。这种情况只能恢复歌曲、进度和暂停状态,不能做到物理意义上的无缝续播。
主题兼容处理
音乐墙不是独立的全屏站点,而是嵌入 Hexo 原有页面结构中,所以顶部导航仍然属于主题。插件会自动识别常见主内容容器,例如:
#l_main |
如果主题结构经过深度修改,可以手动指定:
music_wall: |
目前实际回归过 Hexo 默认 Landscape 和 Volantis。Butterfly、NexT、Fluid 使用的常见容器也已经加入自动识别,但主题升级或大幅改造 DOM 后,仍建议重新检查页面宽度、固定导航和 PJAX 行为。
卡片很多时为什么不会全部渲染
最早的实现会把整张歌单的卡片全部放进 DOM,并且每一帧更新模糊、透视、缩放和透明度。歌单越来越长后,Chrome 中很容易出现明显卡顿。
现在音乐墙会根据视口和中心距离只保留一部分可见卡片:
- 桌面端最多渲染约 48 张卡片。
- 移动端最多渲染约 30 张卡片。
- 封面只有进入可见范围后才加载。
- 位置变化集中在
requestAnimationFrame中更新。 - 可视化 Canvas 会限制像素总量和刷新频率。
用户仍然可以拖拽浏览完整歌单,但浏览器不需要同时维护全部图片和玻璃效果。
常见问题
歌单能显示,但某些歌曲无法播放
这通常不是卡片渲染问题,而是第三方 API 没有返回可用音频、歌曲存在版权限制,或者临时音频链接已经失效。可以先切换 API 节点,再检查浏览器网络请求。
刷新后为什么没有自动播放
现代浏览器普遍限制没有用户手势的自动播放。插件只默认选中歌单第一首,等待用户点击播放,这是预期行为。
切换页面后为什么音乐还是停了
先确认 navigation_mode 没有设置为 native。如果主题有自己的 PJAX,还要检查主题是否在导航前主动暂停全局音频。直接刷新或修改地址栏则无法保持同一个音频实例。
页面宽度不正确
优先配置 content_selector 指向主题真正的主内容容器。插件不会删除主题侧边栏,只会尝试让音乐页使用主题允许的全宽布局。
总结
hexo-generator-music-wall 的目标不是替代专业音乐客户端,而是给 Hexo 博客增加一个有探索感、同时不破坏主题导航的音乐页面。
现在只需要安装插件、填写网易云歌单 ID,再把 /music/ 放到合适的入口,就可以得到完整的音乐墙、播放控制、歌词和跨页悬浮播放器。后续我还会继续处理更多主题兼容、公开 API 稳定性和长歌单性能问题。
项目源码和更新记录都在 GitHub: