DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-cloudmusic-player

j

dsh-cloudmusic-player

Manifest valid★ 1

DSH 悬浮播放器:联动本机网易云音乐客户端,调音量 / 切歌 / 滚动歌词(含译文),适配 Web / CLI / 桌面版

UI (client)hasBundlePatch
dsh-cloudmusic-player

dsh-cloudmusic-player

DSH 里的一块悬浮小播放器,联动你本机的网易云音乐客户端。

切歌 · 播放暂停 · 拖音量 · 跟着滚的歌词(外语歌带中文译文)

License: MIT Node DSH Windows

悬浮播放器

它是什么

一块浮在 DSH 界面右下角的小卡片。点开是一个迷你播放器,控制的是你本来就开着的那个网易云客户端——不是另起一个播放器,不下载、不登录、不建歌单。

能做什么说明
换歌 / 播放暂停上一首、下一首、播放暂停
音量APP 只改网易云自己的音量(不动别的程序,也不动系统总音量);SYS 改系统总音量。两路各自独立读数
滚动歌词当前行居中高亮、上下淡出;进度连续插值,不是两秒跳一格
外语歌译文原文下面多一行小字中文,来自网易云自己的翻译
拖动 / 收起拖到任意位置,位置记在 localStorage;可收成一个只有歌名的小胶囊
给模型用装好后模型多一个 cloudmusic_player 工具,可以替你暂停、切歌、调音量、读歌词
深色 / 浅色跟着 DSH 主题走,对比度按 WCAG AA 调过

它做不到:不能拖动进度条(APP/native 车道没有 seek 通道)、不能搜索歌曲、不能改播放列表。

进度从哪来

网易云 3.x 在 Windows 10 上不注册系统媒体会话(cloudmusic.dll 里能直接看到 [SMTCWrapper] Failed to set play status ret=),但会把自己的播放事件写进 %LOCALAPPDATA%\NetEase\CloudMusic\cloudmusic.elog。插件解码这个日志并回放状态机,拿到曲目、songId、时长、精确到毫秒的播放位置、暂停/继续、seek。

冷启动解码 8.9 MB / 3 万行只要 14 ms,之后每 400 ms 只读新增的尾巴。不读也不落盘日志里的 musicurl(带签名的播放地址),不需要登录、不碰 cookie。

客户端如果真的注册了 SMTC,就优先走 SMTC(那里还能 seek)。两条都不通就如实说「没在放歌」——绝不接管别的程序的会话(早期版本在这里踩过坑:按暂停暂停的是浏览器里的视频)。


装

# Web / CLI
dsh plugin --profile web add dsh-cloudmusic-player
# dsh 桌面版(dsh-desktop)
dsh plugin --profile desktop add dsh-cloudmusic-player
node scripts/enable-desktop.mjs      # 把包接进桌面 profile(幂等)

然后重开 DSH。右下角出现小胶囊,点 ⌃ 展开。

从源码装 / 本地开发
git clone https://github.com/jx70/dsh-cloudmusic-player.git
cd dsh-cloudmusic-player
npm install
dsh plugin --profile web add link:"$PWD"     # Windows 上把 $PWD 换成绝对路径 D:/...

开发态和安装态不一样,值得记住:

源码在哪改代码之后
本地开发(link:)你的工作目录,profile 里只是个 junction 指过来重载插件就生效
dsh plugin add(发行版)复制进 ~/.dsh/profiles/<profile>/node_modules/要重新 add 一次新版本

装好后 DSH 的 profile 里只有两行相关的东西:package.json 的 "dsh-cloudmusic-player": "link:…",和 dsh.profile.bundles 里的包名。DSH 本体目录里没有副本。

在 dsh 桌面版里为什么多一步

桌面版不是另一份代码——是另一个 profile(--profile desktop)+ Electron 壳 + WebContentsView 加载同一个 Web UI,所以悬浮框、歌词、音量、模型工具全都原样可用,client.js 一行都没为桌面版改过。

要多一步是因为桌面版每次启动都会重写 profiles/desktop/package.json 和它的 patch 层(prepareDesktopProfile() 里是无条件覆盖),手改活不过一次启动。所以 scripts/enable-desktop.mjs 做两件事:建 junction 到包目录;往 ~/.dsh/cordis.patch.yml(home patch 层,桌面版不覆盖)追加一段带 !!js 条件的 insert —— 只在当前 profile 里出现 @dsh-desktop/client 时启用,免得 web profile 里也插一份、两边抢同一批路由。

