起因
我的 Hugo 博客使用 Reimu 主题的 APlayer + MetingJS 组件来展示歌单。默认情况下,MetingJS 调用公共 Meting API 解析网易云音乐链接,生成的播放器只能播放 30 秒试听片段——即使是自己上传的歌曲或已购买的专辑。
本文记录了从 30 秒试听到完整播放的全过程。
架构链路
浏览器 (MetingJS)
→ Meting API(解析歌单 / 获取音频流 URL)
→ 网易云音乐 API(携带 Cookie 鉴权)
→ 完整音频文件
核心思路:将网易云的认证 Cookie 注入 Meting API,使其以登录态请求音频链接,从而获取完整版。
第一步:部署自己的 Meting API
公共 Meting API(api.i-meto.com)使用的匿名 Token 只能获取试听片段。需要部署自己的实例并注入个人 Cookie。
我 Fork 了社区维护的 Meting-API(Node.js 版),首先部署到 Vercel:
- 仓库自带
vercel.json,导入即可部署 - 默认域名形如
xxx.vercel.app - 在 Vercel 面板设置环境变量
NETEASE_COOKIE
网易云 Cookie 的获取方式:登录网页版 → F12 → Network → 任意请求的 Cookie 请求头。
部署后通过 /api?server=netease&type=playlist&id=歌单ID 即可获取歌单数据。
第二步:解决国内访问
Vercel 的默认域名在国内 DNS 污染严重。尝试了两个方案:
Cloudflare Worker 代理:将请求转发到 Vercel,并对响应 JSON 做域名重写,确保所有子请求也走代理。但 workers.dev 域名在国内同样不稳定。
Deno Deploy:项目原生支持 Deno(有 deno.js 入口),deno.dev 域名在国内可达。切换后需要改造环境变量读取——原代码用 process.env,Deno 用 Deno.env.get(),写了一个 getEnv() 工具函数统一两套运行时。
// src/util.js
export const getEnv = (key) => {
if (globalThis?.process?.env?.[key]) return globalThis.process.env[key]
if (globalThis?.Deno?.env?.get(key)) return globalThis.Deno.env.get(key)
return null
}
同时精简了依赖树。原 package.json 中有 @esbuild-plugins/node-globals-polyfill 等包,其传递依赖 core-js 的 postinstall 脚本在 Deno Deploy 构建环境会失败(Deno 的 node 别名不支持 -e 参数)。删除这些仅用于 Cloudflare Workers 构建的 polyfill 后部署成功。
第三步:Cookie 过期告警
网易云 Cookie 通常 2-4 周过期。为免博客歌单悄无声息地退回 30 秒,加了自动化健康检查:
- 定时检查:用
Deno.cron()每天 UTC 1:00(北京时间 9:00)执行 - 健康逻辑:用已保存的 Cookie 请求测试歌曲的音频 URL,判断返回的是完整版还是试听版
- 邮件通知:Cookie 失效时通过 Resend API 发邮件告警
Deno.cron('cookie-health-check', '0 1 * * *', async () => {
const result = await runHealthCheck('netease')
console.log(`[Cron] Cookie status: ${result.status}`)
})
第四步:自动化部署
博客源码推送到私有仓库 blog,构建产物(public/)推送到公开仓库 hinanawiteriko.github.io(GitHub Pages)。配置了 GitHub Actions 工作流,每次 push 源码自动 build Hugo 并部署:
- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
external_repository: HinanawiTeriko/hinanawiteriko.github.io
deploy_key: ${{ secrets.DEPLOY_KEY }}
publish_dir: ./public
总结
整个过程涉及的技术栈和解决的问题:
| 环节 | 技术 | 解决的问题 |
|---|---|---|
| 音频解析 | Meting API + 网易云 Cookie | 30 秒 → 完整版 |
| 网络可达 | Deno Deploy | 国内直连 |
| 运行时适配 | getEnv() 工具函数 | Node.js / Deno 双运行时 |
| 依赖精简 | 删除 polyfill 包 | Deno Deploy 构建失败 |
| 过期告警 | Deno.cron + Resend | Cookie 失效自动通知 |
| 部署自动化 | GitHub Actions | push 源码即部署 |
完整代码见 GitHub。

