dsh-plugin-netease-lyrics
yardonyan/dsh-plugin-netease-lyrics
Windows-only stealth lyrics readout: reads the desktop Netease Cloud Music client through Windows SMTC (song, artist, play state), fetches its LRC and translation from the public Netease API, and renders the currently sung line directly beside the DSH activity line ("深度求索中,用时 X s") with font, size and color cloned from that line via computed style, so it reads as one longer sentence. The stopwatch-based progress freezes on pause and resets on track change; lyrics hide entirely when no activity line exists; an anchorText config retargets non-Chinese hosts; 1.0.5+ fails over between two Netease search endpoints when rate-limited. Needs the Netease "SMTC" toggle enabled.
インストール
dsh plugin --profile web add github:yardonyan/dsh-plugin-netease-lyricsREADME
dsh-plugin-netease-lyrics
DeepSeek Harness(DSH)摸鱼歌词插件:桌面网易云音乐在放什么,DSH 输入框上方的「深度求索中,用时 X 秒 …」状态行右边就同步浮现当前那句歌词——同字体、同字号、同颜色,看起来只是那句话有点长。
灵感:工作时要听歌,但把网易云切出来看歌词太张扬。不如让歌词藏进 DSH 自己的状态行里。
目前只支持 Windows 10 / 11 宿主加桌面版网易云音乐。 其他系统与其他音乐平台的适配,欢迎一起做:有想法先到 Discussions 说,准备动手前看 CONTRIBUTING.md。
快速开始
三个前提,缺一条就跑不起来:
| 前提 | 说明 |
|---|---|
| DSH,Windows 10 / 11 宿主 | dsh 要在 PATH 上,终端里敲 dsh -V 有版本号返回 |
| 桌面版网易云音乐 | 设置 → 常规 → 系统 → 勾选「开启SMTC」。不开的话系统层面读不到播放状态,插件拿不到任何数据 |
| pnpm | dsh plugin 自己不装包,它把参数转发给 pnpm 执行。找不到 pnpm 时会以 dsh: pnpm was not found 退出 |
第一步:装插件
一条命令,不用克隆仓库:
dsh plugin --profile web add github:YardonYan/dsh-plugin-netease-lyrics
这条命令做两件事:把仓库当 npm 包装进 web profile 的依赖,并在同一份 package.json 的 dsh.profile.bundles 里登记。装完重启 dsh web(Host 进程要在启动时加载新插件),再刷新页面。
第二步:确认真的装上了
dsh --profile web --dump-config
输出里应当出现这样一段:
# == dsh-plugin-netease-lyrics
- id: netease-lyrics
name: dsh-plugin-netease-lyrics
config: {}
没有这一段就是没装上。 这点必须单独确认:add 返回 0 不代表装对了,包名或路径指错时 pnpm 可能装进一个空壳依赖然后正常退出。
第三步:让它转起来
打开桌面网易云放一首歌,在 DSH 里随便发一条消息。状态行出现时,歌词就贴在它右边。
让 AI 替你装
DSH 会话里的 AI 能执行终端命令的话,把下面整段贴进去。这段提示词的关键在于装完必须自证,不靠「命令没报错」下结论:
帮我装一个 DSH 插件,装完自己验证一遍,不要改代码绕过问题。
仓库:https://github.com/YardonYan/dsh-plugin-netease-lyrics
按顺序做三步,每步的原始输出都留着:
1. 装:dsh plugin --profile web add github:YardonYan/dsh-plugin-netease-lyrics
2. 验:dsh --profile web --dump-config
输出里应有 id: netease-lyrics 那一段,把它原文贴给我
3. 报:命令退出码、dump-config 里有没有 netease-lyrics、pnpm -v 的结果
任何一步失败,把完整报错原文贴给我,不要换安装方式硬试,也不要改插件代码。
最后提醒我两件事:重启 dsh web 并刷新页面;去网易云「设置 → 常规 → 系统」勾上「开启SMTC」。
为什么非要写第二步:dsh plugin add 把参数转发给 pnpm,而 pnpm 遇到「目录里没有 package.json」不一定报错,可能装成一个空壳依赖再正常退出。所以判断装没装对,看的是配置树里有没有这个条目。
如果你的 DSH 会话没有执行命令的权限,直接手动把第一步、第二步的命令复制到 PowerShell 里跑一遍即可。
想改代码:本地克隆方式
要调试或改插件本身,克隆下来装成本地链接:
$dir = "$env:USERPROFILE\dsh-plugins\dsh-plugin-netease-lyrics"
git clone https://github.com/YardonYan/dsh-plugin-netease-lyrics.git $dir
dsh plugin --profile web add $dir
本地目录会被 pnpm 记成 link: 依赖,克隆目录就是插件的实体:删了、挪了、换盘符了,插件立刻失效。别放临时目录或下载目录。
改完源码不用重装:index.js 改动后重启 dsh web,只改 client.js 刷新页面即可。
更新:一次提示词,不用重新下载
这个插件需要跟着宿主与网易云的更新走。 DSH 改 UI、网易云改客户端,都可能让某个版本的插件部分失灵——本仓库的修复记录全是这类跟进(定位方式、限流对策、激活防护,见 CHANGELOG.md)。所以强烈建议用上面的"本地克隆方式"安装:克隆目录就是插件实体,更新 = 拉取增量,不用每次整套重下。
装好之后,把下面这段存好。插件哪天失灵了,把它整段发给 DSH 会话,AI 会自动完成"拉新版 → 判断是否需要重启 → 告诉你结论":
我装的 DSH 插件 dsh-plugin-netease-lyrics 最近可能因为 DSH 或网易云音乐更新而失灵了。
插件装在本地克隆目录里(默认 %USERPROFILE%\dsh-plugins\dsh-plugin-netease-lyrics,
如果你知道实际路径就直接用它)。
请按顺序做,每步原始输出都留着:
1. 进该目录执行 git pull --ff-only,把最新代码拉下来;告诉我更新到了哪个版本
(看 package.json 的 version 字段)。
2. 对照仓库 CHANGELOG.md 里比我旧版本新的条目,判断这次更新改了什么:
- 只改了 client.js → 告诉我刷新浏览器页面即可;
- 改了 index.js 或 smtc-worker.ps1 → 提醒我重启 dsh web;
- 改了安装清单(package.json / cordis.patch.yml)→ 重新执行
dsh plugin --profile web add <克隆路径> 再重启。
3. 如果 git pull 冲突或失败,把报错原文贴给我,不要强行 reset。
拉完之后提醒我:对照 README 的"前置开关"和"排障速查"过一遍,再让 AI 转一轮
验证歌词是否恢复;还没恢复就把 F12 控制台里 [netease-lyrics] 开头的告警贴出来。
为什么不用 zip 下载安装:zip 是整套快照,每次更新都得手动重下重装;clone 安装的更新只是网络增量,且上面的提示词能全自动完成。两种方式的取舍已经写进安装一节。
网络受限环境:git pull 走 GitHub 可能遇到 SSL 握手抖动,重试一两次通常就过;代理用户给 git 配上代理端口即可(例如 git config --global http.proxy http://127.0.0.1:7897)。
使用
- 打开桌面网易云放一首歌
- 在 DSH 里随便发一条消息让 AI 转起来
- 「深度求索中」状态行右边会出现同样式的歌词,跟着演唱进度换行
- 鼠标悬停歌词可看完整句和翻译(如果有);浮层不拦截点击,下方控件照常可用
歌词语言不用挑——中文、英文、韩文、日文都能出,只要这首歌在网易云有词。插件按歌曲搜索拿原始 LRC,原文是什么语言就显示什么语言,带官方翻译的歌还会在悬停时给翻译。
效果预览
DSH 里的样子——歌词贴在「深度求索中」右边,一模一样的橙色小字:


此时网易云里正在放的歌(对应上面两张图):


非中文歌同样直接上——韩文歌词和中文混排,样式完全一致:

不仔细看,只会觉得这句状态话有点长——只有你知道那是歌词。
工作原理
桌面网易云音乐 ──播放──▶ Windows SMTC 系统媒体接口(歌名 / 歌手 / 播放状态)
│
▼
插件 Host 端(DSH 宿主进程内)
├─ 常驻 PowerShell worker 每秒读一次 SMTC
├─ Host 秒表推算播放进度*(见"已知限制")
└─ 拉取网易云歌词 API(LRC + 翻译,7 天缓存)
│ 同源 HTTP 路由 /plugin/netease-lyrics/*
▼
Client 端(浏览器 bundle)
└─ 每秒轮询,把当前歌词行以 fixed 定位
贴在「深度求索中」状态行右侧,
computed style 现场克隆其字体字号颜色
* 网易云 PC 客户端没有通过 SMTC 上报播放位置,所以插件自己跑秒表:切歌归零、暂停停表、恢复续走。这个判断的依据与复测方法见 docs/playback-position.md。
当前支持范围
目前只验证了 Windows 加网易云音乐这一种组合,其他组合都还没做:
| 维度 | 已支持 | 尚未支持 |
|---|---|---|
| 宿主系统 | Windows 10 / 11 | macOS、Linux |
| 音乐客户端 | 桌面版网易云音乐 | QQ 音乐、酷狗、Spotify、Apple Music 等 |
这不是改个配置就能切的事,而是实现层面的绑定:
- 播放状态来自 Windows 的系统媒体传输控件(SMTC),属于 Windows 独占接口。macOS 要另找系统级正在播放接口,Linux 走 MPRIS(D-Bus),取数方式与 Windows 完全不同
- 歌词检索走网易云的公开接口,换音乐平台就得另接歌词源,还要按对方的曲目 ID 体系重写匹配逻辑
- 播放状态与歌词源必须成对替换,只换一边跑不起来
配置
在 profile 的 cordis.patch.yml 顶层数组里追加一条按 id 命中的补丁。不要写成 insert,那会新增一行插件,而不是改这一行:
- id: netease-lyrics
config:
anchorText: "深度求索中,用时" # 换成你的宿主状态行文案(英文界面等)
同目录下的其他插件都用这个形式,宿主按 id 找到已加载的那一行并合并 config。改完这条配置会作为第二个参数传进插件的 apply,1.0.2 起只认这条通道,不再去上下文里取。
关于 anchorText 的三点:
- 只认这一个键,值的用途是在页面里定位宿主状态行,不是替换歌词内容
- 未配置、配置成非字符串或空字符串时,回退到内置默认值
深度求索中,用时 - 客户端在加载时读取该值,改完要刷新页面;改动
index.js才需要重启dsh web
文案本身要选状态行里稳定出现的一小段。太短容易误匹配聊天正文,太长在状态行拆分文本节点时会匹配不到。
更新与卸载
# 更新到仓库最新提交
dsh plugin --profile web update dsh-plugin-netease-lyrics
# 卸载
dsh plugin --profile web remove dsh-plugin-netease-lyrics
两条都要重启 dsh web 生效。想确认当前实际在用哪个版本:
dsh plugin --profile web why dsh-plugin-netease-lyrics
改动记录见 CHANGELOG.md,逐版说明在 Releases。上面的 更新:一次提示词 一节有一条 AI 全自动更新提示词,适合插件失灵时直接整段发给 DSH 会话。
必读:注意事项与已知限制
前置开关(不开就一定用不了)
网易云桌面版必须打开 「开启SMTC」 开关,否则 Windows 系统层面根本看不到网易云在放什么,插件拿不到任何数据:
网易云音乐 → 设置 → 常规 → 系统 → 勾选「开启SMTC」(开启后播放信息同步到系统菜单栏及壁纸等第三方软件),勾完切一次歌生效。

这个开关也是排查「歌词不显示」的第一检查项。
已知限制
| 限制 | 原因 | 缓解办法 |
|---|---|---|
| 歌词不显示的第一排查项 | 网易云没开「开启SMTC」开关(设置 → 常规 → 系统) | 勾选后切一次歌生效,见上方截图 |
| 拖动网易云进度条后歌词漂移 | SMTC 不上报 seek,秒表感知不到 | 换一首歌再换回来,即重新对齐 |
| 单曲循环时秒表会走出歌尾 | 秒表不知道歌曲总长 | 同上 |
| 仅适配中文界面 | 锚点匹配「深度求索中,用时」文案 | 在插件配置里改 anchorText(见上) |
| AI 空闲时歌词不显示 | 设计行为:状态行不在 = 歌词隐藏(隐蔽优先) | 想常显需自行改 client.js 的 stealth 判断 |
| 仅本机访问 | 路由只响应 loopback + Origin 校验 | 这是安全特性,不开放外露 |
| 歌词取不到 | 两种原因:曲目在网易云没有版权(例如周杰伦的作品整库不在),或搜索命中的候选曲目本身没有歌词 | 无版权时插件无能为力;候选无歌词时当前只试第一条、不会继续试后面的候选 |
| 歌词长时间(小时级)空白 | 网易云公开搜索接口的 IP 限流(响应 code: 405 操作频繁),窗口实测可达一小时以上 | 1.0.5 起自动处理,无需操作:插件会切换到限流计数独立的备用搜索端点,歌词最坏延迟到下一首换歌时。旧版本(≤1.0.4)遇到限流会把空结果缓存一周,请升级 |
上表里与进度有关的两条(拖动进度条后漂移、单曲循环走出歌尾)是同一个成因:网易云不通过 SMTC 上报播放位置,插件只能自己跑秒表推。这个缺口的成因、四条可选路径(系统时间轴 / UI Automation / 登录态 API / 音频指纹)与改动草案写在 docs/playback-position.md。
排障速查
先分清是装的问题,还是跑的问题。--dump-config 里有 netease-lyrics 条目,说明装好了,剩下的都属运行侧。
安装阶段
| 现象 | 原因与处理 |
|---|---|
dsh: pnpm was not found | dsh plugin 依赖 PATH 上的 pnpm。装 pnpm(npm i -g pnpm 或 corepack enable pnpm)后重跑 |
命令成功,但 --dump-config 里没有 netease-lyrics | 包名或路径指错。用 dsh plugin --profile web why dsh-plugin-netease-lyrics 看实际装进去的是什么,是空壳就 remove 掉重装 |
| 下载卡住或超时 | 走的是 codeload.github.com,网络受限时会很慢。确认能访问后重试,或改用上面的本地克隆方式 |
dsh 不是可用的命令 | dsh 没进 PATH。检查 Node 的全局 bin 目录,或用 npx @deepseek-ai/dsh ... 调用 |
运行阶段
歌词完全不出现?
- 网易云在放吗?→ 放着才有效
- 网易云「开启SMTC」开关开了吗?→ 设置 → 常规 → 系统(见"前置开关"截图)
- AI 在转吗(「深度求索中」行存在)?→ 空闲时按设计隐藏
- 浏览器 F12 控制台有没有
[netease-lyrics]警告?→ worker 挂了会在这里提示 - 歌在放、前面都对,还是没有?→ 去网页版网易云搜同一首歌,确认它是否被收录、有没有歌词。整库没有版权的歌手(例如周杰伦)插件取不到,这不是插件能解决的
歌词突然卡住不走? 网易云被暂停又恢复过、或拖动过进度条 → 切一首歌再切回来。
颜色/位置不对? 歌词样式是从状态行现场克隆的,若 DSH 更新改了状态行实现,重新刷新页面即可。
隐私与安全
- 插件不读取网易云账号、Cookie 或任何客户端数据,只读 Windows 系统媒体会话的公开快照(歌名 / 歌手 / 状态)
- 歌词经
music.163.com公开接口按歌名搜索,无需登录 - HTTP 路由仅接受本机回环地址,带 Origin 校验,防 DNS rebinding
目录结构
dsh-plugin-netease-lyrics/
├── package.json # 插件清单(dsh.bundle.patch + dsh.client)
├── cordis.patch.yml # Loader 补丁
├── index.js # Host 端:SMTC worker 监管 + 歌词代理路由
├── client.js # 浏览器端:锚点定位 + 歌词渲染 + 悬停浮层
├── smtc-worker.ps1 # Windows SMTC 探测 worker(ASCII-only,PS 5.1 兼容)
├── scripts/
│ └── smtc-probe.ps1 # 单独验证 SMTC 能否读到网易云会话与时间轴
├── test/
│ └── apply-guard.test.mjs # 客户端挂载回归测试(npm test)
├── docs/ # 效果截图与方案文档
├── locale/ # 展示名称与描述(en / zh)
├── .github/ # Issue 与 Pull Request 模板
├── CONTRIBUTING.md # 贡献流程、代码约定与提交规范
├── SECURITY.md # 安全问题报告方式与关注范围
├── CHANGELOG.md # 版本变更记录
└── icon.svg # 插件图标
一起共创
仓库已经开源,缺陷、适配、新功能都欢迎直接提。还没想清方案的,先到 Discussions 聊,定了再写代码也不迟。
最值得做的两件事:
- 适配其他系统:把
smtc-worker.ps1换成对应系统的取数方式,宿主端与浏览器端基本不用动 - 适配其他音乐平台:
smtc-worker.ps1目前按*cloudmusic*过滤会话,放开匹配就能拿到别的播放器,剩下要补的是歌词源
换歌词源、修歌词匹配、调界面细节、补截图与文档同样欢迎,流程与代码约定见 CONTRIBUTING.md。
提交前自检
环境准备、本地生效方式、代码约定与提交规范见 CONTRIBUTING.md。只想先跑一遍语法自检:
npm run check
提缺陷时请附上系统媒体控件开关状态,以及控制台里 [netease-lyrics] 开头的告警原文,缺这两项多数问题无法定位。安全问题按 SECURITY.md 走私密报告,不要开公开 issue。
致谢
- NeteaseCloudMusicApi 社区 摸清的公开歌词接口参数
- JasonCHTT/dsh-netease-music 的 README 提供了 DSH 插件挂载点参考