node scripts/enable-desktop.mjs --check    # 只看状态
node scripts/enable-desktop.mjs --remove   # 卸载

另一个原因是宿主版本:桌面版捆绑的 dsh 是 0.1.0-rc.6,那代没有 connection.fetch,所以插件内置三条传输车道自动挑(fetch → webserver → none)。/health 的 transport 字段会告诉你走的哪条。

要求

系统Windows 10 1809 以上
PowerShell5.1(powershell.exe)。PowerShell 7 没有 WinRT 投影,播放控制会不可用
客户端网易云音乐桌面版(注册不注册 SMTC 都能用)
DSH≥ 0.1.0-rc.6,Node ≥ 22。Web / CLI / 桌面版都行

macOS / Linux 上插件照样能装:悬浮框和歌词都在,只是播放控制与音量会显示「本机不支持」(后端是插拔式的,见 docs/DESIGN.md)。


用

  • 拖动:按住卡片顶部空白处(或收起态的胶囊)拖到任意位置。
  • 收起:右上角 ⌃ → 变成只有歌名的小胶囊,再点 ⌃ 展开。
  • 音量:拖滑块,松手后 110 ms 内的连续拖动会合并成一次请求。APP / SYS 切换作用域,滑块与百分比始终显示当前作用域那一路。
  • 歌词:有 songId 时直取(最准),否则按「歌名 + 歌手 + 时长」搜索。作词/作曲/编曲/制作人 这类署名行照常显示(更淡)但不参与高亮——否则歌前那十几秒高亮会钉在「制作人」上不动,看着像卡死。
  • 外语歌译文:网易云的 tlyric 与 lrc 同格式,按时间戳逐行叠起来(精确相等直接配,少量不齐用 ≤60 ms 最近邻,宁缺不错)。中文歌的 tlyric 本来就是空的,所以不用判语种。关掉:lyricsTranslation: false。
  • 不能拖进度:native 车道的控制是模拟客户端全局热键,没有「跳到某处」的键,所以进度条只展示。SMTC 车道能 seek。
  • 歌词对不上时:点歌词里当前那一句,就把那行的 LRC 时间戳当作「现在播到这里」(兜底路径,只在日志读不到时出现;锚点按歌记 30 分钟)。

配置

~/.dsh/profiles/<profile>/cordis.patch.yml 里覆盖:

- insert:
    - id: cloudmusic-player
      name: dsh-cloudmusic-player
      config:
        processName: cloudmusic          # 进程名,不含 .exe
        aumidPattern: 'cloudmusic|netease|wangyi'
        volumeScope: process             # process | system
        lyricsEnabled: true
        lyricsTranslation: true          # 外语歌叠中文译文
        lyricsOffsetMs: 0                # 歌词整体提前/推后(毫秒)
        powershellPath: powershell.exe   # 别填 pwsh.exe
        hotkeyPlayPause: 'Ctrl+Alt+P'    # 要和客户端「设置 → 快捷键」里一致
        hotkeyNext: 'Ctrl+Alt+Right'
        hotkeyPrev: 'Ctrl+Alt+Left'
        elogEnabled: true                # 读客户端日志拿真进度
        elogPath: ''                     # 留空 = 自动找
        elogPollMs: 400

其余(lyricsApiBase / requestTimeoutMs / restartLimit)见 docs/DESIGN.md。

标了 .volatile() 的几项(volumeScope / lyricsEnabled / lyricsTranslation / lyricsOffsetMs / requestTimeoutMs / restartLimit / elogEnabled / elogPollMs)改完即时生效,不用重载。


排错

先看自检端点,它是唯一权威:

http://127.0.0.1:3080/api/cloudmusic-player/health?deep=1

(桌面版换成它的随机端口。)

现象先看什么
显示「没在放歌」网易云真在放吗?pids 空 = processName 不对
按暂停暂停的是别的程序不该发生了。看 media[].aumid 是不是被写进了 aumidPattern
切歌没反应hotkeyNext / hotkeyPrev 和客户端的全局快捷键不一致
进度条不出现elog.available: false → 看 elog.reason(missing / no-track-yet / client-exited)
显示「后台没响应」点重试;还不行看 stderr 字段,或 transport 是不是 none
音量拖了没反应pids 空(没匹配到进程);或 SYS 作用域下系统端点被独占
外语歌没有小字译文lyricsTranslation 是不是关了;中文歌本来没有;也可能这首就没翻译
桌面版里报错node scripts/enable-desktop.mjs --check,跑完记得重启 dsh-desktop

