Folia QQ音乐音源接入教程MQTT长连线扫码背后的完整原理【免费下载链接】folia-major专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器项目地址: https://gitcode.com/GitHub_Trending/fo/folia-majorFolia 是一款专注全屏歌词动画的在线音乐播放器内置 QQ音乐、网易云、酷狗与 Navidrome 音源。本文带你快速接入 Folia QQ 音乐音源并讲清楚一个有趣的问题为什么 QQ 扫码登录必须靠一条 MQTT 长连线才能守住二维码接入 QQ 音乐后能获得什么连接 QQ 音乐账号后Folia 不只是能搜索播放——它会同步你的账号数据能力说明在线搜索与播放搜索歌曲、歌手、专辑自动加载封面与歌词账号歌单拉取你的 QQ 音乐歌单并直接播放我喜欢 / 收藏专辑同步我喜欢列表与收藏专辑全屏歌词动画播放时驱动 Folia 的沉浸式歌词渲染前端登录、轮询二维码、发现可用通道的完整链路收拢在 Omni 在线音乐层入口是 src/services/onlineMusic/omni.tsQQ 音源的适配器在 src/services/onlineMusic/qqProvider.ts。快速开始3 个配置项搞定接入桌面版用户直接打开就能用。Electron 主进程会在本地拉起 QQ 音乐 API 服务见 electron/qqApiStartup.cjs登录态存在系统安全存储里无需任何配置。Web 版用户Vercel / Cloudflare只需要两个变量VITE_QQ_API_BASE/api/qq QQ_SESSION_SECRET一段至少 32 字节的随机密钥VITE_QQ_API_BASE指向仓库内置的 serverless 入口worker/qq.ts / api-ts/qq.tsQQ_SESSION_SECRET用于加密封装登录态千万不要加VITE_前缀——加了就会被编进前端资源Docker 用户则完全免配置deploy/docker/compose.yaml 已内置qq-api服务docker compose up -d即可详见 deploy/docker/qq-api/README.md。两种扫码方式为什么有的平台只支持微信Folia 提供微信扫码与QQ 扫码两种方式不同部署形态的支持范围并不一样部署方式微信扫码QQ 扫码Electron 桌面版 / Docker / 裸 Node✅✅Cloudflare Durable Object✅✅Vercel / Cloudflare默认✅❌⚠️ Vercel 缺少 QQ 扫码不是配置错误而是平台能力限制QQ 扫码需要在二维码有效期内持续保持一条 MQTT WebSocket 长连线而 Vercel 没有可跨请求持有这条连接的运行时原语见 docs/qq-music-deployment.md。打开登录弹窗时前端会先请求/login/channels做能力发现后端如实声明当前运行时支持哪些通道界面自动显示对应选项——不需要改任何前端代码。核心原理QQ 扫码为什么非 MQTT 长连线不可这是全文最关键的部分。QQ 扫码走的是MQTT over WebSocket协议登录流程大致是后端向上游发起设备注册与二维码创建拿到qrcodeID和二维码图后端用qrcodeID建立 MQTT 连接并订阅该二维码的事件你用 QQ 扫码后上游通过这条连接推送scanned已扫码、cookies换取凭证的令牌等事件前端每隔约 2 秒轮询一次事件拿到cookies后完成凭证交换难点在于这条连接守不住就全盘皆输CONNECT 请求的是 clean session订阅是 unicast——断连期间上游既不保留也不补送如果两次轮询之间连接断了重新连上时scanned、cookies事件已经错过而cookies里装的正是换凭证的令牌漏掉就是死局这就是源码注释里那句必须有个能跨调用活着的东西握住这条连接的由来worker/qqQrChannel.ts。Cloudflare 的解法用 Durable Object 托管这条长连线在 Serverless 平台上一次 HTTP 请求结束连接就没了而 Cloudflare 的Durable Object恰好能跨调用存活。Folia 用它实现了QqQrChannel类worker/qqQrChannel.ts设计上有几个值得学习的细节① 订阅必须先于二维码显示open要等到 MQTT 订阅确认SUBACK才返回。否则显示后、订阅前这一小段时间里被扫事件不会补送worker/qqQrChannel.ts。② 三重保险保证连接一定关得掉出向 WebSocket 期间 Durable Object 不能休眠按在线时间计费。所以open幂等同一二维码只开一条 socket、前端关闭弹窗时显式调用/close释放、再用alarm兜底——即使前两个都失效二维码到期时连接也会被强制释放worker/qqQrChannel.ts。③ Durable Object 里不存任何凭证它只搬运登录阶段的暂态qrcodeID、二维码图、已收到的 MQTT 事件。真正的凭证交换留在请求侧完成登录态封在加密 token 里。想要启用这条通道只需在wrangler.jsonc中加上QQ_QR_CHANNEL绑定绑定名和类名必须精确匹配再重新部署/login/channels就会从[wechat]变成[qq,wechat]。登录态与设备身份两个容易被忽视的细节Sealed Token加密封装令牌Serverless 形态下服务端不保存任何凭证登录态由QQ_SESSION_SECRET加密后封进 token由客户端携带。这意味着密钥丢失或轮换时所有用户需要重新扫码——Folia 提供了QQ_SESSION_SECRET_PREVIOUS变量做旧令牌过渡验证避免全员掉线。稳定的设备身份QQ 扫码协议要求 QIMEI 引导和后续调用跑在同一个装置身份上所以设备标识需要跨进程重启保留Docker 里挂在qq-api-state具名卷上。该文件只存设备识别值不含任何账号凭证。一句话排错表现象优先检查页面显示Login Error/api/qq/login/channels是否返回 JSON 而不是 HTML 页面返回501QQ_SESSION_SECRET未设置或设置后未重新部署Vercel 只有微信扫码正常行为非故障Cloudflare 只有微信检查QQ_QR_CHANNEL绑定与 migration修改VITE_QQ_API_BASE后仍请求旧地址该变量构建时写入必须重新构建部署扫码后上游返回20279先在 QQ 音乐账号中清理旧登录设备再重新扫码写在最后Folia 接入 QQ 音乐音源桌面端开箱即用Web 端则是一次很好的用 Serverless 承载长连线的工程案例MQTT 的 clean session unicast 语义决定了长连线一刻不能松而 Durable Object 恰好是 Cloudflare 上唯一能替你在两次请求之间握着这条线的原语。理解了open 幂等 close 显式释放 alarm 兜底这套组合拳你基本也就读懂了这类扫码登录的实现精髓。完整的环境变量说明与部署步骤建议对照 docs/qq-music-deployment.md 和 Omni 层架构说明 src/services/onlineMusic/README.md 一起阅读。【免费下载链接】folia-major专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考