在使用 Hexo 搭建博客时,我们常常使用 Aplayer + MetingJS 来插入背景音乐。然而,由于版权保护和反爬策略,公共的 Meting API 往往无法解析 VIP 歌曲,导致博客上的歌单经常变灰或无法播放。
今天我终于解决了这个问题,通过自建本地 Meting API 并配合 NeteaseCloudMusicApi 和 内网穿透 ,完美实现了 VIP 歌曲的播放。
这里复盘一下这次 Debug 的过程,并整理成教程指导后人。
可以看见这里的播放时长只有45s,这其实就是网易云会员音乐的试播时长
问题复盘 Aplayer 配合 MetingJS 的工作原理是:前端网页向 Meting API 发送请求(如 GET /api?server=netease&type=url&id=xxx),API 返回歌曲的真实 MP3 链接。
公共 API 失效的原因通常有两点:
IP 限制 :API 服务器的 IP 被网易云拉黑。
Cookie 缺失 :没有 VIP 账号的 Cookie,无法调用获取 VIP 歌曲链接的接口。
解决方案非常直观:自己跑一个 API 。并在 API 请求中带上自己的 VIP Cookie,然后让 Hexo 博客去请求这个私有 API。
解决方案 我的方案架构如下:
本地后端 :在本地运行一个 Node.js 服务,使用 NeteaseCloudMusicApi 库转发请求。
内网穿透 :通过 FRP 或 Cloudflare Tunnel 将本地服务暴露到公网(如 api.wenmozhu.de5.net)。
前端配置 :修改 Hexo 的 _config.yml,将 meting_api 指向我们自己的域名。
第一步:编写后端代码 在博客根目录下创建一个 local-meting 文件夹,这就是我们的 API 服务端。
1. 初始化项目并安装依赖
1 2 3 cd local-metingnpm init -y npm install express cors NeteaseCloudMusicApi dotenv
2. 编写 app.js
这是核心代码,负责处理请求并注入 VIP Cookie。
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 const express = require ('express' );require ('dotenv' ).config (); const { song_url, lyric, playlist_track_all, song_detail, playlist_detail } = require ('NeteaseCloudMusicApi' );const cors = require ('cors' );const app = express ();const port = 3000 ;const MY_COOKIE = process.env .METING_COOKIE || '' ; app.use (cors ()); const createMetingResponse = (req, list ) => { const { headers } = req; const host = headers.host ; const baseUrl = `https://${host} /` ; return list.map (item => { return { title : item.name , author : item.ar ? item.ar .map (a => a.name ).join ('/' ) : 'Unknown' , url : `${baseUrl} ?server=netease&type=url&id=${item.id} ` , pic : `${baseUrl} ?server=netease&type=pic&id=${item.id} ` , lrc : `${baseUrl} ?server=netease&type=lrc&id=${item.id} ` }; }); }; const handleRequest = async (req, res ) => { const { server, type, id } = req.query ; if (server !== 'netease' ) return res.json ({ error : 'Only netease is supported locally' }); try { const commonConfig = { cookie : MY_COOKIE , realIP : '116.25.146.177' }; if (type === 'playlist' ) { const data = await playlist_detail ({ id, ...commonConfig }); const list = data.body .playlist .tracks || []; return res.json (createMetingResponse (req, list)); } if (type === 'url' ) { const data = await song_url ({ id, ...commonConfig }); if (data.body .data && data.body .data [0 ].url ) { return res.redirect (data.body .data [0 ].url ); } else { return res.status (404 ).send ('Not found' ); } } } catch (err) { console .error (err); res.status (500 ).json ({ error : err.message }); } }; app.get ('/' , handleRequest); app.get ('/api' , handleRequest); app.listen (port, () => { console .log (`Local Meting API running at http://localhost:${port} ` ); });
第二步:配置环境变量与安全措施 为了保护你的 Cookie 不被泄露(尤其是如果你打算将代码提交到 GitHub),我们需要将敏感信息放入 .env 文件。
1. 创建 .env 文件
在 local-meting 目录下创建 .env:
1 METING_COOKIE="你的完整网易云 Cookie"
2. 配置 .gitignore
在博客根目录的 .gitignore 中加入以下内容,防止敏感文件被上传:
1 2 3 # Meting API Security local-meting/node_modules/ local-meting/.env
第三步:配置内网穿透 这里我使用的是 Cloudflare Tunnel(或者 FRP),将本地的 localhost:3000 映射到了公网域名 https://api.wenmozhu.de5.net。
这一步保证了无论访客在何处访问博客,都能通过这个公网域名请求到我本地运行的 API。
第三步:修改 Hexo 配置 打开站点配置文件 _config.yml,找到 aplayer 配置项,启用自定义 API:
1 2 3 4 5 6 aplayer: meting: true meting_api: 'https://api.wenmozhu.de5.net/api?server=:server&type=:type&id=:id&r=:r' asset_inject: false
第四步:静默启动脚本 为了方便,我写了一个 VBS 脚本 start_meting_hidden.vbs,可以后台静默启动 API 服务,看不到黑框框:
1 2 3 Set WshShell = CreateObject ("WScript.Shell" ) WshShell.Run "cmd /c cd local-meting && node app.js" , 0 Set WshShell = Nothing
将该脚本放入启动文件夹或每次开机运行即可。
效果展示 配置完成后,重新部署 Hexo (hexo clean && hexo g && hexo d)。
现在打开博客,原本灰色的 VIP 歌曲已经可以流畅播放了!因为请求实际上是经过你的本地服务,带着你的 VIP Cookie 去向网易云要数据的。
注意 :
1.请妥善保管你的cookie!不要上传到github等网站!
2.这样处理主要是因为我的vps在海外,网易云把我的地址屏蔽了,如果你有一个在国内的vps,那么完全可以在上面跑。
3.只要你有cookie,替换掉app.js的cookie即可使用