完整排错表(含 403、webserver: duplicate exact route、!!js 求值等)在 docs/DESIGN.md。


已知限制

  1. 不登录、不搜索、不建歌单——只控制「已经在放的那首」。
  2. native 车道不能拖 seek,canSeek 恒为 false(SMTC 车道可以)。
  3. 进度依赖客户端日志。日志读不到(旧版客户端 / 被关 / 路径不同)时降级为「本地计时 + 点歌词校准」——那时起点是猜的(滞后量 = 打开前已播的时长)。
  4. 播放暂停是切换键。为防「按暂停反而开始播」,发键前先看 2.6 秒内的意图缓存,没有才采 ~150 ms 峰值判定。极静的段落仍可能误判。
  5. 只有 Windows 有真实后端,且必须 PowerShell 5.1。
  6. 歌词与译文都来自网易云的 web 接口(非公开),可能限流或改字段;译文翻错、翻得少是数据源的事,插件不补译。

完整的 20 条(含版权曲目匹配、日志编码版本依赖、旧世代宿主鉴权水位等)在 docs/DESIGN.md。


开发

npm test                      # 72 条:日志解码 26 + 歌词 25 + 传输层 21
node --test test/elog.test.mjs   # 单个文件(目录形式会 Cannot find module)
npm run enable-desktop        # = node scripts/enable-desktop.mjs
npm run sync                  # 推 GitHub

测试不碰系统、不需要开着网易云:解码器与状态机用合成日志,歌词用打桩的 fetch,传输层用假的 connection / webServer。

index.js             Host 半端:Config / 6 条路由 / 模型工具
client.js            Client 半端:shell.overlay 槽里的悬浮框
lib/player.mjs       助手进程生命周期 + 三车道合并
lib/helper.ps1       常驻 PowerShell(WinRT / Core Audio / 窗口标题 / 热键)
lib/elog.mjs         cloudmusic.elog 解码 + 状态机回放
lib/lyrics.mjs       搜索匹配 / LRC 解析 / 译文叠加
lib/cache.mjs        歌词磁盘缓存(30 天)
lib/transport.mjs    三条传输车道 + Fetch↔Node 适配
lib/backend.mjs      平台后端注册表
docs/DESIGN.md       实现层的完整说明

想改实现先读 docs/DESIGN.md——那里记着 GetSimpleAudioVolume 的第二个参数不是 pid、SetMute 的 bool 必须显式封送、为什么传输层要三条车道这些坑,能省你半天。


License

MIT

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 24.1k

CC0-1.0

Python

Nov 10, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.3k

CC0-1.0

Python

Nov 6, 2026

Index only — not installable

by woniuniuniu

DeepSeek Harness 自媒体工作台插件:一句话记灵感,一键生成脚本、封面、配图和分镜

Development & InfrastructureManifest valid

★ 771

↓ 3.7k/wk

MIT

JavaScript

Nov 8, 2026

dsh plugin --profile web add dsh-media-desk

by uumit-ai

Open dsh web from your phone or another computer through a UUMit account, without running your own server or installing another program: a built-in tunnel client connects to UUMit's hosted tunnel, and

Tools & CapabilitiesDevelopment & InfrastructureTerminal & ClientsManifest valid

★ 521

↓ 268/wk

MIT

JavaScript

Oct 21, 2026

dsh plugin --profile web add @uumit-ai/dsh-uumit-remote

by Yuuyuko-uu

DSH 鱼的记忆:给会话一份会淡忘的长期记忆,每条都带时间

Development & InfrastructureMemory & ContextSessions & MessagesManifest valid

★ 508

MIT

JavaScript

Nov 9, 2026

dsh plugin --profile web add dsh-fish-memory

by SAOS-3624

Scene-aware storyboard for DeepSeek Harness: 9-16 numbered cells with timestamps + transcript + an audio envelope, packed into ONE image (384 tokens). Two tools: video_storyboard and video_zoom.

Tools & CapabilitiesVision & MultimodalDevelopment & InfrastructureManifest valid

★ 499

↓ 17k/wk

MIT

JavaScript

Nov 10, 2026

dsh plugin --profile web add dsh-video-storyboard